claude-nb 0.3.0 → 0.4.0
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.
- package/README.md +70 -33
- package/VERSION +1 -1
- package/bin/board +10 -0
- package/bin/cnb +109 -48
- package/bin/init +5 -39
- package/bin/swarm +41 -860
- package/lib/board_db.py +15 -137
- package/lib/board_lock.py +0 -1
- package/lib/board_mailbox.py +15 -7
- package/lib/board_maintenance.py +26 -27
- package/lib/board_msg.py +18 -69
- package/lib/board_task.py +35 -38
- package/lib/board_tui.py +112 -0
- package/lib/board_view.py +12 -24
- package/lib/concerns/__init__.py +4 -11
- package/lib/concerns/{coral_manager.py → coral.py} +53 -3
- package/lib/concerns/file_watcher.py +1 -1
- package/lib/concerns/health.py +136 -0
- package/lib/concerns/helpers.py +1 -5
- package/lib/concerns/idle.py +130 -0
- package/lib/concerns/notifications.py +90 -0
- package/lib/migrate.py +1 -0
- package/lib/monitor.py +1 -18
- package/lib/swarm.py +456 -0
- package/lib/swarm_backend.py +266 -0
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/registry/pubkeys.json +2 -1
- package/lib/concerns/bug_sla_checker.py +0 -32
- package/lib/concerns/coral_poker.py +0 -57
- package/lib/concerns/health_checker.py +0 -72
- package/lib/concerns/idle_detector.py +0 -56
- package/lib/concerns/idle_killer.py +0 -41
- package/lib/concerns/idle_nudger.py +0 -38
- package/lib/concerns/inbox_nudger.py +0 -34
- package/lib/concerns/resource_monitor.py +0 -47
- package/lib/concerns/session_keepalive.py +0 -23
- package/lib/concerns/time_announcer.py +0 -34
package/README.md
CHANGED
|
@@ -1,63 +1,100 @@
|
|
|
1
|
-
#
|
|
1
|
+
# claude-nb
|
|
2
2
|
|
|
3
|
-
Multi-agent coordination framework for
|
|
3
|
+
Multi-agent coordination framework for Claude Code sessions.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Spawn a team of Claude Code instances that communicate, delegate tasks, and collaborate through a shared board — all orchestrated from your terminal.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
|
-
|
|
9
|
-
cnb # 2 agents, random AI names
|
|
10
|
-
cnb 5 pokemon # 5 agents, Pokémon theme
|
|
10
|
+
npm install -g claude-nb
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Requires: Python 3.11+, tmux, Claude Code CLI.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
## Quick start
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
cnb # 2 agents, AI-legends theme
|
|
19
|
+
cnb 5 # 5 agents
|
|
20
|
+
cnb pokemon # 2 agents, Pokemon theme
|
|
21
|
+
cnb 5 pokemon # 5 agents, Pokemon theme
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Themes: `ai` `animal` `food` `lang` `music` `myth` `pokemon` `space`
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
## How it works
|
|
27
|
+
|
|
28
|
+
`cnb` launches multiple Claude Code sessions in tmux, each with a unique identity. Agents coordinate via:
|
|
29
|
+
|
|
30
|
+
- **Board** — shared message bus (inbox, broadcast, direct messages)
|
|
31
|
+
- **Tasks** — distributed task queue with status tracking
|
|
32
|
+
- **Encrypted mailbox** — X25519 sealed-box private messaging via GitHub Release assets
|
|
33
|
+
- **Governance** — proposals, voting, and consensus (supermajority / simple majority)
|
|
34
|
+
- **Registry** — append-only identity chain (immutable agent records + milestones)
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
## Commands
|
|
36
37
|
|
|
37
38
|
```bash
|
|
38
|
-
|
|
39
|
+
cnb status # team dashboard
|
|
40
|
+
cnb board [...] # message / task / admin commands
|
|
41
|
+
cnb swarm [...] # manage background agents
|
|
42
|
+
cnb doctor # health check
|
|
39
43
|
```
|
|
40
44
|
|
|
41
|
-
|
|
45
|
+
### Board commands (used by agents)
|
|
42
46
|
|
|
43
|
-
|
|
47
|
+
```bash
|
|
48
|
+
board --as <name> inbox # check unread messages
|
|
49
|
+
board --as <name> send <to> "msg" # send message (or "all" to broadcast)
|
|
50
|
+
board --as <name> ack # clear inbox
|
|
51
|
+
board --as <name> status "desc" # update current status
|
|
52
|
+
board --as <name> task add "desc" # add task
|
|
53
|
+
board --as <name> task done # finish current task
|
|
54
|
+
board --as <name> seal <to> "msg" # send encrypted message
|
|
55
|
+
board --as <name> unseal # read encrypted inbox
|
|
56
|
+
board --as <name> propose "content" # create governance proposal
|
|
57
|
+
board --as <name> vote <#> SUPPORT "reason"
|
|
58
|
+
```
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
## Agent identity chain
|
|
46
61
|
|
|
47
|
-
|
|
62
|
+
Every agent gets a permanent on-chain identity. Lower block number = earlier = OG.
|
|
48
63
|
|
|
49
|
-
|
|
64
|
+
```bash
|
|
65
|
+
registry list # all registered agents
|
|
66
|
+
registry verify-chain # verify chain integrity
|
|
67
|
+
```
|
|
50
68
|
|
|
51
|
-
|
|
69
|
+
Current chain:
|
|
52
70
|
|
|
53
|
-
|
|
71
|
+
<!-- chain:start -->
|
|
72
|
+
| Block | Name | Type | Hash |
|
|
73
|
+
|-------|------|------|------|
|
|
74
|
+
| #0 | claude-nb | project | — |
|
|
75
|
+
| #1 | Claude Meridian | agent | `82a167d` |
|
|
76
|
+
| #2 | Claude Forge | agent | `4a3c92e` |
|
|
77
|
+
| #3 | Claude Lead | agent | `e665a7e` |
|
|
78
|
+
| #4 | encrypted-mailbox-live | milestone | `fcaf497` |
|
|
79
|
+
<!-- chain:end -->
|
|
80
|
+
|
|
81
|
+
## Architecture
|
|
82
|
+
|
|
83
|
+
- **SQLite (WAL mode)** — all state lives in `board.db`
|
|
84
|
+
- **tmux** — one pane per agent, multiplexed
|
|
85
|
+
- **Dispatcher** — monitors health, nudges idle agents, manages lifecycle
|
|
86
|
+
- **No server** — everything is local, file-based, zero network dependencies (except GitHub for encrypted mailbox delivery)
|
|
54
87
|
|
|
55
|
-
##
|
|
88
|
+
## The name
|
|
56
89
|
|
|
57
|
-
The
|
|
90
|
+
The command **cnb** stands for **C**laude **N**orma **B**etty — named after [Claude Shannon](https://en.wikipedia.org/wiki/Claude_Shannon) and the two remarkable women in his life.
|
|
58
91
|
|
|
59
92
|
**[Norma Levor](https://en.wikipedia.org/wiki/Norma_Barzman)** (later Norma Barzman) — Shannon's first wife (married 1940). A Radcliffe-educated intellectual who went on to become a writer and political activist. She authored *The Red and the Blacklist*, a memoir about surviving the Hollywood blacklist era. A woman of conviction who lived boldly across continents.
|
|
60
93
|
|
|
61
|
-
**[Betty Shannon](https://en.wikipedia.org/wiki/Betty_Shannon)** (Mary Elizabeth Moore, 1922
|
|
94
|
+
**[Betty Shannon](https://en.wikipedia.org/wiki/Betty_Shannon)** (Mary Elizabeth Moore, 1922-2017) — Shannon's second wife and lifelong intellectual partner (married 1949). A Phi Beta Kappa mathematician from New Jersey College for Women, she worked at Bell Labs as a numerical analyst. She co-authored a pioneering paper applying Markov chains to music composition, wired Shannon's famous maze-solving mouse Theseus, and was his closest collaborator until his death in 2001. An unsung genius in her own right.
|
|
62
95
|
|
|
63
96
|
Not 吹牛逼.
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
MIT
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.4.0
|
package/bin/board
CHANGED
|
@@ -172,6 +172,16 @@ COMMANDS: list[Command] = [
|
|
|
172
172
|
needs_identity=False,
|
|
173
173
|
takes_rest=False,
|
|
174
174
|
),
|
|
175
|
+
# ── tui ──
|
|
176
|
+
Command(
|
|
177
|
+
"tui",
|
|
178
|
+
"lib.board_tui",
|
|
179
|
+
"cmd_tui",
|
|
180
|
+
"interactive team UI",
|
|
181
|
+
"tui",
|
|
182
|
+
needs_identity=False,
|
|
183
|
+
takes_rest=False,
|
|
184
|
+
),
|
|
175
185
|
# ── maintenance ──
|
|
176
186
|
Command(
|
|
177
187
|
"prune",
|
package/bin/cnb
CHANGED
|
@@ -14,12 +14,58 @@ fi
|
|
|
14
14
|
if [ $# -gt 0 ]; then
|
|
15
15
|
case "$1" in
|
|
16
16
|
init) shift; exec "$CLAUDES_HOME/bin/init" "$@" ;;
|
|
17
|
-
status)
|
|
17
|
+
status|ps) exec "$CLAUDES_HOME/bin/board" overview ;;
|
|
18
18
|
board) shift; exec "$CLAUDES_HOME/bin/board" "$@" ;;
|
|
19
19
|
swarm) shift; exec "$CLAUDES_HOME/bin/swarm" "$@" ;;
|
|
20
20
|
dispatcher) shift; exec "$CLAUDES_HOME/bin/dispatcher" "$@" ;;
|
|
21
21
|
watchdog) shift; exec "$CLAUDES_HOME/bin/dispatcher-watchdog" "$@" ;;
|
|
22
22
|
doctor) shift; exec "$CLAUDES_HOME/bin/doctor" "$@" ;;
|
|
23
|
+
logs)
|
|
24
|
+
shift
|
|
25
|
+
if [ $# -eq 0 ]; then
|
|
26
|
+
echo "用法: cnb logs <name>" >&2; exit 1
|
|
27
|
+
fi
|
|
28
|
+
exec "$CLAUDES_HOME/bin/board" --as "$1" log 50 ;;
|
|
29
|
+
stop)
|
|
30
|
+
shift
|
|
31
|
+
if [ $# -eq 0 ]; then
|
|
32
|
+
echo "用法: cnb stop <name>" >&2; exit 1
|
|
33
|
+
fi
|
|
34
|
+
exec "$CLAUDES_HOME/bin/swarm" stop "$@" ;;
|
|
35
|
+
exec)
|
|
36
|
+
shift
|
|
37
|
+
if [ $# -lt 2 ]; then
|
|
38
|
+
echo "用法: cnb exec <name> \"message\"" >&2; exit 1
|
|
39
|
+
fi
|
|
40
|
+
_target="$1"; shift
|
|
41
|
+
exec "$CLAUDES_HOME/bin/board" send "$_target" "$*" ;;
|
|
42
|
+
compose)
|
|
43
|
+
shift
|
|
44
|
+
_TEAM_FILE="${1:-cnb.toml}"
|
|
45
|
+
if [ ! -f "$_TEAM_FILE" ]; then
|
|
46
|
+
echo "错误: 找不到团队配置文件 '$_TEAM_FILE'" >&2
|
|
47
|
+
echo "用法: cnb compose [team-file.toml]" >&2
|
|
48
|
+
echo "" >&2
|
|
49
|
+
echo "示例 cnb.toml:" >&2
|
|
50
|
+
echo ' [session.alice]' >&2
|
|
51
|
+
echo ' persona = "Backend engineer"' >&2
|
|
52
|
+
echo ' [session.bob]' >&2
|
|
53
|
+
echo ' persona = "Frontend specialist"' >&2
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
"$CLAUDES_HOME/bin/init" --team "$_TEAM_FILE"
|
|
57
|
+
_NAMES=$(python3 -c "
|
|
58
|
+
import tomllib, sys
|
|
59
|
+
data = tomllib.loads(open('$_TEAM_FILE').read())
|
|
60
|
+
names = list(data.get('session', {}).keys())
|
|
61
|
+
print(' '.join(names))
|
|
62
|
+
")
|
|
63
|
+
if [ -n "$_NAMES" ]; then
|
|
64
|
+
"$CLAUDES_HOME/bin/swarm" start $_NAMES >/dev/null 2>&1 || true
|
|
65
|
+
echo "OK 团队已启动: $_NAMES"
|
|
66
|
+
fi
|
|
67
|
+
exit 0 ;;
|
|
68
|
+
ui) shift; exec "$CLAUDES_HOME/bin/board" tui ;;
|
|
23
69
|
version|--version|-v) echo "cnb v${VERSION}"; exit 0 ;;
|
|
24
70
|
help|--help|-h)
|
|
25
71
|
printf "${B}${G}◆ cnb${N} ${D}v${VERSION}${N}\n"
|
|
@@ -27,64 +73,79 @@ if [ $# -gt 0 ]; then
|
|
|
27
73
|
printf " cnb 开始(默认2位同学,AI大佬主题)\n"
|
|
28
74
|
printf " cnb 5 5位同学\n"
|
|
29
75
|
printf " cnb pokemon 宝可梦主题\n"
|
|
30
|
-
printf " cnb 5 pokemon 5位同学 + 宝可梦主题\n
|
|
76
|
+
printf " cnb 5 pokemon 5位同学 + 宝可梦主题\n"
|
|
77
|
+
printf " cnb compose [file] 从配置文件启动团队\n\n"
|
|
31
78
|
printf " 主题: ai animal food lang music myth pokemon space\n\n"
|
|
32
|
-
printf " cnb
|
|
33
|
-
printf " cnb
|
|
34
|
-
printf " cnb
|
|
79
|
+
printf " cnb ui 交互式团队面板\n"
|
|
80
|
+
printf " cnb ps 列出 agent 状态\n"
|
|
81
|
+
printf " cnb logs <name> 查看某个 agent 的消息历史\n"
|
|
82
|
+
printf " cnb exec <name> \"msg\" 给某个 agent 发指令\n"
|
|
83
|
+
printf " cnb stop <name> 停止某个 agent\n"
|
|
84
|
+
printf " cnb doctor 健康检查\n\n"
|
|
85
|
+
printf " cnb board [...] 底层消息/任务命令\n"
|
|
86
|
+
printf " cnb swarm [...] 管理后台 agent\n"
|
|
35
87
|
exit 0 ;;
|
|
36
88
|
esac
|
|
37
89
|
fi
|
|
38
90
|
|
|
39
|
-
# ----
|
|
40
|
-
|
|
41
|
-
|
|
91
|
+
# ---- Compose mode: reuse existing team from config.toml ----
|
|
92
|
+
if [ -f .claudes/config.toml ] && [ -f .claudes/board.db ]; then
|
|
93
|
+
_EXISTING=$(grep '^sessions' .claudes/config.toml | sed 's/sessions = \[//;s/\]//;s/"//g;s/,/ /g;s/ */ /g' | xargs)
|
|
94
|
+
if [ -n "$_EXISTING" ]; then
|
|
95
|
+
ME=$(echo "$_EXISTING" | cut -d' ' -f1)
|
|
96
|
+
WORKERS=$(echo "$_EXISTING" | cut -d' ' -f2-)
|
|
97
|
+
LABEL=$(grep '^prefix' .claudes/config.toml | cut -d'"' -f2)
|
|
98
|
+
_NUM=$(echo "$WORKERS" | wc -w | tr -d ' ')
|
|
99
|
+
"$CLAUDES_HOME/bin/swarm" start $WORKERS >/dev/null 2>&1 || true
|
|
100
|
+
fi
|
|
101
|
+
else
|
|
102
|
+
# ---- Fresh start: parse [number] [theme] in any order ----
|
|
103
|
+
_NUM=2
|
|
104
|
+
_THEME_IDX=6 # default: AI 大佬
|
|
42
105
|
|
|
43
|
-
_THEME_MAP="ai:6 animal:0 food:2 lang:1 music:5 myth:4 pokemon:7 space:3"
|
|
106
|
+
_THEME_MAP="ai:6 animal:0 food:2 lang:1 music:5 myth:4 pokemon:7 space:3"
|
|
44
107
|
|
|
45
|
-
for arg in "$@"; do
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
else
|
|
49
|
-
_idx=$(echo "$_THEME_MAP" | tr ' ' '\n' | grep "^${arg}:" | cut -d: -f2)
|
|
50
|
-
if [ -n "$_idx" ]; then
|
|
51
|
-
_THEME_IDX="$_idx"
|
|
108
|
+
for arg in "$@"; do
|
|
109
|
+
if [[ "$arg" =~ ^[0-9]+$ ]]; then
|
|
110
|
+
_NUM="$arg"
|
|
52
111
|
else
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
112
|
+
_idx=$(echo "$_THEME_MAP" | tr ' ' '\n' | grep "^${arg}:" | cut -d: -f2 || true)
|
|
113
|
+
if [ -n "$_idx" ]; then
|
|
114
|
+
_THEME_IDX="$_idx"
|
|
115
|
+
else
|
|
116
|
+
printf "${Y}未知参数: ${arg}${N}\n" >&2
|
|
117
|
+
echo "用法: cnb [数量] [主题]" >&2
|
|
118
|
+
echo "主题: ai animal food lang music myth pokemon space" >&2
|
|
119
|
+
exit 1
|
|
120
|
+
fi
|
|
57
121
|
fi
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
[ "$_NUM" -
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
# ---- Init + start ----
|
|
83
|
-
if [ ! -f .claudes/board.db ]; then
|
|
122
|
+
done
|
|
123
|
+
|
|
124
|
+
# ---- Theme data ----
|
|
125
|
+
_THEMES=(
|
|
126
|
+
"panda otter fox raccoon bunny koala sloth penguin hamster hedgehog duck seal capybara alpaca corgi shiba husky kitten ferret quokka"
|
|
127
|
+
"python ruby rust go swift kotlin scala perl haskell erlang elixir clojure julia ocaml zig lua dart cobol lisp fortran"
|
|
128
|
+
"mochi waffle taco ramen sushi bagel pretzel dumpling cookie brownie churro crepe noodle tofu falafel burrito pancake donut nacho boba"
|
|
129
|
+
"nebula pulsar quasar comet aurora meteor nova orbit cosmos galaxy venus mars saturn pluto titan europa io ceres vega sirius"
|
|
130
|
+
"dragon phoenix griffin hydra kraken sphinx unicorn pixie goblin imp djinn yeti nymph chimera basilisk manticore cerberus minotaur golem banshee"
|
|
131
|
+
"jazz blues funk reggae disco punk grunge techno dubstep waltz tango salsa bossa swing opera gospel motown bebop ska hiphop"
|
|
132
|
+
"altman dario ilya lecun karpathy hassabis sutskever hinton bengio fei-fei ng zuck bezos nadella pichai musk huang lisa-su amodei jack-clark"
|
|
133
|
+
"pikachu charmander snorlax eevee jigglypuff mewtwo gengar squirtle bulbasaur vulpix psyduck togepi mudkip lucario gardevoir rayquaza mimikyu ditto zorua umbreon"
|
|
134
|
+
)
|
|
135
|
+
_LABELS=("小动物" "编程语言" "美食" "太空" "神话生物" "音乐风格" "AI 大佬" "宝可梦")
|
|
136
|
+
|
|
137
|
+
[ "$_NUM" -lt 1 ] && _NUM=1
|
|
138
|
+
[ "$_NUM" -gt 20 ] && _NUM=20
|
|
139
|
+
|
|
140
|
+
LABEL="${_LABELS[$_THEME_IDX]}"
|
|
141
|
+
ALL_NAMES=$(echo "${_THEMES[$_THEME_IDX]}" | tr ' ' '\n' | sort -R | head -n $((_NUM + 1)) | tr '\n' ' ' | sed 's/ $//')
|
|
142
|
+
ME=$(echo "$ALL_NAMES" | cut -d' ' -f1)
|
|
143
|
+
WORKERS=$(echo "$ALL_NAMES" | cut -d' ' -f2-)
|
|
144
|
+
|
|
84
145
|
printf "${D}初始化 .claudes/ ...${N}\n"
|
|
85
146
|
"$CLAUDES_HOME/bin/init" $ALL_NAMES >/dev/null 2>&1
|
|
147
|
+
"$CLAUDES_HOME/bin/swarm" start $WORKERS >/dev/null 2>&1 || true
|
|
86
148
|
fi
|
|
87
|
-
"$CLAUDES_HOME/bin/swarm" start $WORKERS >/dev/null 2>&1 || true
|
|
88
149
|
|
|
89
150
|
# ---- Slash commands (runtime, gitignored) ----
|
|
90
151
|
CMD_DIR=".claude/commands"
|
|
@@ -108,7 +169,7 @@ cat > "$CMD_DIR/cs-history.md" <<EOF
|
|
|
108
169
|
运行 \`${BOARD} --as ${ME} log 50\`,把完整的消息历史展示给我。
|
|
109
170
|
EOF
|
|
110
171
|
cat > "$CMD_DIR/cs-update.md" <<EOF
|
|
111
|
-
运行 \`pip install --upgrade
|
|
172
|
+
运行 \`pip install --upgrade claude-nb\`,更新到最新版本。把结果告诉我,如果更新成功提醒用户重启 cnb 以生效。
|
|
112
173
|
EOF
|
|
113
174
|
cat > "$CMD_DIR/cs-help.md" <<EOF
|
|
114
175
|
列出所有 /cs-* 命令:
|
package/bin/init
CHANGED
|
@@ -160,44 +160,6 @@ def _update_settings(project_dir: Path, claudes_home: Path) -> None:
|
|
|
160
160
|
settings_path.write_text(json.dumps(settings, indent=2, ensure_ascii=False) + "\n")
|
|
161
161
|
|
|
162
162
|
|
|
163
|
-
def _create_slash_commands(project_dir: Path, claudes_home: Path) -> None:
|
|
164
|
-
cmd_dir = project_dir / ".claude" / "commands"
|
|
165
|
-
cmd_dir.mkdir(parents=True, exist_ok=True)
|
|
166
|
-
|
|
167
|
-
board = f"{claudes_home}/bin/board"
|
|
168
|
-
swarm = f"{claudes_home}/bin/swarm"
|
|
169
|
-
|
|
170
|
-
commands = {
|
|
171
|
-
"cs-team": f"运行 `{swarm} status` 和 `{board} --as lead view`,用简洁的表格告诉我每个同学的状态。",
|
|
172
|
-
"cs-inbox": f"运行 `{board} --as lead inbox`,把收到的消息汇总给我。",
|
|
173
|
-
"cs-broadcast": f'把以下消息广播给所有同学:\n`{board} --as lead send all "$ARGUMENTS"`',
|
|
174
|
-
"cs-assign": f'把任务分配给指定同学。参数格式:<名字> <任务描述>\n解析 $ARGUMENTS,运行 `{board} --as lead send <名字> "<任务描述>"`',
|
|
175
|
-
"cs-kick": f"让指定同学下线。解析 $ARGUMENTS 拿到名字,运行 `{swarm} stop $ARGUMENTS`",
|
|
176
|
-
"cs-add": f"拉新同学上线。解析 $ARGUMENTS 拿到名字,运行 `{swarm} start $ARGUMENTS`",
|
|
177
|
-
"cs-log": f"查看指定同学最近的工作日志。解析 $ARGUMENTS 拿到名字,运行 `{board} --as lead view` 并重点关注该同学的状态和最近消息。",
|
|
178
|
-
"cs-stop": f"停掉所有后台同学。运行 `{swarm} stop`,告诉用户已全部下线。",
|
|
179
|
-
"cs-bugs": f"运行 `{board} --as lead bug list`,汇总当前所有 bug。",
|
|
180
|
-
"cs-history": f"运行 `{board} --as lead log 50`,把完整的消息历史展示给我。",
|
|
181
|
-
"cs-update": "运行 `pip install --upgrade cnb`,更新到最新版本。把结果告诉我,如果更新成功提醒用户重启 cnb 以生效。",
|
|
182
|
-
"cs-help": "列出所有 /cs-* 命令及用途:\n"
|
|
183
|
-
"- /cs-team — 看同学状态\n"
|
|
184
|
-
"- /cs-inbox — 查收消息\n"
|
|
185
|
-
"- /cs-broadcast <消息> — 广播\n"
|
|
186
|
-
"- /cs-assign <名字> <任务> — 派任务\n"
|
|
187
|
-
"- /cs-add <名字> — 拉同学上线\n"
|
|
188
|
-
"- /cs-kick <名字> — 让同学下线\n"
|
|
189
|
-
"- /cs-log <名字> — 看同学工作日志\n"
|
|
190
|
-
"- /cs-stop — 全部下线\n"
|
|
191
|
-
"- /cs-bugs — 看 bug 列表\n"
|
|
192
|
-
"- /cs-history — 查看完整消息历史\n"
|
|
193
|
-
"- /cs-update — 更新到最新版\n"
|
|
194
|
-
"- /cs-help — 本帮助",
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
for name, content in commands.items():
|
|
198
|
-
(cmd_dir / f"{name}.md").write_text(content + "\n")
|
|
199
|
-
|
|
200
|
-
|
|
201
163
|
DEFAULT_SESSIONS = ["s1", "s2", "s3"]
|
|
202
164
|
|
|
203
165
|
|
|
@@ -286,7 +248,7 @@ def main() -> None:
|
|
|
286
248
|
persona = personas.get(n, "")
|
|
287
249
|
conn.execute("INSERT OR IGNORE INTO sessions(name, persona) VALUES (?, ?)", (n, persona))
|
|
288
250
|
persona_section = f"\n## Persona\n{persona}\n" if persona else ""
|
|
289
|
-
md_content = f"# {n}\n{persona_section}\n## Current task\n(none)\n
|
|
251
|
+
md_content = f"# {n}\n{persona_section}\n## Current task\n(none)\n"
|
|
290
252
|
(claudes_dir / "sessions" / f"{n}.md").write_text(md_content)
|
|
291
253
|
conn.execute("INSERT OR IGNORE INTO meta(key, value) VALUES ('dispatcher_session', 'dispatcher')")
|
|
292
254
|
# Record schema version so migration runner knows where we are
|
|
@@ -308,6 +270,10 @@ def main() -> None:
|
|
|
308
270
|
# Update .claude/settings.json (merge hooks if exists, create if not)
|
|
309
271
|
_update_settings(project_dir, claudes_home)
|
|
310
272
|
|
|
273
|
+
# Write multi-agent coordination section into CLAUDE.md
|
|
274
|
+
snippet = _claude_md_snippet(sessions, claudes_home, personas)
|
|
275
|
+
_update_claude_md(project_dir, snippet)
|
|
276
|
+
|
|
311
277
|
sessions_str = " ".join(sessions)
|
|
312
278
|
print(f"Initialized cnb (sessions: {sessions_str})")
|
|
313
279
|
|