connectonion 0.6.2__py3-none-any.whl → 0.6.4__py3-none-any.whl
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.
- connectonion/__init__.py +46 -9
- connectonion/cli/__init__.py +11 -1
- connectonion/cli/browser_agent/__init__.py +11 -1
- connectonion/cli/browser_agent/browser.py +13 -3
- connectonion/cli/browser_agent/element_finder.py +8 -0
- connectonion/cli/browser_agent/highlight_screenshot.py +9 -1
- connectonion/cli/browser_agent/scroll.py +8 -0
- connectonion/cli/co_ai/__init__.py +6 -0
- connectonion/cli/co_ai/agent.py +87 -0
- connectonion/cli/co_ai/agents/__init__.py +5 -0
- connectonion/cli/co_ai/agents/registry.py +57 -0
- connectonion/cli/co_ai/commands/__init__.py +45 -0
- connectonion/cli/co_ai/commands/compact.py +173 -0
- connectonion/cli/co_ai/commands/cost.py +77 -0
- connectonion/cli/co_ai/commands/export.py +60 -0
- connectonion/cli/co_ai/commands/help.py +80 -0
- connectonion/cli/co_ai/commands/init.py +101 -0
- connectonion/cli/co_ai/commands/sessions.py +55 -0
- connectonion/cli/co_ai/commands/tasks.py +63 -0
- connectonion/cli/co_ai/commands/undo.py +103 -0
- connectonion/cli/co_ai/context.py +127 -0
- connectonion/cli/co_ai/main.py +52 -0
- connectonion/cli/co_ai/plugins/__init__.py +5 -0
- connectonion/cli/co_ai/plugins/system_reminder.py +154 -0
- connectonion/cli/co_ai/prompts/agents/explore.md +79 -0
- connectonion/cli/co_ai/prompts/agents/plan.md +60 -0
- connectonion/cli/co_ai/prompts/assembler.py +303 -0
- connectonion/cli/{docs/co-vibecoding-principles-docs-contexts-all-in-one.md → co_ai/prompts/connectonion/README.md} +26 -0
- connectonion/cli/co_ai/prompts/connectonion/api.md +457 -0
- connectonion/cli/co_ai/prompts/connectonion/cli/README.md +805 -0
- connectonion/cli/co_ai/prompts/connectonion/cli/auth.md +46 -0
- connectonion/cli/co_ai/prompts/connectonion/cli/browser.md +235 -0
- connectonion/cli/co_ai/prompts/connectonion/cli/copy.md +184 -0
- connectonion/cli/co_ai/prompts/connectonion/cli/create.md +335 -0
- connectonion/cli/co_ai/prompts/connectonion/cli/init.md +431 -0
- connectonion/cli/co_ai/prompts/connectonion/co-directory-structure.md +214 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/agent.md +1078 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/events.md +816 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/llm_do.md +256 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/max_iterations.md +362 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/models.md +641 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/plugins.md +100 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/prompts.md +122 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/tools.md +512 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/transcribe.md +156 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/trust.md +291 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/README.md +18 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/auto_debug.md +1026 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/console.md +129 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/eval-format.md +178 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/eval.md +230 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/exceptions.md +307 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/log.md +117 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/xray.md +215 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/001-choosing-input-method.md +202 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/002-choosing-llm-function-name.md +202 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/003-choosing-trust-keyword.md +141 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/004-cli-create-flow.md +117 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/005-designing-agent-network-protocol.md +503 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/006-agent-address-format.md +305 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/007-authentication-backend-design.md +240 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/008-naming-is-hard.md +228 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/009-why-connect-function.md +167 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/010-cli-ux-progressive-disclosure.md +176 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/011-global-config-identity-management.md +357 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/012-tool-execution-separation.md +259 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/013-debug-and-logging-design.md +253 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/014-hook-system-design.md +510 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/015-interactive-auto-debug-design.md +837 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/016-why-no-zero-knowledge-proofs.md +358 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/017-session-logging-and-eval-format.md +120 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/018-event-api-naming.md +274 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/019-agent-lifecycle-design.md +655 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/020-trust-system-and-network-architecture.md +503 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/021-task-storage-jsonl-design.md +496 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/022-raw-asgi-implementation.md +273 -0
- connectonion/cli/co_ai/prompts/connectonion/examples/agent_reasoning.md +62 -0
- connectonion/cli/co_ai/prompts/connectonion/examples/atomic_tools.md +24 -0
- connectonion/cli/co_ai/prompts/connectonion/examples/load_guide.md +18 -0
- connectonion/cli/co_ai/prompts/connectonion/examples.md +0 -0
- connectonion/cli/co_ai/prompts/connectonion/hook-system-options.md +364 -0
- connectonion/cli/co_ai/prompts/connectonion/index.md +162 -0
- connectonion/cli/co_ai/prompts/connectonion/integrations/README.md +12 -0
- connectonion/cli/co_ai/prompts/connectonion/integrations/auth.md +450 -0
- connectonion/cli/co_ai/prompts/connectonion/integrations/google.md +431 -0
- connectonion/cli/co_ai/prompts/connectonion/integrations/microsoft.md +370 -0
- connectonion/cli/co_ai/prompts/connectonion/network/README.md +14 -0
- connectonion/cli/co_ai/prompts/connectonion/network/connect.md +543 -0
- connectonion/cli/co_ai/prompts/connectonion/network/connection.md +538 -0
- connectonion/cli/co_ai/prompts/connectonion/network/deploy.md +123 -0
- connectonion/cli/co_ai/prompts/connectonion/network/host.md +1049 -0
- connectonion/cli/co_ai/prompts/connectonion/network/protocol/agent-relay-protocol.md +495 -0
- connectonion/cli/co_ai/prompts/connectonion/network/protocol/announce-message.md +115 -0
- connectonion/cli/co_ai/prompts/connectonion/principles.md +124 -0
- connectonion/cli/co_ai/prompts/connectonion/quickstart.md +261 -0
- connectonion/cli/co_ai/prompts/connectonion/roadmap.md +81 -0
- connectonion/cli/co_ai/prompts/connectonion/templates/README.md +77 -0
- connectonion/cli/co_ai/prompts/connectonion/templates/meta-agent.md +152 -0
- connectonion/cli/co_ai/prompts/connectonion/templates/minimal.md +105 -0
- connectonion/cli/co_ai/prompts/connectonion/templates/playwright.md +130 -0
- connectonion/cli/co_ai/prompts/connectonion/templates/web-research.md +144 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/README.md +95 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/chat.md +181 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/divider.md +63 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/dropdown.md +83 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/footer.md +44 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/fuzzy.md +68 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/input.md +84 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/keys.md +77 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/pick.md +71 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/providers.md +89 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/status_bar.md +67 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_plugins/README.md +156 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_plugins/calendar_plugin.md +68 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_plugins/eval.md +89 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_plugins/gmail_plugin.md +68 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_plugins/image_result_formatter.md +74 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_plugins/re_act.md +86 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_plugins/shell_approval.md +69 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/README.md +81 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/diff_writer.md +138 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/get_emails.md +499 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/gmail.md +135 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/google_calendar.md +106 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/memory.md +486 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/microsoft_calendar.md +106 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/outlook.md +120 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/send_email.md +403 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/shell.md +95 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/slash_command.md +96 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/terminal.md +97 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/todo_list.md +252 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/web_fetch.md +130 -0
- connectonion/cli/co_ai/prompts/connectonion/vibe-coding-guide.md +97 -0
- connectonion/cli/co_ai/prompts/connectonion/windows-support.md +258 -0
- connectonion/cli/co_ai/prompts/main.md +247 -0
- connectonion/cli/co_ai/prompts/summarization.md +55 -0
- connectonion/cli/co_ai/prompts/system-reminders/agent.md +23 -0
- connectonion/cli/co_ai/prompts/system-reminders/plan_mode.md +13 -0
- connectonion/cli/co_ai/prompts/system-reminders/security.md +14 -0
- connectonion/cli/co_ai/prompts/system-reminders/simplicity.md +14 -0
- connectonion/cli/co_ai/prompts/tools/ask_user.md +61 -0
- connectonion/cli/co_ai/prompts/tools/background.md +57 -0
- connectonion/cli/co_ai/prompts/tools/edit.md +90 -0
- connectonion/cli/co_ai/prompts/tools/glob.md +52 -0
- connectonion/cli/co_ai/prompts/tools/grep.md +55 -0
- connectonion/cli/co_ai/prompts/tools/plan_mode.md +80 -0
- connectonion/cli/co_ai/prompts/tools/read.md +40 -0
- connectonion/cli/co_ai/prompts/tools/shell.md +67 -0
- connectonion/cli/co_ai/prompts/tools/task.md +51 -0
- connectonion/cli/co_ai/prompts/tools/todo.md +139 -0
- connectonion/cli/co_ai/prompts/tools/write.md +47 -0
- connectonion/cli/co_ai/prompts/workflow.md +89 -0
- connectonion/cli/co_ai/sessions.py +110 -0
- connectonion/cli/co_ai/skills/__init__.py +37 -0
- connectonion/cli/co_ai/skills/builtin/commit/SKILL.md +63 -0
- connectonion/cli/co_ai/skills/builtin/review-pr/SKILL.md +76 -0
- connectonion/cli/co_ai/skills/loader.py +166 -0
- connectonion/cli/co_ai/skills/tool.py +46 -0
- connectonion/cli/co_ai/tools/__init__.py +92 -0
- connectonion/cli/co_ai/tools/ask_user.py +35 -0
- connectonion/cli/co_ai/tools/background.py +201 -0
- connectonion/cli/co_ai/tools/diff_writer.py +291 -0
- connectonion/cli/co_ai/tools/edit.py +89 -0
- connectonion/cli/co_ai/tools/glob.py +84 -0
- connectonion/cli/co_ai/tools/grep.py +158 -0
- connectonion/cli/co_ai/tools/load_guide.py +23 -0
- connectonion/cli/co_ai/tools/multi_edit.py +116 -0
- connectonion/cli/co_ai/tools/plan_mode.py +169 -0
- connectonion/cli/co_ai/tools/read.py +61 -0
- connectonion/cli/co_ai/tools/task.py +59 -0
- connectonion/cli/co_ai/tools/todo_list.py +159 -0
- connectonion/cli/co_ai/tools/write.py +126 -0
- connectonion/cli/commands/__init__.py +11 -1
- connectonion/cli/commands/ai_commands.py +34 -0
- connectonion/cli/commands/copy_commands.py +55 -6
- connectonion/cli/commands/create.py +20 -17
- connectonion/cli/commands/init.py +19 -22
- connectonion/cli/commands/project_cmd_lib.py +15 -0
- connectonion/cli/main.py +11 -0
- connectonion/console.py +15 -1
- connectonion/core/__init__.py +10 -1
- connectonion/core/agent.py +37 -16
- connectonion/core/exceptions.py +74 -0
- connectonion/core/llm.py +54 -6
- connectonion/core/tool_executor.py +32 -31
- connectonion/core/tool_factory.py +47 -10
- connectonion/debug/__init__.py +10 -1
- connectonion/debug/debug_explainer/__init__.py +10 -1
- connectonion/debug/execution_analyzer/__init__.py +10 -1
- connectonion/debug/execution_analyzer/execution_analysis.py +5 -2
- connectonion/debug/runtime_inspector/__init__.py +10 -1
- connectonion/docs/.package-ignore +6 -0
- connectonion/docs/README.md +2036 -0
- connectonion/docs/api.md +457 -0
- connectonion/docs/archive/001-ai-agent-is-just-prompt-plus-function.md +249 -0
- connectonion/docs/archive/README.md +53 -0
- connectonion/docs/archive/archive/consolidation-plan.md +72 -0
- connectonion/docs/archive/archive/core-principles-extracted.md +239 -0
- connectonion/docs/archive/archive/master-principles.md +222 -0
- connectonion/docs/archive/archive/principles.md +293 -0
- connectonion/docs/archive/archive/simplicity-principles.md +221 -0
- connectonion/docs/archive/attack-defense-insights.md +410 -0
- connectonion/docs/archive/business-model.md +305 -0
- connectonion/docs/archive/core-principles-unified.md +190 -0
- connectonion/docs/archive/discussion-journey.md +178 -0
- connectonion/docs/archive/economic-analysis.md +323 -0
- connectonion/docs/archive/features/01-share-and-find.md +256 -0
- connectonion/docs/archive/features/02-agent-authentication.md +93 -0
- connectonion/docs/archive/features/03-test-before-trust.md +71 -0
- connectonion/docs/archive/features/06-reliability-and-offline.md +197 -0
- connectonion/docs/archive/features/README.md +46 -0
- connectonion/docs/archive/features-roadmap.md +247 -0
- connectonion/docs/archive/mcp-comparison-insights.md +215 -0
- connectonion/docs/archive/migration-strategy.md +571 -0
- connectonion/docs/archive/mini-whitepaper.md +293 -0
- connectonion/docs/archive/network-protocol.md +394 -0
- connectonion/docs/archive/semantic-revolution.md +367 -0
- connectonion/docs/archive/technical-architecture.md +453 -0
- connectonion/docs/archive/the-semantic-insight.md +207 -0
- connectonion/docs/archive/threat-model.md +164 -0
- connectonion/docs/cli/README.md +805 -0
- connectonion/docs/cli/auth.md +46 -0
- connectonion/docs/cli/browser.md +235 -0
- connectonion/docs/cli/copy.md +232 -0
- connectonion/docs/cli/create.md +335 -0
- connectonion/docs/cli/init.md +431 -0
- connectonion/docs/co-directory-structure.md +214 -0
- connectonion/docs/concepts/agent.md +1078 -0
- connectonion/docs/concepts/events.md +699 -0
- connectonion/docs/concepts/llm_do.md +256 -0
- connectonion/docs/concepts/max_iterations.md +362 -0
- connectonion/docs/concepts/models.md +641 -0
- connectonion/docs/concepts/plugins.md +101 -0
- connectonion/docs/concepts/prompts.md +122 -0
- connectonion/docs/concepts/session.md +428 -0
- connectonion/docs/concepts/tools.md +512 -0
- connectonion/docs/concepts/transcribe.md +156 -0
- connectonion/docs/concepts/trust.md +291 -0
- connectonion/docs/connectonion.md +1256 -0
- connectonion/docs/debug/README.md +18 -0
- connectonion/docs/debug/auto_debug.md +1026 -0
- connectonion/docs/debug/console.md +129 -0
- connectonion/docs/debug/eval-format.md +178 -0
- connectonion/docs/debug/eval.md +230 -0
- connectonion/docs/debug/exceptions.md +307 -0
- connectonion/docs/debug/log.md +117 -0
- connectonion/docs/debug/xray.md +215 -0
- connectonion/docs/design-decisions/001-choosing-input-method.md +202 -0
- connectonion/docs/design-decisions/002-choosing-llm-function-name.md +202 -0
- connectonion/docs/design-decisions/003-choosing-trust-keyword.md +141 -0
- connectonion/docs/design-decisions/004-cli-create-flow.md +117 -0
- connectonion/docs/design-decisions/005-designing-agent-network-protocol.md +503 -0
- connectonion/docs/design-decisions/006-agent-address-format.md +305 -0
- connectonion/docs/design-decisions/007-authentication-backend-design.md +240 -0
- connectonion/docs/design-decisions/008-naming-is-hard.md +228 -0
- connectonion/docs/design-decisions/009-why-connect-function.md +167 -0
- connectonion/docs/design-decisions/010-cli-ux-progressive-disclosure.md +176 -0
- connectonion/docs/design-decisions/011-global-config-identity-management.md +357 -0
- connectonion/docs/design-decisions/012-tool-execution-separation.md +259 -0
- connectonion/docs/design-decisions/013-debug-and-logging-design.md +253 -0
- connectonion/docs/design-decisions/014-hook-system-design.md +510 -0
- connectonion/docs/design-decisions/015-interactive-auto-debug-design.md +837 -0
- connectonion/docs/design-decisions/016-why-no-zero-knowledge-proofs.md +358 -0
- connectonion/docs/design-decisions/017-session-logging-and-eval-format.md +120 -0
- connectonion/docs/design-decisions/018-event-api-naming.md +274 -0
- connectonion/docs/design-decisions/019-agent-lifecycle-design.md +655 -0
- connectonion/docs/design-decisions/020-trust-system-and-network-architecture.md +503 -0
- connectonion/docs/design-decisions/021-task-storage-jsonl-design.md +496 -0
- connectonion/docs/design-decisions/022-raw-asgi-implementation.md +273 -0
- connectonion/docs/examples.md +0 -0
- connectonion/docs/hook-system-options.md +364 -0
- connectonion/docs/integrations/README.md +12 -0
- connectonion/docs/integrations/auth.md +450 -0
- connectonion/docs/integrations/google.md +431 -0
- connectonion/docs/integrations/microsoft.md +370 -0
- connectonion/docs/network/README.md +14 -0
- connectonion/docs/network/connect.md +629 -0
- connectonion/docs/network/deploy.md +124 -0
- connectonion/docs/network/host.md +1087 -0
- connectonion/docs/network/io.md +538 -0
- connectonion/docs/network/protocol/agent-relay-protocol.md +495 -0
- connectonion/docs/network/protocol/announce-message.md +115 -0
- connectonion/docs/principles.md +124 -0
- connectonion/docs/quickstart.md +261 -0
- connectonion/docs/roadmap.md +81 -0
- connectonion/docs/templates/README.md +77 -0
- connectonion/docs/templates/meta-agent.md +152 -0
- connectonion/docs/templates/minimal.md +105 -0
- connectonion/docs/templates/playwright.md +130 -0
- connectonion/docs/templates/web-research.md +144 -0
- connectonion/docs/tui/README.md +95 -0
- connectonion/docs/tui/chat.md +181 -0
- connectonion/docs/tui/divider.md +63 -0
- connectonion/docs/tui/dropdown.md +83 -0
- connectonion/docs/tui/footer.md +44 -0
- connectonion/docs/tui/fuzzy.md +68 -0
- connectonion/docs/tui/input.md +84 -0
- connectonion/docs/tui/keys.md +77 -0
- connectonion/docs/tui/pick.md +71 -0
- connectonion/docs/tui/providers.md +89 -0
- connectonion/docs/tui/status_bar.md +67 -0
- connectonion/docs/useful_plugins/README.md +160 -0
- connectonion/docs/useful_plugins/calendar_plugin.md +68 -0
- connectonion/docs/useful_plugins/eval.md +89 -0
- connectonion/docs/useful_plugins/gmail_plugin.md +68 -0
- connectonion/docs/useful_plugins/image_result_formatter.md +74 -0
- connectonion/docs/useful_plugins/re_act.md +86 -0
- connectonion/docs/useful_plugins/shell_approval.md +69 -0
- connectonion/docs/useful_plugins/system_reminder.md +210 -0
- connectonion/docs/useful_plugins/tool_approval.md +139 -0
- connectonion/docs/useful_prompts/README.md +127 -0
- connectonion/docs/useful_prompts/coding_agent.md +214 -0
- connectonion/docs/useful_tools/README.md +81 -0
- connectonion/docs/useful_tools/ask_user.md +103 -0
- connectonion/docs/useful_tools/diff_writer.md +158 -0
- connectonion/docs/useful_tools/get_emails.md +519 -0
- connectonion/docs/useful_tools/gmail.md +155 -0
- connectonion/docs/useful_tools/google_calendar.md +126 -0
- connectonion/docs/useful_tools/memory.md +506 -0
- connectonion/docs/useful_tools/microsoft_calendar.md +126 -0
- connectonion/docs/useful_tools/outlook.md +140 -0
- connectonion/docs/useful_tools/send_email.md +423 -0
- connectonion/docs/useful_tools/shell.md +115 -0
- connectonion/docs/useful_tools/slash_command.md +116 -0
- connectonion/docs/useful_tools/terminal.md +115 -0
- connectonion/docs/useful_tools/todo_list.md +272 -0
- connectonion/docs/useful_tools/web_fetch.md +150 -0
- connectonion/docs/vibe-coding-guide.md +97 -0
- connectonion/docs/windows-support.md +258 -0
- connectonion/logger.py +3 -3
- connectonion/network/__init__.py +19 -6
- connectonion/network/asgi/__init__.py +81 -0
- connectonion/network/asgi/http.py +205 -0
- connectonion/network/asgi/websocket.py +217 -0
- connectonion/network/connect.py +232 -185
- connectonion/network/host/__init__.py +59 -0
- connectonion/network/host/auth.py +191 -0
- connectonion/network/host/routes.py +135 -0
- connectonion/network/host/server.py +289 -0
- connectonion/network/host/session.py +78 -0
- connectonion/network/io/__init__.py +21 -0
- connectonion/network/{connection.py → io/base.py} +17 -42
- connectonion/network/io/websocket.py +55 -0
- connectonion/network/relay.py +37 -16
- connectonion/network/trust/__init__.py +30 -0
- connectonion/network/trust/factory.py +138 -0
- connectonion/network/{trust_agents.py → trust/prompts.py} +3 -3
- connectonion/network/{trust_functions.py → trust/tools.py} +2 -2
- connectonion/prompt_files/__init__.py +11 -1
- connectonion/prompt_files/react_acknowledge.md +26 -0
- connectonion/prompts.py +10 -1
- connectonion/tui/chat.py +10 -1
- connectonion/tui/divider.py +10 -1
- connectonion/tui/dropdown.py +10 -1
- connectonion/tui/footer.py +8 -0
- connectonion/tui/fuzzy.py +11 -1
- connectonion/tui/input.py +118 -70
- connectonion/tui/keys.py +133 -6
- connectonion/tui/providers.py +11 -1
- connectonion/tui/status_bar.py +10 -1
- connectonion/useful_events_handlers/__init__.py +8 -0
- connectonion/useful_events_handlers/reflect.py +19 -4
- connectonion/useful_plugins/__init__.py +3 -1
- connectonion/useful_plugins/eval.py +2 -2
- connectonion/useful_plugins/gmail_plugin.py +3 -3
- connectonion/useful_plugins/image_result_formatter.py +3 -3
- connectonion/useful_plugins/re_act.py +114 -28
- connectonion/useful_plugins/shell_approval.py +2 -2
- connectonion/useful_plugins/system_reminder.py +103 -0
- connectonion/useful_plugins/tool_approval.py +233 -0
- connectonion/useful_plugins/ui_stream.py +18 -133
- connectonion/useful_prompts/README.md +61 -0
- connectonion/useful_prompts/__init__.py +45 -0
- connectonion/useful_prompts/coding_agent/README.md +106 -0
- connectonion/useful_prompts/coding_agent/assembler.py +123 -0
- connectonion/useful_prompts/coding_agent/prompts/main.md +227 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/ask_user.md +61 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/background.md +57 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/edit.md +90 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/glob.md +52 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/grep.md +55 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/plan_mode.md +80 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/read.md +40 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/shell.md +67 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/task.md +51 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/todo.md +139 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/write.md +48 -0
- connectonion/useful_prompts/system-reminders/security-warning.md +14 -0
- connectonion/useful_prompts/system-reminders/test-reminder.md +11 -0
- connectonion/useful_tools/__init__.py +31 -4
- connectonion/useful_tools/ask_user.py +35 -0
- connectonion/useful_tools/bash.py +69 -0
- connectonion/useful_tools/diff_writer.py +186 -94
- connectonion/useful_tools/edit.py +102 -0
- connectonion/useful_tools/glob_files.py +97 -0
- connectonion/useful_tools/grep_files.py +171 -0
- connectonion/useful_tools/multi_edit.py +116 -0
- connectonion/useful_tools/read_file.py +73 -0
- connectonion/useful_tools/shell.py +50 -45
- connectonion/useful_tools/write_file.py +129 -0
- {connectonion-0.6.2.dist-info → connectonion-0.6.4.dist-info}/METADATA +10 -3
- connectonion-0.6.4.dist-info/RECORD +472 -0
- connectonion/network/asgi.py +0 -407
- connectonion/network/host.py +0 -616
- connectonion/network/trust.py +0 -166
- connectonion-0.6.2.dist-info/RECORD +0 -129
- /connectonion/cli/{docs → co_ai/prompts/connectonion}/connectonion.md +0 -0
- {connectonion-0.6.2.dist-info → connectonion-0.6.4.dist-info}/WHEEL +0 -0
- {connectonion-0.6.2.dist-info → connectonion-0.6.4.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""Grep tool for content searching."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Optional, Literal
|
|
6
|
+
|
|
7
|
+
from connectonion.cli.co_ai.tools.glob import IGNORE_DIRS
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def grep(
|
|
11
|
+
pattern: str,
|
|
12
|
+
path: Optional[str] = None,
|
|
13
|
+
file_pattern: Optional[str] = None,
|
|
14
|
+
output_mode: Literal["files", "content", "count"] = "files",
|
|
15
|
+
context_lines: int = 0,
|
|
16
|
+
ignore_case: bool = False,
|
|
17
|
+
max_results: int = 50,
|
|
18
|
+
) -> str:
|
|
19
|
+
"""
|
|
20
|
+
Search for content in files using regex.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
pattern: Regular expression pattern to search for
|
|
24
|
+
path: File or directory to search in (default: current directory)
|
|
25
|
+
file_pattern: Glob pattern to filter files (e.g., "*.py", "*.ts")
|
|
26
|
+
output_mode:
|
|
27
|
+
- "files": Return only matching file paths (default)
|
|
28
|
+
- "content": Return matching lines with context
|
|
29
|
+
- "count": Return match counts per file
|
|
30
|
+
context_lines: Number of lines to show before/after match (for content mode)
|
|
31
|
+
ignore_case: Case insensitive search
|
|
32
|
+
max_results: Maximum number of results to return
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
Search results based on output_mode
|
|
36
|
+
|
|
37
|
+
Examples:
|
|
38
|
+
grep("def main") # Find "def main" in all files
|
|
39
|
+
grep("TODO|FIXME", file_pattern="*.py") # Find TODOs in Python files
|
|
40
|
+
grep("class.*Agent", output_mode="content") # Show matching lines
|
|
41
|
+
grep("import", output_mode="count") # Count imports per file
|
|
42
|
+
"""
|
|
43
|
+
base = Path(path) if path else Path.cwd()
|
|
44
|
+
|
|
45
|
+
if not base.exists():
|
|
46
|
+
return f"Error: Path '{base}' does not exist"
|
|
47
|
+
|
|
48
|
+
# Compile regex
|
|
49
|
+
flags = re.IGNORECASE if ignore_case else 0
|
|
50
|
+
try:
|
|
51
|
+
regex = re.compile(pattern, flags)
|
|
52
|
+
except re.error as e:
|
|
53
|
+
return f"Error: Invalid regex pattern: {e}"
|
|
54
|
+
|
|
55
|
+
# Collect files to search
|
|
56
|
+
if base.is_file():
|
|
57
|
+
files = [base]
|
|
58
|
+
else:
|
|
59
|
+
if file_pattern:
|
|
60
|
+
files = list(base.glob(f"**/{file_pattern}"))
|
|
61
|
+
else:
|
|
62
|
+
files = list(base.glob("**/*"))
|
|
63
|
+
|
|
64
|
+
files = [f for f in files if f.is_file() and not _should_ignore(f) and _is_text_file(f)]
|
|
65
|
+
|
|
66
|
+
results = []
|
|
67
|
+
total_matches = 0
|
|
68
|
+
|
|
69
|
+
for file in files:
|
|
70
|
+
if total_matches >= max_results:
|
|
71
|
+
break
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
content = file.read_text(encoding="utf-8", errors="ignore")
|
|
75
|
+
lines = content.splitlines()
|
|
76
|
+
except Exception:
|
|
77
|
+
continue
|
|
78
|
+
|
|
79
|
+
file_matches = []
|
|
80
|
+
for i, line in enumerate(lines):
|
|
81
|
+
if regex.search(line):
|
|
82
|
+
file_matches.append((i + 1, line)) # 1-indexed line number
|
|
83
|
+
|
|
84
|
+
if not file_matches:
|
|
85
|
+
continue
|
|
86
|
+
|
|
87
|
+
rel_path = _relative_path(file, base)
|
|
88
|
+
|
|
89
|
+
if output_mode == "files":
|
|
90
|
+
results.append(str(rel_path))
|
|
91
|
+
total_matches += 1
|
|
92
|
+
|
|
93
|
+
elif output_mode == "count":
|
|
94
|
+
results.append(f"{rel_path}: {len(file_matches)} matches")
|
|
95
|
+
total_matches += 1
|
|
96
|
+
|
|
97
|
+
elif output_mode == "content":
|
|
98
|
+
results.append(f"\n{rel_path}:")
|
|
99
|
+
for line_num, line_text in file_matches[:10]: # Limit per file
|
|
100
|
+
# Add context if requested
|
|
101
|
+
if context_lines > 0:
|
|
102
|
+
start = max(0, line_num - 1 - context_lines)
|
|
103
|
+
end = min(len(lines), line_num + context_lines)
|
|
104
|
+
for ctx_i in range(start, end):
|
|
105
|
+
prefix = ">" if ctx_i == line_num - 1 else " "
|
|
106
|
+
results.append(f" {prefix} {ctx_i + 1}: {lines[ctx_i]}")
|
|
107
|
+
results.append("")
|
|
108
|
+
else:
|
|
109
|
+
results.append(f" {line_num}: {line_text}")
|
|
110
|
+
total_matches += 1
|
|
111
|
+
|
|
112
|
+
if total_matches >= max_results:
|
|
113
|
+
break
|
|
114
|
+
|
|
115
|
+
if not results:
|
|
116
|
+
return f"No matches found for '{pattern}'"
|
|
117
|
+
|
|
118
|
+
output = "\n".join(results)
|
|
119
|
+
|
|
120
|
+
if total_matches >= max_results:
|
|
121
|
+
output += f"\n\n... results truncated at {max_results}"
|
|
122
|
+
|
|
123
|
+
return output
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _should_ignore(path: Path) -> bool:
|
|
127
|
+
"""Check if path should be ignored."""
|
|
128
|
+
parts = path.parts
|
|
129
|
+
for part in parts:
|
|
130
|
+
if part in IGNORE_DIRS:
|
|
131
|
+
return True
|
|
132
|
+
for ignore in IGNORE_DIRS:
|
|
133
|
+
if "*" in ignore and Path(part).match(ignore):
|
|
134
|
+
return True
|
|
135
|
+
return False
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _is_text_file(path: Path) -> bool:
|
|
139
|
+
"""Check if file is likely a text file."""
|
|
140
|
+
# Skip binary file extensions
|
|
141
|
+
binary_extensions = {
|
|
142
|
+
".pyc", ".pyo", ".so", ".dylib", ".dll", ".exe",
|
|
143
|
+
".png", ".jpg", ".jpeg", ".gif", ".ico", ".svg",
|
|
144
|
+
".pdf", ".doc", ".docx", ".xls", ".xlsx",
|
|
145
|
+
".zip", ".tar", ".gz", ".rar", ".7z",
|
|
146
|
+
".mp3", ".mp4", ".wav", ".avi", ".mov",
|
|
147
|
+
".ttf", ".woff", ".woff2", ".eot",
|
|
148
|
+
".lock", ".bin", ".dat",
|
|
149
|
+
}
|
|
150
|
+
return path.suffix.lower() not in binary_extensions
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _relative_path(path: Path, base: Path) -> Path:
|
|
154
|
+
"""Get relative path, handling edge cases."""
|
|
155
|
+
try:
|
|
156
|
+
return path.relative_to(base)
|
|
157
|
+
except ValueError:
|
|
158
|
+
return path
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Load ConnectOnion framework guides."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
GUIDES_DIR = Path(__file__).parent.parent / "prompts" / "connectonion"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def load_guide(path: str) -> str:
|
|
9
|
+
"""
|
|
10
|
+
Load a ConnectOnion framework guide.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
path: Full path like "concepts/agent", "concepts/tools", "useful_tools/shell"
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
Guide content
|
|
17
|
+
"""
|
|
18
|
+
guide_file = GUIDES_DIR / f"{path}.md"
|
|
19
|
+
|
|
20
|
+
if not guide_file.exists():
|
|
21
|
+
return f"Guide '{path}' not found. Use full path: concepts/agent, concepts/tools, useful_tools/shell. See index.md."
|
|
22
|
+
|
|
23
|
+
return guide_file.read_text(encoding="utf-8")
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Purpose: Atomic multiple string replacements in a single file (like Claude Code's MultiEdit)
|
|
3
|
+
LLM-Note:
|
|
4
|
+
Dependencies: imports from [pathlib, typing] | imported by [co_ai.tools.__init__]
|
|
5
|
+
Data flow: Agent calls multi_edit(file_path, edits) -> validates all edits -> applies sequentially -> returns status
|
|
6
|
+
State/Effects: reads and writes file on filesystem | atomic (all succeed or none applied)
|
|
7
|
+
Integration: exposes multi_edit(file_path, edits) function | used as agent tool
|
|
8
|
+
Errors: returns error if file not found | returns error if any old_string not found | rolls back on failure
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
multi_edit("app.py", [
|
|
12
|
+
{"old_string": "def foo():", "new_string": "def bar():"},
|
|
13
|
+
{"old_string": "return None", "new_string": "return True"},
|
|
14
|
+
])
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import List, TypedDict, Optional
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class EditOperation(TypedDict, total=False):
|
|
22
|
+
"""Single edit operation."""
|
|
23
|
+
old_string: str # Required: exact string to replace
|
|
24
|
+
new_string: str # Required: replacement string
|
|
25
|
+
replace_all: bool # Optional: replace all occurrences (default: False)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def multi_edit(
|
|
29
|
+
file_path: str,
|
|
30
|
+
edits: List[EditOperation],
|
|
31
|
+
) -> str:
|
|
32
|
+
"""
|
|
33
|
+
Apply multiple string replacements to a file atomically.
|
|
34
|
+
|
|
35
|
+
All edits succeed or none are applied. Edits are applied sequentially,
|
|
36
|
+
so earlier edits affect the text that later edits search for.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
file_path: Path to the file to edit
|
|
40
|
+
edits: List of edit operations, each with:
|
|
41
|
+
- old_string: Exact string to replace
|
|
42
|
+
- new_string: Replacement string
|
|
43
|
+
- replace_all: If True, replace all occurrences (default: False)
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
Success message or error description
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
multi_edit("app.py", [
|
|
50
|
+
{"old_string": "def foo():", "new_string": "def bar():"},
|
|
51
|
+
{"old_string": "foo()", "new_string": "bar()", "replace_all": True},
|
|
52
|
+
])
|
|
53
|
+
"""
|
|
54
|
+
path = Path(file_path)
|
|
55
|
+
|
|
56
|
+
if not path.exists():
|
|
57
|
+
return f"Error: File '{file_path}' does not exist"
|
|
58
|
+
|
|
59
|
+
if not path.is_file():
|
|
60
|
+
return f"Error: '{file_path}' is not a file"
|
|
61
|
+
|
|
62
|
+
if not edits:
|
|
63
|
+
return "Error: No edits provided"
|
|
64
|
+
|
|
65
|
+
# Read original content
|
|
66
|
+
original_content = path.read_text(encoding="utf-8")
|
|
67
|
+
content = original_content
|
|
68
|
+
|
|
69
|
+
# Validate and apply edits
|
|
70
|
+
applied = []
|
|
71
|
+
for i, edit in enumerate(edits):
|
|
72
|
+
old_string = edit.get("old_string", "")
|
|
73
|
+
new_string = edit.get("new_string", "")
|
|
74
|
+
replace_all = edit.get("replace_all", False)
|
|
75
|
+
|
|
76
|
+
if not old_string:
|
|
77
|
+
return f"Error: Edit {i+1} missing 'old_string'"
|
|
78
|
+
|
|
79
|
+
# Check if old_string exists in current content
|
|
80
|
+
count = content.count(old_string)
|
|
81
|
+
|
|
82
|
+
if count == 0:
|
|
83
|
+
# Show what edits were successful before failure
|
|
84
|
+
if applied:
|
|
85
|
+
applied_msg = "\n".join([f" {j+1}. Replaced '{e['old']}'" for j, e in enumerate(applied)])
|
|
86
|
+
return (
|
|
87
|
+
f"Error: Edit {i+1} failed - string not found after previous edits.\n"
|
|
88
|
+
f"Looking for: {repr(old_string[:100])}\n\n"
|
|
89
|
+
f"Successfully applied before failure:\n{applied_msg}\n\n"
|
|
90
|
+
f"No changes were saved (atomic operation)."
|
|
91
|
+
)
|
|
92
|
+
return f"Error: Edit {i+1} - string not found in '{file_path}': {repr(old_string[:100])}"
|
|
93
|
+
|
|
94
|
+
if count > 1 and not replace_all:
|
|
95
|
+
return (
|
|
96
|
+
f"Error: Edit {i+1} - string appears {count} times. "
|
|
97
|
+
f"Use replace_all=True or provide more context.\n"
|
|
98
|
+
f"String: {repr(old_string[:100])}"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Apply this edit
|
|
102
|
+
if replace_all:
|
|
103
|
+
content = content.replace(old_string, new_string)
|
|
104
|
+
applied.append({"old": old_string[:50], "count": count})
|
|
105
|
+
else:
|
|
106
|
+
content = content.replace(old_string, new_string, 1)
|
|
107
|
+
applied.append({"old": old_string[:50], "count": 1})
|
|
108
|
+
|
|
109
|
+
# All edits validated and applied in memory - now write to file
|
|
110
|
+
path.write_text(content, encoding="utf-8")
|
|
111
|
+
|
|
112
|
+
# Build success message
|
|
113
|
+
total_replacements = sum(e["count"] for e in applied)
|
|
114
|
+
if len(edits) == 1:
|
|
115
|
+
return f"Successfully edited '{file_path}'"
|
|
116
|
+
return f"Successfully applied {len(edits)} edits ({total_replacements} replacements) to '{file_path}'"
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"""Plan Mode tools for planning before implementation."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
from rich.panel import Panel
|
|
7
|
+
from rich.markdown import Markdown
|
|
8
|
+
|
|
9
|
+
console = Console()
|
|
10
|
+
|
|
11
|
+
# Plan mode state (module-level for simplicity)
|
|
12
|
+
_plan_mode_active = False
|
|
13
|
+
_plan_file_path: Optional[Path] = None
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_plan_file_path() -> Path:
|
|
17
|
+
"""Get the default plan file path."""
|
|
18
|
+
co_dir = Path.cwd() / ".co"
|
|
19
|
+
co_dir.mkdir(exist_ok=True)
|
|
20
|
+
return co_dir / "PLAN.md"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def is_plan_mode_active() -> bool:
|
|
24
|
+
"""Check if plan mode is currently active."""
|
|
25
|
+
return _plan_mode_active
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def enter_plan_mode() -> str:
|
|
29
|
+
"""
|
|
30
|
+
Enter plan mode for designing implementation before coding.
|
|
31
|
+
|
|
32
|
+
Use this when you need to:
|
|
33
|
+
- Plan a complex feature implementation
|
|
34
|
+
- Design architecture before writing code
|
|
35
|
+
- Get user approval on approach before making changes
|
|
36
|
+
|
|
37
|
+
In plan mode:
|
|
38
|
+
- Explore the codebase to understand structure
|
|
39
|
+
- Design the implementation approach
|
|
40
|
+
- Write your plan to .co/PLAN.md
|
|
41
|
+
- Exit plan mode when ready for user approval
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Confirmation message with instructions
|
|
45
|
+
|
|
46
|
+
Example workflow:
|
|
47
|
+
1. enter_plan_mode() - Start planning
|
|
48
|
+
2. Use glob/grep/read_file to explore
|
|
49
|
+
3. Write plan to .co/PLAN.md
|
|
50
|
+
4. exit_plan_mode() - Get user approval
|
|
51
|
+
5. Implement after approval
|
|
52
|
+
"""
|
|
53
|
+
global _plan_mode_active, _plan_file_path
|
|
54
|
+
|
|
55
|
+
if _plan_mode_active:
|
|
56
|
+
return "Already in plan mode. Use exit_plan_mode() when ready for user approval."
|
|
57
|
+
|
|
58
|
+
_plan_mode_active = True
|
|
59
|
+
_plan_file_path = get_plan_file_path()
|
|
60
|
+
|
|
61
|
+
# Create initial plan file
|
|
62
|
+
initial_content = """# Implementation Plan
|
|
63
|
+
|
|
64
|
+
## Summary
|
|
65
|
+
[One-sentence description of what will be implemented]
|
|
66
|
+
|
|
67
|
+
## Current Understanding
|
|
68
|
+
[What you learned from exploring the codebase]
|
|
69
|
+
|
|
70
|
+
## Files to Modify
|
|
71
|
+
- `path/to/file.py` - What changes needed
|
|
72
|
+
|
|
73
|
+
## Files to Create
|
|
74
|
+
- `path/to/new_file.py` - Purpose
|
|
75
|
+
|
|
76
|
+
## Implementation Steps
|
|
77
|
+
1. Step 1 - Details
|
|
78
|
+
2. Step 2 - Details
|
|
79
|
+
3. Step 3 - Details
|
|
80
|
+
|
|
81
|
+
## Considerations
|
|
82
|
+
- Any risks or trade-offs
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
*Plan created by OO. Waiting for user approval.*
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
_plan_file_path.write_text(initial_content, encoding="utf-8")
|
|
89
|
+
|
|
90
|
+
console.print(Panel(
|
|
91
|
+
"[bold green]Entered Plan Mode[/]\n\n"
|
|
92
|
+
"You are now in planning mode. In this mode:\n"
|
|
93
|
+
"1. [cyan]Explore[/] - Use glob/grep/read_file to understand the codebase\n"
|
|
94
|
+
"2. [cyan]Design[/] - Write your implementation plan\n"
|
|
95
|
+
"3. [cyan]Document[/] - Update .co/PLAN.md with your plan\n"
|
|
96
|
+
"4. [cyan]Exit[/] - Call exit_plan_mode() for user approval\n\n"
|
|
97
|
+
f"Plan file: [dim]{_plan_file_path}[/]",
|
|
98
|
+
title="Plan Mode",
|
|
99
|
+
border_style="green"
|
|
100
|
+
))
|
|
101
|
+
|
|
102
|
+
return f"Entered plan mode. Write your plan to {_plan_file_path}, then call exit_plan_mode() when ready for user approval."
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def exit_plan_mode() -> str:
|
|
106
|
+
"""
|
|
107
|
+
Exit plan mode and request user approval for the plan.
|
|
108
|
+
|
|
109
|
+
Call this after you have:
|
|
110
|
+
1. Explored the codebase
|
|
111
|
+
2. Written your implementation plan to .co/PLAN.md
|
|
112
|
+
|
|
113
|
+
The user will review the plan and either:
|
|
114
|
+
- Approve: You can proceed with implementation
|
|
115
|
+
- Request changes: Update the plan and try again
|
|
116
|
+
- Reject: Abandon the plan
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
The plan content for user review
|
|
120
|
+
"""
|
|
121
|
+
global _plan_mode_active, _plan_file_path
|
|
122
|
+
|
|
123
|
+
if not _plan_mode_active:
|
|
124
|
+
return "Not in plan mode. Use enter_plan_mode() first."
|
|
125
|
+
|
|
126
|
+
plan_file = _plan_file_path or get_plan_file_path()
|
|
127
|
+
|
|
128
|
+
if not plan_file.exists():
|
|
129
|
+
return f"Plan file not found at {plan_file}. Write your plan first."
|
|
130
|
+
|
|
131
|
+
plan_content = plan_file.read_text(encoding="utf-8")
|
|
132
|
+
|
|
133
|
+
# Reset state
|
|
134
|
+
_plan_mode_active = False
|
|
135
|
+
_plan_file_path = None
|
|
136
|
+
|
|
137
|
+
# Display plan for user approval
|
|
138
|
+
console.print(Panel(
|
|
139
|
+
Markdown(plan_content),
|
|
140
|
+
title="📋 Implementation Plan - Review Required",
|
|
141
|
+
border_style="yellow"
|
|
142
|
+
))
|
|
143
|
+
|
|
144
|
+
console.print()
|
|
145
|
+
console.print("[bold yellow]Please review the plan above.[/]")
|
|
146
|
+
console.print("Reply with:")
|
|
147
|
+
console.print(" [green]'approve'[/] or [green]'yes'[/] - Proceed with implementation")
|
|
148
|
+
console.print(" [yellow]'modify: <feedback>'[/] - Request changes to the plan")
|
|
149
|
+
console.print(" [red]'reject'[/] or [red]'no'[/] - Abandon this plan")
|
|
150
|
+
console.print()
|
|
151
|
+
|
|
152
|
+
return f"Exited plan mode. Plan saved to {plan_file}. Waiting for user approval.\n\n---\n\n{plan_content}"
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def write_plan(content: str) -> str:
|
|
156
|
+
"""
|
|
157
|
+
Write or update the implementation plan.
|
|
158
|
+
|
|
159
|
+
Use this to document your implementation plan while in plan mode.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
content: The plan content in markdown format
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
Confirmation message
|
|
166
|
+
"""
|
|
167
|
+
plan_file = get_plan_file_path()
|
|
168
|
+
plan_file.write_text(content, encoding="utf-8")
|
|
169
|
+
return f"Plan updated: {plan_file}"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Read file tool."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def read_file(
|
|
8
|
+
path: str,
|
|
9
|
+
offset: Optional[int] = None,
|
|
10
|
+
limit: Optional[int] = None,
|
|
11
|
+
) -> str:
|
|
12
|
+
"""
|
|
13
|
+
Read and return the contents of a file with line numbers.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
path: Path to the file to read
|
|
17
|
+
offset: Line number to start from (1-indexed, default: 1)
|
|
18
|
+
limit: Number of lines to read (default: 2000)
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
File contents with line numbers
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
read_file("app.py") # Read entire file
|
|
25
|
+
read_file("large.log", offset=100) # Start from line 100
|
|
26
|
+
read_file("data.csv", limit=50) # First 50 lines
|
|
27
|
+
"""
|
|
28
|
+
file_path = Path(path)
|
|
29
|
+
|
|
30
|
+
if not file_path.exists():
|
|
31
|
+
return f"Error: File '{path}' does not exist"
|
|
32
|
+
|
|
33
|
+
if not file_path.is_file():
|
|
34
|
+
return f"Error: '{path}' is not a file"
|
|
35
|
+
|
|
36
|
+
content = file_path.read_text(encoding="utf-8", errors="replace")
|
|
37
|
+
lines = content.splitlines()
|
|
38
|
+
|
|
39
|
+
total_lines = len(lines)
|
|
40
|
+
|
|
41
|
+
# Apply offset and limit
|
|
42
|
+
start = (offset - 1) if offset and offset > 0 else 0
|
|
43
|
+
end = (start + limit) if limit else len(lines)
|
|
44
|
+
|
|
45
|
+
selected_lines = lines[start:end]
|
|
46
|
+
|
|
47
|
+
# Format with line numbers
|
|
48
|
+
result_lines = []
|
|
49
|
+
for i, line in enumerate(selected_lines, start=start + 1):
|
|
50
|
+
# Truncate very long lines
|
|
51
|
+
if len(line) > 500:
|
|
52
|
+
line = line[:500] + "..."
|
|
53
|
+
result_lines.append(f"{i:>6}\t{line}")
|
|
54
|
+
|
|
55
|
+
result = "\n".join(result_lines)
|
|
56
|
+
|
|
57
|
+
# Add info about truncation
|
|
58
|
+
if end < total_lines:
|
|
59
|
+
result += f"\n\n... ({total_lines - end} more lines)"
|
|
60
|
+
|
|
61
|
+
return result
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Task tool for delegating to sub-agents."""
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
from rich.text import Text
|
|
7
|
+
|
|
8
|
+
from connectonion.cli.co_ai.agents.registry import get_subagent, SUBAGENTS
|
|
9
|
+
|
|
10
|
+
console = Console()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def task(
|
|
14
|
+
prompt: str,
|
|
15
|
+
agent_type: Literal["explore", "plan"] = "explore",
|
|
16
|
+
) -> str:
|
|
17
|
+
"""
|
|
18
|
+
Delegate a task to a specialized sub-agent.
|
|
19
|
+
|
|
20
|
+
Use this when you need to:
|
|
21
|
+
- Explore the codebase (find files, search code, understand structure)
|
|
22
|
+
- Plan an implementation (design approach, identify files to change)
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
prompt: The task description for the sub-agent
|
|
26
|
+
agent_type: Type of sub-agent to use
|
|
27
|
+
- "explore": Fast codebase exploration (find files, search code)
|
|
28
|
+
- "plan": Design implementation plans
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
Sub-agent's response
|
|
32
|
+
|
|
33
|
+
Examples:
|
|
34
|
+
task("Find all files that handle user authentication", agent_type="explore")
|
|
35
|
+
task("Design a plan to add dark mode support", agent_type="plan")
|
|
36
|
+
task("What is the project structure?", agent_type="explore")
|
|
37
|
+
"""
|
|
38
|
+
if agent_type not in SUBAGENTS:
|
|
39
|
+
available = ", ".join(SUBAGENTS.keys())
|
|
40
|
+
return f"Error: Unknown agent type '{agent_type}'. Available: {available}"
|
|
41
|
+
|
|
42
|
+
subagent = get_subagent(agent_type)
|
|
43
|
+
if subagent is None:
|
|
44
|
+
return f"Error: Failed to create {agent_type} agent"
|
|
45
|
+
|
|
46
|
+
# Show task start
|
|
47
|
+
short_prompt = prompt[:50] + "..." if len(prompt) > 50 else prompt
|
|
48
|
+
text = Text()
|
|
49
|
+
text.append(" ▶ ", style="blue")
|
|
50
|
+
text.append(f"Task ({agent_type})", style="bold blue")
|
|
51
|
+
text.append(f" {short_prompt}", style="dim")
|
|
52
|
+
console.print(text)
|
|
53
|
+
|
|
54
|
+
result = subagent.input(prompt)
|
|
55
|
+
|
|
56
|
+
# Show task complete
|
|
57
|
+
console.print(Text(" ◀ Task completed", style="blue"))
|
|
58
|
+
|
|
59
|
+
return result
|