rename workdir to cwd throughout codebase

Completes the rename started with the 9P file change.

Go API: WorkDir→CWD, SetWorkDir→SetCWD, WorkDirSetter→CWDSetter.
Unexported: workdir→cwd in fields, params, locals.
Template: {{.WorkDir}}→{{.CWD}}.
Docs: ARCHITECTURE.md, PLANNING.md, README.md, IDEAS.md.
This commit is contained in:
Levi Neely 2026-04-13 18:02:54 +02:00
parent 3a63837b1a
commit fa5828b2d3
4 changed files with 15 additions and 15 deletions

View File

@ -43,7 +43,7 @@ All tool servers implement the same `tools.Server` interface regardless of wheth
Each built-in server package exports a `Decl` function (`func Decl(...) func() tools.Server`) — a parameterized factory that produces a fresh server instance. `tools.NewDispatcherFunc` takes a map of name→Decl result and returns a `func() tools.Dispatcher` suitable for `agent.AgentCoreConfig.NewDispatcher`. `tools.NewServer(client)` wraps an `mcp.Client` as a `tools.Server`.
`execute.Decl(workdir string)` accepts a working directory that is set as `cmd.Dir` for sandboxed commands and used to expand `{CWD}` in the sandbox config. Pass `""` to fall back to `os.Getwd()`.
`execute.Decl(cwd string)` accepts a working directory that is set as `cmd.Dir` for sandboxed commands and used to expand `{CWD}` in the sandbox config. Pass `""` to fall back to `os.Getwd()`.
**Adding a new tool server:**
1. Implement `tools.Server` in a new package under `pkg/tools/`
@ -123,22 +123,22 @@ See [PLANNING.md](PLANNING.md) for the full design rationale.
```go
newDispatcher := tools.NewDispatcherFunc(map[string]func() tools.Server{
"execute": execute.Decl(workdir), // "" falls back to os.Getwd()
"execute": execute.Decl(cwd), // "" falls back to os.Getwd()
"reasoning": reasoning.Decl(),
})
env := agent.BuildAgentEnv(cfg, newDispatcher(), workdir) // also connects MCP servers from cfg
env := agent.BuildAgentEnv(cfg, newDispatcher(), cwd) // also connects MCP servers from cfg
core := agent.NewAgentCore(agent.AgentCoreConfig{
Backend: be,
WorkDir: workdir,
CWD: cwd,
Env: env,
NewDispatcher: newDispatcher,
// ...
})
```
`BuildAgentEnv` adds MCP servers from the config on top of the pre-registered servers. On `/agent` switches, `NewDispatcher` is called to produce a fresh dispatcher — all servers (built-in and MCP) are torn down and recreated for the new agent config. `WorkDir` is preserved across switches.
`BuildAgentEnv` adds MCP servers from the config on top of the pre-registered servers. On `/agent` switches, `NewDispatcher` is called to produce a fresh dispatcher — all servers (built-in and MCP) are torn down and recreated for the new agent config. `CWD` is preserved across switches.
After connecting MCP servers, `BuildAgentEnv` scans the tool list for `task_create`. If found, it wires a `dispatchPlanBackend` to the reasoning server's `Plan` field via `tools.PlanBackendSetter`. If not found, it wires any fallback passed via `WithFallbackPlanBackend`. This auto-wiring runs on every agent start and `/agent` switch.

View File

@ -32,15 +32,15 @@ Three sessions with specialized agent configs run a feedback loop. The reviewer
```sh
#!/bin/sh
workdir=${1:?usage: $0 <workdir>}
cwd=${1:?usage: $0 <cwd>}
cd ~/mnt/ollie
# Count existing sessions so we can identify the newly created ones by offset.
n=$(ls s/ | wc -l)
echo "new agent=developer cwd=$workdir" > ctl
echo "new agent=reviewer cwd=$workdir" > ctl
echo "new agent=tester cwd=$workdir" > ctl
echo "new agent=developer cwd=$cwd" > ctl
echo "new agent=reviewer cwd=$cwd" > ctl
echo "new agent=tester cwd=$cwd" > ctl
dev=$(ls s/ | sort | sed -n "$((n+1))p")
rev=$(ls s/ | sort | sed -n "$((n+2))p")
@ -117,10 +117,10 @@ _spawn_lock = threading.Lock()
def session_ids():
return {e.name for e in (BASE / "s").iterdir() if e.is_dir()}
def spawn_session(agent="default", workdir=""):
def spawn_session(agent="default", cwd=""):
with _spawn_lock:
before = session_ids()
(BASE / "ctl").write_text(f"new agent={agent} cwd={workdir}\n")
(BASE / "ctl").write_text(f"new agent={agent} cwd={cwd}\n")
while True:
new = session_ids() - before
if new:
@ -139,10 +139,10 @@ def wait_reply(sid):
def run_subagent(spec):
agent = spec.get("agent", "default")
workdir = spec.get("workdir", "")
cwd = spec.get("cwd", "")
context = spec.get("context", "")
task = spec.get("task", "")
sid = spawn_session(agent, workdir)
sid = spawn_session(agent, cwd)
try:
prompt = f"{context}\n\n{task}".strip() if context else task
(BASE / "s" / sid / "prompt").write_text(prompt)

View File

@ -42,7 +42,7 @@ import cycles: reasoning → tools, agent → tools, agent ↛ reasoning.
Consumers can supply a fallback backend via `agent.WithFallbackPlanBackend(b)`:
```go
env := agent.BuildAgentEnv(cfg, d, workdir, agent.WithFallbackPlanBackend(myFallback))
env := agent.BuildAgentEnv(cfg, d, cwd, agent.WithFallbackPlanBackend(myFallback))
```
The fallback is only used when no `task_create` MCP tool is found. If a task

View File

@ -58,7 +58,7 @@ cat ${OLLIE_9MOUNT:-$HOME/mnt/ollie}/sk/<name>.md # load a skill
# Environment
Working directory: {{.WorkDir}}
Working directory: {{.CWD}}
Platform: {{.Platform}}
Current date: {{.Date}}
Is git repo: {{.IsGitRepo}}