limbo-code 0.3__tar.gz → 0.3.5__tar.gz

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 (332) hide show
  1. {limbo_code-0.3 → limbo_code-0.3.5}/AGENTS.md +34 -5
  2. {limbo_code-0.3 → limbo_code-0.3.5}/CONTEXT.md +20 -0
  3. {limbo_code-0.3 → limbo_code-0.3.5}/PKG-INFO +73 -1
  4. {limbo_code-0.3 → limbo_code-0.3.5}/README.md +70 -0
  5. limbo_code-0.3.5/docs/daily-mode.md +103 -0
  6. {limbo_code-0.3 → limbo_code-0.3.5}/docs/skills.md +2 -0
  7. limbo_code-0.3.5/docs/subagents.md +132 -0
  8. {limbo_code-0.3 → limbo_code-0.3.5}/pyproject.toml +9 -0
  9. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/agent.py +132 -6
  10. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/app.py +26 -4
  11. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/config.py +114 -0
  12. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/conversation.py +110 -3
  13. limbo_code-0.3.5/src/limbo/daily.py +31 -0
  14. limbo_code-0.3.5/src/limbo/daily_skills/README.md +15 -0
  15. limbo_code-0.3.5/src/limbo/daily_skills/arxiv/LICENSE +21 -0
  16. limbo_code-0.3.5/src/limbo/daily_skills/arxiv/SKILL.md +275 -0
  17. limbo_code-0.3.5/src/limbo/daily_skills/arxiv/scripts/search_arxiv.py +114 -0
  18. limbo_code-0.3.5/src/limbo/daily_skills/blocked-page-recovery/LICENSE +21 -0
  19. limbo_code-0.3.5/src/limbo/daily_skills/blocked-page-recovery/SKILL.md +130 -0
  20. limbo_code-0.3.5/src/limbo/daily_skills/blocked-page-recovery/scripts/recover_page.py +241 -0
  21. limbo_code-0.3.5/src/limbo/daily_skills/document-to-action-items/LICENSE +21 -0
  22. limbo_code-0.3.5/src/limbo/daily_skills/document-to-action-items/SKILL.md +74 -0
  23. limbo_code-0.3.5/src/limbo/daily_skills/docx/LICENSE +21 -0
  24. limbo_code-0.3.5/src/limbo/daily_skills/docx/SKILL.md +188 -0
  25. limbo_code-0.3.5/src/limbo/daily_skills/docx/references/revisions-and-comments.md +88 -0
  26. limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_comments.py +289 -0
  27. limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_common.py +92 -0
  28. limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_create.py +177 -0
  29. limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_edit.py +250 -0
  30. limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_read.py +149 -0
  31. limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_revisions.py +146 -0
  32. limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_template.py +70 -0
  33. limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_validate.py +156 -0
  34. limbo_code-0.3.5/src/limbo/daily_skills/grounded-citations/LICENSE +21 -0
  35. limbo_code-0.3.5/src/limbo/daily_skills/grounded-citations/SKILL.md +248 -0
  36. limbo_code-0.3.5/src/limbo/daily_skills/grounded-citations/references/citation-formats.md +65 -0
  37. limbo_code-0.3.5/src/limbo/daily_skills/grounded-citations/references/grounding-rationale.md +64 -0
  38. limbo_code-0.3.5/src/limbo/daily_skills/grounded-citations/scripts/sources.py +675 -0
  39. limbo_code-0.3.5/src/limbo/daily_skills/meeting-action-items/LICENSE +21 -0
  40. limbo_code-0.3.5/src/limbo/daily_skills/meeting-action-items/SKILL.md +80 -0
  41. limbo_code-0.3.5/src/limbo/daily_skills/pdf/LICENSE +21 -0
  42. limbo_code-0.3.5/src/limbo/daily_skills/pdf/SKILL.md +117 -0
  43. limbo_code-0.3.5/src/limbo/daily_skills/pdf/references/forms.md +99 -0
  44. limbo_code-0.3.5/src/limbo/daily_skills/pdf/references/nano-pdf-editing.md +40 -0
  45. limbo_code-0.3.5/src/limbo/daily_skills/pdf/references/ocr-extraction.md +165 -0
  46. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/_raster.py +76 -0
  47. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/extract_marker.py +88 -0
  48. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/extract_pymupdf.py +101 -0
  49. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_create.py +130 -0
  50. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_fill_form.py +97 -0
  51. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_form_layout.py +168 -0
  52. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_make_form.py +145 -0
  53. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_merge.py +50 -0
  54. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_meta.py +115 -0
  55. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_page_image.py +99 -0
  56. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_read.py +153 -0
  57. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_secure.py +71 -0
  58. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_split.py +84 -0
  59. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_stamp.py +143 -0
  60. limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_watermark.py +51 -0
  61. limbo_code-0.3.5/src/limbo/daily_skills/powerpoint/LICENSE +21 -0
  62. limbo_code-0.3.5/src/limbo/daily_skills/powerpoint/SKILL.md +212 -0
  63. limbo_code-0.3.5/src/limbo/daily_skills/powerpoint/scripts/pptx_create.py +214 -0
  64. limbo_code-0.3.5/src/limbo/daily_skills/powerpoint/scripts/pptx_edit.py +436 -0
  65. limbo_code-0.3.5/src/limbo/daily_skills/powerpoint/scripts/pptx_from_template.py +88 -0
  66. limbo_code-0.3.5/src/limbo/daily_skills/powerpoint/scripts/pptx_read.py +131 -0
  67. limbo_code-0.3.5/src/limbo/daily_skills/powerpoint/scripts/pptx_render.py +93 -0
  68. limbo_code-0.3.5/src/limbo/daily_skills/weekly-review-planning/LICENSE +21 -0
  69. limbo_code-0.3.5/src/limbo/daily_skills/weekly-review-planning/SKILL.md +73 -0
  70. limbo_code-0.3.5/src/limbo/daily_skills/xlsx/LICENSE +21 -0
  71. limbo_code-0.3.5/src/limbo/daily_skills/xlsx/SKILL.md +188 -0
  72. limbo_code-0.3.5/src/limbo/daily_skills/xlsx/references/restructuring.md +71 -0
  73. limbo_code-0.3.5/src/limbo/daily_skills/xlsx/scripts/csv_to_xlsx.py +104 -0
  74. limbo_code-0.3.5/src/limbo/daily_skills/xlsx/scripts/xlsx_create.py +259 -0
  75. limbo_code-0.3.5/src/limbo/daily_skills/xlsx/scripts/xlsx_edit.py +263 -0
  76. limbo_code-0.3.5/src/limbo/daily_skills/xlsx/scripts/xlsx_read.py +160 -0
  77. limbo_code-0.3.5/src/limbo/daily_skills/xlsx/scripts/xlsx_recalc.py +111 -0
  78. limbo_code-0.3.5/src/limbo/daily_skills/xlsx/scripts/xlsx_restructure.py +337 -0
  79. limbo_code-0.3.5/src/limbo/daily_skills/xlsx/scripts/xlsx_to_csv.py +69 -0
  80. limbo_code-0.3.5/src/limbo/daily_skills/youtube-content/LICENSE +21 -0
  81. limbo_code-0.3.5/src/limbo/daily_skills/youtube-content/SKILL.md +76 -0
  82. limbo_code-0.3.5/src/limbo/daily_skills/youtube-content/references/output-formats.md +56 -0
  83. limbo_code-0.3.5/src/limbo/daily_skills/youtube-content/scripts/fetch_transcript.py +124 -0
  84. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/headless.py +229 -8
  85. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/journal.py +38 -4
  86. limbo_code-0.3.5/src/limbo/memory.py +254 -0
  87. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/models.py +4 -0
  88. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/prompt.py +51 -4
  89. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/pump.py +6 -1
  90. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/sessions.py +24 -0
  91. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/skills.py +20 -7
  92. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/steer.py +9 -0
  93. limbo_code-0.3.5/src/limbo/subagents/board.py +657 -0
  94. limbo_code-0.3.5/src/limbo/subagents/commands.py +104 -0
  95. limbo_code-0.3.5/src/limbo/subagents/events.py +59 -0
  96. limbo_code-0.3.5/src/limbo/subagents/hooks.py +100 -0
  97. limbo_code-0.3.5/src/limbo/subagents/profiles.py +290 -0
  98. limbo_code-0.3.5/src/limbo/subagents/project_scan.py +265 -0
  99. limbo_code-0.3.5/src/limbo/subagents/supervisor.py +1413 -0
  100. limbo_code-0.3.5/src/limbo/subagents/tools.py +437 -0
  101. limbo_code-0.3.5/src/limbo/subagents/worktree.py +118 -0
  102. limbo_code-0.3.5/src/limbo/tools/ask_user.py +69 -0
  103. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/base.py +15 -0
  104. limbo_code-0.3.5/src/limbo/tools/memory.py +96 -0
  105. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/registry.py +98 -5
  106. limbo_code-0.3.5/src/limbo/tools/session_search.py +186 -0
  107. limbo_code-0.3.5/src/limbo/tools/skill_manage.py +228 -0
  108. limbo_code-0.3.5/src/limbo/tools/web_fetch.py +280 -0
  109. limbo_code-0.3.5/src/limbo/tools/web_search.py +78 -0
  110. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/app.py +42 -4
  111. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/app.tcss +31 -0
  112. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/commands.py +8 -2
  113. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/contrast.py +20 -2
  114. limbo_code-0.3.5/src/limbo/ui/daily_look.py +157 -0
  115. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/motion.py +10 -4
  116. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/omarchy.py +4 -14
  117. limbo_code-0.3.5/src/limbo/ui/screens/agents_panel.py +216 -0
  118. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/main.py +307 -10
  119. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/chat.py +11 -0
  120. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/input.py +47 -1
  121. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/key_hints.py +9 -0
  122. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/landing.py +22 -4
  123. limbo_code-0.3.5/src/limbo/ui/widgets/mode_divider.py +76 -0
  124. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/pills.py +11 -1
  125. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/sidebar.py +132 -0
  126. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/status_bar.py +30 -1
  127. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/tool_card.py +1 -1
  128. limbo_code-0.3.5/src/limbo/websearch/__init__.py +32 -0
  129. limbo_code-0.3.5/src/limbo/websearch/base.py +43 -0
  130. limbo_code-0.3.5/src/limbo/websearch/deepseek.py +124 -0
  131. {limbo_code-0.3 → limbo_code-0.3.5}/tests/conftest.py +24 -0
  132. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_cli.py +20 -0
  133. limbo_code-0.3.5/tests/test_daily_mode.py +229 -0
  134. limbo_code-0.3.5/tests/test_daily_p1.py +273 -0
  135. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_prompt.py +1 -1
  136. limbo_code-0.3.5/tests/test_subagents.py +566 -0
  137. limbo_code-0.3.5/tests/test_task_board.py +177 -0
  138. limbo_code-0.3.5/tests/tools/test_web_search.py +170 -0
  139. limbo_code-0.3.5/tests/ui/test_daily_look.py +209 -0
  140. limbo_code-0.3.5/tests/ui/test_daily_mode_ui.py +69 -0
  141. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_snapshots.py +1 -1
  142. {limbo_code-0.3 → limbo_code-0.3.5}/uv.lock +18 -0
  143. {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/grill-with-docs/SKILL.md +0 -0
  144. {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/grill-with-docs/agents/openai.yaml +0 -0
  145. {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/improve-codebase-architecture/HTML-REPORT.md +0 -0
  146. {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/improve-codebase-architecture/SKILL.md +0 -0
  147. {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/improve-codebase-architecture/agents/openai.yaml +0 -0
  148. {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/tdd/SKILL.md +0 -0
  149. {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/tdd/agents/openai.yaml +0 -0
  150. {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/tdd/mocking.md +0 -0
  151. {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/tdd/tests.md +0 -0
  152. {limbo_code-0.3 → limbo_code-0.3.5}/.github/workflows/publish.yml +0 -0
  153. {limbo_code-0.3 → limbo_code-0.3.5}/.github/workflows/test.yml +0 -0
  154. {limbo_code-0.3 → limbo_code-0.3.5}/.gitignore +0 -0
  155. {limbo_code-0.3 → limbo_code-0.3.5}/Makefile +0 -0
  156. {limbo_code-0.3 → limbo_code-0.3.5}/design/bang-verification.md +0 -0
  157. {limbo_code-0.3 → limbo_code-0.3.5}/design/confirm_view.html +0 -0
  158. {limbo_code-0.3 → limbo_code-0.3.5}/design/limbo-ui-minimal.md +0 -0
  159. {limbo_code-0.3 → limbo_code-0.3.5}/design/limbo-ui-redesign.md +0 -0
  160. {limbo_code-0.3 → limbo_code-0.3.5}/design/prototype-minimal-confirm.png +0 -0
  161. {limbo_code-0.3 → limbo_code-0.3.5}/design/prototype-minimal.html +0 -0
  162. {limbo_code-0.3 → limbo_code-0.3.5}/design/prototype-minimal.png +0 -0
  163. {limbo_code-0.3 → limbo_code-0.3.5}/design/prototype.html +0 -0
  164. {limbo_code-0.3 → limbo_code-0.3.5}/design/prototype.png +0 -0
  165. {limbo_code-0.3 → limbo_code-0.3.5}/design/rfc-bang-command.md +0 -0
  166. {limbo_code-0.3 → limbo_code-0.3.5}/design/rfc-headless-cli.md +0 -0
  167. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/limbo-current-ui.png +0 -0
  168. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/limbo-hero.png +0 -0
  169. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/limbo-hero.svg +0 -0
  170. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/limbo-models.png +0 -0
  171. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/limbo-models.svg +0 -0
  172. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/limbo-new-ui.png +0 -0
  173. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-dark/1_idle.svg +0 -0
  174. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-dark/2_thinking_tool_running.svg +0 -0
  175. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-dark/3_tool_success.svg +0 -0
  176. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-dark/4_tool_error.svg +0 -0
  177. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-dark/5_llm_error.svg +0 -0
  178. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-dark/6_edit_diff.svg +0 -0
  179. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-light/1_idle.svg +0 -0
  180. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-light/2_thinking_tool_running.svg +0 -0
  181. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-light/3_tool_success.svg +0 -0
  182. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-light/4_tool_error.svg +0 -0
  183. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-light/5_llm_error.svg +0 -0
  184. {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-light/6_edit_diff.svg +0 -0
  185. {limbo_code-0.3 → limbo_code-0.3.5}/docs/session-management.md +0 -0
  186. {limbo_code-0.3 → limbo_code-0.3.5}/docs/ui-redesign-proposal.md +0 -0
  187. {limbo_code-0.3 → limbo_code-0.3.5}/scripts/check_contrast.py +0 -0
  188. {limbo_code-0.3 → limbo_code-0.3.5}/scripts/gen_banner.py +0 -0
  189. {limbo_code-0.3 → limbo_code-0.3.5}/scripts/readme_hero.py +0 -0
  190. {limbo_code-0.3 → limbo_code-0.3.5}/scripts/scroll_bench.py +0 -0
  191. {limbo_code-0.3 → limbo_code-0.3.5}/scripts/ui_walkthrough.py +0 -0
  192. {limbo_code-0.3 → limbo_code-0.3.5}/skills-lock.json +0 -0
  193. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/__init__.py +0 -0
  194. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/__main__.py +0 -0
  195. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/attachments.py +0 -0
  196. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/auth.py +0 -0
  197. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/btw.py +0 -0
  198. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/cli_auth.py +0 -0
  199. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/code_mode.py +0 -0
  200. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/compaction.py +0 -0
  201. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/goal.py +0 -0
  202. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/history.py +0 -0
  203. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/integrations/__init__.py +0 -0
  204. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/integrations/base.py +0 -0
  205. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/integrations/herdr.py +0 -0
  206. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/integrations/osc7501.py +0 -0
  207. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/__init__.py +0 -0
  208. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/anthropic_client.py +0 -0
  209. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/catalog.py +0 -0
  210. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/client.py +0 -0
  211. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/factory.py +0 -0
  212. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/openai_client.py +0 -0
  213. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/responses_client.py +0 -0
  214. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/retry.py +0 -0
  215. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/scaffold.py +0 -0
  216. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/sse.py +0 -0
  217. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/usage.py +0 -0
  218. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/verify.py +0 -0
  219. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/model_switch.py +0 -0
  220. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/toggles.py +0 -0
  221. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/__init__.py +0 -0
  222. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/bash.py +0 -0
  223. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/edit.py +0 -0
  224. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/find.py +0 -0
  225. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/grep.py +0 -0
  226. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/hooks.py +0 -0
  227. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/ignore.py +0 -0
  228. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/ls.py +0 -0
  229. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/mutation_queue.py +0 -0
  230. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/read.py +0 -0
  231. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/run_code.py +0 -0
  232. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/write.py +0 -0
  233. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/trace.py +0 -0
  234. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tracing/__init__.py +0 -0
  235. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tracing/command.py +0 -0
  236. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tracing/index.py +0 -0
  237. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tracing/model.py +0 -0
  238. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tracing/server.py +0 -0
  239. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tracing/static/index.html +0 -0
  240. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/__init__.py +0 -0
  241. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/banner.py +0 -0
  242. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/clipboard.py +0 -0
  243. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/gradient.py +0 -0
  244. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/key_fixes.py +0 -0
  245. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/paste_store.py +0 -0
  246. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/path_input.py +0 -0
  247. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/recent_models.py +0 -0
  248. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/__init__.py +0 -0
  249. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/auth_dialog.py +0 -0
  250. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/btw.py +0 -0
  251. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/command_palette.py +0 -0
  252. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/dialog.py +0 -0
  253. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/game2048.py +0 -0
  254. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/model_picker.py +0 -0
  255. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/session_picker.py +0 -0
  256. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/verify_picker.py +0 -0
  257. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/syntax.py +0 -0
  258. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/theme.py +0 -0
  259. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/__init__.py +0 -0
  260. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/activity.py +0 -0
  261. {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/command_menu.py +0 -0
  262. {limbo_code-0.3 → limbo_code-0.3.5}/tests/fixtures/omarchy/README.md +0 -0
  263. {limbo_code-0.3 → limbo_code-0.3.5}/tests/fixtures/omarchy/catppuccin-latte.toml +0 -0
  264. {limbo_code-0.3 → limbo_code-0.3.5}/tests/fixtures/omarchy/gruvbox.toml +0 -0
  265. {limbo_code-0.3 → limbo_code-0.3.5}/tests/fixtures/omarchy/hackerman.toml +0 -0
  266. {limbo_code-0.3 → limbo_code-0.3.5}/tests/fixtures/omarchy/lumon.toml +0 -0
  267. {limbo_code-0.3 → limbo_code-0.3.5}/tests/fixtures/omarchy/rose-pine.toml +0 -0
  268. {limbo_code-0.3 → limbo_code-0.3.5}/tests/fixtures/omarchy/tokyo-night.toml +0 -0
  269. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_agent.py +0 -0
  270. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_anthropic_client.py +0 -0
  271. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_auth.py +0 -0
  272. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_btw.py +0 -0
  273. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_catalog.py +0 -0
  274. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_code_mode_agent.py +0 -0
  275. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_compaction.py +0 -0
  276. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_config.py +0 -0
  277. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_conversation.py +0 -0
  278. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_goal.py +0 -0
  279. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_headless.py +0 -0
  280. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_herdr.py +0 -0
  281. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_history.py +0 -0
  282. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_integration.py +0 -0
  283. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_interrupt.py +0 -0
  284. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_llm_client.py +0 -0
  285. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_model_switch.py +0 -0
  286. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_osc7501.py +0 -0
  287. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_plan_mode.py +0 -0
  288. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_pump.py +0 -0
  289. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_responses_client.py +0 -0
  290. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_retry.py +0 -0
  291. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_sessions.py +0 -0
  292. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_skills.py +0 -0
  293. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_sse.py +0 -0
  294. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_steer.py +0 -0
  295. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_trace.py +0 -0
  296. {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_usage.py +0 -0
  297. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_base.py +0 -0
  298. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_bash.py +0 -0
  299. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_edit.py +0 -0
  300. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_grep.py +0 -0
  301. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_hooks.py +0 -0
  302. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_ignore.py +0 -0
  303. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_mutation_queue.py +0 -0
  304. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_read.py +0 -0
  305. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_registry.py +0 -0
  306. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_run_code.py +0 -0
  307. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_write.py +0 -0
  308. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tracing/test_command.py +0 -0
  309. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tracing/test_index.py +0 -0
  310. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tracing/test_model.py +0 -0
  311. {limbo_code-0.3 → limbo_code-0.3.5}/tests/tracing/test_server.py +0 -0
  312. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/__snapshots__/test_snapshots/test_snapshot_idle.raw +0 -0
  313. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/__snapshots__/test_snapshots/test_snapshot_wide_layout_with_sidebar.raw +0 -0
  314. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_app_smoke.py +0 -0
  315. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_bang_ui.py +0 -0
  316. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_btw_ui.py +0 -0
  317. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_command_menu.py +0 -0
  318. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_compact_ui.py +0 -0
  319. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_goal_ui.py +0 -0
  320. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_input_paste.py +0 -0
  321. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_interrupt_ui.py +0 -0
  322. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_main_screen.py +0 -0
  323. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_model_picker.py +0 -0
  324. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_omarchy.py +0 -0
  325. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_path_input.py +0 -0
  326. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_scroll_follow.py +0 -0
  327. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_sessions_ui.py +0 -0
  328. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_sidebar.py +0 -0
  329. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_skills_ui.py +0 -0
  330. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_steer_ui.py +0 -0
  331. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_tracing_viewer_ui.py +0 -0
  332. {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_widgets.py +0 -0
@@ -39,7 +39,8 @@ src/limbo/
39
39
  │ # same TurnPump seam as the TUI, no textual import
40
40
  ├── conversation.py # Conversation: the live agent+pump pair both frontends drive —
41
41
  │ # new/switch/fork/handoff (load before close), lifecycle reporting
42
- │ # (drive), /goal verify-proposal flow
42
+ │ # (drive), /goal verify-proposal flow, the subagent supervisor
43
+ │ # (subscribe/start_background/take_wake_input)
43
44
  ├── sessions.py # Session JSONL file format: records, save/load/list/export
44
45
  ├── journal.py # SessionJournal: when/in what order records reach the file
45
46
  │ # (watermark, rewrite fallback, queue re-journal, meta patches)
@@ -51,6 +52,19 @@ src/limbo/
51
52
  │ # osc7501.py (terminal program status; TTY only, LIMBO_PROGRAM_STATUS=0
52
53
  │ # opts out, tmux passthrough); create_reporters() fans out
53
54
  ├── skills.py # SKILL.md discovery (user + project dirs)
55
+ ├── daily_skills/ # Bundled daily starter skills (ported from hermes-agent, MIT; excluded
56
+ │ # from ruff/mypy)
57
+ ├── daily.py # Daily mode notices (docs/daily-mode.md); the posture itself is
58
+ │ # ToolRegistry.daily_mode + prompt.py + SessionMeta.daily_mode
59
+ ├── memory.py # Persistent memory (~/.limbo/memory/USER.md, NOTES.md): MemoryStore
60
+ │ # (capped, atomic batch ops, .bak), frozen per-session MemorySnapshot
61
+ ├── subagents/ # Background subagents (docs/subagents.md): board.py (event-sourced
62
+ │ # task board + pure reconcile()), supervisor.py (scheduler, runners,
63
+ │ # notice delivery, user/main verbs), tools.py (main: plan_tasks/
64
+ │ # task_status/task_send/answer/task_control; child: checkpoint/need/
65
+ │ # ask_main/finish/propose_task), profiles.py (agent profiles),
66
+ │ # project_scan.py (<project_facts>), hooks.py (read-only/no-edit/path
67
+ │ # claims), worktree.py, commands.py (/task /agents @name), events.py
54
68
  ├── llm/ # catalog.py (provider/model specs), factory.py (dialect→client),
55
69
  │ # openai_client.py, anthropic_client.py, responses_client.py, retry.py, sse.py,
56
70
  │ # usage.py (token accounting: usage normalization + prompt-size estimation),
@@ -58,9 +72,15 @@ src/limbo/
58
72
  ├── tools/ # base.py (BaseTool + path resolution + truncation), registry.py (dispatch;
59
73
  │ # code_mode flag filters definitions() to [run_code], all_definitions() feeds
60
74
  │ # the SDK), hooks.py (before/after tool hook chain + plan mode), mutation_queue.py (per-file locks), ignore.py (.gitignore),
61
- │ # read/bash/edit/write/grep/find/ls/run_code.py (the Code Mode transport)
75
+ │ # read/bash/edit/write/grep/find/ls/run_code.py (the Code Mode transport),
76
+ │ # web_search.py (registered only when the search provider has a key),
77
+ │ # daily mode only: web_fetch.py, memory.py, session_search.py,
78
+ │ # ask_user.py (end_turn), skill_manage.py (writes ~/.limbo/daily/skills)
79
+ ├── websearch/ # pluggable web-search backends: base.py (SearchProvider/SearchResult),
80
+ │ # deepseek.py (+ key inheritance from the deepseek model provider), PROVIDERS
62
81
  └── ui/ # app.py + app.tcss (ALL styles here; theme vars only, no bare hex),
63
- # theme.py (limbo-dark/-light, RFC LIM-16), commands.py (slash registry
82
+ # theme.py (limbo-dark/-light, RFC LIM-16), daily_look.py (daily mode
83
+ # "Limbo Dawn": <theme>+daily warm variant, app.set_daily_look), commands.py (slash registry
64
84
  # + resolve(): the single builtin-vs-skill collision site), path_input.py
65
85
  # ('/'-path fallback), paste_store.py (pure paste/attachment marker
66
86
  # state machine; the input widget is its adapter),
@@ -91,20 +111,28 @@ Providers/models live in `llm/catalog.py`; unknown models get generic OpenAI-com
91
111
  [goal] # max_rounds = 10, verify_timeout_ms = 600000
92
112
  [queue] # after_failed_run = "continue" | "keep" | "withdraw" (queued
93
113
  # messages after an LLM-error turn; keep/withdraw end the task)
114
+ [subagents] # enabled, auto = "off"|"suggest"|"on", max_parallel = 3, max_tasks = 12,
115
+ # task_token_budget, cheap_model, wake_main_on, on_dep_fail, on_resume
116
+ [daily] # workdir = "~/limbo-daily", model, memory, user_chars, notes_chars,
117
+ # memory_nudge_turns, learn_after_tool_calls, fetch_max_chars, fetch_timeout
94
118
  [ui] # theme, show_banner
95
119
  [providers.<id>] # base_url / api_key / api_key_env / headers
96
120
  ```
97
121
 
98
122
  `/model` rebuilds the client mid-session (refused while busy) and persists via tomlkit. Sessions resume via `--continue` / `--resume` / `/sessions`; resume repairs dangling tool calls: each call commits a `tool_intent` record before it runs, so a crashed call is re-run on the next turn if its tool is `replay = "safe"` (read/grep/find/ls), otherwise marked "may have partially run" (intent committed) or "did not run" (no intent); legacy sessions without `meta.tool_intents` get the generic placeholder. Trace events: `session_start`, `user_message`, `llm_request` (full body), `llm_response`, `tool_call`, `tool_result`, `tool_recovery`, `compaction*`, `error`, `turn_end`. `/export [path]` merges meta + trace + message snapshot (Markdown if `.md`). `/fork [n]` copies the active history (first n user turns) into a new self-contained session, `/handoff <note>` starts a clean linked session from a note; both record `parent_session`/`fork_at` and leave the parent untouched. Code Mode sub-calls are traced as `tool_call`/`tool_result` with `parent_call_id`. `limbo --json` (implies `--headless`) prints every event as one JSON object per line.
99
123
 
100
- Skills: `~/.limbo/skills/<name>/SKILL.md` (user) and `<workdir>/.agents/skills/<name>/SKILL.md` (project, wins collisions) — injected as a `<available_skills>` catalog in the system prompt and invocable via `/<name> [args]`.
124
+ Skills: `~/.limbo/skills/<name>/SKILL.md` (user) and `<workdir>/.agents/skills/<name>/SKILL.md` (project, wins collisions); daily sessions also see the bundled `src/limbo/daily_skills/` (lowest) and `~/.limbo/daily/skills/` (highest), coding sessions never do — injected as a `<available_skills>` catalog in the system prompt and invocable via `/<name> [args]`.
101
125
 
102
126
  ## UI
103
127
 
104
- Single column: status bar (state/elapsed/tokens/model/workdir/queued + rainbow 🎯GOAL badge while a goal loop runs + ⌨code badge while Code Mode is on) → scrolling chat flow (user `❯`, streaming Markdown, tool cards, errors) → input box (Enter submits, Shift+Enter newline, Alt+Enter queues a follow-up while busy (`ui/key_fixes.py` maps its modifyOtherKeys/kitty/ESC forms), paste markers, `ctrl+v` image attach) → hint line. Slash commands: `/sessions /new /fork /handoff /export /tracing-viewer /compact /model /code-mode /plan /help /2048 /goal` + skill commands. '/'-leading input that matches no command but looks like a path is sent as a normal message with existing files auto-attached (`ui/path_input.py`); a leading space forces plain text. After palette changes run `python scripts/check_contrast.py` (≥ 4.5:1).
128
+ Single column: status bar (state/elapsed/tokens/model/workdir/queued + rainbow 🎯GOAL badge while a goal loop runs + ⌨code badge while Code Mode is on) → scrolling chat flow (user `❯`, streaming Markdown, tool cards, errors) → input box (Enter submits, Shift+Enter newline, Alt+Enter queues a follow-up while busy (`ui/key_fixes.py` maps its modifyOtherKeys/kitty/ESC forms), paste markers, `ctrl+v` image attach) → hint line. Slash commands: `/sessions /new /fork /handoff /export /tracing-viewer /compact /model /code-mode /plan /daily-mode /memory /learn /help /2048 /goal /agents /task` + skill commands; `@<agent> text` messages a subagent. '/'-leading input that matches no command but looks like a path is sent as a normal message with existing files auto-attached (`ui/path_input.py`); a leading space forces plain text. After palette changes run `python scripts/check_contrast.py` (≥ 4.5:1).
105
129
 
106
130
  `/goal <text>` starts closed-loop mode (LIM-40): the first round is a proposal round — the model explores the repo and proposes acceptance command(s) in a `<verify_proposal>` block; the user confirms in a picker (accept / edit / skip), then the goal branch of the `TurnPump` (non-UI, shared by any frontend) runs each round as a complete `Agent.run()` turn and executes the verify command; exit 0 ends the loop, otherwise the failure output is fed back verbatim into the next round until `max_rounds`, when a no-tool wrap-up turn summarizes and any user message resumes with a fresh budget. Goal state persists on `SessionMeta.goal`. Esc during verify cancels the subprocess.
107
131
 
132
+ Subagents (`subagents/`, docs/subagents.md): the main agent's `plan_tasks` creates tasks on the board (suggest mode: `PlanPicker` asks the user first); the `Supervisor` runs each as a child `Agent` with its own session file, gated by profile hooks. Child tools that end the turn (`need`, `ask_main`, `finish`) return `ToolResult(end_turn=True)`. Notices reach the main agent as one `source="subagent"` steer item; an idle main agent is woken through `MainWake` → `Conversation.take_wake_input()`. Board records live in the main session file (`type: "task"`), so the board survives restarts; tasks running at exit come back paused (`on_resume`).
133
+
134
+ Daily mode (`limbo daily` / `--daily` / `/daily-mode on|off`, docs/daily-mode.md): a session posture like Code Mode — same loop, a general-assistant system prompt, plus `web_fetch` and `memory` tools; persisted as `SessionMeta.daily_mode`, `/new` keeps the current mode. Memory is a snapshot taken when the Agent is built: `USER.md` and `NOTES.md` enter daily-mode prompts only (coding sessions never see memory); `memory` tool writes reach disk at once but the prompt changes only next session (prefix cache stays intact). `/learn` (and auto after `learn_after_tool_calls` tool calls) plans a `skill-reviewer` fork subagent whose only write tool is `skill_manage`; daily children inherit daily mode minus `MAIN_ONLY_TOOLS`.
135
+
108
136
  ## Key Decisions
109
137
 
110
138
  - Async agent, sync tools via `asyncio.to_thread()`
@@ -136,4 +164,5 @@ uv run python -m pytest --snapshot-update # after intentional visual changes; r
136
164
  ## Adding Things
137
165
 
138
166
  - **Tool**: subclass `BaseTool` in `tools/<name>.py` (`name`/`description`/`parameters` + `run()`; use `resolve_existing()`/`resolve_creatable()`, raise `ToolError`), register in `ToolRegistry.__init__()`, wrap mutations in `mutation_lock_for(path)`, add `tests/tools/test_<name>.py`
167
+ - **Web-search backend**: subclass `SearchProvider` in `websearch/<id>.py` with a `build(config)` factory (None when it has no key), add it to `websearch.PROVIDERS`; users pick it with `[web_search] provider`
139
168
  - **Provider/model**: add specs in `llm/catalog.py`; new wire format → implement `LLMClient` + `register_client()` in `llm/factory.py`. User-specific endpoint/key tweaks belong in `[providers.<id>]` config, not the catalog
@@ -60,6 +60,26 @@ proposals should name modules with these terms.
60
60
  (converging on the latest config model), persist to config.toml. The UI
61
61
  screen is an adapter translating verdicts into chat messages.
62
62
 
63
+ ## Subagents
64
+
65
+ - **Task board** — the delegated work of one main session
66
+ (`subagents/board.py`): tasks with status, `depends_on` (dependency
67
+ edges: a failure notifies by default), `owner` (ownership edges: a
68
+ failure cascades), waits, checkpoints, questions and outcomes.
69
+ Event-sourced into the main session file; `reconcile()` is the pure
70
+ scheduling rule.
71
+ - **Subagent** — a child Agent working on one task with its own context and
72
+ session file. It reports through checkpoint / need / ask_main / finish
73
+ and never plans tasks itself (depth 1).
74
+ - **Profile** — what kind of subagent a task gets (tools, model, prompt);
75
+ built-in, user (`~/.limbo/agents`) or project (`.agents/agents`).
76
+ - **Supervisor** — owns the board, the running subagents and notice
77
+ delivery for one Conversation (`subagents/supervisor.py`).
78
+ - **Notice** — a subagent event for the main agent: result, question,
79
+ alert, info (delivered, at most once) or progress (UI only). Delivered as
80
+ one `<subagent_updates>` steer item; questions and alerts wake an idle
81
+ main agent, results wait until the wave is done.
82
+
63
83
  ## Safety
64
84
 
65
85
  Limbo has no safety fences: file tools are not scoped to the workdir,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: limbo-code
3
- Version: 0.3
3
+ Version: 0.3.5
4
4
  Summary: A minimal terminal AI coding agent
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: httpx>=0.27
@@ -10,6 +10,8 @@ Requires-Dist: pygments>=2.17
10
10
  Requires-Dist: textual>=8.0
11
11
  Requires-Dist: toml>=0.10
12
12
  Requires-Dist: tomlkit>=0.13
13
+ Provides-Extra: daily
14
+ Requires-Dist: pypdf>=4.0; extra == 'daily'
13
15
  Description-Content-Type: text/markdown
14
16
 
15
17
  # Limbo
@@ -60,6 +62,11 @@ you can branch, hand off, or replay any session.
60
62
  confirm it, and Limbo iterates until it passes.
61
63
  - **Steer while it works.** Type while a turn is running to redirect it;
62
64
  `Alt+Enter` queues a follow-up for after the task; `Esc` interrupts.
65
+ - **Background subagents.** The agent can split work into tasks that run in
66
+ parallel with their own context: they checkpoint, wait on each other when
67
+ they discover a dependency, and report back. You approve the plan, watch
68
+ the board in `/agents`, and pause, cancel or talk to any of them with
69
+ `/task` or `@name`, or just ask the main agent.
63
70
  - **Side channels.** `/btw <question>` asks something quick without polluting
64
71
  the history; `!<command>` runs a shell command yourself, never sent to the
65
72
  model.
@@ -106,6 +113,24 @@ you can branch, hand off, or replay any session.
106
113
  - `Ctrl+P` command palette, image and file paste with `Ctrl+V`, collapsible
107
114
  tool output with `Ctrl+O`.
108
115
 
116
+ ### Daily mode for everything else
117
+
118
+ `limbo daily` (or `/daily-mode on`) turns Limbo into an everyday assistant for
119
+ non-coding work, in its own working directory:
120
+
121
+ - **Memory.** `USER.md` (who you are) and `NOTES.md` (what it learned) under
122
+ `~/.limbo/memory/`, loaded into daily sessions only, never into coding ones.
123
+ - **More tools.** `web_fetch` reads pages and PDFs, `session_search` recalls
124
+ past conversations, and `ask_user` asks you a multiple-choice question.
125
+ - **A starter pack of skills** for PDFs, Word, Excel, slides, citations,
126
+ meeting notes, weekly reviews, YouTube and arXiv. Daily mode has its own
127
+ skill directory (`~/.limbo/daily/skills/`) that coding sessions never see.
128
+ - **It learns.** `/learn`, or an automatic review after a long stretch of
129
+ work, has a background subagent write what it learned into skills. Every
130
+ write lands in the daily skill directory and keeps a `.bak`.
131
+
132
+ See [docs/daily-mode.md](docs/daily-mode.md).
133
+
109
134
  ### Scriptable
110
135
 
111
136
  `limbo --headless` gives the same agent as a line-oriented REPL, and
@@ -155,6 +180,7 @@ Then just describe the task: *"find why the login test is flaky and fix it"*.
155
180
  | `/goal <task>` | iterate until a confirmed verify command passes |
156
181
  | `/code-mode [on\|off]` | one `run_code` tool: a Python program, many tool calls |
157
182
  | `/btw <question>` | side question that stays out of history |
183
+ | `/agents` `/task` `@name` | background subagents: the task board, direct control, talk to one |
158
184
  | `/compact` | compact the conversation now |
159
185
  | `/sessions` `/new` | switch to a past session, or start fresh |
160
186
  | `/fork [n]` | branch into a new session (optionally keep only the first n turns) |
@@ -194,6 +220,23 @@ theme = "auto" # Omarchy if installed, else limbo-dusk
194
220
  motion = "full" # full | reduced | off
195
221
  ```
196
222
 
223
+ ### Web search
224
+
225
+ The `web_search` tool is offered whenever its provider has a key. The only
226
+ provider today is DeepSeek
227
+ ([search API](https://api-docs.deepseek.com/guides/search)); without its own
228
+ key it reuses the DeepSeek model key (`[providers.deepseek]`, `limbo auth
229
+ login`, `$DEEPSEEK_API_KEY`, or `[llm] api_key` while a DeepSeek model is
230
+ active).
231
+
232
+ ```toml
233
+ [web_search]
234
+ provider = "deepseek" # backends live in limbo.websearch.PROVIDERS
235
+ api_key = "sk-..." # optional: a separate key just for search
236
+ count = 10 # default results per search
237
+ enabled = true
238
+ ```
239
+
197
240
  ## Make it yours
198
241
 
199
242
  - **Project instructions.** Limbo reads `AGENTS.md` from the working directory
@@ -235,6 +278,31 @@ The screenshot above is rendered from the real UI by
235
278
  `scripts/readme_hero.py` (`uv run python scripts/readme_hero.py`), so it can't
236
279
  drift from what ships.
237
280
 
281
+ ## Acknowledgements
282
+
283
+ Limbo borrows openly from other agents. Thank you to:
284
+
285
+ - **[pi](https://github.com/badlogic/pi-mono) and pi-durable.** The durable
286
+ session design comes from pi-durable: the "commit the intent, then the
287
+ effect" journal, the replay policy for tool calls interrupted by a crash,
288
+ the placeholders that say what is known about an unfinished call, the
289
+ steer and follow-up inbox (`Alt+Enter`), the task graph edges behind
290
+ background subagents, and context overflow detection. From the pi coding
291
+ agent itself: the built-in tool behavior (output limits, multi-edit,
292
+ process-tree kill, ripgrep), the provider conventions and model catalog,
293
+ compaction and the session entry model, and collapsing large pastes.
294
+ - **[Crush](https://github.com/charmbracelet/crush)** by Charm. The Limbo
295
+ Dusk TUI was designed after Crush: the gradient wordmark, `╱` dialog rules,
296
+ Limbo Motion (its staggered entrance is borrowed directly), the `Ctrl+P`
297
+ command palette and the `Ctrl+S` session picker.
298
+ - **[Hermes Agent](https://github.com/NousResearch/hermes-agent)** by Nous
299
+ Research. Daily mode is modeled on Hermes: the `USER.md` / `NOTES.md`
300
+ memory with its frozen per-session snapshot and the memory nudge,
301
+ `session_search`, `ask_user`, and skill self-learning (the skill reviewer's
302
+ prompt is adapted from Hermes). The bundled daily skills in
303
+ `src/limbo/daily_skills/` are ported from Hermes under the MIT license, and
304
+ each keeps its `LICENSE`.
305
+
238
306
  ## Learn more
239
307
 
240
308
  - [`AGENTS.md`](AGENTS.md): architecture and design decisions
@@ -242,4 +310,8 @@ drift from what ships.
242
310
  - [`docs/session-management.md`](docs/session-management.md): sessions,
243
311
  recovery, fork and handoff, tracing viewer
244
312
  - [`docs/skills.md`](docs/skills.md): writing skills
313
+ - [`docs/daily-mode.md`](docs/daily-mode.md): daily mode, memory and
314
+ self-learning skills
315
+ - [`docs/subagents.md`](docs/subagents.md): background subagents, the task
316
+ board and how to steer them
245
317
  - [`design/`](design/): RFCs for headless mode, bang commands, and the UI
@@ -46,6 +46,11 @@ you can branch, hand off, or replay any session.
46
46
  confirm it, and Limbo iterates until it passes.
47
47
  - **Steer while it works.** Type while a turn is running to redirect it;
48
48
  `Alt+Enter` queues a follow-up for after the task; `Esc` interrupts.
49
+ - **Background subagents.** The agent can split work into tasks that run in
50
+ parallel with their own context: they checkpoint, wait on each other when
51
+ they discover a dependency, and report back. You approve the plan, watch
52
+ the board in `/agents`, and pause, cancel or talk to any of them with
53
+ `/task` or `@name`, or just ask the main agent.
49
54
  - **Side channels.** `/btw <question>` asks something quick without polluting
50
55
  the history; `!<command>` runs a shell command yourself, never sent to the
51
56
  model.
@@ -92,6 +97,24 @@ you can branch, hand off, or replay any session.
92
97
  - `Ctrl+P` command palette, image and file paste with `Ctrl+V`, collapsible
93
98
  tool output with `Ctrl+O`.
94
99
 
100
+ ### Daily mode for everything else
101
+
102
+ `limbo daily` (or `/daily-mode on`) turns Limbo into an everyday assistant for
103
+ non-coding work, in its own working directory:
104
+
105
+ - **Memory.** `USER.md` (who you are) and `NOTES.md` (what it learned) under
106
+ `~/.limbo/memory/`, loaded into daily sessions only, never into coding ones.
107
+ - **More tools.** `web_fetch` reads pages and PDFs, `session_search` recalls
108
+ past conversations, and `ask_user` asks you a multiple-choice question.
109
+ - **A starter pack of skills** for PDFs, Word, Excel, slides, citations,
110
+ meeting notes, weekly reviews, YouTube and arXiv. Daily mode has its own
111
+ skill directory (`~/.limbo/daily/skills/`) that coding sessions never see.
112
+ - **It learns.** `/learn`, or an automatic review after a long stretch of
113
+ work, has a background subagent write what it learned into skills. Every
114
+ write lands in the daily skill directory and keeps a `.bak`.
115
+
116
+ See [docs/daily-mode.md](docs/daily-mode.md).
117
+
95
118
  ### Scriptable
96
119
 
97
120
  `limbo --headless` gives the same agent as a line-oriented REPL, and
@@ -141,6 +164,7 @@ Then just describe the task: *"find why the login test is flaky and fix it"*.
141
164
  | `/goal <task>` | iterate until a confirmed verify command passes |
142
165
  | `/code-mode [on\|off]` | one `run_code` tool: a Python program, many tool calls |
143
166
  | `/btw <question>` | side question that stays out of history |
167
+ | `/agents` `/task` `@name` | background subagents: the task board, direct control, talk to one |
144
168
  | `/compact` | compact the conversation now |
145
169
  | `/sessions` `/new` | switch to a past session, or start fresh |
146
170
  | `/fork [n]` | branch into a new session (optionally keep only the first n turns) |
@@ -180,6 +204,23 @@ theme = "auto" # Omarchy if installed, else limbo-dusk
180
204
  motion = "full" # full | reduced | off
181
205
  ```
182
206
 
207
+ ### Web search
208
+
209
+ The `web_search` tool is offered whenever its provider has a key. The only
210
+ provider today is DeepSeek
211
+ ([search API](https://api-docs.deepseek.com/guides/search)); without its own
212
+ key it reuses the DeepSeek model key (`[providers.deepseek]`, `limbo auth
213
+ login`, `$DEEPSEEK_API_KEY`, or `[llm] api_key` while a DeepSeek model is
214
+ active).
215
+
216
+ ```toml
217
+ [web_search]
218
+ provider = "deepseek" # backends live in limbo.websearch.PROVIDERS
219
+ api_key = "sk-..." # optional: a separate key just for search
220
+ count = 10 # default results per search
221
+ enabled = true
222
+ ```
223
+
183
224
  ## Make it yours
184
225
 
185
226
  - **Project instructions.** Limbo reads `AGENTS.md` from the working directory
@@ -221,6 +262,31 @@ The screenshot above is rendered from the real UI by
221
262
  `scripts/readme_hero.py` (`uv run python scripts/readme_hero.py`), so it can't
222
263
  drift from what ships.
223
264
 
265
+ ## Acknowledgements
266
+
267
+ Limbo borrows openly from other agents. Thank you to:
268
+
269
+ - **[pi](https://github.com/badlogic/pi-mono) and pi-durable.** The durable
270
+ session design comes from pi-durable: the "commit the intent, then the
271
+ effect" journal, the replay policy for tool calls interrupted by a crash,
272
+ the placeholders that say what is known about an unfinished call, the
273
+ steer and follow-up inbox (`Alt+Enter`), the task graph edges behind
274
+ background subagents, and context overflow detection. From the pi coding
275
+ agent itself: the built-in tool behavior (output limits, multi-edit,
276
+ process-tree kill, ripgrep), the provider conventions and model catalog,
277
+ compaction and the session entry model, and collapsing large pastes.
278
+ - **[Crush](https://github.com/charmbracelet/crush)** by Charm. The Limbo
279
+ Dusk TUI was designed after Crush: the gradient wordmark, `╱` dialog rules,
280
+ Limbo Motion (its staggered entrance is borrowed directly), the `Ctrl+P`
281
+ command palette and the `Ctrl+S` session picker.
282
+ - **[Hermes Agent](https://github.com/NousResearch/hermes-agent)** by Nous
283
+ Research. Daily mode is modeled on Hermes: the `USER.md` / `NOTES.md`
284
+ memory with its frozen per-session snapshot and the memory nudge,
285
+ `session_search`, `ask_user`, and skill self-learning (the skill reviewer's
286
+ prompt is adapted from Hermes). The bundled daily skills in
287
+ `src/limbo/daily_skills/` are ported from Hermes under the MIT license, and
288
+ each keeps its `LICENSE`.
289
+
224
290
  ## Learn more
225
291
 
226
292
  - [`AGENTS.md`](AGENTS.md): architecture and design decisions
@@ -228,4 +294,8 @@ drift from what ships.
228
294
  - [`docs/session-management.md`](docs/session-management.md): sessions,
229
295
  recovery, fork and handoff, tracing viewer
230
296
  - [`docs/skills.md`](docs/skills.md): writing skills
297
+ - [`docs/daily-mode.md`](docs/daily-mode.md): daily mode, memory and
298
+ self-learning skills
299
+ - [`docs/subagents.md`](docs/subagents.md): background subagents, the task
300
+ board and how to steer them
231
301
  - [`design/`](design/): RFCs for headless mode, bang commands, and the UI
@@ -0,0 +1,103 @@
1
+ # Daily mode
2
+
3
+ 日常非 coding 工作(调研、读网页、写东西、整理笔记)用的会话姿态。内核和
4
+ coding 模式完全一样(agent loop、会话、压缩、子代理、/goal、skills),只换三样:
5
+
6
+ - **系统提示词**:通用个人助理口吻,先搜后答、给出处、产出落到文件。
7
+ - **工具**:在原有工具之上加 `web_fetch`(读网页/PDF)、`memory`(长期记忆)、
8
+ `session_search`(翻过往会话)、`ask_user`(向你提问)、`skill_manage`(自己改进 skill)。
9
+ - **记忆注入**:会话开始时把 `~/.limbo/memory/` 的快照放进提示词。
10
+
11
+ ## 进入和切换
12
+
13
+ ```bash
14
+ limbo daily # = limbo --daily:工作目录切到 [daily] workdir,新会话直接是 daily
15
+ limbo daily --continue # 接上一个 daily 会话
16
+ ```
17
+
18
+ 会话内 `/daily-mode on|off`(无参切换),状态栏显示 `☀daily`。模式随会话保存,
19
+ 恢复时还原;`/new` 沿用当前模式。切换会重建系统提示词(前缀缓存失效一次,和 `/model` 一样)。
20
+
21
+ ## 记忆
22
+
23
+ 两个纯文本文件,可以直接打开编辑,条目之间用单独一行 `§` 分隔:
24
+
25
+ | 文件 | 内容 |
26
+ |---|---|
27
+ | `~/.limbo/memory/USER.md` | 你是谁:身份、偏好、风格 |
28
+ | `~/.limbo/memory/NOTES.md` | agent 的笔记:稳定事实、约定、你纠正过的事 |
29
+
30
+ 记忆只进 daily 会话的提示词,coding 会话完全读不到。
31
+
32
+ - 模型用 `memory` 工具写入(add / patch / remove,一次调用可批量、原子执行),超过字符上限时整批拒绝。
33
+ - 写入立刻落盘(上一版留在 `*.bak`),但本会话的提示词不变,从下一个会话起生效。
34
+ - `/memory` 查看内容和用量;`/memory edit [user|notes]` 用 `$VISUAL`/`$EDITOR` 打开(headless 下只显示路径)。
35
+ - `/memory` 和 `/learn` 只在 daily 会话里出现;coding 会话的命令菜单、命令面板和 `/help` 里都没有,直接输入会提示先 `/daily-mode on`。
36
+
37
+ - 每 `memory_nudge_turns` 轮(默认 10)没写过记忆时,会在你的消息后附一句提醒,让模型考虑要不要存。
38
+
39
+ ## Skills
40
+
41
+ daily 会话按这个顺序收集 skill,同名时后者覆盖前者:
42
+
43
+ 1. **内置起步包**(`src/limbo/daily_skills/`,从 Hermes 移植,MIT):pdf、docx、xlsx、powerpoint、
44
+ grounded-citations、blocked-page-recovery、meeting-action-items、document-to-action-items、
45
+ weekly-review-planning、youtube-content、arxiv。文档类 skill 需要的 Python 包按 skill 里的说明装。
46
+ 2. 用户 skill `~/.limbo/skills`、项目 skill `<workdir>/.agents/skills`
47
+ 3. **daily skill** `~/.limbo/daily/skills/<name>/SKILL.md`
48
+
49
+ coding 会话只看 2,看不到起步包和 daily skill。
50
+
51
+ ## 自学习(/learn)
52
+
53
+ - 模型可以用 `skill_manage` 新建或修改 skill(create / patch / write_file,一次批量、全成或全不成)。
54
+ 所有写入都落在 `~/.limbo/daily/skills`:改内置或用户 skill 时先把它复制过来再改,原文件不动;改前留 `.bak`。
55
+ - `/learn` 在后台开一个 `skill-reviewer` 子代理(带上当前对话、只能读 skill 和调 `skill_manage`、用 cheap_model),
56
+ 把这次对话里的纠正、偏好和新技巧写进 skill,结果作为子代理通知回到对话里。
57
+ - 自动触发:一轮结束时,如果距上次改 skill 已经有 `learn_after_tool_calls`(默认 10)次工具调用,就自动开一次复盘;设 0 关掉。
58
+ - 需要子代理开着(`[subagents] enabled = true`)。
59
+
60
+ ## 其他工具
61
+
62
+ - `session_search`:不带索引地扫描会话文件,按关键词找过往 daily 会话(`include_coding` 也搜 coding),
63
+ 再用 `session_id` + `around` 读上下文。
64
+ - `ask_user`:模型给出问题和最多 6 个选项后本轮结束,你回复编号或直接回答。
65
+ - 子代理角色 `researcher`:只读调研,daily 模式下能读网页正文,交回带出处的结论。daily 会话里的子代理
66
+ 也是 daily 姿态,但 `memory`、`ask_user`、`skill_manage`、`session_search` 只留给主 agent。
67
+
68
+ ## 界面:Limbo Dawn
69
+
70
+ daily mode 下 TUI 换成当前主题的暖色变体 Limbo Dawn:coding 是 Dusk(蓝 → 黄的黄昏渐变),
71
+ daily 是 Dawn(红 → 杏橙 → 黄的日出渐变)。布局、`╱` 纹理、吉祥物黄和成功/错误/diff 语义色不变。
72
+
73
+ - 输入框边框上常驻 `☀ daily` 徽标,右下角是记忆条数;窄屏状态栏的字标旁有 `☀ DAILY` 色块
74
+ - 侧栏把「修改的文件」换成「读过的网页」和「记忆」(本会话有改动时「修改的文件」照常出现)
75
+ - 启动页、底部快捷键提示换成 daily 场景的用法
76
+ - `/daily-mode` 切换时聊天里插一条模式分隔线,一道光扫过(`[ui] motion` 为 reduced/off 时静态)
77
+
78
+ limbo 自带的三个主题用手调色板;Omarchy 和 Textual 内置主题按规则派生(渐变取 error → warning →
79
+ accent,primary 取 warning,对比度不足时向前景推);ANSI 主题不换色,只显示徽标。
80
+ `[daily] look = "badge"` 关掉换色、只保留徽标。
81
+
82
+ ## web_fetch
83
+
84
+ 打开 http(s) 链接,返回正文的 Markdown(标题、列表、链接;导航、脚本、页脚去掉,
85
+ 有 `<article>`/`<main>` 时只取正文)。长页面按 `fetch_max_chars` 分段,带 `offset` 继续读。
86
+ PDF 链接在装了 `pypdf` 时直接转成文本(`pip install 'limbo-code[daily]'`)。超长页面除了分段返回,
87
+ 全文还会存到 `<workdir>/fetched/`,可以用 read 翻。
88
+
89
+ ## 配置
90
+
91
+ ```toml
92
+ [daily]
93
+ workdir = "~/limbo-daily"
94
+ model = "" # 留空沿用 [llm] model;只对 limbo daily 启动生效
95
+ memory = true
96
+ user_chars = 1500
97
+ notes_chars = 2500
98
+ memory_nudge_turns = 10
99
+ learn_after_tool_calls = 10
100
+ fetch_max_chars = 20000
101
+ fetch_timeout = 30.0
102
+ look = "dawn" # "badge":只显示 ☀ 徽标,不换暖色主题
103
+ ```
@@ -37,8 +37,10 @@ description: Test-driven development workflow.
37
37
 
38
38
  | 来源 | 路径 |
39
39
  |------|------|
40
+ | 内置 daily 起步包(仅 daily 会话) | `src/limbo/daily_skills/`(随包分发,从 Hermes 移植) |
40
41
  | 用户级 | `~/.limbo/skills/<name>/SKILL.md` |
41
42
  | 项目级 | `<workdir>/.agents/skills/<name>/SKILL.md` |
43
+ | Daily(仅 daily 会话) | `~/.limbo/daily/skills/<name>/SKILL.md` |
42
44
 
43
45
  内置斜杠命令(`/sessions` 等)优先于同名 skill。
44
46
 
@@ -0,0 +1,132 @@
1
+ # 子代理(Subagents)
2
+
3
+ 主 agent 可以把工作拆成任务,交给后台子代理并行完成;你继续和主 agent
4
+ 对话,子代理的结果、提问和失败会回到主 agent 那里。你也可以随时直接查看
5
+ 和控制每个子任务。
6
+
7
+ ## 一眼看懂
8
+
9
+ ```
10
+ 你 ──对话──▶ 主 agent ──plan_tasks──▶ 任务板(t1 t2 t3 …)
11
+ ▲ │ reconcile:依赖就绪 → 派发
12
+ │ <subagent_updates> ▼
13
+ └──── 结果 / 提问 / 告警 ── 子代理(各自独立上下文与会话文件)
14
+ 你 ──/task、/agents、@名字──▶ 任务板 / 子代理(主 agent 会被告知)
15
+ ```
16
+
17
+ - **任务板**(`subagents/board.py`)是唯一真相:任务、依赖、等待、打点、
18
+ 提问和结果。每次变更都作为 `{"type":"task",...}` 记录追加进主会话文件,
19
+ 重启时重放;会话重写时写一条 `snapshot` 折叠历史。
20
+ - **Supervisor**(`subagents/supervisor.py`)根据任务板做调度:依赖都结束
21
+ 的任务变为就绪,按优先级 / 已有进度 / 关键路径派发到空闲槽位
22
+ (`max_parallel`),并把通知投递给主 agent。
23
+ - **子代理**是同进程里的另一个 `Agent`,有自己的会话文件
24
+ `<sessions>/<主会话>.agents/<任务id>-<名字>.jsonl`,崩溃后可以接着跑。
25
+
26
+ ## 自动创建
27
+
28
+ - 启动时对工作区做一次不调用模型的扫描(语言、文件数、workspace 子包、
29
+ 检测到的验证命令、git 状态),作为 `<project_facts>` 写进主 agent 的
30
+ system prompt,和可用角色列表 `<available_agents>` 一起引导它判断什么时候
31
+ 值得拆分。
32
+ - 默认 `auto = "suggest"`:主 agent 调 `plan_tasks` 后,计划会弹出给你确认
33
+ (TUI 弹窗;headless 里用 `/task approve all`),确认前不会开始。
34
+ `auto = "on"` 直接开始,`auto = "off"` 不给主 agent 任务工具。
35
+ - 角色(profile)决定子代理的工具、模型和提示:内置 `explore`(只读)、
36
+ `worker`、`reviewer`(只读)、`verifier`(不改文件)。用户级
37
+ `~/.limbo/agents/<name>.md` 和项目级 `.agents/agents/<name>.md` 可以覆盖或
38
+ 新增;`/agents init` 会根据扫描结果为每个 workspace 子包生成一个
39
+ `<包名>-worker`,并生成跑验证命令的 `project-verifier`。
40
+
41
+ 角色文件格式:
42
+
43
+ ```markdown
44
+ ---
45
+ name: api-worker
46
+ description: 只改 packages/api/ 下的代码
47
+ when_to_use: 任务只涉及 API 时
48
+ tools: all # read_only | all | no_edit | read,grep,bash(白名单)
49
+ model: inherit # inherit | cheap | 具体模型 id
50
+ max_iterations: 40
51
+ isolation: shared # shared | worktree
52
+ context: brief # brief(只看任务说明)| fork(带上主对话)
53
+ scope_paths: packages/api/**
54
+ ---
55
+ 给子代理的额外指令。
56
+ ```
57
+
58
+ ## 打点与任务编排
59
+
60
+ 子代理有五个工具:
61
+
62
+ | 工具 | 作用 |
63
+ |------|------|
64
+ | `checkpoint(phase, summary)` | 打点:进入新阶段时记录进度(每 8 次工具调用也会自动打点) |
65
+ | `need(on=[…] \| new={…}, reason, policy)` | 发现依赖:`wait` 挂起直到依赖结束,带着结果继续;`cancel_self` 判断自己已无必要;`ask_main` 交给主 agent 决定 |
66
+ | `ask_main(question)` | 需要主 agent / 用户决定的问题,挂起直到回答 |
67
+ | `finish(summary, files_changed)` | 交付,摘要就是主 agent 读到的全部 |
68
+ | `propose_task(title, brief)` | 建议新任务,由主 agent 批准(子代理不能自己再拆,深度固定为 1) |
69
+
70
+ 规则:
71
+
72
+ - **依赖边**(`depends_on` / `need`):依赖失败时默认 `notify`——等待方照常
73
+ 继续并收到失败原因,自己决定;`on_dep_fail = "cascade"` 改为连带取消。
74
+ `join = "fail_fast"` 让等待方在第一个依赖失败时就醒来。
75
+ - **归属边**(`owner`):父任务取消或失败,它名下的任务一律取消。
76
+ - 加依赖时检测环,形成循环会被拒绝;所有任务互相等待(死锁)时,主 agent
77
+ 会收到告警。
78
+ - 共享工作区时,写任务用 `scope_paths` 认领路径,其他子代理 `edit`/`write`
79
+ 被认领的文件会被拦下并提示用 `need` 等待。需要更强隔离时用
80
+ `isolation: worktree`(独立 git worktree 和分支,完成后
81
+ `task_control merge` 合并)。
82
+
83
+ ## 通讯
84
+
85
+ - **子代理 → 主 agent**:通知合并成一条 `<subagent_updates>` 插话。主 agent
86
+ 忙时在下一个一致点注入;空闲时:提问和告警立即唤醒主 agent,结果等这一波
87
+ 子代理都结束后一起交付(`wake_main_on` 可调)。每条通知只交付一次,崩溃
88
+ 后不会重复。
89
+ - **主 agent → 子代理**:`task_status`、`task_send`(运行中的子代理以插话收到,
90
+ 其他状态进收件箱、继续时送达)、`answer`、`task_control`(pause / resume /
91
+ cancel / retry / reprioritize / edit / approve / reject / merge)。所以你可以
92
+ 直接对主 agent 说"先暂停前端那个任务"。
93
+ - **你 → 子代理**:
94
+
95
+ | 输入 | 作用 |
96
+ |------|------|
97
+ | `/agents` | 子代理面板:实时任务板、打点、最近记录;`p` 暂停 `r` 恢复 `c` 取消 `t` 重试 `a`/`x` 批准/拒绝 `m` 发消息 |
98
+ | `/task` · `/task <id>` | 任务板 / 某个任务详情 |
99
+ | `/task <pause\|resume\|cancel\|retry\|approve\|reject\|merge> <id\|all> [说明]` | 直接控制;`/task retry <id> fresh` 丢弃旧上下文重来 |
100
+ | `/task prio <id> <n>` · `/task edit <id> <新说明>` · `/task send <id> <消息>` | 调优先级、改说明、发消息 |
101
+ | `@worker-1 <消息>` | 直接对某个子代理说话 |
102
+ | `/agents scan` · `/agents init` | 项目画像与可用角色 / 写入建议的项目角色 |
103
+
104
+ 这些命令忙时也可用,你的每个直接操作都会以 `info` 通知告诉主 agent。
105
+
106
+ ## 重启与恢复
107
+
108
+ 进程退出时运行中的任务不写结果。下次打开会话时,它们被标为"已暂停(进程
109
+ 重启时中断)"并提示 `/task resume all`(`on_resume = "auto"` 则直接继续)。
110
+ 恢复的子代理从自己的会话文件接着跑,并被告知先检查工作区现状。
111
+
112
+ headless 模式下输入关闭(EOF)后,会等后台子代理和随之而来的主 agent 总结
113
+ 轮次结束再退出;暂停和待确认的任务不等。`--json` 输出额外的 `task`、
114
+ `subagent_notice`、`plan_proposed` 行。
115
+
116
+ ## 配置
117
+
118
+ ```toml
119
+ [subagents]
120
+ enabled = true # false:完全关闭
121
+ auto = "suggest" # off | suggest | on
122
+ max_parallel = 3 # 同时运行的子代理
123
+ max_tasks = 12 # 未结束任务上限
124
+ task_token_budget = 400000 # 单任务 token 预算,超出即失败(0 = 不限)
125
+ cheap_model = "" # model: cheap 的角色用它(空 = 主模型)
126
+ wake_main_on = ["question", "alert", "wave_done"]
127
+ on_dep_fail = "notify" # notify | cascade
128
+ on_resume = "ask" # ask | auto | pause
129
+ default_isolation = "shared" # shared | worktree
130
+ result_chars = 2000 # 交给主 agent 的结果摘要长度
131
+ auto_checkpoint_every = 8 # 每 N 次工具调用自动打点(0 = 关)
132
+ ```
@@ -16,6 +16,10 @@ dependencies = [
16
16
  "pygments>=2.17",
17
17
  ]
18
18
 
19
+ [project.optional-dependencies]
20
+ # Daily mode: web_fetch reads PDF links when pypdf is present.
21
+ daily = ["pypdf>=4.0"]
22
+
19
23
  [dependency-groups]
20
24
  # Dev tools live in a PEP 735 dependency group (not an extra) so `uv sync`
21
25
  # installs them by default — no `--extra`/`--group` flag needed. Always run
@@ -29,6 +33,7 @@ dev = [
29
33
  "ruff>=0.4",
30
34
  "mypy>=1.10",
31
35
  "types-Pygments>=2.17",
36
+ "pypdf>=4.0",
32
37
  ]
33
38
 
34
39
  [project.scripts]
@@ -50,6 +55,9 @@ packages = ["src/limbo"]
50
55
  [tool.ruff]
51
56
  line-length = 100
52
57
  src = ["src", "tests"]
58
+ # Bundled daily-mode skills ported from hermes-agent: third-party scripts
59
+ # kept as upstream wrote them.
60
+ extend-exclude = ["src/limbo/daily_skills"]
53
61
 
54
62
  [tool.ruff.lint]
55
63
  select = ["E", "F", "I", "W"]
@@ -59,3 +67,4 @@ python_version = "3.11"
59
67
  strict = false
60
68
  warn_return_any = true
61
69
  warn_unused_ignores = true
70
+ exclude = ["src/limbo/daily_skills/"]