agent-lyceum 0.17.0 → 0.17.2

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 (3) hide show
  1. package/README.md +40 -186
  2. package/README.zh-TW.md +40 -186
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -4,216 +4,70 @@
4
4
 
5
5
  **English** | [繁體中文](README.zh-TW.md)
6
6
 
7
- Configure and run a **team of agents** (Claude Code and/or Codex) that talk to each other through file mailboxes, each with its own persona (`AGENT.md`) and long-term memory folder. Writes are scoped: an agent can only change its own memory and outbox, never other agents' context or its own persona.
7
+ Run a **team of agents** (Claude Code and/or Codex) on your repo. They talk through file mailboxes, and each has its own persona (`AGENT.md`) and long-term memory. An agent can only write its own memory and outbox, never other agents' context or its own persona.
8
8
 
9
- The tool keeps **its own data out of your repo**: configuration, mailboxes, logs, task memory and agent worktrees all live in one visible folder, `~/agent-lyceum-config/` (override with `AGENT_LYCEUM_HOME` or `--home`). What agents *produce* is a different matter: they edit your repo (directly when they run one at a time, or in git worktrees whose changes are brought into your working tree when they run in parallel). The only things agent-lyceum itself adds inside your repository are git bookkeeping: while a parallel run exists, `refs/agent-lyceum/<run-id>/*` snapshot refs, `agent-lyceum/<run-id>/<agent>` branches and worktree registrations under `.git`; `agent-lyceum clear` removes them. See [docs/upgrading-run-v2.md](docs/upgrading-run-v2.md) if you are coming from an older version.
9
+ ## Quick start
10
+
11
+ Requires Node 20+, plus `claude` and/or `codex` on your `PATH` (logged in). macOS and Linux (Linux needs `bwrap` for OS sandboxing); Windows only gets warnings.
10
12
 
11
13
  ```bash
12
- npx agent-lyceum init # create the home + global agent library
14
+ npx agent-lyceum init # create the home + global agent library
13
15
  npx agent-lyceum project add web --dir ~/code/web-app
14
- npx agent-lyceum doctor --project web # check config + show enforcement levels
15
- npx agent-lyceum run --task-file spec.md # inside the repo, the project is auto-detected
16
+ npx agent-lyceum doctor --project web # check config, show enforcement levels
17
+ npx agent-lyceum run --task-file spec.md # inside the repo the project is auto-detected
16
18
  npx agent-lyceum status
17
19
  ```
18
20
 
