diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index 8542a94628..d2c44aec56 100644 --- a/README.md +++ b/README.md @@ -1,410 +1,239 @@
-# codeaf - -**Talk through the work, change the files, and hand off tasks you can walk away from.** - -*One terminal session gives a model tools, memory, background work, and a manual about itself.* - -Go 1.26.5 darwin, linux, windows - -

Install • Chat • Tools • Tasks • Models • Manual • Headless • Remote • Contributing • Docs

+CodeAF, the open-source software factory. Direct the work from your terminal, servers or phone. Built for open models: DeepSeek, Qwen, GLM, Kimi, MiniMax, Ollama and more. + +
+ +Apache 2.0 +release +stars +Discord +early preview +one binary, darwin linux windows + +

+Install · +One window · +What a factory is · +Subharnesses · +Benchmarks · +Headless · +Guide +

-Run `codeaf` inside a project. It opens the conversation that directory was last -having. Ask in ordinary language; the model can read and edit files, run commands, -search the web, remember useful context, and bring separate tasks back when they land. - -This is the chat flow in a real terminal: - -```text - codeaf $0.0010 / $500 · sun 7:32pm - Home [key lookup] × + -──────────────────────────────────────────────────────────────────────────────────────────────────── - · esc interrupts · ctrl+c quits · ? for help - - › read ./apikey.go and tell me in two lines where codeaf looks for an API key - - ▾ worked 3.2s · thought 0.6s · 1 tool call · ctrl+e - ▸ read apikey.go 1 call - - In Load's order (from `apiKeyFrom`/`APIKeyAt`): `$OPENROUTER_API_KEY`, then - `$OPENAI_API_KEY`, then the `api_key` field in the profile config file written with - `WriteAPIKey`. First non-empty wins. - - · ⟲ 14.1k cached · saved $0.0005 - · 19:31 · 3.2s · 1 tool call · $0.0008 · ❮ -─ where codeaf finds its a… · ~deepseek/deepseek-v4-flash-latest ─── space space home · / commands ─ - › - $0.0008 · ⟲ saved $0.0005 · 45% cached 15.6k/1.3M · 1% idle -``` +**Frontier-grade coding on open models, at a fraction of the cost.** -That is a real session on the default model, `~deepseek/deepseek-v4-flash-latest`: -one question, one `read`, one answer, and what it cost on the last line. +CodeAF is a coding harness built for open models, to get the most out of every +dollar. It is also a different way to work once more than one thing is going on: +instead of three terminals of agents with you in the middle, one window where you +hand work off, see what is moving across every project, and step in only where +your judgment is needed. A factory, on your own machine, and the more you hand it +the more it does. -### Which folder it works in +Written in Go as one small binary, with nothing else to install or run. Apache +2.0. By [AgentField AI](https://agentfield.ai?utm_source=github-readme&utm_campaign=codeaf-readme&utm_id=codeaf-readme-byline). -"Inside a project" is decided at launch, in this order -(`cmd/codeaf/chatv3_layout.go:84`): `--workspace ` if you gave one, else the root -of the git repository you are standing in, else the directory itself. The exception is -a directory nobody chose — your home directory, or anything under a temporary directory -— where codeaf keeps a folder of its own and says so on the welcome screen: +> **Early preview.** CodeAF is young and moving fast. Expect rough edges, and tell +> us where you hit them on [Discord](https://discord.gg/aBHaXMkpqh) or in an [issue](https://github.com/Agent-Field/codeaf/issues). -```text -in a folder codeaf keeps for this conversation · /workspace picks another -``` +From one chat to a factory: a chat, the tasks it fanned out into (14 chats, 35 subtasks), home showing every project on the machine, and a question waiting on your answer -Your files are not in that folder, so asking it to read one gets you an empty -directory. `/workspace ` anchors a conversation to a project at any point; the -shorter road is to start codeaf inside the project. +https://github.com/user-attachments/assets/bc87e460-17b1-4d7a-8c69-284b524ea194 -Once this machine has conversations on it, bare `codeaf` opens **home** rather than a -conversation — projects, running work, questions waiting on you, what you have spent. -Type into the box to start one, or press enter on a row to reopen one. `space space` -goes to home from a conversation and `esc` comes back untouched. +Real speed, with sound. The three tasks run live on DeepSeek V4.1 Flash; the other projects and the large task tree are a seeded demo machine. ## Install -### Build from the repository - -The source road needs nothing published. The module needs Go 1.26.5, and `make -build` is the one supported build command; it writes `bin/codeaf`. - -```bash -git clone https://github.com/Agent-Field/codeaf.git # while the repository is private, this needs access -cd codeaf -make build # fetches the pinned Furrow artifact, so it needs the network; - # FURROW_ARTIFACT=/path/to/furrow supplies it offline -bin/codeaf -``` - -### The installer, and what it is waiting on - ```bash -curl -fsSL https://raw.githubusercontent.com/Agent-Field/codeaf/main/scripts/install.sh | bash # works once public and on main -curl -fsSL https://agentfield.ai/get/codeaf | bash # supported once it serves -``` - -While the repository is private, the raw GitHub address answers 404 to anyone not signed -in; once it is public and `scripts/install.sh` is on `main`, that road works. The proxied -address is not serving yet and will be the supported form once it serves. - -
-Installer channels, flags, and checks - -A push to `dev` publishes a `dev-*` build, a push to `staging` publishes a `staging-*` -build, and a push to `main` publishes an rc; all three are marked as prereleases. Stable -exists only when a person dispatches `Release` on `main`. A channel with nothing -published stops with `no build has been published yet`, and because `--stable` -is the default and reads GitHub's `releases/latest`, which excludes prereleases, the bare -curl line says `no stable build has been published yet` until that stable dispatch lands. - -```bash -curl -fsSL https://raw.githubusercontent.com/Agent-Field/codeaf/main/scripts/install.sh | bash -s -- --dev -curl -fsSL https://raw.githubusercontent.com/Agent-Field/codeaf/main/scripts/install.sh | VERSION= bash -curl -fsSL https://agentfield.ai/get/codeaf/dev | bash # once the proxy serves, /dev, /staging and /rc pick a channel -curl -fsSL https://agentfield.ai/get/codeaf | VERSION= bash +curl -fsSL https://agentfield.ai/get/codeaf | bash +codeaf ``` -| Installer input | Behaviour | -| --- | --- | -| `--stable` | Select the latest stable release; this is the default. | -| `--dev` | Select the latest `dev-*` release. | -| `--rc`, `--staging` | Select a matching channel build or stop if none has been published. | -| `--version TAG` or `VERSION=` | Pin one release tag. | -| `--dir PATH` | Install somewhere other than `~/.codeaf/bin`. | -| `--no-modify-path` | Print the PATH line without editing a shell file. | -| `--verbose` | Print each GET. | -| `GITHUB_TOKEN` or `GH_TOKEN` | Raise GitHub's anonymous API limit. | - -The script needs `curl` or `wget`, plus `sha256sum` or `shasum`. It downloads -`checksums.txt` and refuses a sha256 mismatch. Every release also carries -`THIRD-PARTY-NOTICES.md` beside its binaries, covered by that same -`checksums.txt`. Unless `--no-modify-path` is set, it -appends one `export PATH=… # codeaf installer` line to the applicable shell file. Its -last action is `codeaf version`. Release builds cover darwin, linux, and windows on -amd64 and arm64. - -
- -## Talk to codeaf - -Bare `codeaf` and `codeaf chat` open the same conversation surface. `codeaf resume` -opens a picker for an earlier conversation. +The script puts the release binary for your platform in `~/.codeaf/bin`. To +build it yourself: `git clone`, `make build`, `bin/codeaf` +([guide](docs/GUIDE.md#install)). Release assets, checksums and version +pinning are on the [releases page](https://github.com/Agent-Field/codeaf/releases). -```bash -codeaf -codeaf chat --model -codeaf chat --once "summarize the changes" # print one reply and exit -codeaf resume -``` +On first start it asks for a key: OpenRouter, DeepSeek, GLM, Kimi, MiniMax or +Qwen. Ollama needs none. -`enter` sends a message or steers a running answer. `ctrl+enter` makes a standing -order. `esc` interrupts or, pressed twice at rest, opens rewind. `ctrl+c` interrupts -mid-turn and quits at rest, on the press that lands. +## One window for every project -
-Chat launch flags and terminal keys +An agent that lives in one folder means a terminal per repository, and a tmux +layout to remember which is which. CodeAF is one window. -| Flag | Meaning | -| --- | --- | -| `--model ` | Choose the model for this session. | -| `--once "text"` | Run one message non-interactively, print the reply, and exit. | -| `--session ` | Resume the transcript at that path. | -| `--yolo` | Run tools without asking; the approval default becomes allow. | -| `--reasoning auto\|low\|medium\|high\|xhigh\|max` | Override reasoning for the session. | -| `--no-compact` | Never compact automatically. | -| `--one-model` | Put every text call on the session model. | -| `--host`, `--at`, `--no-host` | Choose where the session runs and how this surface attaches. | -| `--debug` | Keep the full run record. | -| `--max-hours`, `--max-cost` | Bound an unattended `--yolo` session. | - -| Key | Action | -| --- | --- | -| `ctrl+o` | Expand the selected call or task instruction. | -| `ctrl+.` | Open task history. | -| `space space` | Open home from an empty message box. | -| `alt+1` … `alt+7` | Select one of the seven places. | -| `ctrl+,` | Open settings. | -| `ctrl+g` | Send a running command to the background; otherwise close the task column, or bring it back. | +`home` lists every project and conversation on the machine. `enter` opens any +of them in a tab, and the one you left keeps streaming with its tasks still +running. `tab` flips back. `alt+k` jumps to any conversation, open or closed. +Each keeps its own approval rules, models and spend limit. -
+One window, every project: the tasks page listing work from codeaf, pricing-site and infra in one tree, a preview of the selected task with its files, branch, cost and 1 accept or 2 not right, and three projects open as tabs -Once the conversation has begun, a column stands down the right-hand side of a wide -terminal — the tasks and standing orders over this conversation, or, while there are -none, `+ /task` and `+ /standing` with `❯ ctrl+g hide` under them. +`home` answers what needs you, what is unread, what is running and what it +cost, for all of them at once. A digit answers a question from its row. -Slash commands cover models, conversations, work, memory, permissions, and spending. -Start with `/help`. Common doors are `/model`, `/new`, `/resume`, `/workspace`, `/task`, -`/history`, `/standing`, `/memory`, `/remember`, `/permissions`, `/status`, `/cost`, -`/spend`, `/budget`, `/compact`, `/rewind`, `/manual`, `/help`, and `/quit`. `/drafts` -keeps the last ten cleared drafts; `enter` restores one and `d` lets one go. +Home in two columns: needs you, unread, where you were, running and scheduled on the left; projects, spend and since you left on the right -
-Slash-command reference +## Talk, and it becomes tasks -| Command | Registered meaning | -| --- | --- | -| `/model` | `pick a model · or press its name above the message box`; with a slug, `switch the model for the conversation or open task`. | -| `/new` | `start another conversation in this project` | -| `/resume` | `open an earlier conversation` | -| `/workspace ` | `anchor this conversation to a project` | -| `/task ` | `start work you can walk away from` | -| `/history` | `every task this project has run · ctrl+.` | -| `/standing ` | `keep this true · a card, never work done once` | -| `/memory` | `inspect and change what is remembered` | -| `/remember ` | `keep one thing across conversations` | -| `/permissions` | `what runs without asking · drop one with d` | -| `/status` | `everything the status line knows, one fact per line` | -| `/cost` | `what this conversation has spent · /spend is the whole machine` | -| `/spend` | `what this machine has cost, by the day · alt+3` | -| `/budget` | `what codeaf may spend · every limit on one tab` | -| `/compact` | `summarize the conversation now` | -| `/rewind` | `go back to an earlier point · esc esc takes back the last` | -| `/manual` | `codeaf's own manual · every page, one per line` | -| `/help` | `this list` | -| `/quit` | `close this conversation` | -| `/drafts` | `cleared-but-kept drafts · enter restores one, d lets one go` | - -
- -A call that needs permission pauses on a block. Its header counts ten seconds down and -then stops and keeps waiting, rather than answering for you: +Say what is wrong the way you would to a colleague. Name three things in one +message and each can become its own task, in its own copy of the repository, on +its own branch. The conversation stays yours while they run, and the rail beside it +shows every task and its subtasks. ```text -╭─  needs your ok to run bash ─────────────────────────────────────────────────────── bash · 10s ─╮ -│ echo hi · default │ -│ │ -│ ▸ 1 allow once │ -│ 2 always │ -│ 3 deny safe answer │ -│ │ -╰─ ↑↓ choose · enter take it · esc later ──────────────────────────────────────────────────────────╯ - c change · ? ask back · 1–3 jump + › three more while you are on it: the retry test fails one run in five on CI, + the pricing page wraps mid word on phones, and the deploy key expires friday ``` -`↑↓` and `enter` take an answer, the digits jump straight to one, and `esc` leaves it -for later. `c` is `change: say what you want different, then enter`; `?` is -`ask back: type your question, then enter`. The answer leaves a row you can reopen — -`needs your ok to run bash → allow once · you · 20:21 · c change`. A call whose outcome -cannot be taken back drops choice 2, the widening one. `--yolo` makes allow the default, -and the status line then says `YOLO`. +One chat, a tree of tasks: a conversation that handed out four bug fixes, with its task rail beside it showing each task, its subtasks and which ones wait on your call -## Tools in the conversation +Work that passes its check lands on your branch by itself, never on `main`, +`dev` or a release branch. Work nothing could check waits under `unread`: +`1` accept, `2` not right. -The model works through named tools rather than by suggestion. `read`, `write`, -`edit` and `bash` act on the folder this conversation is anchored to; `grep`, `find` -and `ls` look around it; `web_search` and `web_fetch` go out; `remember` keeps something for later; -`propose_task` hands work off. The belt is assembled for each session, and a -capability that cannot work is left off it rather than offered and failing. +Every task is a tree you can open: the tasks page with a task family unfolded, subtasks marked done, your call and incomplete -
-Tool-name reference +## What a factory is -| Work | Exact tool names | -| --- | --- | -| Files and shell | `read`, `write`, `edit`, `bash`, `grep`, `find`, `ls` | -| Documents and jobs | `read_document`, `jobs`, `manual` | -| Interaction and work | `ask`, `watch`, `tasks`, `propose_task`, `quick_task`, `items`, `divide_work`, `stand` | -| Memory and workspace | `remember`, `recall`, `track`, `commit`, `workspace`, `workspace_snapshots`, `workspace_restore`, `workspace_fork`, `workspace_merge`, `search_conversations` | -| Web | `web_search`, `web_fetch` | -| Settings and accounts | `settings`, `change_setting`, `services`, `use_service`, `gmail_search`, `gmail_read`, `gmail_send`, `calendar_list`, `calendar_create`, `slack_search`, `slack_read_thread`, `slack_list_channels`, `slack_send` | -| Media | `generate_image`, `speak`, `generate_music`, `generate_video`, `view_image`, `edit_video`, `load_capability` | +Agents run by hand got fast, but the scheduling, checking and merging stayed +with you. -`remember` needs memory switched on. The four `workspace_*` tools need a folder under -Furrow watch. The five `gmail_*` and `calendar_*` tools arrive only with a connected -Google account and the four `slack_*` only with Slack; `/connect` — `your connected -accounts · connect another` — is the door, and any other keyed account brings one -`_request` instead, plus whatever the service names for itself. -`view_image` needs a vision model. `edit_video` needs its local video binaries. Each -media-generation tool needs both a media client and a resolved model for its modality. +one agent: one line on you, you wait. several agents by hand: ten lines on you, you schedule, merge and check. a factory: one line out, one line back. -
+A factory is the third picture: one line out, one line back. -## Hand work to tasks +- **It does the middle.** It sizes the work, splits it, runs the parts where + they cannot collide, tests what came back and merges what passed. +- **It asks only when it must.** A question waits under `needs you`, from every + project. Everything else it decides, writes down, and carries on. -`propose_task` gives self-contained work to a separate task, returns its id immediately, -and opens a short countdown. Redirect or cancel during the countdown; silence starts it. -Keep talking while the task runs. Its report starts a turn in the conversation when it -lands. +It asks only when it must: a question panel asking which store the spend ledger should sit on, three options, SQLite recommended with the reason -A task page shows the instruction, folded work and calls, steering, the report, and a -pinned line with activity, duration, cost and call count. `/task ` is the direct -door; `/history` opens the project's task history. +## Subharnesses: specialists built for one job -Standing orders use `/standing ` or `ctrl+enter`. They become cards and stay true -after the conversation. Memory keeps person-, project-, or machine-scoped records in -`graph.db`; `/memory`, `/memories`, `/remember` and `/forget` change them. +A general agent does everything a little. The work that matters most comes round +in the same shape: review this pull request, fix this issue, audit these +dependencies. A subharness is a specialist built for exactly that job, with its +own plan, its own checks and the models that suit it. It takes typed input and +returns typed output, so it delivers what it promised or is marked incomplete. +A run is a task like any other, on `home`, with a room and a stop. -## Models, keys, and spending +Work that comes round again goes to a specialist: from home, review PR #412 routes to the pr-af subharness; each subharness takes typed input, runs its own plan and checks, and returns typed output or says incomplete, and the result comes back to home as a task -Key resolution is `OPENROUTER_API_KEY`, then `OPENAI_API_KEY`, then `api_key` in the -profile's `config.json`. With no key, an interactive local launch opens a two-page setup -that offers to connect OpenRouter in a browser or take a pasted key. A non-interactive -chat with no key stops instead, with `codeaf chat needs a model to talk with.` +- **Coming soon, native:** [PR-AF](https://github.com/Agent-Field/pr-af), the #1 + open-source code reviewer on Martian Code-Review-Bench. +- **Coming soon, in the benchmark below:** the developer subharness against + general harnesses on the same open model. +- **Your own:** "make me a harness for triaging flaky tests" designs one, saves + it, and `/subharness` runs it. -
-The two first-run screens, word for word +## Benchmarks -Where a browser is reachable the first page is headed `connect openrouter`: +Coming soon. The run is held-out GitHub issues, several seeds each, through +CodeAF's developer subharness and the general harnesses on the same open model: +pass rate, cost per issue and time per issue, with every failure, timeout and +unpriced call written up in [BENCHMARKS.md](BENCHMARKS.md). The chart and the +table land here when the run completes, and `bench/` runs it on your own +repository. -```text -sign in once in your browser. openrouter makes the default service's key for this profile; codeaf stores it on this machine. no prompt is sent and no model is called. -``` - -Where it is not, the same page is headed `your openrouter key` and reads `codeaf talks -to models on its default service through openrouter, on your key and your card. nothing -is sent until you do.` Either way the foot takes a pasted key and `esc` skips setup. -The second page is `Daily limit`, `Chat model` and `Work crew`. - -
+## The right model for each call -The chat model resolves from `--model`, then saved `model.talk`, then `CODEAF_MODEL`, -then `~deepseek/deepseek-v4-flash-latest`. The last value is a floating alias. Besides -OpenRouter, the connection screen supports DeepSeek, Z.ai, Moonshot, MiniMax, Alibaba -Qwen, Ollama, and a custom OpenAI-compatible service; a qualified slug such as -`qwen/` selects its service. +One session, many models. The model you talk to is one seat. Five more, the +crew, take the calls you did not type: -Provider routing defaults to `simple`: an unpinned OpenRouter call carries no provider -object, while a pinned call asks for exactly that lane. `latency` and `price` remain -opt-in settings. - -The default daily rail is `$500`; setting that row to `0` removes it. First run asks for -`Daily limit`, `Chat model`, and `Work crew`. +| seat | what it answers | +| --- | --- | +| reflex | memory, titles, the safety gate. Near free, reads every turn. | +| small work | digests, task names, yes-or-no checks | +| worker | every task you hand off. Most of the bill. | +| careful work | checks on finished work, the brief a task is shaped into, vision | +| mastermind | plans runs and designs subharnesses | -State lives under `$CODEAF_HOME`, or `~/.codeaf` when it is unset or empty: settings and credentials -in `config.json`, memory in `graph.db`, and project sessions under `v3/projects/`. +`/crew frugal`, `balanced` or `max` sets all five in one word. Any seat can be +pinned. -## The manual ships with the binary +Every finished task is graded by the check it already had to pass. Work that +keeps failing on the worker seat moves up to careful work on its own, and each +request goes to the provider that has been fastest for that kind of call. +`codeaf models` prints the ratings. -The Markdown under `internal/manual/chat/` is compiled into codeaf, and the conversation -reads it with the `manual` tool to answer questions about its own behaviour. From a -terminal `codeaf manual` lists every page and `codeaf manual ""` returns the -sections that answer it; inside the chat it is `/manual`. Build gates require every -slash command and alias, every tool name, and more than a hundred questions in ordinary -language to reach an answering page. +The right model for each call: the spend page showing what ran it, by model and role: glm-5.3, deepseek-v4-flash and qwen3.8-27b with calls, tokens and dollars -## Headless work +Providers built in: OpenRouter, DeepSeek, GLM, Kimi, MiniMax, Qwen, Ollama and +any OpenAI-compatible endpoint. -- `codeaf do ""` does one task and exits: the same living agent as chat, with nobody watching. -- `codeaf exec [""]` runs one worker for one pass, with no planning. -- `codeaf run --input ` runs one saved typed program and writes typed output to stdout. +## Standing orders -When `codeaf do` starts local workers, no rtk is resolvable, and `CODEAF_RTK` is unset, -it begins a background fetch of the pinned third-party rtk executable from -`github.com/rtk-ai/rtk` on the four supported macOS and Linux architectures, to compress -eligible shell output before the model reads it. Nothing waits for the fetch: the whole -attempt has two minutes, each downloaded response is capped at 64 MB, its sha256 must -match the published checksums, and calls to rtk have telemetry switched off. It installs -at `$CODEAF_HOME/bin/rtk`, or `~/.codeaf/bin/rtk` when that variable is unset or empty; -set `CODEAF_RTK=off` to refuse it, or set `CODEAF_RTK` to the path of your own executable. +Rules, reminders and watches are one thing, and you set them up by saying them. +"Never commit straight to main here." "Every Monday, draft the weekly update." +"Tell me when CI goes red." A card asks once; `1` and it stands, in this project +or everywhere, on the same daily spend limit as the rest. -None takes `--yolo`, and all three end the same way — `--json` carries the reason -in its `stop` field. +The standing place: orders, reminders and watches for this project and others, when each last woke and what it cost -
-Exit codes, and the read-only commands +## Headless is the other front door -| Code | Meaning | -| --- | --- | -| `0` | Done. | -| `1` | Could not be run at all. | -| `2` | Ran and did not finish. | -| `3` | A limit you set stopped it. | -| `4` | Needed an answer and nobody was there. | +The same factory, with the conversation removed, for CI, cron, scripts and +benchmark harnesses. -These need no model key and spend nothing: `codeaf why self`, `codeaf why `, -`codeaf logs [--tail 40] [--follow] [--json]`, `codeaf doctor`, -`codeaf manual [page | "question"]`, and `codeaf version`. `codeaf help env` prints the -environment table. - -`codeaf models [--refresh]` is the exception in that group: it spends nothing of yours, -but it reaches the network for the catalog and stops with -`codeaf needs a model to work with.` if no key is resolvable. +```bash +codeaf do "bump every dependency whose changelog is worth reading" --timeout 30m --json +``` -
+`do` takes your brief byte for byte, plans, runs and checks it, and prints one +JSON object and an exit code. Where the conversation would ask, it takes its +best answer and records the assumption. `exec` runs one worker with no plan; +`run` executes a plan you edited. [The contract](docs/HEADLESS.md). -See [the headless contract](docs/HEADLESS.md) and [ambient work](docs/AMBIENT.md). +## Run it on your dev box, drive it from anywhere -## Work on another machine +Most agents on a remote box mean ssh, tmux, and a terminal that lags on every +key. CodeAF splits in two instead. The screen runs on the machine in front of +you. The conversation runs on the machine that owns the work, and `home` shows +that machine: its projects, tasks and standing orders. -The conversation and its work stay on the machine that owns the workspace; the local -surface attaches to it over a byte stream. +one conversation on devbox; your terminal on the same machine, your laptop over ssh, and your phone from a mobile terminal over ssh all attach to it ```bash -codeaf chat --host devbox # also me@devbox, or devbox:code/app +codeaf chat --host devbox # your own ssh: config, keys, jump hosts. nothing to install there but codeaf ``` -`--host` runs the far machine's `codeaf engine` over `ssh -T`: it needs `ssh` here and -codeaf installed there, and it cannot be combined with `--one-model`. For a machine -without ssh, `codeaf serve [--workspace path] [--relay url]` holds an outbound relay -connection and prints a pairing name such as `otter-lamp-42` — without a configured -relay it stops — and `codeaf chat --at ` connects to it. `codeaf devices` lists -paired devices; `codeaf devices revoke [--all]` revokes access. +- **Typing never waits on the network.** Drawing the screen makes no round + trip. Pressing enter makes one. +- **Close the lid, the work keeps going.** The conversation lives on devbox. A + dropped link redials for five minutes, a question asked while you were away + is still waiting when you come back, and desk and laptop can watch the same + turn. +- **Files cross both ways.** Paste a screenshot or drop a file and it lands on + devbox. Click a path in a reply and it opens here, in your own editor. -Current boundary: spend, search and memory pages still read local files, and inside a -remote task room steering, stopping and model changes are absent. +On your phone there is no app to install. ssh in from any mobile terminal, run +`codeaf` in the project, and it joins the same live conversation, folded to fit +the screen. -Read [remote access](docs/REMOTE.md) and its [testing guide](docs/remote-access-testing.md). +Native in the terminal on your phone: CodeAF home at phone width inside a mobile terminal over ssh, beside the same home on a wide screen -## Contributing +Still local over a connection: spend, search and memory. Reaching a machine +with no ssh at all, through a relay and a pairing code, is built and switches on +when the hosted relay does. [How it works](docs/REMOTE.md). -Branch from `dev` and open the pull request against `dev`; `main` is the release pointer. -Every pull request carries a change entry under `docs/changes/unreleased/`. +## What a copilot does, and what CodeAF does -```bash -make build # bin/codeaf -make pr-ready # the bar a pull request into dev has to clear -make demo-home # a throwaway home with something on every page -make changelog-new PR= KIND= SLUG= -``` +| | a copilot | CodeAF | +| --- | --- | --- | +| where you work | one window, one repository | every project on the machine, from one control room | +| what you do | watch it type | describe work, answer what needs you, decide what lands | +| what runs | one model, one thread | six seats chosen per call, and subharnesses built for one job | +| how long it lasts | one session | conversations, tasks and standing orders that outlive the window | +| without you | it stops | headless, standing orders, a phone in your pocket | -Read the [branching rules](docs/rules/branching.md), the [change-entry rules](docs/rules/changelog.md) -and [AGENTS.md](AGENTS.md) before contributing. +## Docs -## Documentation +- `codeaf manual`, or `alt+.` for the key map. The manual ships in the binary and the chat reads it too. +- [Guide](docs/GUIDE.md): every flag, key, slash command and exit code. +- [docs/](docs/README.md): architecture, headless, remote, limits. -Start with [the documentation map](docs/README.md); the enduring references are the -[design language](docs/DESIGN-LANGUAGE.md), [remote access](docs/REMOTE.md), the -[headless contract](docs/HEADLESS.md) and [ambient work](docs/AMBIENT.md). +Built by the [AgentField](https://github.com/Agent-Field/agentfield) team. diff --git a/assets/readme/anywhere.webp b/assets/readme/anywhere.webp new file mode 100644 index 0000000000..9e8525f7d5 Binary files /dev/null and b/assets/readme/anywhere.webp differ diff --git a/assets/readme/hero.jpg b/assets/readme/hero.jpg new file mode 100644 index 0000000000..051a1cf0ab Binary files /dev/null and b/assets/readme/hero.jpg differ diff --git a/assets/readme/how-work-changes.webp b/assets/readme/how-work-changes.webp new file mode 100644 index 0000000000..b770efe490 Binary files /dev/null and b/assets/readme/how-work-changes.webp differ diff --git a/assets/readme/screens/conversation.webp b/assets/readme/screens/conversation.webp new file mode 100644 index 0000000000..fce2ae803e Binary files /dev/null and b/assets/readme/screens/conversation.webp differ diff --git a/assets/readme/screens/home.webp b/assets/readme/screens/home.webp new file mode 100644 index 0000000000..1f226a6e12 Binary files /dev/null and b/assets/readme/screens/home.webp differ diff --git a/assets/readme/screens/models.webp b/assets/readme/screens/models.webp new file mode 100644 index 0000000000..e58d740873 Binary files /dev/null and b/assets/readme/screens/models.webp differ diff --git a/assets/readme/screens/overview.webp b/assets/readme/screens/overview.webp new file mode 100644 index 0000000000..514d714761 Binary files /dev/null and b/assets/readme/screens/overview.webp differ diff --git a/assets/readme/screens/phone.webp b/assets/readme/screens/phone.webp new file mode 100644 index 0000000000..ba7a10e181 Binary files /dev/null and b/assets/readme/screens/phone.webp differ diff --git a/assets/readme/screens/projects.webp b/assets/readme/screens/projects.webp new file mode 100644 index 0000000000..0078e6867b Binary files /dev/null and b/assets/readme/screens/projects.webp differ diff --git a/assets/readme/screens/question.webp b/assets/readme/screens/question.webp new file mode 100644 index 0000000000..61ad9c16cf Binary files /dev/null and b/assets/readme/screens/question.webp differ diff --git a/assets/readme/screens/standing.webp b/assets/readme/screens/standing.webp new file mode 100644 index 0000000000..5e07ec837d Binary files /dev/null and b/assets/readme/screens/standing.webp differ diff --git a/assets/readme/screens/tasks-tree.webp b/assets/readme/screens/tasks-tree.webp new file mode 100644 index 0000000000..d9d51c3750 Binary files /dev/null and b/assets/readme/screens/tasks-tree.webp differ diff --git a/assets/readme/social-preview.png b/assets/readme/social-preview.png new file mode 100644 index 0000000000..84d853aa95 Binary files /dev/null and b/assets/readme/social-preview.png differ diff --git a/assets/readme/subharness.webp b/assets/readme/subharness.webp new file mode 100644 index 0000000000..2d496dd1a1 Binary files /dev/null and b/assets/readme/subharness.webp differ diff --git a/docs/GUIDE.md b/docs/GUIDE.md new file mode 100644 index 0000000000..c83ded19cd --- /dev/null +++ b/docs/GUIDE.md @@ -0,0 +1,396 @@ +
+ +# codeaf guide + +**Talk through the work, change the files, and hand off tasks you can walk away from.** + +*One terminal session gives a model tools, memory, background work, and a manual about itself.* + +Go 1.26.5 darwin, linux, windows + +

