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.
- {limbo_code-0.3 → limbo_code-0.3.5}/AGENTS.md +34 -5
- {limbo_code-0.3 → limbo_code-0.3.5}/CONTEXT.md +20 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/PKG-INFO +73 -1
- {limbo_code-0.3 → limbo_code-0.3.5}/README.md +70 -0
- limbo_code-0.3.5/docs/daily-mode.md +103 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/skills.md +2 -0
- limbo_code-0.3.5/docs/subagents.md +132 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/pyproject.toml +9 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/agent.py +132 -6
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/app.py +26 -4
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/config.py +114 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/conversation.py +110 -3
- limbo_code-0.3.5/src/limbo/daily.py +31 -0
- limbo_code-0.3.5/src/limbo/daily_skills/README.md +15 -0
- limbo_code-0.3.5/src/limbo/daily_skills/arxiv/LICENSE +21 -0
- limbo_code-0.3.5/src/limbo/daily_skills/arxiv/SKILL.md +275 -0
- limbo_code-0.3.5/src/limbo/daily_skills/arxiv/scripts/search_arxiv.py +114 -0
- limbo_code-0.3.5/src/limbo/daily_skills/blocked-page-recovery/LICENSE +21 -0
- limbo_code-0.3.5/src/limbo/daily_skills/blocked-page-recovery/SKILL.md +130 -0
- limbo_code-0.3.5/src/limbo/daily_skills/blocked-page-recovery/scripts/recover_page.py +241 -0
- limbo_code-0.3.5/src/limbo/daily_skills/document-to-action-items/LICENSE +21 -0
- limbo_code-0.3.5/src/limbo/daily_skills/document-to-action-items/SKILL.md +74 -0
- limbo_code-0.3.5/src/limbo/daily_skills/docx/LICENSE +21 -0
- limbo_code-0.3.5/src/limbo/daily_skills/docx/SKILL.md +188 -0
- limbo_code-0.3.5/src/limbo/daily_skills/docx/references/revisions-and-comments.md +88 -0
- limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_comments.py +289 -0
- limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_common.py +92 -0
- limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_create.py +177 -0
- limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_edit.py +250 -0
- limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_read.py +149 -0
- limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_revisions.py +146 -0
- limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_template.py +70 -0
- limbo_code-0.3.5/src/limbo/daily_skills/docx/scripts/docx_validate.py +156 -0
- limbo_code-0.3.5/src/limbo/daily_skills/grounded-citations/LICENSE +21 -0
- limbo_code-0.3.5/src/limbo/daily_skills/grounded-citations/SKILL.md +248 -0
- limbo_code-0.3.5/src/limbo/daily_skills/grounded-citations/references/citation-formats.md +65 -0
- limbo_code-0.3.5/src/limbo/daily_skills/grounded-citations/references/grounding-rationale.md +64 -0
- limbo_code-0.3.5/src/limbo/daily_skills/grounded-citations/scripts/sources.py +675 -0
- limbo_code-0.3.5/src/limbo/daily_skills/meeting-action-items/LICENSE +21 -0
- limbo_code-0.3.5/src/limbo/daily_skills/meeting-action-items/SKILL.md +80 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/LICENSE +21 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/SKILL.md +117 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/references/forms.md +99 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/references/nano-pdf-editing.md +40 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/references/ocr-extraction.md +165 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/_raster.py +76 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/extract_marker.py +88 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/extract_pymupdf.py +101 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_create.py +130 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_fill_form.py +97 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_form_layout.py +168 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_make_form.py +145 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_merge.py +50 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_meta.py +115 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_page_image.py +99 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_read.py +153 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_secure.py +71 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_split.py +84 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_stamp.py +143 -0
- limbo_code-0.3.5/src/limbo/daily_skills/pdf/scripts/pdf_watermark.py +51 -0
- limbo_code-0.3.5/src/limbo/daily_skills/powerpoint/LICENSE +21 -0
- limbo_code-0.3.5/src/limbo/daily_skills/powerpoint/SKILL.md +212 -0
- limbo_code-0.3.5/src/limbo/daily_skills/powerpoint/scripts/pptx_create.py +214 -0
- limbo_code-0.3.5/src/limbo/daily_skills/powerpoint/scripts/pptx_edit.py +436 -0
- limbo_code-0.3.5/src/limbo/daily_skills/powerpoint/scripts/pptx_from_template.py +88 -0
- limbo_code-0.3.5/src/limbo/daily_skills/powerpoint/scripts/pptx_read.py +131 -0
- limbo_code-0.3.5/src/limbo/daily_skills/powerpoint/scripts/pptx_render.py +93 -0
- limbo_code-0.3.5/src/limbo/daily_skills/weekly-review-planning/LICENSE +21 -0
- limbo_code-0.3.5/src/limbo/daily_skills/weekly-review-planning/SKILL.md +73 -0
- limbo_code-0.3.5/src/limbo/daily_skills/xlsx/LICENSE +21 -0
- limbo_code-0.3.5/src/limbo/daily_skills/xlsx/SKILL.md +188 -0
- limbo_code-0.3.5/src/limbo/daily_skills/xlsx/references/restructuring.md +71 -0
- limbo_code-0.3.5/src/limbo/daily_skills/xlsx/scripts/csv_to_xlsx.py +104 -0
- limbo_code-0.3.5/src/limbo/daily_skills/xlsx/scripts/xlsx_create.py +259 -0
- limbo_code-0.3.5/src/limbo/daily_skills/xlsx/scripts/xlsx_edit.py +263 -0
- limbo_code-0.3.5/src/limbo/daily_skills/xlsx/scripts/xlsx_read.py +160 -0
- limbo_code-0.3.5/src/limbo/daily_skills/xlsx/scripts/xlsx_recalc.py +111 -0
- limbo_code-0.3.5/src/limbo/daily_skills/xlsx/scripts/xlsx_restructure.py +337 -0
- limbo_code-0.3.5/src/limbo/daily_skills/xlsx/scripts/xlsx_to_csv.py +69 -0
- limbo_code-0.3.5/src/limbo/daily_skills/youtube-content/LICENSE +21 -0
- limbo_code-0.3.5/src/limbo/daily_skills/youtube-content/SKILL.md +76 -0
- limbo_code-0.3.5/src/limbo/daily_skills/youtube-content/references/output-formats.md +56 -0
- limbo_code-0.3.5/src/limbo/daily_skills/youtube-content/scripts/fetch_transcript.py +124 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/headless.py +229 -8
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/journal.py +38 -4
- limbo_code-0.3.5/src/limbo/memory.py +254 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/models.py +4 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/prompt.py +51 -4
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/pump.py +6 -1
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/sessions.py +24 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/skills.py +20 -7
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/steer.py +9 -0
- limbo_code-0.3.5/src/limbo/subagents/board.py +657 -0
- limbo_code-0.3.5/src/limbo/subagents/commands.py +104 -0
- limbo_code-0.3.5/src/limbo/subagents/events.py +59 -0
- limbo_code-0.3.5/src/limbo/subagents/hooks.py +100 -0
- limbo_code-0.3.5/src/limbo/subagents/profiles.py +290 -0
- limbo_code-0.3.5/src/limbo/subagents/project_scan.py +265 -0
- limbo_code-0.3.5/src/limbo/subagents/supervisor.py +1413 -0
- limbo_code-0.3.5/src/limbo/subagents/tools.py +437 -0
- limbo_code-0.3.5/src/limbo/subagents/worktree.py +118 -0
- limbo_code-0.3.5/src/limbo/tools/ask_user.py +69 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/base.py +15 -0
- limbo_code-0.3.5/src/limbo/tools/memory.py +96 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/registry.py +98 -5
- limbo_code-0.3.5/src/limbo/tools/session_search.py +186 -0
- limbo_code-0.3.5/src/limbo/tools/skill_manage.py +228 -0
- limbo_code-0.3.5/src/limbo/tools/web_fetch.py +280 -0
- limbo_code-0.3.5/src/limbo/tools/web_search.py +78 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/app.py +42 -4
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/app.tcss +31 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/commands.py +8 -2
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/contrast.py +20 -2
- limbo_code-0.3.5/src/limbo/ui/daily_look.py +157 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/motion.py +10 -4
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/omarchy.py +4 -14
- limbo_code-0.3.5/src/limbo/ui/screens/agents_panel.py +216 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/main.py +307 -10
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/chat.py +11 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/input.py +47 -1
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/key_hints.py +9 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/landing.py +22 -4
- limbo_code-0.3.5/src/limbo/ui/widgets/mode_divider.py +76 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/pills.py +11 -1
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/sidebar.py +132 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/status_bar.py +30 -1
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/tool_card.py +1 -1
- limbo_code-0.3.5/src/limbo/websearch/__init__.py +32 -0
- limbo_code-0.3.5/src/limbo/websearch/base.py +43 -0
- limbo_code-0.3.5/src/limbo/websearch/deepseek.py +124 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/conftest.py +24 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_cli.py +20 -0
- limbo_code-0.3.5/tests/test_daily_mode.py +229 -0
- limbo_code-0.3.5/tests/test_daily_p1.py +273 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_prompt.py +1 -1
- limbo_code-0.3.5/tests/test_subagents.py +566 -0
- limbo_code-0.3.5/tests/test_task_board.py +177 -0
- limbo_code-0.3.5/tests/tools/test_web_search.py +170 -0
- limbo_code-0.3.5/tests/ui/test_daily_look.py +209 -0
- limbo_code-0.3.5/tests/ui/test_daily_mode_ui.py +69 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_snapshots.py +1 -1
- {limbo_code-0.3 → limbo_code-0.3.5}/uv.lock +18 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/grill-with-docs/SKILL.md +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/grill-with-docs/agents/openai.yaml +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/improve-codebase-architecture/HTML-REPORT.md +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/improve-codebase-architecture/SKILL.md +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/improve-codebase-architecture/agents/openai.yaml +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/tdd/SKILL.md +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/tdd/agents/openai.yaml +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/tdd/mocking.md +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/.agents/skills/tdd/tests.md +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/.github/workflows/publish.yml +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/.github/workflows/test.yml +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/.gitignore +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/Makefile +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/design/bang-verification.md +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/design/confirm_view.html +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/design/limbo-ui-minimal.md +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/design/limbo-ui-redesign.md +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/design/prototype-minimal-confirm.png +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/design/prototype-minimal.html +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/design/prototype-minimal.png +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/design/prototype.html +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/design/prototype.png +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/design/rfc-bang-command.md +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/design/rfc-headless-cli.md +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/limbo-current-ui.png +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/limbo-hero.png +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/limbo-hero.svg +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/limbo-models.png +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/limbo-models.svg +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/limbo-new-ui.png +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-dark/1_idle.svg +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-dark/2_thinking_tool_running.svg +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-dark/3_tool_success.svg +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-dark/4_tool_error.svg +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-dark/5_llm_error.svg +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-dark/6_edit_diff.svg +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-light/1_idle.svg +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-light/2_thinking_tool_running.svg +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-light/3_tool_success.svg +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-light/4_tool_error.svg +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-light/5_llm_error.svg +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/assets/walkthrough/limbo-light/6_edit_diff.svg +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/session-management.md +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/docs/ui-redesign-proposal.md +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/scripts/check_contrast.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/scripts/gen_banner.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/scripts/readme_hero.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/scripts/scroll_bench.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/scripts/ui_walkthrough.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/skills-lock.json +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/__init__.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/__main__.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/attachments.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/auth.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/btw.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/cli_auth.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/code_mode.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/compaction.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/goal.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/history.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/integrations/__init__.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/integrations/base.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/integrations/herdr.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/integrations/osc7501.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/__init__.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/anthropic_client.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/catalog.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/client.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/factory.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/openai_client.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/responses_client.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/retry.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/scaffold.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/sse.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/usage.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/llm/verify.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/model_switch.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/toggles.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/__init__.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/bash.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/edit.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/find.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/grep.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/hooks.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/ignore.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/ls.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/mutation_queue.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/read.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/run_code.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tools/write.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/trace.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tracing/__init__.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tracing/command.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tracing/index.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tracing/model.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tracing/server.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/tracing/static/index.html +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/__init__.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/banner.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/clipboard.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/gradient.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/key_fixes.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/paste_store.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/path_input.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/recent_models.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/__init__.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/auth_dialog.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/btw.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/command_palette.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/dialog.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/game2048.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/model_picker.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/session_picker.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/screens/verify_picker.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/syntax.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/theme.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/__init__.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/activity.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/src/limbo/ui/widgets/command_menu.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/fixtures/omarchy/README.md +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/fixtures/omarchy/catppuccin-latte.toml +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/fixtures/omarchy/gruvbox.toml +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/fixtures/omarchy/hackerman.toml +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/fixtures/omarchy/lumon.toml +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/fixtures/omarchy/rose-pine.toml +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/fixtures/omarchy/tokyo-night.toml +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_agent.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_anthropic_client.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_auth.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_btw.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_catalog.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_code_mode_agent.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_compaction.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_config.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_conversation.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_goal.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_headless.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_herdr.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_history.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_integration.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_interrupt.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_llm_client.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_model_switch.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_osc7501.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_plan_mode.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_pump.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_responses_client.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_retry.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_sessions.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_skills.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_sse.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_steer.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_trace.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/test_usage.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_base.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_bash.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_edit.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_grep.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_hooks.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_ignore.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_mutation_queue.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_read.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_registry.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_run_code.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tools/test_write.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tracing/test_command.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tracing/test_index.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tracing/test_model.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/tracing/test_server.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/__snapshots__/test_snapshots/test_snapshot_idle.raw +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/__snapshots__/test_snapshots/test_snapshot_wide_layout_with_sidebar.raw +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_app_smoke.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_bang_ui.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_btw_ui.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_command_menu.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_compact_ui.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_goal_ui.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_input_paste.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_interrupt_ui.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_main_screen.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_model_picker.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_omarchy.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_path_input.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_scroll_follow.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_sessions_ui.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_sidebar.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_skills_ui.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_steer_ui.py +0 -0
- {limbo_code-0.3 → limbo_code-0.3.5}/tests/ui/test_tracing_viewer_ui.py +0 -0
- {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),
|
|
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/"]
|