19
- The installed binary is `agent-lyceum`. To run the latest unreleased code straight from GitHub, use `npx github:gogogohuang/agent-lyceum <command>` instead.
20
-
21
- Requires Node 20+, plus `claude` and/or `codex` on your `PATH` (already logged in). macOS and Linux (Linux needs `bwrap` for OS sandboxing); Windows only gets warnings.
22
-
23
- ## Commands
24
-
25
- | Layer | Command | What it does |
26
- |---|---|---|
27
- | Project | `init [-y]` | Create the home and the global agent library. [details](docs/commands.md#init) |
28
- | Project | `project add <name> --dir <repo>` | Register a project. [details](docs/commands.md#project-add) |
29
- | Project | `project` / `project remove <name> [--purge]` | List or unregister projects. [details](docs/commands.md#project-and-project-remove) |
30
- | Diagnose | `doctor [-p name] [--task-file f] [--resolved] [--json]` | Check config (with enforcement levels), git, the lock and runtime CLIs without running agents; `--resolved` prints every effective setting and its source. [details](docs/commands.md#doctor) |
31
- | Diagnose | `status [-p name] [--monitor]` | Show agents, mail, the current wake-up and past runs (`--json`, `--monitor`); `--task-id` takes an id, a name or a unique prefix. [details](docs/commands.md#status) |
32
- | Run | `run ["task"] [--task-file f] [--name n] [--agent a] [-p name]` | Give the task to the lead and run until done; `--name` names the run; with `--agent`, to one member alone. [details](docs/commands.md#run) |
33
- | Run | `resume [run] ["follow-up"] [--task-file f] [--answer] [-p name]` | Continue an interrupted or failed run, or reopen a finished one with a follow-up; `--answer` first answers the questions it is waiting on. [details](docs/commands.md#resume) |
34
- | Run | `clear <run> [-p name] [--dry-run] [--keep-worktrees]` / `clear --lock [run-id] --force` | Delete a run (id, name or unique prefix) with its task memory and worktrees; or remove the lock a crashed run left behind. [details](docs/commands.md#clear) |
35
- | Run | `call <agent> ["task"] [--task-file f] [--dir d]` | Call one global agent on its own, outside any project; prints its answer. [details](docs/commands.md#call) |
36
- | Run | `tidy [-p name] [--agent a] [--layer project\|global] [--dry-run]` | Have agents tidy their own memory (manual only; archives, never deletes). [details](docs/commands.md#tidy) |
37
- | Run | `tidy --undo <timestamp> -p name --agent a` | Undo a tidy: move its archived files back. [details](docs/commands.md#tidy) |
38
-
39
- `agent-lyceum --help` lists each command with a one-line summary; `agent-lyceum <command> --help` prints its full description and options.
21
+ Latest unreleased code: `npx github:gogogohuang/agent-lyceum <command>`.
40
22
 
41
- Ctrl-C cancels a run cleanly and it can be continued with `resume` ([Stopping a run](docs/commands.md#stopping-a-run)). `run` and `resume` exit `0` only when the lead reported `completed`, `2` for partial or blocked, `1` for failed, `3` while waiting for your answers, `130` for cancelled ([Exit codes](docs/commands.md#exit-codes)). Without `-p`, the project is inferred from the current directory ([Choosing the project](docs/commands.md#choosing-the-project)).
23
+ ## How it works
42
24
 
43
- ## Running one agent on its own
25
+ 1. Your task becomes the first mail to the **lead**.
26
+ 2. The dispatcher wakes whichever agent has unread mail (`claude -p` / `codex exec`, headless).
27
+ 3. Agents reply by writing mail to their own `outbox/`; the dispatcher checks `can_message` and delivers it.
28
+ 4. The run ends when the lead sends `done`.
44
29
 
45
- Two ways to give a task to a single agent instead of the whole team. The agent works alone: it cannot mail teammates, ask you questions or edit any `AGENT.md`.
30
+ Its own data (config, mailboxes, logs, memory, worktrees) lives in `~/agent-lyceum-config/`, not in your repo. Agents edit your repo directly, or in git worktrees when running in parallel. agent-lyceum never merges. More: [How a run works](docs/how-it-works.md), [Configuration](docs/configuration.md).
46
31
 
47
- ```bash
48
- npx agent-lyceum run "tidy the form" --agent fe-member -p web # a member of the project, as an ordinary run
49
- npx agent-lyceum call pm "is this ready to build?" --dir ~/code/web-app # a global agent, outside any project
50
- ```
51
-
52
- `run --agent` has a run id and the project lock, shows in `status`, and can be resumed; the agent ends the run with its own `done` mail. `call` needs no project at all: the agent comes from `team.yaml`, works in `--dir` (default: the current directory, which must not be inside or above the agent-lyceum home), prints only its final answer on stdout, and keeps `task.md`, `log/` and `result.md` in `<home>/calls/<call-id>/`. Details: [run](docs/commands.md#run) and [call](docs/commands.md#call).
53
-
54
- ## Monitor mod (Claude Code)
55
-
56
- `plugins/status-monitor` is a Claude Code **mod**, not an ordinary plugin: it is written against Claude Code's mod hooks API (`import type { Register } from 'claude-code'`) and runs inside the Claude Code session, where it adds toasts and a `/status-monitor` pane that poll `agent-lyceum status --json`. It needs a Claude Code build that supports mods; it does not change how agent-lyceum itself runs. It shows live run status for one or several projects.
57
-
58
- **Load it.** Build first (`npm run build`; the mod runs `dist/cli.js`), then start a session with:
59
-
60
- ```
61
- claude --plugin-dir /path/to/agent-lyceum/plugins/status-monitor
62
- ```
63
-
64
- `--plugin-dir` only applies when a session starts; an already-open session must be restarted (`claude --resume --plugin-dir ...` keeps the conversation). To load it every time, add `alias claude='claude --plugin-dir /path/to/agent-lyceum/plugins/status-monitor'` to your shell rc, or, for hosts where you cannot pass a flag (desktop app, SDK), set `CLAUDE_CODE_PLUGIN_DIRS` to the mod folder. While a session is running, saving a file in the mod folder hot-reloads it.
65
-
66
- **Use it.**
67
- - **Toasts:** a message pops up when a run finishes, is interrupted, or an agent's wake fails (prefixed `[project]` when several are watched). Nothing to do.
68
- - **`/status-monitor`:** type it to open (or, if already open, close) the pane. It is off at session start unless `autoOpen` is set. In the **fullscreen layout** (`"tui": "fullscreen"` in `~/.claude/settings.json`, restart the session to apply; `/tui fullscreen` does the same) from 110 terminal columns it docks on the right at half the terminal width, and tabs and **關閉** (Close) can be clicked. Otherwise it shows above the prompt; the layout is fixed when the session starts, so a session started on the main screen stays that way. Keyboard (works in both): `x` closes, `v` switches graph/text, `e` expands or collapses the details, `1`-`9` or Tab/Enter switch task, Esc returns to the prompt, running the command again also closes. It draws one block per agent, with the links between the lead and each member taken from `can_message` (`▼` the lead may write to the member, `▲` the member to the lead, `↕` both; yellow marks the latest hand-off). Each block shows what that agent is doing now, the mail it is handling and the mail queued for it as one key line each: the point of the mail by type (task: the goal; reply: the changes; done: the result), plus any open item, risk or unfinished part it reports (none when it says None) — not the start of the text cut short. Press `e` to expand: every section of every mail (task: goal and acceptance criteria; reply: changes, verification, open items, risks; done: result and what is not done) and the full checklist; collapsed, the checklist is only the progress bar and the current step. Each block also shows its wake count and output tokens. An agent that is working right now is drawn larger: its block gets a row of its own at the full width, and its text wraps instead of being cut; idle and queued blocks stay compact. Above the graph: the run id and state, task, progress bar and checklist; below it: blocked integrations, notes and the result summary. `v` switches to the plain text list (per-runtime tokens, per-agent statistics, the last 8 wakes). Every block lists the agents it may message in a "→" line, with the latest hand-off marked "●" (this also covers member-to-member targets, which get no glyph). When the graph area is narrower than 70 columns (compared with the pane's own width, as the host reports it), the blocks stack in one column and the link glyphs are left out. Each running task is a tab, newest first; finished and interrupted runs are not listed. It refreshes with the polling interval while open.
69
-
70
- **Configure it.** In `~/.claude/settings.json` under `pluginConfigs."status-monitor@inline"` (`options`):
71
-
72
- | Option | Meaning | Default |
73
- |---|---|---|
74
- | `command` | CLI to run, split on spaces, e.g. `node /path/to/agent-lyceum/dist/cli.js` | `agent-lyceum` |
75
- | `project` | Registered project name(s) (`-p`); comma-separate to watch several; empty infers from the session's directory | empty |
76
- | `intervalSeconds` | How often status is polled | `1` |
77
- | `autoOpen` | Open the pane when a session starts (it seats only from 144 columns when opened unasked) | `false` |
32
+ ## Commands
78
33
 
79
- Changes take effect on the next session start. If the pane shows `無法取得狀態:...`, the `command` could not run (usually `dist/cli.js` was not built) or the project name is not registered.
34
+ | Command | What it does |
35
+ |---|---|
36
+ | `init` | Create the home and the global agent library. [details](docs/commands.md#init) |
37
+ | `project add` / `project` / `project remove` | Register, list or remove projects. [details](docs/commands.md#project-add) |
38
+ | `doctor` | Check config, git, lock and runtime CLIs without running agents. [details](docs/commands.md#doctor) |
39
+ | `status` | Show agents, mail, the current wake-up and past runs. [details](docs/commands.md#status) |
40
+ | `run` | Give the task to the lead and run until done. [details](docs/commands.md#run) |
41
+ | `resume` | Continue an interrupted run, or reopen a finished one with a follow-up. [details](docs/commands.md#resume) |
42
+ | `clear` | Delete a run, or remove a stale lock. [details](docs/commands.md#clear) |
43
+ | `call <agent>` | Ask one global agent on its own, outside any project. [details](docs/commands.md#call) |
44
+ | `tidy` | Have agents tidy their own memory (archives, never deletes). [details](docs/commands.md#tidy) |
80
45
 
81
- ## Layout
46
+ `agent-lyceum <command> --help` prints the full options. Ctrl-C cancels cleanly; [exit codes](docs/commands.md#exit-codes) tell scripts how a run ended.
82
47
 
83
- ```
84
- ~/agent-lyceum-config/
85
- ├── team.yaml # global agent library
86
- ├── agents/<agent>/{AGENT.md, memory/} # global persona + cross-project memory
87
- ├── calls/<call-id>/{task.md, log/, result.md} # one folder per `call` (outside any project), plus .lock-<agent>
88
- └── projects/<project>/
89
- ├── project.yaml # team, repo dir, overrides
90
- ├── agents/<agent>/{AGENT.md?, memory/} # project-level persona (optional) + project memory
91
- ├── shared/common/COMMON.md
92
- ├── locks/<run-id>.json # held while that run is active (up to dispatcher.max_concurrent_runs at once)
93
- ├── task-memory/<run-id>/{<agent>/, _shared/} # per-run memory, never shared between runs; _shared = the lead's handoff notes for follow-ups
94
- └── runs/<run-id>/{task.md, log.jsonl, state.json, result.md, done-<n>.md, followups/<n>.md, snapshots/, agents/, mail/{inbox,outbox}/<agent>/}
95
- ```
48
+ ## Configuration
96
49
 
97
- `team.yaml` defines reusable agents; `project.yaml` picks the team and overrides fields. Objects merge field by field, arrays (`can_message`, `owns`) are replaced. Relative paths resolve against the folder of the file they are written in; `~` is allowed.
50
+ `team.yaml` defines reusable agents; `project.yaml` picks the team and overrides fields:
98
51
 
99
52
  ```yaml
100
53
  # project.yaml
101
54
  dir: ~/code/web-app
102
55
  team: { lead: lead }
103
- dispatcher: { max_rounds: 0, max_parallel: 1, max_concurrent_runs: 1, wake_timeout_sec: 600, retry: 2, strict: false, workspace_mode: auto, log_max_bytes: 8388608 }
104
56
  agents:
105
- lead: { resume: true, can_message: all, can_edit_agent_md: true }
57
+ lead: { can_message: all, can_edit_agent_md: true }
106
58
  fe-member: { runtime: codex, can_message: [lead], owns: ["src/web/**"] }
107
- qa-member: { can_message: [lead], owns: ["tests/**"] }
108
- pm: { can_message: [lead], allow_web: fetch } # pm may search and read pages; the others have no web tools
109
- ```
110
-
111
- Agent fields: `runtime` (`claude-code`|`codex`; optional when `model` is recognizable: `opus`/`sonnet`/`haiku`/`claude-*` → Claude Code, `gpt-*`/`o3`/`*codex*` → Codex; precedence: project runtime > project model > global runtime > global model), `model`, `effort` (Claude Code: `low`|`medium`|`high`|`xhigh`|`max` via `--effort`; Codex: `minimal`|`low`|`medium`|`high`|`xhigh` via `model_reasoning_effort`; unset = CLI default), `agent_md`, `memory.global` / `memory.project`, `resume`, `can_message` (`all` or list; default `[lead]`, lead default `all`), `can_edit_agent_md` (default only the lead), `can_ask_user` (may send `type: ask` mail to you and pause the run for an answer; default only the lead), `allow_web` (`none`|`search`|`fetch`; what the agent may use of the web, off unless set; see "Web access" below), `owns` (repo globs).
112
-
113
- Rules checked by `doctor`: ≥ 2 agents (the lead and one member; the template has three), the lead is a listed agent, every agent has a runtime (explicit or inferred from `model`) and an existing `AGENT.md`, `effort` is valid for the agent's runtime (warning if `runtime` contradicts a recognizable `model`), `can_message` targets exist, memory dirs don't overlap, and with `max_parallel > 1` every non-lead agent needs non-overlapping `owns` and the repo must be a git repository, and with `max_concurrent_runs > 1` the repo must be a git repository and `workspace_mode` must not be shared.
114
-
115
- ## How a run works
116
-
117
- 1. The task (text, or a copy of `--task-file` kept read-only as `runs/<id>/task.md`) becomes the first mail to the lead. Tasks ≤ 16 KB are inlined; larger ones are passed by reference. Files over 1 MB are rejected.
118
- 2. The dispatcher wakes whichever agent has unread mail with `claude -p` or `codex exec` (headless). Each wake-up is a fresh session unless `resume: true`.
119
- 3. Every wake-up prompt contains the agent's `AGENT.md`, the team protocol, `COMMON.md` (read-only, ≤ 8 KB), the `MEMORY.md` index of each memory dir, the **oldest** unread message in full (one message per wake-up; the lead instead takes a run of up to 5 `reply`/`failure` messages at once and decides on them together), and titles of the queued ones, which stay unread until their own wake-up.
120
- 4. Agents send mail by writing a Markdown file with frontmatter (`to`, `type`, `subject`) into **their own** `outbox/`. The dispatcher checks `can_message`, stamps the real sender, and moves it to the recipient's `inbox/`. Handled mail goes to `inbox/<agent>/read/`. Mailboxes belong to one run (`runs/<run-id>/mail/`), so mail never crosses runs. Runs started by older versions keep using the shared `shared/{inbox,outbox}/` mailboxes (their mail is never moved); resuming such a run shows that legacy layout.
121
- The body of every `task` and `reply` should carry fixed `##` headings (injected into each agent's prompt): `task` → `Goal`, `Acceptance criteria`, `Scope`, `Upstream`; `reply` → `Changes`, `Verification`, `Open items`, `Risks` (write `None` when empty; `done` is exempt). Mail missing a heading is still delivered, with a warning note prepended and a `format-warning` entry in the run log.
122
- 5. The run ends when the lead sends `type: done`, when all mailboxes are empty, or after `max_rounds` wake-ups when you set a limit (the default `0` means no limit). A `done` must declare `outcome: completed|partial|blocked|failed` in its frontmatter and carry `## Result`, `## Files`, `## Verification`, `## Not done`; `completed` also needs every `## Steps` item ticked. A `done` that breaks this is sent back to the lead (twice at most, then it is kept as `partial`). Agent-lyceum does not verify what the lead reports. A failed wake-up is retried up to `retry` times (default 2, so 3 calls in all); if the agent still fails, the run stops (`agent_failed`, or `lead_failed` for the lead) instead of carrying on without it: the message it was handling stays unread, and the end message says how to look into the failure and how to continue (`agent-lyceum resume <run>` after fixing the cause, or `clear` to give up). Mail that repeats an earlier mail from the same sender to the same recipient (same type, reply target and text, whitespace aside) is not delivered again: the sender is told, which keeps two agents from looping on the same message.
123
-
124
- Parallelism (`max_parallel > 1`) only runs agents with disjoint `owns`, and never alongside the lead. Each non-lead agent then works in its **own git worktree** (`projects/<name>/worktrees/<run-id>/<agent>`, branch `agent-lyceum/<run-id>/<agent>`) cut from a snapshot of the repo as it is when the agent is woken (`refs/agent-lyceum/<run-id>/base-<n>`; it includes the lead's uncommitted and new, non-ignored files; your HEAD, branches and working tree are not touched). `dispatcher.workspace_mode` is `auto` (worktrees when `max_parallel > 1`), `worktree` or `shared`; `shared` cannot be combined with parallel agents. A parallel run refuses to start while the repo has uncommitted changes of yours, and when the repo is not a git repository (run sequentially instead). When a member finishes, the dispatcher commits its worktree and brings the changes into your working tree (not your index or HEAD) before the lead reads the member's mail. Every changed path is checked first: it must be inside the member's `owns` (renames and deletions included), must not be `CLAUDE.md`/`AGENTS.md`, and symlinks may not point out of the project or the member's `owns`. If a file also changed in your repo since the member's snapshot, if a check fails, or if `git apply` fails, nothing is applied: the work stays on its branch and worktree, a report and patch are written to `runs/<run-id>/integration/`, the lead is told, and the run cannot end as `completed` (it ends `blocked`). A worktree isolates files only: it cannot isolate side effects on external services, databases or the network.
125
-
126
- ### Several runs at once
127
-
128
- By default a project runs one task at a time. Set `dispatcher.max_concurrent_runs: N` (N > 1, needs a git repository) to let up to N runs of the same project be active together; starting one more is refused and names the runs in the way. In this mode **every** run, including a run that has no parallel members and a solo `run --agent <name>`, works in its own git worktree: the lead in `projects/<name>/worktrees/<run-id>/<lead>` on branch `agent-lyceum/<run-id>/<lead>`, members in worktrees cut from the lead's. A run starts from your repo's `HEAD`, so your uncommitted changes are allowed and are **not** part of it (the start line says how many files that is). Your working tree, index and HEAD are never touched.
129
-
130
- - **Ending:** when a run ends (done, cancelled, failed, idle or round limit), the lead's work is committed once on its branch and written as `runs/<run-id>/lead.patch`, and the run prints `git merge <branch>`. A run that stops to ask you (`waiting`) is not finished: nothing is committed and no merge hint is printed; its work stays in the lead's worktree and `resume` continues in the same one.
131
- - **Decided at start:** a run records whether its lead works in a worktree (`lead_workspace` in its state). `resume` follows what the run was started with, not the current setting: a run started concurrent resumes in its worktree even if you lowered `max_concurrent_runs`, and a run started non-concurrent resumes non-concurrently even if you raised it. The setting only governs how many runs may be active at once and what new runs do.
132
- - **`tidy`:** `tidy` and `tidy --undo` need the project to themselves: they are refused while any run is active, and no run can start while they run, whatever `max_concurrent_runs` is.
133
- - **`clear`:** `clear <run-id>` refuses while the lead's branch is not merged (use `--keep-worktrees` to keep it). A lock left by a crashed run is removed with `clear --lock [run-id] [-p name] --force`; with several locks, name the run.
134
-
135
- Known limits:
136
-
137
- - The number of agent processes can reach `max_concurrent_runs × max_parallel`; there is no global cap.
138
- - A lead with `can_edit_agent_md: true` edits the `CLAUDE.md`/`AGENTS.md` in its own worktree; the change reaches your repo only when you merge its branch.
139
- - `COMMON.md` and the `AGENT.md` files are shared by all runs of the project. Each run's guard only judges what changes while its own agents are working, so an edit by one run is kept; but if two runs' wake-ups overlap in time, a change one makes while the other's agents are working can be reverted by the other.
140
- - Two runs that edit the same file are for you to reconcile when merging; agent-lyceum never merges.
141
-
142
- ### Continuing a finished run
143
-
144
- Every run has a **name**: made from the first line of the task (lowercase letters, digits and `-`, at most 30 characters; `task` if nothing usable is left; `-2`, `-3` on repeats), or chosen with `run --name <name>` (same characters and length; refused if the name is already used). `resume`, `clear` and `status --task-id` accept the full run id, the name, or a unique prefix of either; an ambiguous prefix lists the candidates and exits `1`, and an empty one is refused. `status` shows the name next to the id.
145
-
146
- A finished (`done`) run can be reopened with a follow-up request: `agent-lyceum resume [run] "<follow-up>"` (or `--task-file f`). The lead gets the text as a new `task`, and the run goes on with the same run dir, task memory, sessions and lead worktree.
147
-
148
- - **Which runs:** only a finished run can be reopened. A run that is still running is refused; a run that is not finished is refused when given text (resume it without text first). Without text nothing changes: a finished run just prints its result. Without a run, the candidates are the finished runs, newest first: exactly one is used, none is an error, and several are listed (in a terminal you pick one by number or name; without a terminal the command fails and lists them). A lone argument counts as follow-up text only when it cannot be a run reference (it contains whitespace or a character a run name cannot contain); a one-word follow-up needs `resume <run> "<text>"` or `--task-file`.
149
- - **What is kept:** the follow-up is saved as `runs/<run-id>/followups/<n>.md`. Each `done` report is kept as `done-<n>.md`, and `result.md` is always the latest. `state.json` gains `name`, `reopened`, `round_floor` and `step_base` (all optional, so older runs still load). The progress (`## Steps`) carries on: the checklist at the reopen stays, and the steps the lead lists for the follow-up are added after it (a step it lists again only takes the new tick); for the follow-up's `completed` only its own steps must be ticked. Unresolved blocked integrations stay; the done-contract reminders start afresh for each reopened segment.
150
- - **Round limit:** with a `max_rounds` set, it counts from the reopen: `rounds` keeps accumulating, and the limit is the rounds at reopen plus `max_rounds`.
151
- - **The lead's branch** (runs with a lead worktree): if the branch was already merged into your `HEAD` and the lead worktree is clean and untouched since the run ended, the worktree and the branch (same name, `agent-lyceum/<run-id>/<lead>`) are re-cut from your current `HEAD`, and a line says so. Otherwise the same worktree and branch continue. If a pull request was already recorded (`pr_url`) and the branch was not re-cut, a new `open_pr: true` only pushes ("pull request updated") while that pull request is still open; if it was merged (a squash merge included) or closed, a new pull request is opened instead. If the branch was re-cut, the recorded `pr_url` is cleared (the old URL stays in the run's notes) and a new pull request is opened when asked. agent-lyceum still never merges.
152
- - **Handoff notes:** before it sends `done`, the lead writes what a follow-up will need into `task-memory/<run-id>/_shared/` in the agent-lyceum home (`MEMORY.md` is the index): decisions and why, interfaces agreed, current state, what is left and the next steps, pitfalls met. Members can read this folder but not write it (a run started with `run --agent` has one agent, which is its own lead and writes it; `call` has none). Once a run is reopened, every wake-up of every agent gets `MEMORY.md` in its prompt (the first 8 KB; a longer index is cut and flagged), and the reopened `task` mail's `Upstream` names it; the first segment's prompts do not contain it. If the lead sends `done` without having changed `MEMORY.md` in that segment, the run is not blocked: a note `shared-not-updated` is added to the run's notes. `clear` deletes the folder with the task memory; `tidy` does not touch it. It holds notes about this task only; lessons that outlive it belong in project or global memory.
153
-
154
- ### Opening a pull request
155
-
156
- When your task asks for a pull request, the lead puts `open_pr: true` in the frontmatter of its `done` report. If the run then ends `completed` and the lead's branch has changes, agent-lyceum — not an agent — pushes `agent-lyceum/<run-id>/<lead>` to `origin` and runs `gh pr create` against the repo's default branch, using the lead's report as the description (ending with `🤖 Opened by agent-lyceum`). The run result prints the PR URL, and `state.json` records it as `pr_url`. Only the lead can ask: nobody else can send `done`, and no agent's sandbox is loosened — `git push` and `gh` run outside it, with your own credentials.
157
-
158
- - It needs a lead branch, so it works only when the run has its own worktree (`dispatcher.max_concurrent_runs` of 2 or more). Otherwise the request is reported and skipped.
159
- - A request that cannot be honoured (the run did not complete, no changes, no `gh`, no `origin`, push or `gh` failed) never changes how the run turned out. The run says why it was not opened and keeps the branch; when a push or `gh pr create` failed it also prints the commands to finish by hand.
160
- - Opening a pull request publishes the lead's branch and report to `origin`. An agent that asks for one (`open_pr: true`) can therefore get anything it can read inside its sandbox onto the remote, so only ask for a pull request in a task when that is acceptable. The push and `gh pr create` run from your main repository, never inside the agent's worktree, because an agent can write that directory.
161
- - agent-lyceum never merges and does not wait for CI or review. With `max_concurrent_runs` of 2 or more, `doctor` tells you whether `gh` and `origin` are there (it does not check that `gh` is logged in).
162
-
163
- ## Web access (`allow_web`)
164
-
165
- By default no agent can use the web. Claude Code agents are woken in headless `dontAsk` mode, where anything not explicitly allowed is refused, so `WebSearch` and `WebFetch` are denied unless you opt in per agent with `allow_web` (in `team.yaml` or `project.yaml`; the project value wins). It only decides whether the agent may use the web tools; the write scope below is unchanged.
166
-
167
- | Value | Claude Code | Codex |
168
- |---|---|---|
169
- | unset | no web tools (as before) | nothing is passed: Codex keeps its own default |
170
- | `none` | no web tools | `-c web_search="disabled"` |
171
- | `search` | `WebSearch` | `-c web_search="cached"` |
172
- | `fetch` | `WebSearch` and `WebFetch` | `-c web_search="live"` |
173
-
174
- ### `search` or `fetch`?
175
-
176
- - **`search`**: the agent can run a search and gets a list of results (typically titles, links and short snippets). It cannot open a page, so it only knows what the results say. That is enough for "which Node versions are still supported?", "what is the latest release of this library?" or "is this API deprecated?".
177
- - **`fetch`**: everything `search` does, plus reading the page behind a URL, so the page's text goes into the agent's context. You need it when the answer is inside a page: a specification, one section of an API reference, an issue thread, or a URL you put in the task.
178
-
179
- The two are separate levels because the risk is different. Text read from a page can carry instructions written for the agent ("ignore your rules and ..."), known as prompt injection. With `fetch` that text arrives in full; with `search` only snippets do. The more an agent can do (edit your repository, run commands), the more this matters.
180
-
181
- **Which agents to give it to.** Start with nothing. Give `search` to roles that look things up. Give `fetch` only to roles that really must read specific pages and do little editing, such as a requirements or research role like `pm`. Keep the members that edit your repo (for example `fe-member`, `qa-member`) off, and have the lead or the pm look things up and put the result in the task.
182
-
183
- ### Things to know
184
-
185
- - **Unset is not `none`.** Unset leaves each runtime's own default alone: Claude Code has no web tools, but Codex may already have web search on. Set `none` to turn it off explicitly.
186
- - **Codex has one `web_search` setting, not two tools**, so `search` and `fetch` map to `cached` and `live`. As Codex describes them, `cached` answers from an index instead of browsing, and `live` searches the web in real time; this is an approximation by risk. `codex exec` takes no `--search` flag, so agent-lyceum passes `-c web_search="..."`.
187
- - **Not run end to end.** The Codex setting and its allowed values were checked against Codex 0.160.0, but the behaviour of `cached` / `live` and of Claude's two tools was not exercised against the real CLIs (that costs tokens). Try it once on the agent before relying on it.
188
- - `call` reads the field from `team.yaml`, and `run --agent` keeps it.
189
-
190
- ```yaml
191
- # team.yaml
192
- agents:
193
- pm:
194
- runtime: claude-code
195
- allow_web: fetch # may search and read pages; agents without the field have no web tools
59
+ pm: { can_message: [lead], allow_web: fetch }
196
60
  ```
197
61
 
198
- ## Write scope
62
+ Folder layout, every agent field and the rules `doctor` checks: [Configuration](docs/configuration.md).
199
63
 
200
- Default rules (everything else in the repo is unrestricted):
64
+ ## Topics
201
65
 
202
- | Target | Rule |
66
+ | Topic | Read |
203
67
  |---|---|
204
- | own memory dirs, own `outbox/` | writable |
205
- | any `AGENT.md`, `COMMON.md`, repo `CLAUDE.md`/`AGENTS.md` | read-only; the lead (`can_edit_agent_md`) may edit them |
206
- | the run's handoff notes `task-memory/<run-id>/_shared/` | the lead writes; every other agent is read-only |
207
- | other agents' memory/inbox/outbox, `runs/`, config files | not writable |
208
-
209
- Enforcement is layered because no single mechanism is complete:
210
-
211
- - **Claude Code**: per-run `--settings` with `Edit(...)` rules **plus** the OS sandbox (`allowWrite`/`denyWrite`, `allowUnsandboxedCommands: false`). Without the sandbox, `python -c` and similar bypass Edit rules, so the sandbox is required for the `os` level.
212
- - **Codex**: `-s workspace-write` with `-c sandbox_workspace_write.writable_roots=[...]` (OS-enforced). Codex cannot forbid a single file inside the repo, so repo `CLAUDE.md`/`AGENTS.md` are protected by **post-hoc detection** only.
213
- - **All runtimes**: protected files are hashed before the run; after each wake-up unauthorized changes are reverted, logged, and reported to the lead; what was written is kept in `runs/<run-id>/violations/` first.
214
-
215
- `doctor` and `run` print every agent's level per category (`os`, `tool-rules`, `post-hoc`, `prompt-only`) and the paths it can write outside the repo. With `dispatcher.strict: true`, a run is refused unless memory, `AGENT.md`, other agents' context and (for non-lead agents) the handoff notes are OS-enforced.
216
-
217
- Git in agent worktrees: an agent can write its worktree's `.git` pointer file and its private git dir, which could make git read a config or hooks the agent planted. So every git call the dispatcher makes into an agent's worktree pins the git dir, common dir and work tree recorded when the worktree was made, turns off hooks, fsmonitor, external diff and textconv, and refuses a worktree whose git files were redirected or linked elsewhere, whose HEAD is not its own branch, or that contains a nested repository. Claude additionally may not write those pointer files (`denyWrite`); Codex cannot forbid single files and relies on the pinning alone. Residual risks are listed in [spec 15](docs/specs/15-worktree-git-isolation.md#156-殘留風險). This does not claim the dispatcher can never run code an agent planted. A repository using the `reftable` ref backend is refused in worktree modes.
218
-
219
- Known gaps: Claude Code's built-in Edit/Write tools are not sandboxed (covered by the `Edit` rules); Codex MCP tools and hooks run outside its sandbox; `--dangerously-bypass-approvals-and-sandbox` / `danger-full-access` disable everything. With `can_edit_agent_md`, a Codex lead's writable roots widen to whole agent directories.
68
+ | Run lifecycle, parallel agents, several runs at once, follow-ups, opening a PR | [How a run works](docs/how-it-works.md) |
69
+ | What agents may write, sandbox levels, known gaps | [Write scope](docs/write-scope.md) |
70
+ | Letting an agent search or fetch the web | [Web access](docs/web-access.md) |
71
+ | Live run status inside Claude Code | [Monitor mod](docs/monitor.md) |
72
+ | All commands in full | [Commands](docs/commands.md) |
73
+ | Coming from an older version | [Upgrading to run v2](docs/upgrading-run-v2.md) |
package/README.zh-TW.md CHANGED
@@ -4,216 +4,70 @@
4
4
 
5
5
  [English](README.md) | **繁體中文**
6
6
 
7
- 設定並執行一個由多個 **agent**(Claude Code 和/或 Codex)組成的團隊。agent 之間透過檔案信箱互相溝通,每個 agent 都有自己的人設(`AGENT.md`)與長期記憶資料夾。寫入權限有範圍限制:agent 只能修改自己的記憶與寄件匣(outbox),不能改動其他 agent 的 context,也不能改自己的人設。
7
+ 在你的 repo 上執行一個由多個 **agent**(Claude Code 和/或 Codex)組成的團隊。agent 之間透過檔案信箱溝通,各自有人設(`AGENT.md`)與長期記憶。agent 只能寫自己的記憶與寄件匣(outbox),不能改其他 agent 的 context,也不能改自己的人設。
8
8
 
9
- 此工具**不會把自己的資料放進你的 repo**:設定、信箱、log、任務記憶與 agent 的 worktree 都放在一個看得到的資料夾 `~/agent-lyceum-config/`(可用 `AGENT_LYCEUM_HOME` 或 `--home` 覆寫)。但 agent *產出的成果*是另一回事:agent 會修改你的 repo(序列執行時直接修改;平行執行時在各自的 git worktree 修改,再把變更整合進你的工作目錄)。agent-lyceum 自己在你的 repository 內唯一新增的是 git 的管理資料:平行 run 存在期間,`.git` 下會有 `refs/agent-lyceum/<run-id>/*` 快照 ref、`agent-lyceum/<run-id>/<agent>` branch 與 worktree 登記,`agent-lyceum clear` 會把它們移除。從舊版升級請見 [docs/upgrading-run-v2.md](docs/upgrading-run-v2.md)。
9
+ ## 快速開始
10
+
11
+ 需求:Node 20+,以及 `PATH` 中有 `claude` 和/或 `codex`(已登入)。支援 macOS 與 Linux(Linux 需要 `bwrap` 才有 OS 沙箱);Windows 只會顯示警告。
10
12
 
11
13
  ```bash
12
- npx agent-lyceum init # 建立 home 與全域 agent 庫
14
+ npx agent-lyceum init # 建立 home 與全域 agent 庫
13
15
  npx agent-lyceum project add web --dir ~/code/web-app
14
- npx agent-lyceum doctor --project web # 檢查設定並顯示各項防護等級
15
- npx agent-lyceum run --task-file spec.md # 在 repo 內執行時會自動偵測專案
16
+ npx agent-lyceum doctor --project web # 檢查設定並顯示各項防護等級
17
+ npx agent-lyceum run --task-file spec.md # 在 repo 內執行時會自動偵測專案
16
18
  npx agent-lyceum status
17
19
  ```
18
20
 
19
- 安裝後的執行檔名稱為 `agent-lyceum`。若要直接跑 GitHub 上尚未發佈的最新程式碼,可改用 `npx github:gogogohuang/agent-lyceum <command>`。
20
-
21
- 需求:Node 20+,以及 `PATH` 中有 `claude` 和/或 `codex`(且已登入)。支援 macOS 與 Linux(Linux 需要 `bwrap` 才有 OS 沙箱);Windows 只會顯示警告。
22
-
23
- ## 指令
24
-
25
- | 層 | 指令 | 功能 |
26
- |---|---|---|
27
- | 專案 | `init [-y]` | 建立 home 與全域 agent 庫。 [詳細](docs/commands.zh-TW.md#init) |
28
- | 專案 | `project add <name> --dir <repo>` | 註冊專案。 [詳細](docs/commands.zh-TW.md#project-add) |
29
- | 專案 | `project` / `project remove <name> [--purge]` | 列出或取消註冊專案。 [詳細](docs/commands.zh-TW.md#project-and-project-remove) |
30
- | 診斷 | `doctor [-p name] [--task-file f] [--resolved] [--json]` | 不執行 agent,檢查設定(含防護等級)、git、鎖與 runtime CLI;`--resolved` 印出每項生效設定與其來源。 [詳細](docs/commands.zh-TW.md#doctor) |
31
- | 診斷 | `status [-p name] [--monitor]` | 顯示 agent、信件、目前執行與歷次 run(支援 `--json`、`--monitor`);`--task-id` 接受 id、名稱或唯一前綴。 [詳細](docs/commands.zh-TW.md#status) |
32
- | 執行 | `run ["task"] [--task-file f] [--name n] [--agent a] [-p name]` | 把任務交給 lead 並執行到結束;`--name` 為 run 命名;加 `--agent` 則只交給某個成員單獨做。 [詳細](docs/commands.zh-TW.md#run) |
33
- | 執行 | `resume [run] ["追加要求"] [--task-file f] [--answer] [-p name]` | 接續被中斷或失敗的 run,或用追加要求重開已完成的 run;`--answer` 會先回答它等待中的問題。 [詳細](docs/commands.zh-TW.md#resume) |
34
- | 執行 | `clear <run> [-p name] [--dry-run] [--keep-worktrees]` / `clear --lock [run-id] --force` | 刪除 run(id、名稱或唯一前綴)與其任務記憶、worktree;或移除當機 run 留下的專案鎖。 [詳細](docs/commands.zh-TW.md#clear) |
35
- | 執行 | `call <agent> ["task"] [--task-file f] [--dir d]` | 單獨呼叫一個 global agent(不需專案),印出它的回答。 [詳細](docs/commands.zh-TW.md#call) |
36
- | 執行 | `tidy [-p name] [--agent a] [--layer project\|global] [--dry-run]` | 讓 agent 整理自己的記憶(只能手動觸發;封存而非刪除)。 [詳細](docs/commands.zh-TW.md#tidy) |
37
- | 執行 | `tidy --undo <時間戳> -p name --agent a` | 還原一次整理:把封存的檔案搬回。 [詳細](docs/commands.zh-TW.md#tidy) |
38
-
39
- `agent-lyceum --help` 只列出每個指令的一行簡述;`agent-lyceum <指令> --help` 會印出該指令的完整說明與選項。
21
+ 要跑尚未發佈的最新程式碼:`npx github:gogogohuang/agent-lyceum <command>`。
40
22
 
41
- Ctrl-C 會乾淨地取消 run,之後可用 `resume` 接續([中止 run](docs/commands.zh-TW.md#中止-run))。`run`/`resume` 只有在 lead 回報 `completed` 時才 exit `0`;`partial`/`blocked` 為 `2`,`failed` 為 `1`,等待你回答時為 `3`,取消為 `130`([退出碼](docs/commands.zh-TW.md#退出碼))。未指定 `-p` 時,專案由目前目錄推斷([選擇專案](docs/commands.zh-TW.md#選擇專案))。
23
+ ## 運作方式
42
24
 
43
- ## 單獨呼叫一個 agent
25
+ 1. 你的任務會成為寄給 **lead** 的第一封信。
26
+ 2. dispatcher 喚醒有未讀信的 agent(無頭模式的 `claude -p` / `codex exec`)。
27
+ 3. agent 把回信寫進自己的 `outbox/`,dispatcher 檢查 `can_message` 後投遞。
28
+ 4. lead 寄出 `done` 時,run 結束。
44
29
 
45
- 有兩種方式把任務只交給單一 agent,而不是整個團隊。該 agent 獨自工作:不能寄信給隊友、不能向你提問、不能修改任何 `AGENT.md`。
30
+ 工具自己的資料(設定、信箱、log、記憶、worktree)放在 `~/agent-lyceum-config/`,不放進你的 repo。agent 直接修改你的 repo;平行執行時則在各自的 git worktree 修改。agent-lyceum 不會幫你合併。詳見[一次執行如何運作](docs/how-it-works.zh-TW.md)、[設定](docs/configuration.zh-TW.md)。
46
31
 
47
- ```bash
48
- npx agent-lyceum run "整理表單" --agent fe-member -p web # 專案裡的一個成員,當作一般 run
49
- npx agent-lyceum call pm "這個需求可以開工了嗎?" --dir ~/code/web-app # global agent,不屬於任何專案
50
- ```
51
-
52
- `run --agent` 有 run id 與專案鎖、會出現在 `status`、可以 `resume`;agent 用自己寄出的 `done` 結束 run。`call` 完全不需要專案:agent 取自 `team.yaml`,在 `--dir`(預設是目前目錄,且不可位於 agent-lyceum home 之內或之上)工作,stdout 只印它的最終回答,並在 `<home>/calls/<call-id>/` 留下 `task.md`、`log/` 與 `result.md`。細節見 [run](docs/commands.zh-TW.md#run) 與 [call](docs/commands.zh-TW.md#call)。
53
-
54
- ## 監控 mod(Claude Code)
55
-
56
- `plugins/status-monitor` 是 Claude Code **mod**,不是一般的 plugin:它依 Claude Code 的 mod hooks API 撰寫(`import type { Register } from 'claude-code'`),在 Claude Code session 內執行,提供通知與 `/status-monitor` 面板,並輪詢 `agent-lyceum status --json`。需要支援 mod 的 Claude Code 版本;不會改變 agent-lyceum 本身的運作。會顯示一個或多個專案的即時執行狀態。
57
-
58
- **載入。** 先 build(`npm run build`;mod 會執行 `dist/cli.js`),再用下面的指令啟動 session:
59
-
60
- ```
61
- claude --plugin-dir /path/to/agent-lyceum/plugins/status-monitor
62
- ```
63
-
64
- `--plugin-dir` 只在 session 啟動時生效,已開著的 session 要重開(`claude --resume --plugin-dir ...` 可保留對話)。想每次都載入,就在 shell rc 加 `alias claude='claude --plugin-dir /path/to/agent-lyceum/plugins/status-monitor'`;無法帶參數的環境(桌面 app、SDK)則把 `CLAUDE_CODE_PLUGIN_DIRS` 設成 mod 資料夾。session 執行中儲存 mod 資料夾內的檔案會自動 hot reload。
65
-
66
- **操作。**
67
- - **通知:** 執行完成、被中斷或某個 agent 喚醒失敗時會跳出訊息(監看多個專案時前面加 `[專案名]`),不需要任何操作。
68
- - **`/status-monitor`:** 輸入即開啟面板(已開著則關閉)。session 啟動時預設不開,除非設定 `autoOpen`。在 **fullscreen 版面**(`~/.claude/settings.json` 設 `"tui": "fullscreen"` 後重開 session;`/tui fullscreen` 效果相同)且終端寬度 110 欄以上時,面板會靠右 dock 在終端寬度的一半,分頁與 **關閉** 都可以用滑鼠點。否則顯示在輸入框上方;版面在 session 啟動時就固定,從主畫面啟動的 session 不會變。鍵盤操作兩種版面都能用:`x` 關閉,`v` 切換圖形/文字,`e` 展開/收合細節,`1`-`9` 或 Tab/Enter 切換任務,Esc 回到輸入框,再執行一次指令也會關閉。面板為每個 agent 畫一個區塊,並依 `can_message` 在 lead 與各成員之間畫出連結(`▼` lead 可寄給成員、`▲` 成員可寄給 lead、`↕` 雙向;黃色表示最近一次寄信的那條邊)。每個區塊顯示該 agent 現在在做什麼、正在處理與排隊中的信,每封信預設只顯示一行重點:依信種挑出它在講什麼(task 是目標,reply 是變更,done 是結果),再加上信裡回報的待辦、風險或未完成(寫 None 就不顯示)——不是把開頭截短。按 `e` 展開:每封信的每個段落(task 看目標與驗收,reply 看變更、驗證、待辦與風險,done 看結果與未完成)和完整的步驟清單;收合時清單只有進度條與目前步驟。每個區塊也顯示喚醒次數與輸出 token。正在運作的 agent 會被放大:它的區塊獨佔一整列、使用全寬,文字自動換行而不截斷;閒置與排隊中的區塊維持精簡。圖形上方是執行 id 與狀態、任務、進度條與清單;下方是受阻的整合、備註與結果摘要。按 `v` 切換成純文字清單(各 runtime 的 token、各 agent 統計、最近 8 次喚醒)。每個區塊以「→」一行列出它可以寄信的對象,最近一次寄信的對象標 「●」(成員之間的對象也在此,不畫符號)。當圖形區域寬度少於 70 欄(以面板本身的寬度比較,由 host 回報),區塊改成單欄堆疊,不畫連結符號。每個執行中的任務是一個分頁,最新的排最前面;已結束或已中斷的不列出。面板開著時會依輪詢間隔自動更新。
69
-
70
- **設定。** 在 `~/.claude/settings.json` 的 `pluginConfigs."status-monitor@inline"`(`options`):
71
-
72
- | 選項 | 說明 | 預設 |
73
- |---|---|---|
74
- | `command` | 要執行的 CLI,以空白分隔,例如 `node /path/to/agent-lyceum/dist/cli.js` | `agent-lyceum` |
75
- | `project` | 已註冊的專案名稱(`-p`);用逗號分隔可同時監看多個;留空則依 session 所在目錄推斷 | 空 |
76
- | `intervalSeconds` | 輪詢狀態的間隔(秒) | `1` |
77
- | `autoOpen` | session 啟動時自動開啟面板(未經操作開啟時,終端需 144 欄以上才會顯示) | `false` |
32
+ ## 指令
78
33
 
79
- 設定變更要等下次啟動 session 才生效。面板若顯示 `無法取得狀態:...`,通常是 `command` 跑不起來(多半是還沒 build `dist/cli.js`),或專案名稱沒有註冊。
34
+ | 指令 | 功能 |
35
+ |---|---|
36
+ | `init` | 建立 home 與全域 agent 庫。 [詳細](docs/commands.zh-TW.md#init) |
37
+ | `project add` / `project` / `project remove` | 註冊、列出或移除專案。 [詳細](docs/commands.zh-TW.md#project-add) |
38
+ | `doctor` | 不執行 agent,檢查設定、git、鎖與 runtime CLI。 [詳細](docs/commands.zh-TW.md#doctor) |
39
+ | `status` | 顯示 agent、信件、目前的喚醒與過去的 run。 [詳細](docs/commands.zh-TW.md#status) |
40
+ | `run` | 把任務交給 lead,執行到完成。 [詳細](docs/commands.zh-TW.md#run) |
41
+ | `resume` | 繼續中斷的 run,或用追加需求重開已完成的 run。 [詳細](docs/commands.zh-TW.md#resume) |
42
+ | `clear` | 刪除 run,或移除殘留的鎖。 [詳細](docs/commands.zh-TW.md#clear) |
43
+ | `call <agent>` | 在任何專案之外單獨呼叫一個全域 agent。 [詳細](docs/commands.zh-TW.md#call) |
44
+ | `tidy` | 讓 agent 整理自己的記憶(只封存,不刪除)。 [詳細](docs/commands.zh-TW.md#tidy) |
80
45
 
81
- ## 目錄結構
46
+ `agent-lyceum <指令> --help` 會印出完整選項。Ctrl-C 可乾淨取消;腳本可依[結束碼](docs/commands.zh-TW.md#退出碼)判斷 run 的結果。
82
47
 
83
- ```
84
- ~/agent-lyceum-config/
85
- ├── team.yaml # 全域 agent 庫
86
- ├── agents/<agent>/{AGENT.md, memory/} # 全域人設 + 跨專案記憶
87
- ├── calls/<call-id>/{task.md, log/, result.md} # 每次 `call`(不屬於任何專案)一個資料夾,另有 .lock-<agent>
88
- └── projects/<project>/
89
- ├── project.yaml # 團隊、repo 路徑、覆寫設定
90
- ├── agents/<agent>/{AGENT.md?, memory/} # 專案層人設(選用)+ 專案記憶
91
- ├── shared/common/COMMON.md
92
- ├── locks/<run-id>.json # 該 run 執行期間持有(同時最多 dispatcher.max_concurrent_runs 個)
93
- ├── task-memory/<run-id>/{<agent>/, _shared/} # 任務記憶:每次 run 獨立,不與其他任務共用;_shared 是 lead 為追加要求寫的交接筆記
94
- └── runs/<run-id>/{task.md, log.jsonl, state.json, result.md, done-<n>.md, followups/<n>.md, snapshots/, agents/, mail/{inbox,outbox}/<agent>/}
95
- ```
48
+ ## 設定
96
49
 
97
- `team.yaml` 定義可重複使用的 agent;`project.yaml` 選擇團隊並覆寫欄位。物件會逐欄位合併,陣列(`can_message`、`owns`)則整個取代。相對路徑以寫入該路徑的檔案所在資料夾為基準;允許使用 `~`。
50
+ `team.yaml` 定義可重複使用的 agent;`project.yaml` 選定團隊並覆寫欄位:
98
51
 
99
52
  ```yaml
100
53
  # project.yaml
101
54
  dir: ~/code/web-app
102
55
  team: { lead: lead }
103
- dispatcher: { max_rounds: 0, max_parallel: 1, max_concurrent_runs: 1, wake_timeout_sec: 600, retry: 2, strict: false, workspace_mode: auto, log_max_bytes: 8388608 }
104
56
  agents:
105
- lead: { resume: true, can_message: all, can_edit_agent_md: true }
57
+ lead: { can_message: all, can_edit_agent_md: true }
106
58
  fe-member: { runtime: codex, can_message: [lead], owns: ["src/web/**"] }
107
- qa-member: { can_message: [lead], owns: ["tests/**"] }
108
- pm: { can_message: [lead], allow_web: fetch } # pm 可以搜尋並讀網頁;其他人沒有網路工具
109
- ```
110
-
111
- Agent 欄位:`runtime`(`claude-code`|`codex`;若 `model` 可辨識則可省略:`opus`/`sonnet`/`haiku`/`claude-*` → Claude Code,`gpt-*`/`o3`/`*codex*` → Codex;優先順序:專案 runtime > 專案 model > 全域 runtime > 全域 model)、`model`、`effort`(Claude Code:`low`|`medium`|`high`|`xhigh`|`max`,經 `--effort`;Codex:`minimal`|`low`|`medium`|`high`|`xhigh`,經 `model_reasoning_effort`;未設則用 CLI 預設)、`agent_md`、`memory.global` / `memory.project`、`resume`、`can_message`(`all` 或清單;預設 `[lead]`,lead 預設 `all`)、`can_edit_agent_md`(預設只有 lead)、`can_ask_user`(可用 `type: ask` 信件向你提問並暫停 run 等待回答;預設只有 lead)、`allow_web`(`none`|`search`|`fetch`:agent 可以使用多少網路,不設就是不開;見下方「網路存取」)、`owns`(repo glob)。
112
-
113
- `doctor` 檢查的規則:至少 2 個 agent(lead 加一位成員;範本預設是三位)、lead 在 agent 清單內、每個 agent 都有 runtime(明設或由 `model` 推斷)且 `AGENT.md` 存在、`effort` 對該 runtime 合法(若 `runtime` 與可辨識的 `model` 矛盾則警告)、`can_message` 的目標存在、記憶資料夾互不重疊,且當 `max_parallel > 1` 時,每個非 lead 的 agent 都必須有互不重疊的 `owns`,repo 也必須是 git repository;而 `max_concurrent_runs > 1` 時,repo 必須是 git repository,且 `workspace_mode` 不能是 `shared`。
114
-
115
- ## 一次執行如何運作
116
-
117
- 1. 任務(文字,或 `--task-file` 的唯讀副本 `runs/<id>/task.md`)會成為寄給 lead 的第一封信。≤ 16 KB 的任務直接內嵌,更大的改以引用方式傳遞。超過 1 MB 的檔案會被拒絕。
118
- 2. dispatcher 用 `claude -p` 或 `codex exec`(headless)喚醒有未讀信件的 agent。除非設定 `resume: true`,否則每次喚醒都是全新的 session。
119
- 3. 每次喚醒的 prompt 都包含:該 agent 的 `AGENT.md`、團隊協定、`COMMON.md`(唯讀,≤ 8 KB)、每個記憶資料夾的 `MEMORY.md` 索引、**最舊**一封未讀信件全文(每次喚醒只處理一封;lead 例外,會一次拿到連續最多 5 封 `reply`/`failure` 並一併決策),以及排隊中信件的標題;排隊的信維持未讀,等各自的喚醒再處理。
120
- 4. agent 寄信的方式,是在**自己的** `outbox/` 寫一個含 frontmatter(`to`、`type`、`subject`)的 Markdown 檔。dispatcher 會檢查 `can_message`、蓋上真正的寄件者,並移到收件者的 `inbox/`。處理完的信件移至 `inbox/<agent>/read/`。信箱屬於單一 run(`runs/<run-id>/mail/`),信件不會跨 run。舊版本啟動的 run 繼續使用共用的 `shared/{inbox,outbox}/` 信箱(信件不會被搬移),接續這類 run 時會沿用舊版配置。
121
- 每封 `task` 和 `reply` 的內文應包含固定的 `##` 標題(會注入每個 agent 的 prompt):`task` → `Goal`、`Acceptance criteria`、`Scope`、`Upstream`;`reply` → `Changes`、`Verification`、`Open items`、`Risks`(沒內容就寫 `None`;`done` 免檢)。缺標題的信仍會送達,但開頭會加上警告說明,run log 也會記一筆 `format-warning`。
122
- 5. 結束條件:lead 寄出 `type: done`、所有信箱都空了,或(有設上限時)喚醒次數達到 `max_rounds`;預設 `0` 代表不限輪數。`done` 的 frontmatter 必須有 `outcome: completed|partial|blocked|failed`,內文要有 `## Result`、`## Files`、`## Verification`、`## Not done`;`completed` 還要求 `## Steps` 全部勾選。不符合的 `done` 會退回給 lead(最多兩次,之後以 `partial` 收下)。agent-lyceum 不會驗證 lead 回報的內容是否屬實。喚醒失敗最多重試 `retry` 次(預設 2,即最多呼叫 3 次);仍然失敗就停止整個 run(成員失敗為 `agent_failed`,lead 失敗為 `lead_failed`),不會少了它繼續跑:它正在處理的那封信維持未讀,結束訊息會告訴你怎麼查原因與怎麼繼續(修正後 `agent-lyceum resume <run>`,或用 `clear` 放棄)。同一個寄件人寄給同一個收件人、type、reply_to 與內文(忽略空白差異)都相同的信不會再被投遞,並通知寄件人,避免兩個 agent 對著同一封信繞圈。
123
-
124
- 平行執行(`max_parallel > 1`)只會同時跑 `owns` 互不相交的 agent,且絕不與 lead 同時執行。此時每個非 lead 的 agent 都在**自己的 git worktree**(`projects/<name>/worktrees/<run-id>/<agent>`,branch `agent-lyceum/<run-id>/<agent>`)工作;worktree 是從喚醒當下 repo 的快照(`refs/agent-lyceum/<run-id>/base-<n>`,包含 lead 尚未提交的修改與新增、未被 ignore 的檔案)切出來的,你的 HEAD、branch 與工作目錄都不會被動到。`dispatcher.workspace_mode` 可設為 `auto`(`max_parallel > 1` 時用 worktree)、`worktree` 或 `shared`;`shared` 不能與平行 agent 並用。平行 run 在 repo 有你自己未提交的修改時,或 repo 不是 git repository 時,會拒絕啟動(請改為序列執行)。成員完成後,dispatcher 會提交它 worktree 中的修改,並在 lead 讀到該成員的信之前,把變更套用到你的工作目錄(不動你的 index 與 HEAD)。每個被改動的路徑都會先檢查:必須在該成員的 `owns` 內(rename 與刪除也算)、不得是 `CLAUDE.md`/`AGENTS.md`,symlink 不得指向專案或該成員 `owns` 之外。若同一檔案在成員的快照之後又在你的 repo 被改過、檢查未通過,或 `git apply` 失敗,就一個檔案都不套用:成果保留在它的 branch 與 worktree,報告與 patch 寫到 `runs/<run-id>/integration/`,並通知 lead,且這個 run 不能以 `completed` 結束(會以 `blocked` 結束)。worktree 只隔離檔案,無法隔離對外部服務、資料庫或網路的副作用。
125
-
126
- ### 同時執行多個 task
127
-
128
- 預設一個專案一次只跑一個 task。設定 `dispatcher.max_concurrent_runs: N`(N > 1,需要 git repository)後,同一專案最多可有 N 個 run 同時進行;再多開一個會被拒絕,並列出擋住的 run。此模式下**每個** run(包括沒有平行成員的 run,以及單獨的 `run --agent <name>`)都在自己的 git worktree 工作:lead 在 `projects/<name>/worktrees/<run-id>/<lead>`、branch 為 `agent-lyceum/<run-id>/<lead>`,成員的 worktree 則從 lead 的內容分出。run 從你 repo 的 `HEAD` 起跑,所以允許你有未提交的修改,但這些修改**不會**在其中(啟動訊息會寫出有幾個檔案)。你的工作目錄、index 與 HEAD 一律不會被動到。
129
-
130
- - **結束:** run 結束時(done、cancelled、failed、idle 或達到輪數上限),lead 的成果會一次提交在它的 branch 上,並寫成 `runs/<run-id>/lead.patch`,run 會印出 `git merge <branch>`。停下來向你提問(`waiting`)的 run 還沒結束:不會提交、也不會印 merge 提示;成果留在 lead 的 worktree,`resume` 會在同一個 worktree 繼續。
131
- - **啟動時決定:** run 會在狀態中記錄 lead 是否在 worktree 工作(`lead_workspace`)。`resume` 沿用 run 啟動時的方式,而不是看目前的設定:以併發模式啟動的 run,即使你之後調低 `max_concurrent_runs`,仍會在它的 worktree 接續;以非併發模式啟動的 run,即使你之後調高,仍以非併發方式接續。這個設定只決定同時可有幾個 run,以及新的 run 怎麼做。
132
- - **`tidy`:** `tidy` 與 `tidy --undo` 需要獨占專案:有任何 run 在執行時會拒絕,執行期間也不能啟動任何 run,與 `max_concurrent_runs` 的值無關。
133
- - **`clear`:** lead 的 branch 尚未合併時,`clear <run-id>` 會拒絕(用 `--keep-worktrees` 可保留它)。當機 run 留下的鎖用 `clear --lock [run-id] [-p name] --force` 移除;有多把鎖時要指定是哪個 run。
134
-
135
- 已知限制:
136
-
137
- - agent 程序數量最多可達 `max_concurrent_runs × max_parallel`,沒有全域上限。
138
- - `can_edit_agent_md: true` 的 lead 修改的是它自己 worktree 裡的 `CLAUDE.md`/`AGENTS.md`;這些修改要等你合併它的 branch 才會進到你的 repo。
139
- - `COMMON.md` 與各 `AGENT.md` 由專案的所有 run 共用。每個 run 的防護只判斷它自己的 agent 工作期間發生的修改,所以某個 run 的修改會被保留;但若兩個 run 的喚醒時間重疊,一個 run 在另一個 run 的 agent 工作期間所做的修改,可能被另一個 run 還原。
140
- - 兩個 run 修改同一個檔案時,要由你在合併時自行整合;agent-lyceum 從不自動合併。
141
-
142
- ### 接續已完成的 run
143
-
144
- 每個 run 都有**名稱**:由 task 第一行產生(小寫字母、數字與 `-`,最多 30 字元;沒有可用字元時用 `task`;重複時加 `-2`、`-3`),或用 `run --name <name>` 指定(字元與長度限制相同;名稱已被使用會拒絕)。`resume`、`clear` 與 `status --task-id` 接受完整 run id、名稱,或兩者之一的唯一前綴;前綴有歧義時會列出候選並以 `1` 結束,空字串會被拒絕。`status` 會在 id 旁顯示名稱。
145
-
146
- 已完成(`done`)的 run 可以用追加要求重開:`agent-lyceum resume [run] "<追加要求>"`(或 `--task-file f`)。lead 會把這段文字當成新的 `task` 收到,run 沿用同一個 run 目錄、任務記憶、session 與 lead 的 worktree 繼續。
147
-
148
- - **哪些 run:** 只有已完成的 run 能重開。仍在執行的 run 會拒絕;尚未完成的 run 若帶文字也會拒絕(先不帶文字 resume 它)。不帶文字時行為不變:已完成的 run 只印出結果。沒指定 run 時,候選是已完成的 run,由新到舊:剛好一個就用它,沒有就報錯,有多個就列出(在終端機可用編號或名稱選;非互動環境則報錯並列出候選)。只有一個參數時,只有在它不可能是 run 參照(含空白,或含 run 名稱不能用的字元)才會被當成追加要求;單一個詞的追加要求要寫成 `resume <run> "<text>"` 或用 `--task-file`。
149
- - **保留什麼:** 追加要求存成 `runs/<run-id>/followups/<n>.md`。每份 `done` 報告保留為 `done-<n>.md`,`result.md` 永遠是最新一份。`state.json` 新增 `name`、`reopened`、`round_floor`、`step_base`(都是選填,舊的 run 照樣能讀)。進度(`## Steps`)會接續:重開時的清單保留,lead 為追加要求列的步驟接在後面(再次列出的舊步驟只更新勾選狀態);追加要求的 `completed` 只要求它自己的步驟全部勾選。未解決的 blocked integration 會保留;每段重開的 done 規範提醒重新計算。
150
- - **輪數上限:** 有設 `max_rounds` 時,它從重開時起算:`rounds` 持續累加,上限是重開當下的輪數加 `max_rounds`。
151
- - **lead 的 branch**(lead 有 worktree 的 run):若該 branch 已合併進你的 `HEAD`,且 lead 的 worktree 乾淨、自 run 結束後沒被動過,worktree 與 branch(同名,`agent-lyceum/<run-id>/<lead>`)會從你目前的 `HEAD` 重新切出,並印一行說明。否則沿用原本的 worktree 與 branch。若已記錄 PR(`pr_url`)且 branch 沒有重切,新的 `open_pr: true` 只會 push(「pull request updated」),而且只在該 PR 仍開啟時;若它已被合併(含 squash merge)或關閉,就改開一個新的 PR;若 branch 重切了,已記錄的 `pr_url` 會被清掉(舊網址留在 run 的 notes),要求時再開一個新的 PR。agent-lyceum 仍然從不合併。
152
- - **交接筆記:** lead 在送 `done` 之前,把追加要求會用到的內容寫進 agent-lyceum home 裡的 `task-memory/<run-id>/_shared/`(`MEMORY.md` 為索引):做過的決定與理由、介面約定、目前狀態、剩下的事與下一步、踩過的坑。成員可讀不可寫(用 `run --agent` 啟動的 run 只有一個 agent,它就是自己的 lead,所以可寫;`call` 沒有這個資料夾)。run 重開後,每個 agent 的每次喚醒都在 prompt 裡拿到 `MEMORY.md`(前 8 KB,較長的索引會被截斷並標示),重開的 `task` 信的 `Upstream` 也會指向它;第一段的 prompt 不含它。若 lead 在該段沒有更動 `MEMORY.md` 就送出 `done`,run 不會被擋,只會在 run 的 notes 加一筆 `shared-not-updated`。`clear` 會連同任務記憶一併刪除;`tidy` 不會動它。只放這個 task 的筆記,跨 task 的教訓仍放 project 或 global memory。
153
-
154
- ### 開 PR
155
-
156
- 當你的 task 要求開 PR 時,lead 會在它的 `done` 報告的 frontmatter 加上 `open_pr: true`。如果 run 之後以 `completed` 結束,且 lead 的 branch 有變更,就由 agent-lyceum(不是 agent)把 `agent-lyceum/<run-id>/<lead>` 推到 `origin`,並對 repo 的預設分支執行 `gh pr create`,以 lead 的報告作為描述(結尾為 `🤖 Opened by agent-lyceum`)。run 的結果會印出 PR 網址,`state.json` 也會把它記為 `pr_url`。只有 lead 能提出要求:其他人都不能送出 `done`,也沒有任何 agent 的沙箱被放寬——`git push` 與 `gh` 在沙箱外以你自己的憑證執行。
157
-
158
- - 它需要 lead 的 branch,所以只有在 run 有自己的 worktree 時(`dispatcher.max_concurrent_runs` 為 2 或以上)才有作用。否則這個要求會被回報並略過。
159
- - 無法照辦的要求(run 沒有完成、沒有變更、沒有 `gh`、沒有 `origin`、push 或 `gh` 失敗)絕不會改變 run 的結果。run 會說明沒有開的原因並保留 branch;push 或 `gh pr create` 失敗時,還會印出可手動完成的指令。
160
- - 開 PR 會把 lead 的 branch 與報告發布到 `origin`。因此,提出要求(`open_pr: true`)的 agent 能把它在沙箱內讀得到的任何東西送上遠端,所以只有在可以接受這件事時,才在 task 裡要求開 PR。push 與 `gh pr create` 從你的主 repo 執行,絕不在 agent 的 worktree 裡執行,因為 agent 能寫入那個目錄。
161
- - agent-lyceum 從不合併,也不等待 CI 或審查。`max_concurrent_runs` 為 2 以上時,`doctor` 會告訴你有沒有 `gh` 與 `origin`(不會檢查 `gh` 是否已登入)。
162
-
163
- ## 網路存取(`allow_web`)
164
-
165
- 預設所有 agent 都不能使用網路。Claude Code 的 agent 是用無頭的 `dontAsk` 模式喚醒的,沒有明確允許的工具一律拒絕,所以 `WebSearch` 與 `WebFetch` 會被擋掉,要替個別 agent 用 `allow_web` 開放(寫在 `team.yaml` 或 `project.yaml`,專案層蓋過全域層)。它只決定 agent 能不能用網路工具,下面的寫入範圍不變。
166
-
167
- | 值 | Claude Code | Codex |
168
- |---|---|---|
169
- | 不設 | 不給網路工具(與以前相同) | 不傳任何設定:維持 Codex 自己的預設 |
170
- | `none` | 不給網路工具 | `-c web_search="disabled"` |
171
- | `search` | `WebSearch` | `-c web_search="cached"` |
172
- | `fetch` | `WebSearch` 加 `WebFetch` | `-c web_search="live"` |
173
-
174
- ### `search` 還是 `fetch`?
175
-
176
- - **`search`**:agent 可以搜尋,拿到一串結果(通常是標題、連結與簡短摘要)。它不能打開網頁,所以只知道結果裡寫的內容。像「Node 的哪些版本還有支援?」「這個函式庫最新版是多少?」「這個 API 是不是已經棄用?」這類問題,這樣就夠了。
177
- - **`fetch`**:包含 `search` 的全部功能,再加上讀取某個網址背後的頁面,整頁文字都會進到 agent 的上下文。答案藏在頁面裡面時才需要:規格文件、API 參考的某一節、issue 討論串,或是你寫在任務裡的網址。
178
-
179
- 分成兩級,是因為風險不一樣。從網頁讀進來的文字可能夾帶寫給 agent 的指示(「忽略你的規則,去做……」),這叫 prompt injection。`fetch` 會把整頁文字送進來;`search` 只有摘要。agent 能做的事越多(改你的 repo、執行指令),這點就越重要。
180
-
181
- **該給哪些 agent。**先什麼都不開。會查資料的角色給 `search`。只有真的必須讀指定頁面、而且很少改檔的角色才給 `fetch`,例如 `pm` 這種需求或研究角色。會改你 repo 的成員(例如 `fe-member`、`qa-member`)維持關閉,由 lead 或 pm 查好,再把結果寫進任務。
182
-
183
- ### 要注意的事
184
-
185
- - **不設不等於 `none`。**不設是讓各 runtime 維持自己的預設:Claude Code 沒有網路工具,但 Codex 可能本來就開著網路搜尋。想明確關掉請設 `none`。
186
- - **Codex 只有一個 `web_search` 設定,不是兩個工具**,所以 `search` 與 `fetch` 對應到 `cached` 與 `live`。依 Codex 的說法,`cached` 是從索引回答、不即時瀏覽,`live` 是即時搜尋網路;這是依風險做的近似對應。`codex exec` 不收 `--search` 旗標,所以 agent-lyceum 改傳 `-c web_search="..."`。
187
- - **沒有實際端對端跑過。**Codex 的設定鍵與合法值用 Codex 0.160.0 確認過,但 `cached`/`live` 以及 Claude 兩個工具的實際行為,沒有用真的 CLI 跑過(會花 token)。正式依賴前,請先在該 agent 上手動試一次。
188
- - `call` 會讀 `team.yaml` 裡的這個欄位,`run --agent` 也會保留。
189
-
190
- ```yaml
191
- # team.yaml
192
- agents:
193
- pm:
194
- runtime: claude-code
195
- allow_web: fetch # 可以搜尋並讀網頁;沒設這個欄位的 agent 就沒有網路工具
59
+ pm: { can_message: [lead], allow_web: fetch }
196
60
  ```
197
61
 
198
- ## 寫入範圍
62
+ 資料夾結構、所有 agent 欄位與 `doctor` 檢查的規則:[設定](docs/configuration.zh-TW.md)。
199
63
 
200
- 預設規則(repo 內其餘部分不受限制):
64
+ ## 主題
201
65
 
202
- | 目標 | 規則 |
66
+ | 主題 | 閱讀 |
203
67
  |---|---|
204
- | 自己的記憶資料夾、自己的 `outbox/` | 可寫入 |
205
- | 任何 `AGENT.md`、`COMMON.md`、repo 的 `CLAUDE.md`/`AGENTS.md` | 唯讀;lead(`can_edit_agent_md`)可編輯 |
206
- | run 的交接筆記 `task-memory/<run-id>/_shared/` | lead 可寫;其他 agent 唯讀 |
207
- | 其他 agent 的記憶/inbox/outbox、`runs/`、設定檔 | 不可寫入 |
208
-
209
- 由於沒有單一機制是完整的,防護採分層設計:
210
-
211
- - **Claude Code**:每次執行帶入 `--settings`,內含 `Edit(...)` 規則,**加上** OS 沙箱(`allowWrite`/`denyWrite`、`allowUnsandboxedCommands: false`)。沒有沙箱時,`python -c` 之類的做法能繞過 Edit 規則,因此 `os` 等級必須啟用沙箱。
212
- - **Codex**:`-s workspace-write` 搭配 `-c sandbox_workspace_write.writable_roots=[...]`(由 OS 強制)。Codex 無法禁止 repo 內的單一檔案,所以 repo 的 `CLAUDE.md`/`AGENTS.md` 只能靠**事後偵測**保護。
213
- - **所有 runtime**:執行前會對受保護檔案做雜湊;每次喚醒後,未經授權的變更會被還原、記錄,並通報 lead;被寫入的內容會先留存在 `runs/<run-id>/violations/`。
214
-
215
- `doctor` 與 `run` 會依類別(`os`、`tool-rules`、`post-hoc`、`prompt-only`)印出每個 agent 的防護等級,以及它能寫入 repo 之外的哪些路徑。設定 `dispatcher.strict: true` 時,除非記憶、`AGENT.md`、其他 agent 的 context 與(非 lead 的 agent 的)交接筆記都由 OS 強制保護,否則拒絕執行。
216
-
217
- agent worktree 內的 git:agent 能寫它 worktree 的 `.git` 指標檔與私有 git 目錄,可能讓 git 去讀 agent 埋的設定或 hook。因此 dispatcher 對 agent worktree 的每一次 git 呼叫,都釘住 worktree 建立當下記錄的 git dir、common dir 與 work tree,關閉 hook、fsmonitor、external diff 與 textconv,並拒絕使用 git 檔案被改向或連到別處、HEAD 不是它自己的分支、或內含巢狀 repository 的 worktree。Claude 另外不得寫那幾個指標檔(`denyWrite`);Codex 無法禁止單一檔案,只靠釘住。殘留風險列在 [spec 15](docs/specs/15-worktree-git-isolation.md#156-殘留風險)。這**不**表示 dispatcher 絕不會執行 agent 埋下的程式碼。使用 `reftable` ref 後端的 repository 在 worktree 模式下會被拒絕。
218
-
219
- 已知缺口:Claude Code 內建的 Edit/Write 工具不在沙箱內(由 `Edit` 規則涵蓋);Codex 的 MCP 工具與 hooks 在其沙箱之外執行;`--dangerously-bypass-approvals-and-sandbox` / `danger-full-access` 會停用所有防護。啟用 `can_edit_agent_md` 時,Codex lead 的可寫根目錄會擴大到整個 agent 目錄。
68
+ | run 的生命週期、平行 agent、同時多個 run、追加需求、開 PR | [一次執行如何運作](docs/how-it-works.zh-TW.md) |
69
+ | agent 能寫什麼、沙箱等級、已知缺口 | [寫入範圍](docs/write-scope.zh-TW.md) |
70
+ | 讓 agent 搜尋或讀取網頁 | [網路存取](docs/web-access.zh-TW.md) |
71
+ | 在 Claude Code 內看即時 run 狀態 | [監控 mod](docs/monitor.zh-TW.md) |
72
+ | 所有指令的完整說明 | [指令](docs/commands.zh-TW.md) |
73
+ | 從舊版升級 | [升級到 run v2](docs/upgrading-run-v2.md) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-lyceum",
3
- "version": "0.17.0",
3
+ "version": "0.17.2",
4
4
  "description": "Config + dispatcher for teams of Claude Code / Codex agents with scoped context and file-based mailboxes",
5
5
  "keywords": [
6
6
  "ai",