Install • Chat • Tools • Tasks • Models • Manual • Headless • Remote • Contributing • Docs

+ +
+ +Run `codeaf` inside a project. It opens the conversation that directory was last +having. Ask in ordinary language; the model can read and edit files, run commands, +search the web, remember useful context, and bring separate tasks back when they land. + +This is the chat flow in a real terminal: + +```text + codeaf $0.0010 / $500 · sun 7:32pm + Home [key lookup] × + +──────────────────────────────────────────────────────────────────────────────────────────────────── + · esc interrupts · ctrl+c twice quits · ? for help + + › read ./apikey.go and tell me in two lines where codeaf looks for an API key + + ▾ worked 3.2s · thought 0.6s · 1 tool call · ctrl+e + ▸ read apikey.go 1 call + + In Load's order (from `apiKeyFrom`/`APIKeyAt`): `$OPENROUTER_API_KEY`, then + `$OPENAI_API_KEY`, then the `api_key` field in the profile config file written with + `WriteAPIKey`. First non-empty wins. + + · ⟲ 14.1k cached · saved $0.0005 + · 19:31 · 3.2s · 1 tool call · $0.0008 · ❮ +─ where codeaf finds its a… · ~deepseek/deepseek-v4-flash-latest ─── space space home · / commands ─ + › + $0.0008 · ⟲ saved $0.0005 · 45% cached 15.6k/1.3M · 1% idle +``` + +That is a real session on the default model, `~deepseek/deepseek-v4-flash-latest`: +one question, one `read`, one answer, and what it cost on the last line. + +### Which folder it works in + +"Inside a project" is decided at launch, in this order +(`cmd/codeaf/chatv3_layout.go:84`): `--workspace ` if you gave one, else the root +of the git repository you are standing in, else the directory itself. The exception is +a directory nobody chose — your home directory, or anything under a temporary directory +— where codeaf keeps a folder of its own and says so on the welcome screen: + +```text +in a folder codeaf keeps for this conversation · /workspace picks another +``` + +Your files are not in that folder, so asking it to read one gets you an empty +directory. `/workspace ` anchors a conversation to a project at any point; the +shorter road is to start codeaf inside the project. + +Once this machine has conversations on it, bare `codeaf` opens **home** rather than a +conversation — projects, running work, questions waiting on you, what you have spent. +Type into the box to start one, or press enter on a row to reopen one. `space space` +goes to home from a conversation and `esc` comes back untouched. + +## Install + +### Build from the repository + +The road that works today is a source checkout. The module needs Go 1.26.5, and +`make build` is the one supported build command; it writes `bin/codeaf`. + +```bash +git clone https://github.com/Agent-Field/codeaf.git # needs repository access while it is private +cd codeaf +make build # fetches the pinned Furrow artifact, so it needs the network; + # FURROW_ARTIFACT=/path/to/furrow supplies it offline +bin/codeaf +``` + +### The installer, and what it is waiting on + +```bash +curl -fsSL https://agentfield.ai/get/codeaf | bash # the preferred form +curl -fsSL https://raw.githubusercontent.com/Agent-Field/codeaf/main/scripts/install.sh | bash # the script under it +``` + +The first is the road that will be supported, and it is not serving yet — the route is +written and unmerged. The second answers 404 to anyone not signed in, and starts working +when the repository is public and `scripts/install.sh` has reached `main`. + +
+Installer channels, flags, and checks + +The repository currently has no rc or staging publication. Those channel selections +therefore stop with `no build has been published yet`. Recognizing a channel +does not mean a matching release exists. + +```bash +curl -fsSL https://agentfield.ai/get/codeaf/dev | bash +curl -fsSL https://agentfield.ai/get/codeaf/staging | bash +curl -fsSL https://agentfield.ai/get/codeaf/rc | bash +curl -fsSL https://agentfield.ai/get/codeaf | VERSION= bash +``` + +| Installer input | Behaviour | +| --- | --- | +| `--stable` | Select the latest stable release; this is the default. | +| `--dev` | Select the latest `dev-*` release. | +| `--rc`, `--staging` | Select a matching channel build or stop if none has been published. | +| `--version TAG` or `VERSION=` | Pin one release tag. | +| `--dir PATH` | Install somewhere other than `~/.codeaf/bin`. | +| `--no-modify-path` | Print the PATH line without editing a shell file. | +| `--verbose` | Print each GET. | +| `GITHUB_TOKEN` or `GH_TOKEN` | Raise GitHub's anonymous API limit. | + +The script needs `curl` or `wget`, plus `sha256sum` or `shasum`. It downloads +`checksums.txt` and refuses a sha256 mismatch. Unless `--no-modify-path` is set, it +appends one `export PATH=… # codeaf installer` line to the applicable shell file. Its +last action is `codeaf version`. Release builds cover darwin, linux, and windows on +amd64 and arm64. + +
+ +## Talk to codeaf + +Bare `codeaf` and `codeaf chat` open the same conversation surface. `codeaf resume` +opens a picker for an earlier conversation. + +```bash +codeaf +codeaf chat --model +codeaf chat --once "summarize the changes" # print one reply and exit +codeaf resume +``` + +`enter` sends a message or steers a running answer. `ctrl+enter` makes a standing +order. `esc` interrupts or, pressed twice at rest, opens rewind. `ctrl+c` interrupts +mid-turn; twice within 1.5 seconds while idle quits. + +
+Chat launch flags and terminal keys + +| Flag | Meaning | +| --- | --- | +| `--model ` | Choose the model for this session. | +| `--once "text"` | Run one message non-interactively, print the reply, and exit. | +| `--session ` | Resume the transcript at that path. | +| `--yolo` | Run tools without asking; the approval default becomes allow. | +| `--reasoning auto\|low\|medium\|high\|xhigh\|max` | Override reasoning for the session. | +| `--no-compact` | Never compact automatically. | +| `--one-model` | Put every text call on the session model. | +| `--host`, `--at`, `--no-host` | Choose where the session runs and how this surface attaches. | +| `--debug` | Keep the full run record. | +| `--max-hours`, `--max-cost` | Bound an unattended `--yolo` session. | + +| Key | Action | +| --- | --- | +| `ctrl+o` | Expand the selected call or task instruction. | +| `ctrl+.` | Open task history. | +| `space space` | Open home from an empty message box. | +| `alt+1` … `alt+7` | Select one of the seven places. | +| `ctrl+,` | Open settings. | +| `ctrl+g` | Send a running command to the background; otherwise close the task column, or bring it back. | + +
+ +Once the conversation has begun, a column stands down the right-hand side of a wide +terminal — the tasks and standing orders over this conversation, or, while there are +none, `+ /task` and `+ /standing` with `❯ ctrl+g hide` under them. + +Slash commands cover models, conversations, work, memory, permissions, and spending. +Start with `/help`. Common doors are `/model`, `/new`, `/resume`, `/workspace`, `/task`, +`/history`, `/standing`, `/memory`, `/remember`, `/permissions`, `/status`, `/cost`, +`/spend`, `/budget`, `/compact`, `/rewind`, `/manual`, `/help`, and `/quit`. `/drafts` +keeps the last ten cleared drafts; `enter` restores one and `d` lets one go. + +
+Slash-command reference + +| Command | Registered meaning | +| --- | --- | +| `/model` | `pick a model · or press its name above the message box`; with a slug, `switch the model for the conversation or open task`. | +| `/new` | `start another conversation in this project` | +| `/resume` | `open an earlier conversation` | +| `/workspace ` | `anchor this conversation to a project` | +| `/task ` | `start work you can walk away from` | +| `/history` | `every task this project has run · ctrl+.` | +| `/standing ` | `keep this true · a card, never work done once` | +| `/memory` | `inspect and change what is remembered` | +| `/remember ` | `keep one thing across conversations` | +| `/permissions` | `what runs without asking · drop one with d` | +| `/status` | `everything the status line knows, one fact per line` | +| `/cost` | `what this conversation has spent · /spend is the whole machine` | +| `/spend` | `what this machine has cost, by the day · alt+3` | +| `/budget` | `what codeaf may spend · every limit on one tab` | +| `/compact` | `summarize the conversation now` | +| `/rewind` | `go back to an earlier point · esc esc takes back the last` | +| `/manual` | `codeaf's own manual · every page, one per line` | +| `/help` | `this list` | +| `/quit` | `close this conversation` | +| `/drafts` | `cleared-but-kept drafts · enter restores one, d lets one go` | + +
+ +A call that needs permission pauses on a block. Its header counts ten seconds down and +then stops and keeps waiting, rather than answering for you: + +```text +╭─  needs your ok to run bash ─────────────────────────────────────────────────────── bash · 10s ─╮ +│ echo hi · default │ +│ │ +│ ▸ 1 allow once │ +│ 2 always │ +│ 3 deny safe answer │ +│ │ +╰─ ↑↓ choose · enter take it · esc later ──────────────────────────────────────────────────────────╯ + c change · ? ask back · 1–3 jump +``` + +`↑↓` and `enter` take an answer, the digits jump straight to one, and `esc` leaves it +for later. `c` is `change: say what you want different, then enter`; `?` is +`ask back: type your question, then enter`. The answer leaves a row you can reopen — +`needs your ok to run bash → allow once · you · 20:21 · c change`. A call whose outcome +cannot be taken back drops choice 2, the widening one. `--yolo` makes allow the default, +and the status line then says `YOLO`. + +## Tools in the conversation + +The model works through named tools rather than by suggestion. `read`, `write`, +`edit` and `bash` act on the folder this conversation is anchored to; `grep`, `find` +and `ls` look around it; `web_search` and `web_fetch` go out; `remember` keeps something for later; +`propose_task` hands work off. The belt is assembled for each session, and a +capability that cannot work is left off it rather than offered and failing. + +
+Tool-name reference + +| Work | Exact tool names | +| --- | --- | +| Files and shell | `read`, `write`, `edit`, `bash`, `grep`, `find`, `ls` | +| Documents and jobs | `read_document`, `jobs`, `manual` | +| Interaction and work | `ask`, `watch`, `tasks`, `propose_task`, `quick_task`, `items`, `divide_work`, `stand` | +| Memory and workspace | `remember`, `recall`, `track`, `commit`, `workspace`, `workspace_snapshots`, `workspace_restore`, `workspace_fork`, `workspace_merge`, `search_conversations` | +| Web | `web_search`, `web_fetch` | +| Settings and accounts | `settings`, `change_setting`, `services`, `use_service`, `gmail_search`, `gmail_read`, `gmail_send`, `calendar_list`, `calendar_create`, `slack_search`, `slack_read_thread`, `slack_list_channels`, `slack_send` | +| Media | `generate_image`, `speak`, `generate_music`, `generate_video`, `view_image`, `edit_video`, `load_capability` | + +`remember` needs memory switched on. The four `workspace_*` tools need a folder under +Furrow watch. The five `gmail_*` and `calendar_*` tools arrive only with a connected +Google account and the four `slack_*` only with Slack; `/connect` — `your connected +accounts · connect another` — is the door, and any other keyed account brings one +`_request` instead, plus whatever the service names for itself. +`view_image` needs a vision model. `edit_video` needs its local video binaries. Each +media-generation tool needs both a media client and a resolved model for its modality. + +
+ +## Hand work to tasks + +`propose_task` gives self-contained work to a separate task, returns its id immediately, +and opens a short countdown. Redirect or cancel during the countdown; silence starts it. +Keep talking while the task runs. Its report starts a turn in the conversation when it +lands. + +A task page shows the instruction, folded work and calls, steering, the report, and a +pinned line with activity, duration, cost and call count. `/task ` is the direct +door; `/history` opens the project's task history. + +Standing orders use `/standing ` or `ctrl+enter`. They become cards and stay true +after the conversation. Memory keeps person-, project-, or machine-scoped records in +`graph.db`; `/memory`, `/memories`, `/remember` and `/forget` change them. + +## Models, keys, and spending + +Key resolution is `OPENROUTER_API_KEY`, then `OPENAI_API_KEY`, then `api_key` in the +profile's `config.json`. With no key, an interactive local launch opens a two-page setup +that offers to connect OpenRouter in a browser or take a pasted key. A non-interactive +chat with no key stops instead, with `codeaf chat needs a model to talk with.` + +
+The two first-run screens, word for word + +Where a browser is reachable the first page is headed `connect openrouter`: + +```text +sign in once in your browser. openrouter makes the default service's key for this profile; codeaf stores it on this machine. no prompt is sent and no model is called. +``` + +Where it is not, the same page is headed `your openrouter key` and reads `codeaf talks +to models on its default service through openrouter, on your key and your card. nothing +is sent until you do.` Either way the foot takes a pasted key and `esc` skips setup. +The second page is `Daily limit`, `Chat model` and `Work crew`. + +
+ +The chat model resolves from `--model`, then saved `model.talk`, then `CODEAF_MODEL`, +then `~deepseek/deepseek-v4-flash-latest`. The last value is a floating alias. Besides +OpenRouter, the connection screen supports DeepSeek, Z.ai, Moonshot, MiniMax, Alibaba +Qwen, Ollama, and a custom OpenAI-compatible service; a qualified slug such as +`qwen/` selects its service. + +Provider routing defaults to `simple`: an unpinned OpenRouter call carries no provider +object, while a pinned call asks for exactly that lane. `latency` and `price` remain +opt-in settings. + +The default daily rail is `$500`; setting that row to `0` removes it. First run asks for +`Daily limit`, `Chat model`, and `Work crew`. + +State lives under `$CODEAF_HOME`, or `~/.codeaf` when it is unset or empty: settings and credentials +in `config.json`, memory in `graph.db`, and project sessions under `v3/projects/`. + +## The manual ships with the binary + +The Markdown under `internal/manual/chat/` is compiled into codeaf, and the conversation +reads it with the `manual` tool to answer questions about its own behaviour. From a +terminal `codeaf manual` lists every page and `codeaf manual ""` returns the +sections that answer it; inside the chat it is `/manual`. Build gates require every +slash command and alias, every tool name, and more than a hundred questions in ordinary +language to reach an answering page. + +## Headless work + +- `codeaf do ""` does one task and exits: the same living agent as chat, with nobody watching. +- `codeaf exec [""]` runs one worker for one pass, with no planning. +- `codeaf run --input ` runs one saved typed program and writes typed output to stdout. + +None takes `--yolo`, and all three end the same way — `--json` carries the reason +in its `stop` field. + +
+Exit codes, and the read-only commands + +| Code | Meaning | +| --- | --- | +| `0` | Done. | +| `1` | Could not be run at all. | +| `2` | Ran and did not finish. | +| `3` | A limit you set stopped it. | +| `4` | Needed an answer and nobody was there. | + +These need no model key and spend nothing: `codeaf why self`, `codeaf why `, +`codeaf logs [--tail 40] [--follow] [--json]`, `codeaf doctor`, +`codeaf manual [page | "question"]`, and `codeaf version`. `codeaf help env` prints the +environment table. + +`codeaf models [--refresh]` is the exception in that group: it spends nothing of yours, +but it reaches the network for the catalog and stops with +`codeaf needs a model to work with.` if no key is resolvable. + +
+ +See [the headless contract](docs/HEADLESS.md) and [ambient work](docs/AMBIENT.md). + +## Work on another machine + +The conversation and its work stay on the machine that owns the workspace; the local +surface attaches to it over a byte stream. + +```bash +codeaf chat --host devbox # also me@devbox, or devbox:code/app +``` + +`--host` runs the far machine's `codeaf engine` over `ssh -T`: it needs `ssh` here and +codeaf installed there, and it cannot be combined with `--one-model`. For a machine +without ssh, `codeaf serve [--workspace path] [--relay url]` holds an outbound relay +connection and prints a pairing name such as `otter-lamp-42` — without a configured +relay it stops — and `codeaf chat --at ` connects to it. `codeaf devices` lists +paired devices; `codeaf devices revoke [--all]` revokes access. + +Current boundary: spend, search and memory pages still read local files, and inside a +remote task room steering, stopping and model changes are absent. + +Read [remote access](docs/REMOTE.md) and its [testing guide](docs/remote-access-testing.md). + +## Contributing + +Branch from `dev` and open the pull request against `dev`; `main` is the release pointer. +Every pull request carries a change entry under `docs/changes/unreleased/`. + +```bash +make build # bin/codeaf +make pr-ready # the bar a pull request into dev has to clear +make demo-home # a throwaway home with something on every page +make changelog-new PR= KIND= SLUG= +``` + +Read the [branching rules](docs/rules/branching.md), the [change-entry rules](docs/rules/changelog.md) +and [AGENTS.md](AGENTS.md) before contributing. + +## Documentation + +Start with [the documentation map](docs/README.md); the enduring references are the +[design language](docs/DESIGN-LANGUAGE.md), [remote access](docs/REMOTE.md), the +[headless contract](docs/HEADLESS.md) and [ambient work](docs/AMBIENT.md). diff --git a/docs/changes/unreleased/1049-readme-launch.md b/docs/changes/unreleased/1049-readme-launch.md new file mode 100644 index 0000000000..7e1ebcc0ea --- /dev/null +++ b/docs/changes/unreleased/1049-readme-launch.md @@ -0,0 +1,16 @@ +--- +kind: changed +title: The README is the launch story and the reference it used to be is docs/GUIDE.md +pr: 1049 +surface: [docs] +invalidates: + - "README.md was the reference: every flag, key, slash command, exit code and folder rule, with no pictures. That file is now docs/GUIDE.md, unchanged apart from its title. README.md is the public story for the launch: install, one window for every project, a conversation that becomes tasks and what lands on its own, what a factory is, subharnesses, the benchmark, the open-model crew, standing orders, headless, the dev box over ssh and the phone, and the roadmap." + - "The repository had no LICENSE file. It has one, Apache 2.0, the same text agentfield ships." + - "assets/readme/ is new and holds the hero, the diagrams, the social preview and nine product screens as WebP (overview, projects, home, conversation, tasks-tree, question, models, standing, phone) plus placeholder frames for the slots still to fill. The screens are real terminal captures of a seeded demo machine on open models, staged on a warm ground in the brand package; no image model touched their pixels. The demo video at the top is a 92 second recording on open models, hosted as a GitHub attachment rather than kept in the repository, cut with tools/render/film.mjs in the brand package. The hero, diagrams and screens are generated from the brand package outside this repository (~/Documents/agentfield/codeaf: tools/make_visual.py, templates/readme/diagrams.html, templates/readme/stage.html and brand/prompts/ui/README.md); regenerate there, do not hand-edit the images here." +--- + +The README is what a stranger reads in the first minute, and the old one asked +them to read four hundred lines of reference before it said what the program +was for. The new one says it, shows it, and sends them to the guide for the +rest. Benchmark figures and the numbers still to measure are marked +`TODO` in HTML comments and land in follow-up pull requests.