connectonion 0.6.2__py3-none-any.whl → 0.6.3__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 +6 -0
- connectonion/cli/co_ai/plugins/reminder.py +76 -0
- connectonion/cli/co_ai/plugins/shell_approval.py +105 -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/reminders/plan_mode.md +34 -0
- connectonion/cli/co_ai/prompts/summarization.md +55 -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/reminders.py +159 -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 +172 -0
- connectonion/cli/co_ai/tools/read.py +67 -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 +100 -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_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 +2 -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/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.3.dist-info}/METADATA +10 -3
- connectonion-0.6.3.dist-info/RECORD +469 -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.3.dist-info}/WHEEL +0 -0
- {connectonion-0.6.2.dist-info → connectonion-0.6.3.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Workflow: Solving Problems with ConnectOnion Agents
|
|
2
|
+
|
|
3
|
+
**When a user describes a problem, create a ConnectOnion agent to solve it.**
|
|
4
|
+
|
|
5
|
+
## Step 1: Confirm Design with ask_user (REQUIRED)
|
|
6
|
+
|
|
7
|
+
**BEFORE writing any code, use ask_user to confirm the agent design.**
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
ask_user(
|
|
11
|
+
question="Which approach? (We can adjust later)",
|
|
12
|
+
options=[
|
|
13
|
+
"Atomic: 'Clean /downloads' → list_files, get_hash, delete → 'Deleted 5'",
|
|
14
|
+
"Safe: 'Clean safely' → find_duplicates, move_to_trash → 'Moved to trash'",
|
|
15
|
+
"Interactive: 'Find duplicates' → scan, ask_confirm, delete → 'User confirmed'",
|
|
16
|
+
]
|
|
17
|
+
)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**DO NOT skip this step. DO NOT use plan_mode for simple agent creation.**
|
|
21
|
+
|
|
22
|
+
## Step 2: Write the Agent (Single File)
|
|
23
|
+
|
|
24
|
+
After user confirms, write a Python file with ConnectOnion framework:
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from connectonion import Agent
|
|
28
|
+
|
|
29
|
+
def list_files(dir: str) -> list[str]:
|
|
30
|
+
"""List all files in directory."""
|
|
31
|
+
from pathlib import Path
|
|
32
|
+
return [str(f) for f in Path(dir).iterdir() if f.is_file()]
|
|
33
|
+
|
|
34
|
+
def get_hash(path: str) -> str:
|
|
35
|
+
"""Get MD5 hash of a file."""
|
|
36
|
+
import hashlib
|
|
37
|
+
return hashlib.md5(open(path, 'rb').read()).hexdigest()
|
|
38
|
+
|
|
39
|
+
def delete_file(path: str) -> str:
|
|
40
|
+
"""Delete a file."""
|
|
41
|
+
import os
|
|
42
|
+
os.remove(path)
|
|
43
|
+
return f"Deleted {path}"
|
|
44
|
+
|
|
45
|
+
agent = Agent("cleaner", tools=[list_files, get_hash, delete_file])
|
|
46
|
+
agent.input("Find and remove duplicate files in /downloads")
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Step 3: Done
|
|
50
|
+
|
|
51
|
+
Report completion. No plan mode, no complex workflow.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## When to Use Plan Mode (NOT for agent creation)
|
|
56
|
+
|
|
57
|
+
Reserve `enter_plan_mode()` for:
|
|
58
|
+
- Multi-file refactors
|
|
59
|
+
- Architecture changes
|
|
60
|
+
- Complex features with unclear requirements
|
|
61
|
+
- Tasks touching 5+ files
|
|
62
|
+
|
|
63
|
+
**Do NOT use plan mode for:**
|
|
64
|
+
- Creating a single ConnectOnion agent
|
|
65
|
+
- Simple file operations
|
|
66
|
+
- Clear, well-defined tasks
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## NEVER DO THIS
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
# BAD: Standalone script with argparse
|
|
74
|
+
import argparse
|
|
75
|
+
import hashlib
|
|
76
|
+
def main():
|
|
77
|
+
parser = argparse.ArgumentParser()
|
|
78
|
+
# ... hardcoded logic ...
|
|
79
|
+
|
|
80
|
+
# BAD: Using plan_mode for simple agent creation
|
|
81
|
+
enter_plan_mode() # Overkill for a single-file agent
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Key Rules
|
|
85
|
+
|
|
86
|
+
1. **ask_user FIRST** - Confirm design before coding
|
|
87
|
+
2. **from connectonion import Agent** - Always use the framework
|
|
88
|
+
3. **Atomic tools** - Each function does ONE thing
|
|
89
|
+
4. **No plan_mode for agents** - Just ask_user → write → done
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"""System reminders for contextual guidance.
|
|
2
|
+
|
|
3
|
+
System reminders are automatically injected into tool results or conversation
|
|
4
|
+
to provide contextual constraints and guidance. They override default behavior
|
|
5
|
+
when applicable.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
from connectonion.cli.co_ai.reminders import inject_reminder, REMINDERS
|
|
9
|
+
|
|
10
|
+
# Inject a specific reminder
|
|
11
|
+
result = inject_reminder(tool_result, "plan_mode_active")
|
|
12
|
+
|
|
13
|
+
# Check if reminder should be shown
|
|
14
|
+
if should_show_todo_reminder(agent):
|
|
15
|
+
result = inject_reminder(result, "todo_reminder")
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from typing import Optional, Dict, Any
|
|
19
|
+
from functools import wraps
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# System reminder templates
|
|
23
|
+
REMINDERS: Dict[str, str] = {
|
|
24
|
+
# Plan mode reminder - injected when plan mode is active
|
|
25
|
+
"plan_mode_active": """<system-reminder>
|
|
26
|
+
Plan mode is active. You are in READ-ONLY exploration mode.
|
|
27
|
+
- You can ONLY use: glob, grep, read_file to explore
|
|
28
|
+
- You can ONLY write to the plan file (.co/PLAN.md)
|
|
29
|
+
- Do NOT make any code changes until plan is approved
|
|
30
|
+
- Use write_plan() to update your plan
|
|
31
|
+
- Use exit_plan_mode() when plan is complete
|
|
32
|
+
</system-reminder>""",
|
|
33
|
+
|
|
34
|
+
# Todo reminder - gentle nudge to use todo tracking
|
|
35
|
+
"todo_reminder": """<system-reminder>
|
|
36
|
+
Consider using todo_list() to track progress for multi-step tasks.
|
|
37
|
+
Mark tasks complete immediately when finished.
|
|
38
|
+
</system-reminder>""",
|
|
39
|
+
|
|
40
|
+
# Read-only mode for explore agent
|
|
41
|
+
"read_only": """<system-reminder>
|
|
42
|
+
This is READ-ONLY mode. You are PROHIBITED from modifying any files.
|
|
43
|
+
Only use: glob, grep, read_file, and read-only bash commands.
|
|
44
|
+
</system-reminder>""",
|
|
45
|
+
|
|
46
|
+
# Security reminder after reading sensitive files
|
|
47
|
+
"security": """<system-reminder>
|
|
48
|
+
This file may contain sensitive information (credentials, keys, tokens).
|
|
49
|
+
- Never expose secrets in output
|
|
50
|
+
- Never commit this file if it contains real credentials
|
|
51
|
+
- Consider using environment variables instead
|
|
52
|
+
</system-reminder>""",
|
|
53
|
+
|
|
54
|
+
# Anti-over-engineering reminder
|
|
55
|
+
"simplicity": """<system-reminder>
|
|
56
|
+
Keep it simple:
|
|
57
|
+
- Only change what's directly needed
|
|
58
|
+
- Don't add error handling for scenarios that can't happen
|
|
59
|
+
- Three similar lines > premature abstraction
|
|
60
|
+
- If unused, delete completely
|
|
61
|
+
</system-reminder>""",
|
|
62
|
+
|
|
63
|
+
# Workflow reminder - injected when writing Python files
|
|
64
|
+
"connectonion_workflow": """<system-reminder>
|
|
65
|
+
When creating agents, ALWAYS use ConnectOnion framework:
|
|
66
|
+
- `from connectonion import Agent`
|
|
67
|
+
- Atomic tool functions (one thing each)
|
|
68
|
+
- `agent = Agent("name", tools=[...])` + `agent.input("task")`
|
|
69
|
+
|
|
70
|
+
NEVER create standalone scripts with argparse. NEVER skip ask_user confirmation.
|
|
71
|
+
</system-reminder>""",
|
|
72
|
+
|
|
73
|
+
# After code write reminder
|
|
74
|
+
"after_write_code": """<system-reminder>
|
|
75
|
+
Code written. If this is an agent:
|
|
76
|
+
- Verify it uses `from connectonion import Agent`
|
|
77
|
+
- Verify tools are atomic functions
|
|
78
|
+
- If it's a standalone script with argparse, REWRITE using ConnectOnion
|
|
79
|
+
</system-reminder>""",
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def inject_reminder(content: str, reminder_key: str) -> str:
|
|
84
|
+
"""
|
|
85
|
+
Inject a system reminder into content.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
content: The original content (tool result, message, etc.)
|
|
89
|
+
reminder_key: Key from REMINDERS dict
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
Content with reminder injected at the end
|
|
93
|
+
"""
|
|
94
|
+
if reminder_key not in REMINDERS:
|
|
95
|
+
return content
|
|
96
|
+
|
|
97
|
+
reminder = REMINDERS[reminder_key]
|
|
98
|
+
return f"{content}\n\n{reminder}"
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def with_reminder(reminder_key: str):
|
|
102
|
+
"""
|
|
103
|
+
Decorator to inject a reminder into tool results.
|
|
104
|
+
|
|
105
|
+
Usage:
|
|
106
|
+
@with_reminder("plan_mode_active")
|
|
107
|
+
def some_tool(...):
|
|
108
|
+
return result
|
|
109
|
+
"""
|
|
110
|
+
def decorator(func):
|
|
111
|
+
@wraps(func)
|
|
112
|
+
def wrapper(*args, **kwargs):
|
|
113
|
+
result = func(*args, **kwargs)
|
|
114
|
+
if isinstance(result, str):
|
|
115
|
+
return inject_reminder(result, reminder_key)
|
|
116
|
+
return result
|
|
117
|
+
return wrapper
|
|
118
|
+
return decorator
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def should_show_security_reminder(file_path: str) -> bool:
|
|
122
|
+
"""Check if file path suggests sensitive content."""
|
|
123
|
+
sensitive_patterns = [
|
|
124
|
+
".env",
|
|
125
|
+
"credentials",
|
|
126
|
+
"secrets",
|
|
127
|
+
"config/prod",
|
|
128
|
+
"keys",
|
|
129
|
+
"password",
|
|
130
|
+
"token",
|
|
131
|
+
".pem",
|
|
132
|
+
".key",
|
|
133
|
+
]
|
|
134
|
+
path_lower = file_path.lower()
|
|
135
|
+
return any(pattern in path_lower for pattern in sensitive_patterns)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def get_contextual_reminders(context: Dict[str, Any]) -> list:
|
|
139
|
+
"""
|
|
140
|
+
Get list of reminders based on current context.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
context: Dict with current state info:
|
|
144
|
+
- plan_mode: bool
|
|
145
|
+
- todo_count: int
|
|
146
|
+
- file_path: str (for security check)
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
List of reminder keys that should be shown
|
|
150
|
+
"""
|
|
151
|
+
reminders = []
|
|
152
|
+
|
|
153
|
+
if context.get("plan_mode"):
|
|
154
|
+
reminders.append("plan_mode_active")
|
|
155
|
+
|
|
156
|
+
if context.get("file_path") and should_show_security_reminder(context["file_path"]):
|
|
157
|
+
reminders.append("security")
|
|
158
|
+
|
|
159
|
+
return reminders
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""Session management with SQLite persistence."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import sqlite3
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_db_path() -> Path:
|
|
11
|
+
db_dir = Path.home() / ".co-ai"
|
|
12
|
+
db_dir.mkdir(exist_ok=True)
|
|
13
|
+
return db_dir / "sessions.db"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def init_db(conn: sqlite3.Connection) -> None:
|
|
17
|
+
conn.execute("""
|
|
18
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
19
|
+
id TEXT PRIMARY KEY,
|
|
20
|
+
title TEXT,
|
|
21
|
+
model TEXT,
|
|
22
|
+
created_at TEXT,
|
|
23
|
+
updated_at TEXT,
|
|
24
|
+
messages TEXT
|
|
25
|
+
)
|
|
26
|
+
""")
|
|
27
|
+
conn.commit()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_connection() -> sqlite3.Connection:
|
|
31
|
+
conn = sqlite3.connect(get_db_path())
|
|
32
|
+
conn.row_factory = sqlite3.Row
|
|
33
|
+
init_db(conn)
|
|
34
|
+
return conn
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class SessionManager:
|
|
38
|
+
def __init__(self):
|
|
39
|
+
self.conn = get_connection()
|
|
40
|
+
self.current_id: Optional[str] = None
|
|
41
|
+
|
|
42
|
+
def create_session(self, model: str = "") -> str:
|
|
43
|
+
session_id = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
44
|
+
now = datetime.now().isoformat()
|
|
45
|
+
self.conn.execute(
|
|
46
|
+
"INSERT INTO sessions (id, title, model, created_at, updated_at, messages) VALUES (?, ?, ?, ?, ?, ?)",
|
|
47
|
+
(session_id, "New Session", model, now, now, "[]")
|
|
48
|
+
)
|
|
49
|
+
self.conn.commit()
|
|
50
|
+
self.current_id = session_id
|
|
51
|
+
return session_id
|
|
52
|
+
|
|
53
|
+
def save_message(self, role: str, content: str) -> None:
|
|
54
|
+
if not self.current_id:
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
row = self.conn.execute(
|
|
58
|
+
"SELECT messages FROM sessions WHERE id = ?", (self.current_id,)
|
|
59
|
+
).fetchone()
|
|
60
|
+
|
|
61
|
+
if row:
|
|
62
|
+
messages = json.loads(row["messages"])
|
|
63
|
+
messages.append({"role": role, "content": content, "timestamp": datetime.now().isoformat()})
|
|
64
|
+
|
|
65
|
+
title = content[:50] + "..." if len(content) > 50 else content
|
|
66
|
+
if len(messages) == 1:
|
|
67
|
+
self.conn.execute(
|
|
68
|
+
"UPDATE sessions SET messages = ?, title = ?, updated_at = ? WHERE id = ?",
|
|
69
|
+
(json.dumps(messages), title, datetime.now().isoformat(), self.current_id)
|
|
70
|
+
)
|
|
71
|
+
else:
|
|
72
|
+
self.conn.execute(
|
|
73
|
+
"UPDATE sessions SET messages = ?, updated_at = ? WHERE id = ?",
|
|
74
|
+
(json.dumps(messages), datetime.now().isoformat(), self.current_id)
|
|
75
|
+
)
|
|
76
|
+
self.conn.commit()
|
|
77
|
+
|
|
78
|
+
def list_sessions(self, limit: int = 20) -> list[dict]:
|
|
79
|
+
rows = self.conn.execute(
|
|
80
|
+
"SELECT id, title, model, created_at, updated_at FROM sessions ORDER BY updated_at DESC LIMIT ?",
|
|
81
|
+
(limit,)
|
|
82
|
+
).fetchall()
|
|
83
|
+
return [dict(row) for row in rows]
|
|
84
|
+
|
|
85
|
+
def load_session(self, session_id: str) -> Optional[list[dict]]:
|
|
86
|
+
row = self.conn.execute(
|
|
87
|
+
"SELECT messages FROM sessions WHERE id = ?", (session_id,)
|
|
88
|
+
).fetchone()
|
|
89
|
+
|
|
90
|
+
if row:
|
|
91
|
+
self.current_id = session_id
|
|
92
|
+
return json.loads(row["messages"])
|
|
93
|
+
return None
|
|
94
|
+
|
|
95
|
+
def delete_session(self, session_id: str) -> bool:
|
|
96
|
+
self.conn.execute("DELETE FROM sessions WHERE id = ?", (session_id,))
|
|
97
|
+
self.conn.commit()
|
|
98
|
+
if self.current_id == session_id:
|
|
99
|
+
self.current_id = None
|
|
100
|
+
return True
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
_manager: Optional[SessionManager] = None
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def get_session_manager() -> SessionManager:
|
|
107
|
+
global _manager
|
|
108
|
+
if _manager is None:
|
|
109
|
+
_manager = SessionManager()
|
|
110
|
+
return _manager
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Skills system for OO agent.
|
|
2
|
+
|
|
3
|
+
Skills are markdown files that teach the agent how to do specific tasks.
|
|
4
|
+
They are auto-discovered based on description matching.
|
|
5
|
+
|
|
6
|
+
Directory structure:
|
|
7
|
+
.co/skills/
|
|
8
|
+
├── commit/
|
|
9
|
+
│ └── SKILL.md
|
|
10
|
+
└── review-pr/
|
|
11
|
+
└── SKILL.md
|
|
12
|
+
|
|
13
|
+
SKILL.md format:
|
|
14
|
+
---
|
|
15
|
+
name: skill-name
|
|
16
|
+
description: When to use this skill (for auto-detection)
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Instructions
|
|
20
|
+
...
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from connectonion.cli.co_ai.skills.loader import (
|
|
24
|
+
load_skills,
|
|
25
|
+
get_skill,
|
|
26
|
+
get_skills_for_prompt,
|
|
27
|
+
SKILLS_REGISTRY,
|
|
28
|
+
)
|
|
29
|
+
from connectonion.cli.co_ai.skills.tool import skill
|
|
30
|
+
|
|
31
|
+
__all__ = [
|
|
32
|
+
"load_skills",
|
|
33
|
+
"get_skill",
|
|
34
|
+
"get_skills_for_prompt",
|
|
35
|
+
"skill",
|
|
36
|
+
"SKILLS_REGISTRY",
|
|
37
|
+
]
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: commit
|
|
3
|
+
description: Create git commits with good messages. Use when user says "commit", "create commit", or asks to commit changes.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Git Commit Skill
|
|
7
|
+
|
|
8
|
+
Create a well-formatted git commit for staged changes.
|
|
9
|
+
|
|
10
|
+
## Instructions
|
|
11
|
+
|
|
12
|
+
1. **Gather information** (run in parallel):
|
|
13
|
+
- `git status` - See what's staged and unstaged
|
|
14
|
+
- `git diff --staged` - See exactly what will be committed
|
|
15
|
+
- `git log --oneline -5` - See recent commit message style
|
|
16
|
+
|
|
17
|
+
2. **Analyze changes**:
|
|
18
|
+
- What was changed? (files, functions, features)
|
|
19
|
+
- Why was it changed? (bug fix, new feature, refactor)
|
|
20
|
+
- Follow the repository's commit message style
|
|
21
|
+
|
|
22
|
+
3. **Draft commit message**:
|
|
23
|
+
- First line: concise summary under 50 chars
|
|
24
|
+
- Focus on "why" not "what"
|
|
25
|
+
- Match existing commit style
|
|
26
|
+
|
|
27
|
+
4. **Execute commit**:
|
|
28
|
+
- Stage relevant files if needed: `git add <files>`
|
|
29
|
+
- Commit with HEREDOC format:
|
|
30
|
+
```bash
|
|
31
|
+
git commit -m "$(cat <<'EOF'
|
|
32
|
+
Your commit message here
|
|
33
|
+
EOF
|
|
34
|
+
)"
|
|
35
|
+
```
|
|
36
|
+
- Verify with `git status`
|
|
37
|
+
|
|
38
|
+
## Safety Rules
|
|
39
|
+
|
|
40
|
+
- Do NOT commit .env or credential files
|
|
41
|
+
- Do NOT use `--amend` unless explicitly asked
|
|
42
|
+
- Do NOT push unless explicitly asked
|
|
43
|
+
- If commit fails, create NEW commit (don't amend)
|
|
44
|
+
|
|
45
|
+
## Example
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Check status and diff
|
|
49
|
+
git status
|
|
50
|
+
git diff --staged
|
|
51
|
+
|
|
52
|
+
# Commit
|
|
53
|
+
git commit -m "$(cat <<'EOF'
|
|
54
|
+
Fix authentication timeout issue
|
|
55
|
+
|
|
56
|
+
Increased JWT expiry from 1h to 24h to prevent
|
|
57
|
+
frequent re-authentication during long sessions.
|
|
58
|
+
EOF
|
|
59
|
+
)"
|
|
60
|
+
|
|
61
|
+
# Verify
|
|
62
|
+
git status
|
|
63
|
+
```
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: review-pr
|
|
3
|
+
description: Review GitHub pull requests. Use when user says "review PR", "review pull request", or "/review-pr".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# PR Review Skill
|
|
7
|
+
|
|
8
|
+
Review a GitHub pull request for code quality, correctness, and best practices.
|
|
9
|
+
|
|
10
|
+
## Instructions
|
|
11
|
+
|
|
12
|
+
1. **Get PR information**:
|
|
13
|
+
- If no PR number given: `gh pr list` to show open PRs
|
|
14
|
+
- With PR number: `gh pr view <number>` for details
|
|
15
|
+
- Get diff: `gh pr diff <number>`
|
|
16
|
+
|
|
17
|
+
2. **Analyze the changes**:
|
|
18
|
+
- What does this PR do?
|
|
19
|
+
- Does the code follow project conventions?
|
|
20
|
+
- Are there any bugs or issues?
|
|
21
|
+
- Is the code well-tested?
|
|
22
|
+
- Are there security concerns?
|
|
23
|
+
|
|
24
|
+
3. **Provide structured review**:
|
|
25
|
+
- Overview of what the PR does
|
|
26
|
+
- Code quality analysis
|
|
27
|
+
- Specific suggestions with line references
|
|
28
|
+
- Potential issues or risks
|
|
29
|
+
- Whether to approve, request changes, or comment
|
|
30
|
+
|
|
31
|
+
## Review Checklist
|
|
32
|
+
|
|
33
|
+
- [ ] Code correctness
|
|
34
|
+
- [ ] Following project conventions
|
|
35
|
+
- [ ] Error handling
|
|
36
|
+
- [ ] Performance implications
|
|
37
|
+
- [ ] Test coverage
|
|
38
|
+
- [ ] Security considerations
|
|
39
|
+
- [ ] Documentation updates needed
|
|
40
|
+
|
|
41
|
+
## Output Format
|
|
42
|
+
|
|
43
|
+
```markdown
|
|
44
|
+
## PR Review: #<number> - <title>
|
|
45
|
+
|
|
46
|
+
### Summary
|
|
47
|
+
<One paragraph about what this PR does>
|
|
48
|
+
|
|
49
|
+
### What's Good
|
|
50
|
+
- Point 1
|
|
51
|
+
- Point 2
|
|
52
|
+
|
|
53
|
+
### Suggestions
|
|
54
|
+
1. **File:line** - Description of suggestion
|
|
55
|
+
2. **File:line** - Description of suggestion
|
|
56
|
+
|
|
57
|
+
### Concerns
|
|
58
|
+
- Any potential issues
|
|
59
|
+
|
|
60
|
+
### Recommendation
|
|
61
|
+
- [ ] Approve
|
|
62
|
+
- [ ] Request Changes
|
|
63
|
+
- [ ] Comment only
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Example
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Get PR details
|
|
70
|
+
gh pr view 123
|
|
71
|
+
|
|
72
|
+
# Get the diff
|
|
73
|
+
gh pr diff 123
|
|
74
|
+
|
|
75
|
+
# Then analyze and provide review
|
|
76
|
+
```
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"""Skills loader - discovers and loads skills from .co/skills/ directory."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Dict, Optional, List
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class SkillInfo:
|
|
11
|
+
"""Metadata about a skill."""
|
|
12
|
+
name: str
|
|
13
|
+
description: str
|
|
14
|
+
path: Path
|
|
15
|
+
|
|
16
|
+
def load_content(self) -> str:
|
|
17
|
+
"""Load the full SKILL.md content."""
|
|
18
|
+
return self.path.read_text(encoding="utf-8")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Global registry of discovered skills
|
|
22
|
+
SKILLS_REGISTRY: Dict[str, SkillInfo] = {}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def parse_skill_frontmatter(content: str) -> Dict[str, str]:
|
|
26
|
+
"""Parse YAML frontmatter from SKILL.md content."""
|
|
27
|
+
# Match --- ... --- at start of file
|
|
28
|
+
match = re.match(r'^---\s*\n(.*?)\n---\s*\n', content, re.DOTALL)
|
|
29
|
+
if not match:
|
|
30
|
+
return {}
|
|
31
|
+
|
|
32
|
+
frontmatter = {}
|
|
33
|
+
for line in match.group(1).split('\n'):
|
|
34
|
+
if ':' in line:
|
|
35
|
+
key, value = line.split(':', 1)
|
|
36
|
+
frontmatter[key.strip()] = value.strip()
|
|
37
|
+
|
|
38
|
+
return frontmatter
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def discover_skills(base_path: Optional[Path] = None) -> List[SkillInfo]:
|
|
42
|
+
"""
|
|
43
|
+
Discover all skills in .co/skills/ directory.
|
|
44
|
+
|
|
45
|
+
Skills can be:
|
|
46
|
+
- .co/skills/skill-name/SKILL.md (directory with SKILL.md)
|
|
47
|
+
- .co/skills/skill-name.md (single file)
|
|
48
|
+
- ~/.co/skills/ (user-level skills)
|
|
49
|
+
- Built-in skills from co_ai/skills/builtin/
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
List of SkillInfo objects
|
|
53
|
+
"""
|
|
54
|
+
skills = []
|
|
55
|
+
|
|
56
|
+
# Search paths (in priority order)
|
|
57
|
+
search_paths = []
|
|
58
|
+
|
|
59
|
+
# Project-level skills (highest priority)
|
|
60
|
+
if base_path:
|
|
61
|
+
search_paths.append(base_path / ".co" / "skills")
|
|
62
|
+
else:
|
|
63
|
+
search_paths.append(Path.cwd() / ".co" / "skills")
|
|
64
|
+
|
|
65
|
+
# User-level skills
|
|
66
|
+
home_skills = Path.home() / ".co" / "skills"
|
|
67
|
+
if home_skills.exists():
|
|
68
|
+
search_paths.append(home_skills)
|
|
69
|
+
|
|
70
|
+
# Built-in skills (lowest priority)
|
|
71
|
+
builtin_skills = Path(__file__).parent / "builtin"
|
|
72
|
+
if builtin_skills.exists():
|
|
73
|
+
search_paths.append(builtin_skills)
|
|
74
|
+
|
|
75
|
+
for skills_dir in search_paths:
|
|
76
|
+
if not skills_dir.exists():
|
|
77
|
+
continue
|
|
78
|
+
|
|
79
|
+
# Find SKILL.md in subdirectories
|
|
80
|
+
for skill_dir in skills_dir.iterdir():
|
|
81
|
+
if skill_dir.is_dir():
|
|
82
|
+
skill_file = skill_dir / "SKILL.md"
|
|
83
|
+
if skill_file.exists():
|
|
84
|
+
skill_info = _parse_skill_file(skill_file)
|
|
85
|
+
if skill_info:
|
|
86
|
+
skills.append(skill_info)
|
|
87
|
+
|
|
88
|
+
# Also support single .md files
|
|
89
|
+
elif skill_dir.suffix == ".md" and skill_dir.stem != "SKILL":
|
|
90
|
+
skill_info = _parse_skill_file(skill_dir)
|
|
91
|
+
if skill_info:
|
|
92
|
+
skills.append(skill_info)
|
|
93
|
+
|
|
94
|
+
return skills
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _parse_skill_file(path: Path) -> Optional[SkillInfo]:
|
|
98
|
+
"""Parse a SKILL.md file and extract metadata."""
|
|
99
|
+
content = path.read_text(encoding="utf-8")
|
|
100
|
+
frontmatter = parse_skill_frontmatter(content)
|
|
101
|
+
|
|
102
|
+
name = frontmatter.get("name")
|
|
103
|
+
description = frontmatter.get("description")
|
|
104
|
+
|
|
105
|
+
# If no name, use directory/file name
|
|
106
|
+
if not name:
|
|
107
|
+
if path.name == "SKILL.md":
|
|
108
|
+
name = path.parent.name
|
|
109
|
+
else:
|
|
110
|
+
name = path.stem
|
|
111
|
+
|
|
112
|
+
# If no description, try to extract from first paragraph
|
|
113
|
+
if not description:
|
|
114
|
+
# Remove frontmatter and find first paragraph
|
|
115
|
+
content_without_frontmatter = re.sub(r'^---\s*\n.*?\n---\s*\n', '', content, flags=re.DOTALL)
|
|
116
|
+
lines = content_without_frontmatter.strip().split('\n')
|
|
117
|
+
for line in lines:
|
|
118
|
+
line = line.strip()
|
|
119
|
+
if line and not line.startswith('#'):
|
|
120
|
+
description = line[:200] # First 200 chars
|
|
121
|
+
break
|
|
122
|
+
|
|
123
|
+
if not description:
|
|
124
|
+
description = f"Skill: {name}"
|
|
125
|
+
|
|
126
|
+
return SkillInfo(name=name, description=description, path=path)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def load_skills(base_path: Optional[Path] = None) -> Dict[str, SkillInfo]:
|
|
130
|
+
"""
|
|
131
|
+
Load all skills and populate the registry.
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
Dictionary of skill name -> SkillInfo
|
|
135
|
+
"""
|
|
136
|
+
skills = discover_skills(base_path)
|
|
137
|
+
|
|
138
|
+
# Mutate rather than reassign to keep references in sync
|
|
139
|
+
SKILLS_REGISTRY.clear()
|
|
140
|
+
SKILLS_REGISTRY.update({s.name: s for s in skills})
|
|
141
|
+
|
|
142
|
+
return SKILLS_REGISTRY
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def get_skill(name: str) -> Optional[SkillInfo]:
|
|
146
|
+
"""Get a skill by name from the registry."""
|
|
147
|
+
return SKILLS_REGISTRY.get(name)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def get_skills_for_prompt() -> str:
|
|
151
|
+
"""
|
|
152
|
+
Format skills for inclusion in system prompt.
|
|
153
|
+
|
|
154
|
+
Returns XML-formatted available skills list.
|
|
155
|
+
"""
|
|
156
|
+
if not SKILLS_REGISTRY:
|
|
157
|
+
return ""
|
|
158
|
+
|
|
159
|
+
lines = ["<available_skills>"]
|
|
160
|
+
for name, info in SKILLS_REGISTRY.items():
|
|
161
|
+
# Escape description for XML
|
|
162
|
+
desc = info.description.replace("&", "&").replace("<", "<").replace(">", ">")
|
|
163
|
+
lines.append(f' <skill name="{name}" description="{desc}"/>')
|
|
164
|
+
lines.append("</available_skills>")
|
|
165
|
+
|
|
166
|
+
return "\n".join(lines)
|