From b386ddac2bff651202784144e8efd8166510479b Mon Sep 17 00:00:00 2001 From: Kanav Bansal <13186335+bansalkanav@users.noreply.github.com> Date: Mon, 20 Apr 2026 10:56:56 +0530 Subject: [PATCH 1/9] Fix separator inconsistency --- .DS_Store | Bin 0 -> 8196 bytes docs/.DS_Store | Bin 0 -> 6148 bytes docs/en/s01-the-agent-loop.md | 2 +- docs/en/s02-tool-use.md | 2 +- docs/en/s03-todo-write.md | 2 +- docs/en/s04-subagent.md | 2 +- docs/en/s05-skill-loading.md | 2 +- docs/en/s07-task-system.md | 2 +- docs/en/s08-background-tasks.md | 2 +- docs/en/s09-agent-teams.md | 2 +- docs/en/s10-team-protocols.md | 2 +- docs/en/s11-autonomous-agents.md | 2 +- 12 files changed, 10 insertions(+), 10 deletions(-) create mode 100644 .DS_Store create mode 100644 docs/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..28e33484e84c28ad278518c97896bcefd85f2e01 GIT binary patch literal 8196 zcmeHMPj4GV6n`&ClekHnP3nd~0j=kvbF2ytgyI_h#m2&D(tw0Kh`C zx&p8O0FzXubf%~|rO0tvhsucQnI(y253mFbj=+ODG=|W&!!lqQunbrRECZH-{{sW` z&X#5JjQ74CwXJ2qGVnq&Amf8eRm!}P9W7Ppphl$tB*&;*71AjWP&TfSc_TYoDpT^Q zvj;S$Xi^N+<}~g~ILW+`9WAvvpf(3IGo#5+P|Z$uu7U&RwY05ez%nq*fXv;eRo>2_ zHIToDz&1ls@k8MgMjopI)un$_Ax$3oC8$9FNecI43OCWk!9!?*KZwRRQt0zNbU@xY z2#C@v!EaJF<8RvR)%oVSvbEPHw+6u`;9P&ljY^#ab$Gt z-1r2Qsfl~VhoW6fyrdZyyy%X6+7%-7ySnG^1*~0mvTK4TUcgzT41y{n$lXr@UKQRpzL#6C293QVNzrE<*SY16?bdOiBFE6@pt=v30$xL3(U3+Jzd>Gcb_=?s} z1x;{-3;Ma&eofjKn0*J8me~*f(cRCV&aBzdWaj+T^o5Hv&g|T!?A+zK`T6YpOA9Z* za^=-4W#^LbRSs*BT`pBTs>Oy^33#oPu%o0HJZ5EQE(P6T)%#Dob{{ne zlYQEu+`Shu#+ARVgM*kQr9OTCQ}1ZE=Y1xwL?R5gMI0o7;QM!DB7HMq^-X>tXz~^j zzSWRJ@g9p}l4U1lQ`+~U$m2CucyurHd=_r;f=CikF9j9B^(JPNTYB7%m~@$Y_lf2- zm;a!vyr~rja$2De>TFjt5_7*)wYtj%XPI1nTR&##t#=jHU<*ogXZ8hr3*W;J@DuzB zzrkPdH;!W#U&Cv76K~=BcpE>)J*;5^o7loHwTqGNZ~nTO%n0m|()-O@#fXQ3*Qih8 zC*U@0(!3k+5fou#@WiNd{$1ZWpN1Vm-hy@bkmObPj85AUt+$%8ljr`w>>ktkKgCW( zfPTBozqIdUCwKKpC+AdwfZK#slxQkEM#u>JiONZ zup4!IogiwTl6Rza8h_eRe4MoUjq<{-&bm>Owc4g2X||AZc9LXG-4ApxYj#X+Xgf-f zMtNy4s8zQrYNK8sR@9)rUahFj+V*f*DlV?9?Ho34)4NPRS-K^Dk4EMle!?>hvzCXj zouxXvf={`gxDnA92QP?^a_}gwM|0%zSPonkW`G%B1}2^Xw?`J|CjLqJ0hs}2;IA2= z{XszqeTTV4vvr{H;8K5qkOVe;{u3&PzQf!idLYu40&S^uR}5*(5mzqHcbHqWrdx{$s_ZkYjQV3dI=>z3*K-^YLXm;3){5qr!4Gw`n%kcGW)FTj%A z+4^m9bk-{91(byHa*JOjFw9YmTsn%Ephgf^WB`4KxkW@E{2^dy;D#CaQwBZ&;A3V( literal 0 HcmV?d00001 diff --git a/docs/en/s01-the-agent-loop.md b/docs/en/s01-the-agent-loop.md index 40564686..1ef11c72 100644 --- a/docs/en/s01-the-agent-loop.md +++ b/docs/en/s01-the-agent-loop.md @@ -1,6 +1,6 @@ # s01: The Agent Loop -`[ s01 ] s02 > s03 > s04 > s05 > s06 | s07 > s08 > s09 > s10 > s11 > s12` +`[ s01 ] > s02 > s03 > s04 > s05 > s06 | s07 > s08 > s09 > s10 > s11 > s12` > *"One loop & Bash is all you need"* -- one tool + one loop = an agent. > diff --git a/docs/en/s02-tool-use.md b/docs/en/s02-tool-use.md index 279774b8..9d16a445 100644 --- a/docs/en/s02-tool-use.md +++ b/docs/en/s02-tool-use.md @@ -1,6 +1,6 @@ # s02: Tool Use -`s01 > [ s02 ] s03 > s04 > s05 > s06 | s07 > s08 > s09 > s10 > s11 > s12` +`s01 > [ s02 ] > s03 > s04 > s05 > s06 | s07 > s08 > s09 > s10 > s11 > s12` > *"Adding a tool means adding one handler"* -- the loop stays the same; new tools register into the dispatch map. > diff --git a/docs/en/s03-todo-write.md b/docs/en/s03-todo-write.md index e4461147..b72d49d7 100644 --- a/docs/en/s03-todo-write.md +++ b/docs/en/s03-todo-write.md @@ -1,6 +1,6 @@ # s03: TodoWrite -`s01 > s02 > [ s03 ] s04 > s05 > s06 | s07 > s08 > s09 > s10 > s11 > s12` +`s01 > s02 > [ s03 ] > s04 > s05 > s06 | s07 > s08 > s09 > s10 > s11 > s12` > *"An agent without a plan drifts"* -- list the steps first, then execute. > diff --git a/docs/en/s04-subagent.md b/docs/en/s04-subagent.md index 8a6ff2a6..c830eda2 100644 --- a/docs/en/s04-subagent.md +++ b/docs/en/s04-subagent.md @@ -1,6 +1,6 @@ # s04: Subagents -`s01 > s02 > s03 > [ s04 ] s05 > s06 | s07 > s08 > s09 > s10 > s11 > s12` +`s01 > s02 > s03 > [ s04 ] > s05 > s06 | s07 > s08 > s09 > s10 > s11 > s12` > *"Break big tasks down; each subtask gets a clean context"* -- subagents use independent messages[], keeping the main conversation clean. > diff --git a/docs/en/s05-skill-loading.md b/docs/en/s05-skill-loading.md index 0cf19385..1e81a611 100644 --- a/docs/en/s05-skill-loading.md +++ b/docs/en/s05-skill-loading.md @@ -1,6 +1,6 @@ # s05: Skills -`s01 > s02 > s03 > s04 > [ s05 ] s06 | s07 > s08 > s09 > s10 > s11 > s12` +`s01 > s02 > s03 > s04 > [ s05 ] > s06 | s07 > s08 > s09 > s10 > s11 > s12` > *"Load knowledge when you need it, not upfront"* -- inject via tool_result, not the system prompt. > diff --git a/docs/en/s07-task-system.md b/docs/en/s07-task-system.md index b110d0ca..562c6425 100644 --- a/docs/en/s07-task-system.md +++ b/docs/en/s07-task-system.md @@ -1,6 +1,6 @@ # s07: Task System -`s01 > s02 > s03 > s04 > s05 > s06 | [ s07 ] s08 > s09 > s10 > s11 > s12` +`s01 > s02 > s03 > s04 > s05 > s06 | [ s07 ] > s08 > s09 > s10 > s11 > s12` > *"Break big goals into small tasks, order them, persist to disk"* -- a file-based task graph with dependencies, laying the foundation for multi-agent collaboration. > diff --git a/docs/en/s08-background-tasks.md b/docs/en/s08-background-tasks.md index 5a98f212..7fdb92b7 100644 --- a/docs/en/s08-background-tasks.md +++ b/docs/en/s08-background-tasks.md @@ -1,6 +1,6 @@ # s08: Background Tasks -`s01 > s02 > s03 > s04 > s05 > s06 | s07 > [ s08 ] s09 > s10 > s11 > s12` +`s01 > s02 > s03 > s04 > s05 > s06 | s07 > [ s08 ] > s09 > s10 > s11 > s12` > *"Run slow operations in the background; the agent keeps thinking"* -- daemon threads run commands, inject notifications on completion. > diff --git a/docs/en/s09-agent-teams.md b/docs/en/s09-agent-teams.md index 9f19723a..e69aa3dd 100644 --- a/docs/en/s09-agent-teams.md +++ b/docs/en/s09-agent-teams.md @@ -1,6 +1,6 @@ # s09: Agent Teams -`s01 > s02 > s03 > s04 > s05 > s06 | s07 > s08 > [ s09 ] s10 > s11 > s12` +`s01 > s02 > s03 > s04 > s05 > s06 | s07 > s08 > [ s09 ] > s10 > s11 > s12` > *"When the task is too big for one, delegate to teammates"* -- persistent teammates + async mailboxes. > diff --git a/docs/en/s10-team-protocols.md b/docs/en/s10-team-protocols.md index e784e5ee..3513de67 100644 --- a/docs/en/s10-team-protocols.md +++ b/docs/en/s10-team-protocols.md @@ -1,6 +1,6 @@ # s10: Team Protocols -`s01 > s02 > s03 > s04 > s05 > s06 | s07 > s08 > s09 > [ s10 ] s11 > s12` +`s01 > s02 > s03 > s04 > s05 > s06 | s07 > s08 > s09 > [ s10 ] > s11 > s12` > *"Teammates need shared communication rules"* -- one request-response pattern drives all negotiation. > diff --git a/docs/en/s11-autonomous-agents.md b/docs/en/s11-autonomous-agents.md index a3c28367..8af6aada 100644 --- a/docs/en/s11-autonomous-agents.md +++ b/docs/en/s11-autonomous-agents.md @@ -1,6 +1,6 @@ # s11: Autonomous Agents -`s01 > s02 > s03 > s04 > s05 > s06 | s07 > s08 > s09 > s10 > [ s11 ] s12` +`s01 > s02 > s03 > s04 > s05 > s06 | s07 > s08 > s09 > s10 > [ s11 ] > s12` > *"Teammates scan the board and claim tasks themselves"* -- no need for the lead to assign each one. > From dad73ecd6e8ed2071fe0ee822c93fa06e4fc8aeb Mon Sep 17 00:00:00 2001 From: Kanav Bansal <13186335+bansalkanav@users.noreply.github.com> Date: Mon, 20 Apr 2026 15:20:38 +0530 Subject: [PATCH 2/9] Delete docs/.DS_Store --- docs/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/.DS_Store diff --git a/docs/.DS_Store b/docs/.DS_Store deleted file mode 100644 index 6f381090fdf80fe0209897b2787fb258979a0624..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKO-lnY5KY#qEh6-w;4$d6Xsd`8FUzV2ude7prS96ItLsMkVZl<^v;G@T{u2L= zzDc6cs#hs81Cuv1nMpQp+hikzkU_6m6QV4HC_)Ln5}F@``bocu=OWWUNn^yRj$zYa zf$L+KYzFAvd7>qIdUCwKKpC+AdwfZK#slxQkEM#u>JiONZ zup4!IogiwTl6Rza8h_eRe4MoUjq<{-&bm>Owc4g2X||AZc9LXG-4ApxYj#X+Xgf-f zMtNy4s8zQrYNK8sR@9)rUahFj+V*f*DlV?9?Ho34)4NPRS-K^Dk4EMle!?>hvzCXj zouxXvf={`gxDnA92QP?^a_}gwM|0%zSPonkW`G%B1}2^Xw?`J|CjLqJ0hs}2;IA2= z{XszqeTTV4vvr{H;8K5qkOVe;{u3&PzQf!idLYu40&S^uR}5*(5mzqHcbHqWrdx{$s_ZkYjQV3dI=>z3*K-^YLXm;3){5qr!4Gw`n%kcGW)FTj%A z+4^m9bk-{91(byHa*JOjFw9YmTsn%Ephgf^WB`4KxkW@E{2^dy;D#CaQwBZ&;A3V( From 71a0f5f1fc7debaa43feddbeca3d5f47ef1b925c Mon Sep 17 00:00:00 2001 From: Kanav Bansal <13186335+bansalkanav@users.noreply.github.com> Date: Mon, 20 Apr 2026 15:21:11 +0530 Subject: [PATCH 3/9] Delete .DS_Store --- .DS_Store | Bin 8196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 28e33484e84c28ad278518c97896bcefd85f2e01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMPj4GV6n`&ClekHnP3nd~0j=kvbF2ytgyI_h#m2&D(tw0Kh`C zx&p8O0FzXubf%~|rO0tvhsucQnI(y253mFbj=+ODG=|W&!!lqQunbrRECZH-{{sW` z&X#5JjQ74CwXJ2qGVnq&Amf8eRm!}P9W7Ppphl$tB*&;*71AjWP&TfSc_TYoDpT^Q zvj;S$Xi^N+<}~g~ILW+`9WAvvpf(3IGo#5+P|Z$uu7U&RwY05ez%nq*fXv;eRo>2_ zHIToDz&1ls@k8MgMjopI)un$_Ax$3oC8$9FNecI43OCWk!9!?*KZwRRQt0zNbU@xY z2#C@v!EaJF<8RvR)%oVSvbEPHw+6u`;9P&ljY^#ab$Gt z-1r2Qsfl~VhoW6fyrdZyyy%X6+7%-7ySnG^1*~0mvTK4TUcgzT41y{n$lXr@UKQRpzL#6C293QVNzrE<*SY16?bdOiBFE6@pt=v30$xL3(U3+Jzd>Gcb_=?s} z1x;{-3;Ma&eofjKn0*J8me~*f(cRCV&aBzdWaj+T^o5Hv&g|T!?A+zK`T6YpOA9Z* za^=-4W#^LbRSs*BT`pBTs>Oy^33#oPu%o0HJZ5EQE(P6T)%#Dob{{ne zlYQEu+`Shu#+ARVgM*kQr9OTCQ}1ZE=Y1xwL?R5gMI0o7;QM!DB7HMq^-X>tXz~^j zzSWRJ@g9p}l4U1lQ`+~U$m2CucyurHd=_r;f=CikF9j9B^(JPNTYB7%m~@$Y_lf2- zm;a!vyr~rja$2De>TFjt5_7*)wYtj%XPI1nTR&##t#=jHU<*ogXZ8hr3*W;J@DuzB zzrkPdH;!W#U&Cv76K~=BcpE>)J*;5^o7loHwTqGNZ~nTO%n0m|()-O@#fXQ3*Qih8 zC*U@0(!3k+5fou#@WiNd{$1ZWpN1Vm-hy@bkmObPj85AUt+$%8ljr`w>>ktkKgCW( zfPTBoz Date: Fri, 15 May 2026 10:56:15 +0800 Subject: [PATCH 4/9] fix: add missing "> /dev/" dangerous command check in s09/s10/s11 s09_agent_teams.py, s10_team_protocols.py, and s11_autonomous_agents.py were missing the "> /dev/" entry in their dangerous command blocklist. This is present in s01, s06, s12, and s_full but was dropped when s09-s11 were written, creating a security regression where commands like `echo y > /dev/sda` could bypass the blocklist. --- agents/s09_agent_teams.py | 2 +- agents/s10_team_protocols.py | 2 +- agents/s11_autonomous_agents.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/agents/s09_agent_teams.py b/agents/s09_agent_teams.py index 90f6760d..bd666552 100644 --- a/agents/s09_agent_teams.py +++ b/agents/s09_agent_teams.py @@ -260,7 +260,7 @@ def _safe_path(p: str) -> Path: def _run_bash(command: str) -> str: - dangerous = ["rm -rf /", "sudo", "shutdown", "reboot"] + dangerous = ["rm -rf /", "sudo", "shutdown", "reboot", "> /dev/"] if any(d in command for d in dangerous): return "Error: Dangerous command blocked" try: diff --git a/agents/s10_team_protocols.py b/agents/s10_team_protocols.py index d5475359..3f9923da 100644 --- a/agents/s10_team_protocols.py +++ b/agents/s10_team_protocols.py @@ -301,7 +301,7 @@ def _safe_path(p: str) -> Path: def _run_bash(command: str) -> str: - dangerous = ["rm -rf /", "sudo", "shutdown", "reboot"] + dangerous = ["rm -rf /", "sudo", "shutdown", "reboot", "> /dev/"] if any(d in command for d in dangerous): return "Error: Dangerous command blocked" try: diff --git a/agents/s11_autonomous_agents.py b/agents/s11_autonomous_agents.py index 3aec416b..c3a62cda 100644 --- a/agents/s11_autonomous_agents.py +++ b/agents/s11_autonomous_agents.py @@ -389,7 +389,7 @@ def _safe_path(p: str) -> Path: def _run_bash(command: str) -> str: - dangerous = ["rm -rf /", "sudo", "shutdown", "reboot"] + dangerous = ["rm -rf /", "sudo", "shutdown", "reboot", "> /dev/"] if any(d in command for d in dangerous): return "Error: Dangerous command blocked" try: From 65b1751dca1548a9b3192a6a52135dfcd053672d Mon Sep 17 00:00:00 2001 From: Yongan Zhang <374456248@qq.com> Date: Sun, 14 Jun 2026 05:47:48 +0800 Subject: [PATCH 5/9] docs: use canonical Kode repository links --- README-ja.md | 4 ++-- README-zh.md | 4 ++-- README.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README-ja.md b/README-ja.md index 08a4812e..794d9baa 100644 --- a/README-ja.md +++ b/README-ja.md @@ -409,13 +409,13 @@ learn-claude-code/ Skill & LSP 対応、Windows 対応、GLM / MiniMax / DeepSeek 等のオープンモデルに接続可能。インストールしてすぐ使える。 -GitHub: **[shareAI-lab/Kode-cli](https://github.com/shareAI-lab/Kode-cli)** +GitHub: **[shareAI-lab/Kode-CLI](https://github.com/shareAI-lab/Kode-CLI)** ### Kode Agent SDK -- アプリにエージェント機能を埋め込む 公式 Claude Code Agent SDK は内部で完全な CLI プロセスと通信する -- 同時ユーザーごとに独立のターミナルプロセスが必要。Kode SDK は独立ライブラリでユーザーごとのプロセスオーバーヘッドがなく、バックエンド、ブラウザ拡張、組み込みデバイス等に埋め込み可能。 -GitHub: **[shareAI-lab/Kode-agent-sdk](https://github.com/shareAI-lab/Kode-agent-sdk)** +GitHub: **[shareAI-lab/kode-agent-sdk](https://github.com/shareAI-lab/kode-agent-sdk)** --- diff --git a/README-zh.md b/README-zh.md index 519e5f01..79c92340 100644 --- a/README-zh.md +++ b/README-zh.md @@ -410,13 +410,13 @@ learn-claude-code/ 支持 Skill & LSP, 适配 Windows, 可接 GLM / MiniMax / DeepSeek 等开放模型。装完即用。 -GitHub: **[shareAI-lab/Kode-cli](https://github.com/shareAI-lab/Kode-cli)** +GitHub: **[shareAI-lab/Kode-CLI](https://github.com/shareAI-lab/Kode-CLI)** ### Kode Agent SDK -- 把 Agent 能力嵌入你的应用 官方 Claude Code Agent SDK 底层与完整 CLI 进程通信 -- 每个并发用户 = 一个终端进程。Kode SDK 是独立库, 无 per-user 进程开销, 可嵌入后端、浏览器插件、嵌入式设备等任意运行时。 -GitHub: **[shareAI-lab/Kode-agent-sdk](https://github.com/shareAI-lab/Kode-agent-sdk)** +GitHub: **[shareAI-lab/kode-agent-sdk](https://github.com/shareAI-lab/kode-agent-sdk)** --- diff --git a/README.md b/README.md index e9f0c931..5acc0f20 100644 --- a/README.md +++ b/README.md @@ -415,7 +415,7 @@ After 20 lessons, you understand harness engineering from the inside out. Two pa Skill and LSP support, Windows compatible, works with GLM / MiniMax / DeepSeek and other open models. Install and go. -GitHub: **[shareAI-lab/Kode-Agent](https://github.com/shareAI-lab/Kode-Agent)** +GitHub: **[shareAI-lab/Kode-CLI](https://github.com/shareAI-lab/Kode-CLI)** ### Kode Agent SDK -- Embed Agent Capabilities in Your Application From 4e594bb84a5515a15a363b55a444af8dbc32c5c6 Mon Sep 17 00:00:00 2001 From: Panda-eyes123 <13237333509@163.com> Date: Sun, 14 Jun 2026 21:54:22 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E6=97=B6SDK=E5=AF=B9=E8=B1=A1=E5=92=8Cdict?= =?UTF-8?q?=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- s12_task_system/code.py | 2 ++ s13_background_tasks/code.py | 2 ++ s15_agent_teams/code.py | 2 ++ s16_team_protocols/code.py | 2 ++ s17_autonomous_agents/code.py | 2 ++ s18_worktree_isolation/code.py | 2 ++ s19_mcp_plugin/code.py | 2 ++ s20_comprehensive/code.py | 4 ++-- 8 files changed, 16 insertions(+), 2 deletions(-) diff --git a/s12_task_system/code.py b/s12_task_system/code.py index d9da2527..7f442ebf 100644 --- a/s12_task_system/code.py +++ b/s12_task_system/code.py @@ -373,4 +373,6 @@ if __name__ == "__main__": for block in history[-1]["content"]: if getattr(block, "type", None) == "text": print(block.text) + elif isinstance(block, dict) and block.get("type") == "text": + print(block.get("text", "")) print() diff --git a/s13_background_tasks/code.py b/s13_background_tasks/code.py index 49a03ad2..a96eabca 100644 --- a/s13_background_tasks/code.py +++ b/s13_background_tasks/code.py @@ -475,4 +475,6 @@ if __name__ == "__main__": for block in history[-1]["content"]: if getattr(block, "type", None) == "text": print(block.text) + elif isinstance(block, dict) and block.get("type") == "text": + print(block.get("text", "")) print() diff --git a/s15_agent_teams/code.py b/s15_agent_teams/code.py index 53324b5a..1df40c7d 100644 --- a/s15_agent_teams/code.py +++ b/s15_agent_teams/code.py @@ -916,6 +916,8 @@ if __name__ == "__main__": for block in history[-1]["content"]: if getattr(block, "type", None) == "text": print(block.text) + elif isinstance(block, dict) and block.get("type") == "text": + print(block.get("text", "")) # Check inbox for teammate results → inject into history inbox = BUS.read_inbox("lead") diff --git a/s16_team_protocols/code.py b/s16_team_protocols/code.py index c1ec6636..d7993fb9 100644 --- a/s16_team_protocols/code.py +++ b/s16_team_protocols/code.py @@ -868,6 +868,8 @@ if __name__ == "__main__": for block in history[-1]["content"]: if getattr(block, "type", None) == "text": print(block.text) + elif isinstance(block, dict) and block.get("type") == "text": + print(block.get("text", "")) # Check inbox → route protocol + inject into history inbox_msgs = consume_lead_inbox(route_protocol=True) diff --git a/s17_autonomous_agents/code.py b/s17_autonomous_agents/code.py index 318e2f3c..f57a14f9 100644 --- a/s17_autonomous_agents/code.py +++ b/s17_autonomous_agents/code.py @@ -800,6 +800,8 @@ if __name__ == "__main__": for block in history[-1]["content"]: if getattr(block, "type", None) == "text": print(block.text) + elif isinstance(block, dict) and block.get("type") == "text": + print(block.get("text", "")) # Consume lead inbox: route protocol + inject into history inbox = consume_lead_inbox(route_protocol=True) diff --git a/s18_worktree_isolation/code.py b/s18_worktree_isolation/code.py index c1ed9d75..c00fcf44 100644 --- a/s18_worktree_isolation/code.py +++ b/s18_worktree_isolation/code.py @@ -984,6 +984,8 @@ if __name__ == "__main__": for block in history[-1]["content"]: if getattr(block, "type", None) == "text": print(block.text) + elif isinstance(block, dict) and block.get("type") == "text": + print(block.get("text", "")) # Consume lead inbox: route protocol + inject into history inbox = consume_lead_inbox(route_protocol=True) diff --git a/s19_mcp_plugin/code.py b/s19_mcp_plugin/code.py index fb3c6c04..eed5acec 100644 --- a/s19_mcp_plugin/code.py +++ b/s19_mcp_plugin/code.py @@ -1013,6 +1013,8 @@ if __name__ == "__main__": for block in history[-1]["content"]: if getattr(block, "type", None) == "text": print(block.text) + elif isinstance(block, dict) and block.get("type") == "text": + print(block.get("text", "")) inbox = consume_lead_inbox(route_protocol=True) if inbox: diff --git a/s20_comprehensive/code.py b/s20_comprehensive/code.py index bd62553e..fb0a81c4 100644 --- a/s20_comprehensive/code.py +++ b/s20_comprehensive/code.py @@ -2063,8 +2063,8 @@ def print_turn_assistants(messages: list, turn_start: int): if msg.get("role") != "assistant": continue for block in msg.get("content", []): - if getattr(block, "type", None) == "text": - terminal_print(block.text) + if block_type(block) == "text": + terminal_print(block["text"] if isinstance(block, dict) else block.text) def cron_autorun_loop(history: list, context: dict): From cbb3bd8c44ec7f1274884cf417a5a50e5e72f2d8 Mon Sep 17 00:00:00 2001 From: chaochaoweb3 <49186707+chaochaoweb3@users.noreply.github.com> Date: Tue, 23 Jun 2026 09:27:43 +0800 Subject: [PATCH 7/9] Remove duplicate idle poll name parameter --- s17_autonomous_agents/code.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/s17_autonomous_agents/code.py b/s17_autonomous_agents/code.py index 318e2f3c..b8c48760 100644 --- a/s17_autonomous_agents/code.py +++ b/s17_autonomous_agents/code.py @@ -301,14 +301,13 @@ def scan_unclaimed_tasks() -> list[dict]: return unclaimed -def idle_poll(agent_name: str, messages: list, - name: str, role: str) -> str: +def idle_poll(name: str, messages: list, role: str) -> str: """Poll for 60s. Return 'work', 'shutdown', or 'timeout'.""" for _ in range(IDLE_TIMEOUT // IDLE_POLL_INTERVAL): time.sleep(IDLE_POLL_INTERVAL) # Check inbox — dispatch protocol messages first - inbox = BUS.read_inbox(agent_name) + inbox = BUS.read_inbox(name) if inbox: # Check for shutdown_request for msg in inbox: @@ -331,7 +330,7 @@ def idle_poll(agent_name: str, messages: list, unclaimed = scan_unclaimed_tasks() if unclaimed: task = unclaimed[0] - result = claim_task(task["id"], agent_name) + result = claim_task(task["id"], name) if "Claimed" in result: messages.append({"role": "user", "content": f"Task {task['id']}: " @@ -498,7 +497,7 @@ def spawn_teammate_thread(name: str, role: str, prompt: str) -> str: break # IDLE phase (s17 new) - idle_result = idle_poll(name, messages, name, role) + idle_result = idle_poll(name, messages, role) if idle_result == "shutdown": break if idle_result == "timeout": From f366a862392ba89887492e15342b7a3683e13c16 Mon Sep 17 00:00:00 2001 From: Haoran Date: Fri, 26 Jun 2026 23:01:53 +0800 Subject: [PATCH 8/9] Sync s17 READMEs with the idle_poll signature change The code change dropped the redundant agent_name parameter, but the trilingual README snippets still showed the old four-arg signature, the double-passed call site, and agent_name inside the function body (read_inbox and claim_task). Update all three language code blocks to the three-arg form and bump the translation-sync markers so the docs match the code. --- s17_autonomous_agents/README.en.md | 10 +++++----- s17_autonomous_agents/README.ja.md | 10 +++++----- s17_autonomous_agents/README.md | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/s17_autonomous_agents/README.en.md b/s17_autonomous_agents/README.en.md index 4269b498..2d676faf 100644 --- a/s17_autonomous_agents/README.en.md +++ b/s17_autonomous_agents/README.en.md @@ -42,13 +42,13 @@ After completing a task, the teammate doesn't exit. It enters the IDLE phase — IDLE_POLL_INTERVAL = 5 # seconds IDLE_TIMEOUT = 60 # seconds -def idle_poll(agent_name, messages, name, role) -> str: +def idle_poll(name, messages, role) -> str: """Return 'work', 'shutdown', or 'timeout'.""" for _ in range(IDLE_TIMEOUT // IDLE_POLL_INTERVAL): time.sleep(IDLE_POLL_INTERVAL) # ① Check inbox (priority) - inbox = BUS.read_inbox(agent_name) + inbox = BUS.read_inbox(name) if inbox: # shutdown_request handled immediately for msg in inbox: @@ -63,7 +63,7 @@ def idle_poll(agent_name, messages, name, role) -> str: unclaimed = scan_unclaimed_tasks() if unclaimed: task = unclaimed[0] - result = claim_task(task["id"], agent_name) + result = claim_task(task["id"], name) if "Claimed" in result: messages.append(...) return "work" @@ -126,7 +126,7 @@ while True: break # WORK phase ends # IDLE phase - idle_result = idle_poll(name, messages, name, role) + idle_result = idle_poll(name, messages, role) if idle_result == "shutdown": break if idle_result == "timeout": @@ -268,4 +268,4 @@ Teaching version's `idle_poll()` merges CC's four mechanisms into one polling fu - + diff --git a/s17_autonomous_agents/README.ja.md b/s17_autonomous_agents/README.ja.md index 1de34c37..a88642d8 100644 --- a/s17_autonomous_agents/README.ja.md +++ b/s17_autonomous_agents/README.ja.md @@ -42,13 +42,13 @@ S16 の教学版 MessageBus とプロトコルツールを踏襲。本章の追 IDLE_POLL_INTERVAL = 5 # seconds IDLE_TIMEOUT = 60 # seconds -def idle_poll(agent_name, messages, name, role) -> str: +def idle_poll(name, messages, role) -> str: """Return 'work', 'shutdown', or 'timeout'.""" for _ in range(IDLE_TIMEOUT // IDLE_POLL_INTERVAL): time.sleep(IDLE_POLL_INTERVAL) # ① 受信箱確認(優先) - inbox = BUS.read_inbox(agent_name) + inbox = BUS.read_inbox(name) if inbox: # shutdown_request は即座に処理 for msg in inbox: @@ -63,7 +63,7 @@ def idle_poll(agent_name, messages, name, role) -> str: unclaimed = scan_unclaimed_tasks() if unclaimed: task = unclaimed[0] - result = claim_task(task["id"], agent_name) + result = claim_task(task["id"], name) if "Claimed" in result: messages.append(...) return "work" @@ -126,7 +126,7 @@ while True: break # WORK フェーズ終了 # IDLE フェーズ - idle_result = idle_poll(name, messages, name, role) + idle_result = idle_poll(name, messages, role) if idle_result == "shutdown": break if idle_result == "timeout": @@ -268,4 +268,4 @@ s18 Worktree Isolation → 各タスクに専用の作業ディレクトリ、 - + diff --git a/s17_autonomous_agents/README.md b/s17_autonomous_agents/README.md index 769da6ca..b3192c2d 100644 --- a/s17_autonomous_agents/README.md +++ b/s17_autonomous_agents/README.md @@ -42,13 +42,13 @@ s16 的队友能通信、能握手关机。但每个队友等 Lead 分配任务 IDLE_POLL_INTERVAL = 5 # seconds IDLE_TIMEOUT = 60 # seconds -def idle_poll(agent_name, messages, name, role) -> str: +def idle_poll(name, messages, role) -> str: """Return 'work', 'shutdown', or 'timeout'.""" for _ in range(IDLE_TIMEOUT // IDLE_POLL_INTERVAL): time.sleep(IDLE_POLL_INTERVAL) # ① 检查收件箱(优先) - inbox = BUS.read_inbox(agent_name) + inbox = BUS.read_inbox(name) if inbox: # shutdown_request 立即处理 for msg in inbox: @@ -63,7 +63,7 @@ def idle_poll(agent_name, messages, name, role) -> str: unclaimed = scan_unclaimed_tasks() if unclaimed: task = unclaimed[0] - result = claim_task(task["id"], agent_name) + result = claim_task(task["id"], name) if "Claimed" in result: messages.append(...) return "work" @@ -126,7 +126,7 @@ while True: break # WORK 阶段结束 # IDLE phase - idle_result = idle_poll(name, messages, name, role) + idle_result = idle_poll(name, messages, role) if idle_result == "shutdown": break if idle_result == "timeout": @@ -268,4 +268,4 @@ s18 Worktree Isolation → 每个任务有自己的工作目录,互不干扰 - + From c32ce1af944a374a45311614dd6277f84e211805 Mon Sep 17 00:00:00 2001 From: Haoran Date: Sat, 27 Jun 2026 01:02:38 +0800 Subject: [PATCH 9/9] Add CONTRIBUTING with scope and review policy State the contribution rules for this teaching repository: tie each PR to an issue, keep teaching code minimal, keep the three language READMEs in sync, target current chapter files, and disclose AI assistance. Note that bulk PRs generated by an agent across many repositories may be closed without detailed review. --- CONTRIBUTING.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..3eb47f9c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,42 @@ +# Contributing + +This is a curated teaching repository. Each chapter (`sNN_topic/`) builds one idea on top of the last, and the code is deliberately minimal. The simplifications are intentional, so the lesson stays legible. Contributions are welcome when they serve that goal. + +## Before opening a PR + +1. Tie it to a specific issue. Say what is wrong and why your change is the right fix. One PR addresses one issue. +2. Keep teaching code minimal. Do not add production hardening, defensive parsing, error handling layers, abstractions, or a test framework unless the chapter is specifically about that. A simplification that looks like a bug is often deliberate, so ask in an issue first. +3. Keep the three languages in sync. Any change to a chapter's `code.py` or a README must be reflected in all three language READMEs in that chapter folder, with the code blocks identical across them. +4. Target the current course files (`sNN_topic/`), not legacy mirrors. +5. Disclose AI assistance. Using an agent is fine. Say so, and make sure you have read and stand behind the change. + +## What gets closed without detailed review + +To keep the review queue useful, we close: + +1. Bulk PRs generated by an agent and opened across many unrelated repositories at once. We cannot responsibly review code the author has not engaged with. +2. Changes that expand a chapter's scope or structure against the teaching design. +3. PRs not tied to an issue, or that restate a deliberate simplification as a bug. + +Focused, clearly explained contributions from people who have actually worked with the material are always welcome. + + +# 贡献指南 + +这是一个**教学仓库**。每一章(`sNN_topic/`)在上一章的基础上只讲清一个点,代码刻意保持最简。简化是有意为之,为的是让讲解保持清晰。欢迎服务于这个目标的贡献。 + +## 提 PR 之前 + +1. 对应一个具体 issue。说清问题是什么、为什么你的改法是对的。一个 PR 只解决一个问题。 +2. 教学代码保持最简。不要加生产级的防御解析、错误处理层、抽象或测试框架,除非这一章本身就在讲这些。某处"像 bug"的简化往往是刻意的,先在 issue 里问一声。 +3. 三语保持同步。对某章 `code.py` 或 README 的改动,必须同步到该章目录下三种语言的 README,且其中代码块完全一致。 +4. 改现行课程文件(`sNN_topic/`),不要改旧的镜像目录。 +5. 声明 AI 协助。用 agent 没问题,但请说明,并确保你读过、也认可这份改动。 + +## 哪些会被直接关闭(不做详细评审) + +1. 在大量互不相关的仓库里一次性批量提交、由 agent 生成的 PR。作者自己都没参与的代码,我们无法负责任地评审。 +2. 让某章范围或结构超出教学设计的改动。 +3. 没有对应 issue、或把刻意的简化当成 bug 来"修"的 PR。 + +真正用过这份材料、聚焦且讲清理由的贡献,我们始终欢迎。