octo-agent 0.11.2
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.
- checksums.yaml +7 -0
- data/.clacky/skills/commit/SKILL.md +423 -0
- data/.clacky/skills/gem-release/SKILL.md +199 -0
- data/.clacky/skills/gem-release/scripts/release.sh +304 -0
- data/.clacky/skills/oss-upload/SKILL.md +47 -0
- data/.octorules +106 -0
- data/.rspec +3 -0
- data/.rubocop.yml +8 -0
- data/CHANGELOG.md +76 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/CONTRIBUTING.md +92 -0
- data/Dockerfile +28 -0
- data/LICENSE.txt +22 -0
- data/POSITIONING.md +46 -0
- data/README.md +134 -0
- data/README_CN.md +134 -0
- data/Rakefile +34 -0
- data/benchmark/fixtures/sample_project/Gemfile +3 -0
- data/benchmark/fixtures/sample_project/lib/api_handler.rb +32 -0
- data/benchmark/fixtures/sample_project/lib/order_calculator.rb +23 -0
- data/benchmark/fixtures/sample_project/lib/user_renderer.rb +20 -0
- data/benchmark/fixtures/sample_project/spec/order_calculator_spec.rb +20 -0
- data/benchmark/results/EVALUATION_REPORT.md +165 -0
- data/benchmark/results/baseline_20260511_174424.json +128 -0
- data/benchmark/results/report_20260511_175256.json +271 -0
- data/benchmark/results/report_20260511_175444.json +271 -0
- data/benchmark/results/treatment_20260511_175103.json +130 -0
- data/benchmark/runner.rb +441 -0
- data/bin/octo +7 -0
- data/docs/agent-first-ui-design.md +77 -0
- data/docs/billing-system.md +318 -0
- data/docs/channel-architecture.md +235 -0
- data/docs/engineering-article.md +343 -0
- data/docs/session-skill-invocation.md +69 -0
- data/docs/time_machine_design.md +247 -0
- data/docs/ui2-architecture.md +124 -0
- data/homebrew/README.md +96 -0
- data/homebrew/openocto.rb +24 -0
- data/lib/octo/agent/hook_manager.rb +61 -0
- data/lib/octo/agent/llm_caller.rb +800 -0
- data/lib/octo/agent/memory_updater.rb +246 -0
- data/lib/octo/agent/message_compressor.rb +225 -0
- data/lib/octo/agent/message_compressor_helper.rb +869 -0
- data/lib/octo/agent/next_message_suggester.rb +215 -0
- data/lib/octo/agent/session_serializer.rb +685 -0
- data/lib/octo/agent/skill_auto_creator.rb +114 -0
- data/lib/octo/agent/skill_evolution.rb +61 -0
- data/lib/octo/agent/skill_manager.rb +466 -0
- data/lib/octo/agent/skill_reflector.rb +89 -0
- data/lib/octo/agent/system_prompt_builder.rb +101 -0
- data/lib/octo/agent/time_machine.rb +214 -0
- data/lib/octo/agent/tool_executor.rb +454 -0
- data/lib/octo/agent/tool_registry.rb +150 -0
- data/lib/octo/agent.rb +2180 -0
- data/lib/octo/agent_config.rb +989 -0
- data/lib/octo/agent_profile.rb +112 -0
- data/lib/octo/anthropic_stream_aggregator.rb +137 -0
- data/lib/octo/background_task_registry.rb +324 -0
- data/lib/octo/banner.rb +34 -0
- data/lib/octo/bedrock_stream_aggregator.rb +137 -0
- data/lib/octo/block_font.rb +331 -0
- data/lib/octo/cli.rb +968 -0
- data/lib/octo/client.rb +623 -0
- data/lib/octo/default_agents/SOUL.md +3 -0
- data/lib/octo/default_agents/USER.md +1 -0
- data/lib/octo/default_agents/base_prompt.md +66 -0
- data/lib/octo/default_agents/coding/profile.yml +2 -0
- data/lib/octo/default_agents/coding/system_prompt.md +67 -0
- data/lib/octo/default_agents/general/profile.yml +2 -0
- data/lib/octo/default_agents/general/system_prompt.md +16 -0
- data/lib/octo/default_parsers/doc_parser.rb +69 -0
- data/lib/octo/default_parsers/docx_parser.rb +188 -0
- data/lib/octo/default_parsers/pdf_parser.rb +120 -0
- data/lib/octo/default_parsers/pdf_parser_ocr.py +103 -0
- data/lib/octo/default_parsers/pdf_parser_plumber.py +62 -0
- data/lib/octo/default_parsers/pptx_parser.rb +140 -0
- data/lib/octo/default_parsers/xlsx_parser.rb +121 -0
- data/lib/octo/default_skills/browser-setup/SKILL.md +426 -0
- data/lib/octo/default_skills/channel-manager/SKILL.md +623 -0
- data/lib/octo/default_skills/channel-manager/dingtalk_setup.rb +191 -0
- data/lib/octo/default_skills/channel-manager/discord_setup.rb +199 -0
- data/lib/octo/default_skills/channel-manager/feishu_setup.rb +574 -0
- data/lib/octo/default_skills/channel-manager/import_lark_skills.rb +97 -0
- data/lib/octo/default_skills/channel-manager/install_feishu_skills.rb +105 -0
- data/lib/octo/default_skills/channel-manager/weixin_setup.rb +274 -0
- data/lib/octo/default_skills/code-explorer/SKILL.md +36 -0
- data/lib/octo/default_skills/cron-task-creator/SKILL.md +257 -0
- data/lib/octo/default_skills/cron-task-creator/evals/evals.json +38 -0
- data/lib/octo/default_skills/onboard/SKILL.md +578 -0
- data/lib/octo/default_skills/onboard/scripts/import_external_skills.rb +413 -0
- data/lib/octo/default_skills/onboard/scripts/install_builtin_skills.rb +97 -0
- data/lib/octo/default_skills/persist-memory/SKILL.md +59 -0
- data/lib/octo/default_skills/personal-website/SKILL.md +113 -0
- data/lib/octo/default_skills/personal-website/publish.rb +235 -0
- data/lib/octo/default_skills/product-help/SKILL.md +123 -0
- data/lib/octo/default_skills/product-help/docs/agent-config.md +74 -0
- data/lib/octo/default_skills/product-help/docs/best-practices.md +49 -0
- data/lib/octo/default_skills/product-help/docs/browser-tool.md +53 -0
- data/lib/octo/default_skills/product-help/docs/built-in-skills.md +43 -0
- data/lib/octo/default_skills/product-help/docs/cli-reference.md +82 -0
- data/lib/octo/default_skills/product-help/docs/create-your-first-skill.md +47 -0
- data/lib/octo/default_skills/product-help/docs/faq.md +98 -0
- data/lib/octo/default_skills/product-help/docs/how-to-use-a-skill.md +58 -0
- data/lib/octo/default_skills/product-help/docs/installation.md +59 -0
- data/lib/octo/default_skills/product-help/docs/memory-system.md +61 -0
- data/lib/octo/default_skills/product-help/docs/octorules.md +62 -0
- data/lib/octo/default_skills/product-help/docs/session-management.md +63 -0
- data/lib/octo/default_skills/product-help/docs/skill-basics.md +55 -0
- data/lib/octo/default_skills/product-help/docs/skill-frontmatter.md +61 -0
- data/lib/octo/default_skills/product-help/docs/web-server.md +49 -0
- data/lib/octo/default_skills/product-help/docs/what-is-octo.md +37 -0
- data/lib/octo/default_skills/product-help/docs/windows-installation.md +36 -0
- data/lib/octo/default_skills/product-help/docs/writing-tips.md +53 -0
- data/lib/octo/default_skills/recall-memory/SKILL.md +65 -0
- data/lib/octo/default_skills/skill-add/SKILL.md +59 -0
- data/lib/octo/default_skills/skill-add/scripts/install_from_zip.rb +295 -0
- data/lib/octo/default_skills/skill-creator/SKILL.md +602 -0
- data/lib/octo/default_skills/skill-creator/agents/analyzer.md +274 -0
- data/lib/octo/default_skills/skill-creator/agents/comparator.md +202 -0
- data/lib/octo/default_skills/skill-creator/agents/grader.md +223 -0
- data/lib/octo/default_skills/skill-creator/eval-viewer/generate_review.py +471 -0
- data/lib/octo/default_skills/skill-creator/eval-viewer/viewer.html +1325 -0
- data/lib/octo/default_skills/skill-creator/references/schemas.md +430 -0
- data/lib/octo/default_skills/skill-creator/scripts/__init__.py +0 -0
- data/lib/octo/default_skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- data/lib/octo/default_skills/skill-creator/scripts/generate_report.py +326 -0
- data/lib/octo/default_skills/skill-creator/scripts/improve_description.py +310 -0
- data/lib/octo/default_skills/skill-creator/scripts/quick_validate.py +103 -0
- data/lib/octo/default_skills/skill-creator/scripts/run_eval.py +317 -0
- data/lib/octo/default_skills/skill-creator/scripts/run_loop.py +331 -0
- data/lib/octo/default_skills/skill-creator/scripts/utils.py +47 -0
- data/lib/octo/default_skills/skill-creator/scripts/validate_skill_frontmatter.rb +143 -0
- data/lib/octo/idle_compression_timer.rb +115 -0
- data/lib/octo/json_ui_controller.rb +204 -0
- data/lib/octo/message_format/anthropic.rb +409 -0
- data/lib/octo/message_format/bedrock.rb +361 -0
- data/lib/octo/message_format/open_ai.rb +222 -0
- data/lib/octo/message_history.rb +373 -0
- data/lib/octo/openai_stream_aggregator.rb +130 -0
- data/lib/octo/plain_ui_controller.rb +166 -0
- data/lib/octo/providers.rb +534 -0
- data/lib/octo/server/browser_manager.rb +397 -0
- data/lib/octo/server/channel/adapters/base.rb +82 -0
- data/lib/octo/server/channel/adapters/dingtalk/adapter.rb +314 -0
- data/lib/octo/server/channel/adapters/dingtalk/api_client.rb +391 -0
- data/lib/octo/server/channel/adapters/dingtalk/stream_client.rb +203 -0
- data/lib/octo/server/channel/adapters/discord/adapter.rb +229 -0
- data/lib/octo/server/channel/adapters/discord/api_client.rb +107 -0
- data/lib/octo/server/channel/adapters/discord/gateway_client.rb +270 -0
- data/lib/octo/server/channel/adapters/feishu/adapter.rb +320 -0
- data/lib/octo/server/channel/adapters/feishu/bot.rb +478 -0
- data/lib/octo/server/channel/adapters/feishu/file_processor.rb +36 -0
- data/lib/octo/server/channel/adapters/feishu/message_parser.rb +129 -0
- data/lib/octo/server/channel/adapters/feishu/ws_client.rb +423 -0
- data/lib/octo/server/channel/adapters/telegram/adapter.rb +375 -0
- data/lib/octo/server/channel/adapters/telegram/api_client.rb +205 -0
- data/lib/octo/server/channel/adapters/wecom/adapter.rb +148 -0
- data/lib/octo/server/channel/adapters/wecom/media_downloader.rb +115 -0
- data/lib/octo/server/channel/adapters/wecom/ws_client.rb +395 -0
- data/lib/octo/server/channel/adapters/weixin/adapter.rb +692 -0
- data/lib/octo/server/channel/adapters/weixin/api_client.rb +402 -0
- data/lib/octo/server/channel/channel_config.rb +178 -0
- data/lib/octo/server/channel/channel_manager.rb +468 -0
- data/lib/octo/server/channel/channel_ui_controller.rb +224 -0
- data/lib/octo/server/channel.rb +33 -0
- data/lib/octo/server/discover.rb +77 -0
- data/lib/octo/server/epipe_safe_io.rb +105 -0
- data/lib/octo/server/http_server.rb +3554 -0
- data/lib/octo/server/scheduler.rb +317 -0
- data/lib/octo/server/server_master.rb +325 -0
- data/lib/octo/server/session_registry.rb +431 -0
- data/lib/octo/server/web_ui_controller.rb +487 -0
- data/lib/octo/session_manager.rb +385 -0
- data/lib/octo/skill.rb +466 -0
- data/lib/octo/skill_loader.rb +328 -0
- data/lib/octo/tools/base.rb +118 -0
- data/lib/octo/tools/browser.rb +625 -0
- data/lib/octo/tools/edit.rb +165 -0
- data/lib/octo/tools/file_reader.rb +549 -0
- data/lib/octo/tools/glob.rb +162 -0
- data/lib/octo/tools/grep.rb +356 -0
- data/lib/octo/tools/invoke_skill.rb +96 -0
- data/lib/octo/tools/list_tasks.rb +54 -0
- data/lib/octo/tools/redo_task.rb +41 -0
- data/lib/octo/tools/request_user_feedback.rb +84 -0
- data/lib/octo/tools/security.rb +333 -0
- data/lib/octo/tools/terminal/output_cleaner.rb +63 -0
- data/lib/octo/tools/terminal/persistent_session.rb +268 -0
- data/lib/octo/tools/terminal/safe_rm.sh +106 -0
- data/lib/octo/tools/terminal/session_manager.rb +213 -0
- data/lib/octo/tools/terminal.rb +1828 -0
- data/lib/octo/tools/todo_manager.rb +374 -0
- data/lib/octo/tools/trash_manager.rb +388 -0
- data/lib/octo/tools/undo_task.rb +35 -0
- data/lib/octo/tools/web_fetch.rb +242 -0
- data/lib/octo/tools/web_search.rb +260 -0
- data/lib/octo/tools/write.rb +77 -0
- data/lib/octo/ui2/block_font.rb +10 -0
- data/lib/octo/ui2/components/base_component.rb +163 -0
- data/lib/octo/ui2/components/command_suggestions.rb +290 -0
- data/lib/octo/ui2/components/common_component.rb +96 -0
- data/lib/octo/ui2/components/inline_input.rb +226 -0
- data/lib/octo/ui2/components/input_area.rb +1338 -0
- data/lib/octo/ui2/components/message_component.rb +99 -0
- data/lib/octo/ui2/components/modal_component.rb +419 -0
- data/lib/octo/ui2/components/todo_area.rb +149 -0
- data/lib/octo/ui2/components/tool_component.rb +107 -0
- data/lib/octo/ui2/components/welcome_banner.rb +139 -0
- data/lib/octo/ui2/layout_manager.rb +807 -0
- data/lib/octo/ui2/line_editor.rb +363 -0
- data/lib/octo/ui2/markdown_renderer.rb +100 -0
- data/lib/octo/ui2/output_buffer.rb +370 -0
- data/lib/octo/ui2/progress_handle.rb +362 -0
- data/lib/octo/ui2/progress_indicator.rb +55 -0
- data/lib/octo/ui2/screen_buffer.rb +273 -0
- data/lib/octo/ui2/terminal_detector.rb +119 -0
- data/lib/octo/ui2/theme_manager.rb +85 -0
- data/lib/octo/ui2/themes/base_theme.rb +105 -0
- data/lib/octo/ui2/themes/hacker_theme.rb +62 -0
- data/lib/octo/ui2/themes/minimal_theme.rb +56 -0
- data/lib/octo/ui2/thinking_verbs.rb +26 -0
- data/lib/octo/ui2/ui_controller.rb +1625 -0
- data/lib/octo/ui2/view_renderer.rb +177 -0
- data/lib/octo/ui2.rb +40 -0
- data/lib/octo/ui_interface.rb +154 -0
- data/lib/octo/utils/arguments_parser.rb +191 -0
- data/lib/octo/utils/browser_detector.rb +195 -0
- data/lib/octo/utils/encoding.rb +92 -0
- data/lib/octo/utils/environment_detector.rb +140 -0
- data/lib/octo/utils/file_ignore_helper.rb +170 -0
- data/lib/octo/utils/file_processor.rb +601 -0
- data/lib/octo/utils/gitignore_parser.rb +154 -0
- data/lib/octo/utils/limit_stack.rb +152 -0
- data/lib/octo/utils/logger.rb +124 -0
- data/lib/octo/utils/login_shell.rb +72 -0
- data/lib/octo/utils/model_pricing.rb +646 -0
- data/lib/octo/utils/parser_manager.rb +165 -0
- data/lib/octo/utils/path_helper.rb +15 -0
- data/lib/octo/utils/scripts_manager.rb +59 -0
- data/lib/octo/utils/string_matcher.rb +158 -0
- data/lib/octo/utils/trash_directory.rb +112 -0
- data/lib/octo/utils/workspace_rules.rb +46 -0
- data/lib/octo/version.rb +5 -0
- data/lib/octo/web/app.css +7141 -0
- data/lib/octo/web/app.js +543 -0
- data/lib/octo/web/apple-touch-icon.png +0 -0
- data/lib/octo/web/auth.js +150 -0
- data/lib/octo/web/channels.js +276 -0
- data/lib/octo/web/datepicker.js +205 -0
- data/lib/octo/web/favicon.png +0 -0
- data/lib/octo/web/i18n.js +1073 -0
- data/lib/octo/web/icon-512.png +0 -0
- data/lib/octo/web/icon-dark.svg +25 -0
- data/lib/octo/web/icon.svg +29 -0
- data/lib/octo/web/index.html +871 -0
- data/lib/octo/web/marked.min.js +69 -0
- data/lib/octo/web/onboard.js +491 -0
- data/lib/octo/web/profile.js +442 -0
- data/lib/octo/web/sessions.js +4421 -0
- data/lib/octo/web/settings.js +913 -0
- data/lib/octo/web/sidebar.js +32 -0
- data/lib/octo/web/skills.js +885 -0
- data/lib/octo/web/tasks.js +297 -0
- data/lib/octo/web/theme.js +105 -0
- data/lib/octo/web/trash.js +343 -0
- data/lib/octo/web/vendor/hljs/highlight.min.js +1244 -0
- data/lib/octo/web/vendor/hljs/hljs-theme.css +95 -0
- data/lib/octo/web/vendor/katex/auto-render.min.js +1 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- data/lib/octo/web/vendor/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- data/lib/octo/web/vendor/katex/katex.min.css +1 -0
- data/lib/octo/web/vendor/katex/katex.min.js +1 -0
- data/lib/octo/web/version.js +449 -0
- data/lib/octo/web/weixin-qr.html +209 -0
- data/lib/octo/web/ws-dispatcher.js +357 -0
- data/lib/octo/web/ws.js +128 -0
- data/lib/octo.rb +145 -0
- data/scripts/build/build.sh +329 -0
- data/scripts/build/lib/apt.sh +56 -0
- data/scripts/build/lib/brew.sh +89 -0
- data/scripts/build/lib/colors.sh +17 -0
- data/scripts/build/lib/gem.sh +95 -0
- data/scripts/build/lib/mise.sh +125 -0
- data/scripts/build/lib/network.sh +157 -0
- data/scripts/build/lib/os.sh +57 -0
- data/scripts/build/lib/shell.sh +37 -0
- data/scripts/build/src/install.sh.cc +174 -0
- data/scripts/build/src/install_browser.sh.cc +101 -0
- data/scripts/build/src/install_full.sh.cc +290 -0
- data/scripts/build/src/install_rails_deps.sh.cc +145 -0
- data/scripts/build/src/install_system_deps.sh.cc +123 -0
- data/scripts/build/src/uninstall.sh.cc +101 -0
- data/scripts/install.ps1 +532 -0
- data/scripts/install.sh +567 -0
- data/scripts/install_browser.sh +479 -0
- data/scripts/install_full.sh +838 -0
- data/scripts/install_rails_deps.sh +746 -0
- data/scripts/install_system_deps.sh +518 -0
- data/scripts/uninstall.sh +287 -0
- data/sig/octo.rbs +4 -0
- metadata +614 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# release.sh — octo gem release automation
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# bash release.sh <version> [--prerelease] [--update-latest]
|
|
6
|
+
#
|
|
7
|
+
# Examples:
|
|
8
|
+
# bash release.sh 1.0.6 # stable release
|
|
9
|
+
# bash release.sh 1.0.6 --dry-run # preview without executing
|
|
10
|
+
# bash release.sh 2.0.0.beta.1 --prerelease # pre-release, skip latest.txt
|
|
11
|
+
# bash release.sh 2.0.0.rc1 --prerelease --update-latest # pre-release, update latest.txt
|
|
12
|
+
#
|
|
13
|
+
# Prerequisites:
|
|
14
|
+
# - gh CLI installed and authenticated
|
|
15
|
+
# - coscli installed at /usr/local/bin/coscli with ~/.cos.yaml
|
|
16
|
+
# - RubyGems credentials configured (gem push)
|
|
17
|
+
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
# ── Colors ──────────────────────────────────────────────────────────────
|
|
21
|
+
RED='\033[0;31m'
|
|
22
|
+
GREEN='\033[0;32m'
|
|
23
|
+
YELLOW='\033[1;33m'
|
|
24
|
+
BLUE='\033[0;34m'
|
|
25
|
+
CYAN='\033[0;36m'
|
|
26
|
+
NC='\033[0m'
|
|
27
|
+
|
|
28
|
+
info() { echo -e "${BLUE}ℹ${NC} $1"; }
|
|
29
|
+
success() { echo -e "${GREEN}✓${NC} $1"; }
|
|
30
|
+
warn() { echo -e "${YELLOW}⚠${NC} $1"; }
|
|
31
|
+
error() { echo -e "${RED}✗${NC} $1" >&2; }
|
|
32
|
+
step() { echo -e "\n${CYAN}▶ Step $1:${NC} $2\n"; }
|
|
33
|
+
die() { error "$1"; exit 1; }
|
|
34
|
+
|
|
35
|
+
# ── Parse args ──────────────────────────────────────────────────────────
|
|
36
|
+
VERSION=""
|
|
37
|
+
PRERELEASE=false
|
|
38
|
+
UPDATE_LATEST=true
|
|
39
|
+
DRY_RUN=false
|
|
40
|
+
|
|
41
|
+
while [[ $# -gt 0 ]]; do
|
|
42
|
+
case "$1" in
|
|
43
|
+
--prerelease) PRERELEASE=true; UPDATE_LATEST=false ;;
|
|
44
|
+
--update-latest) UPDATE_LATEST=true ;;
|
|
45
|
+
--dry-run) DRY_RUN=true ;;
|
|
46
|
+
--help|-h)
|
|
47
|
+
echo "Usage: bash release.sh <version> [--prerelease] [--update-latest] [--dry-run]"
|
|
48
|
+
exit 0
|
|
49
|
+
;;
|
|
50
|
+
-*) die "Unknown option: $1" ;;
|
|
51
|
+
*) VERSION="$1" ;;
|
|
52
|
+
esac
|
|
53
|
+
shift
|
|
54
|
+
done
|
|
55
|
+
|
|
56
|
+
[[ -z "$VERSION" ]] && die "Version argument required. Usage: bash release.sh <version>"
|
|
57
|
+
|
|
58
|
+
# ── Resolve paths ───────────────────────────────────────────────────────
|
|
59
|
+
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || die "Not inside a git repository"
|
|
60
|
+
cd "$REPO_ROOT"
|
|
61
|
+
|
|
62
|
+
VERSION_FILE="lib/octo/version.rb"
|
|
63
|
+
GEMSPEC="octo.gemspec"
|
|
64
|
+
CHANGELOG="CHANGELOG.md"
|
|
65
|
+
GEM_FILE="octo-${VERSION}.gem"
|
|
66
|
+
OSS_BUCKET="cos://octoai-1258723534"
|
|
67
|
+
|
|
68
|
+
[[ -f "$VERSION_FILE" ]] || die "Version file not found: $VERSION_FILE"
|
|
69
|
+
[[ -f "$GEMSPEC" ]] || die "Gemspec not found: $GEMSPEC"
|
|
70
|
+
|
|
71
|
+
CURRENT_VERSION=$(ruby -ne 'puts $1 if /VERSION\s*=\s*"([^"]+)"/' "$VERSION_FILE")
|
|
72
|
+
info "Current version: ${CURRENT_VERSION}"
|
|
73
|
+
info "Target version: ${VERSION}"
|
|
74
|
+
info "Pre-release: ${PRERELEASE}"
|
|
75
|
+
info "Update latest: ${UPDATE_LATEST}"
|
|
76
|
+
info "Dry run: ${DRY_RUN}"
|
|
77
|
+
echo ""
|
|
78
|
+
|
|
79
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
80
|
+
warn "DRY RUN mode — no changes will be made"
|
|
81
|
+
echo ""
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# ── Helper: run or preview ──────────────────────────────────────────────
|
|
85
|
+
run() {
|
|
86
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
87
|
+
echo -e " ${YELLOW}[dry-run]${NC} $*"
|
|
88
|
+
else
|
|
89
|
+
"$@"
|
|
90
|
+
fi
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
94
|
+
# Step 1: Pre-release checks
|
|
95
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
96
|
+
step 1 "Pre-release checks"
|
|
97
|
+
|
|
98
|
+
if [[ -n "$(git status --porcelain)" ]]; then
|
|
99
|
+
die "Working directory is not clean. Commit or stash changes first."
|
|
100
|
+
fi
|
|
101
|
+
success "Working directory is clean"
|
|
102
|
+
|
|
103
|
+
BRANCH=$(git branch --show-current)
|
|
104
|
+
if [[ "$BRANCH" != "main" ]]; then
|
|
105
|
+
warn "Not on main branch (currently on '${BRANCH}')"
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
command -v gh >/dev/null 2>&1 || die "gh CLI not found. Install with: brew install gh"
|
|
109
|
+
command -v coscli >/dev/null 2>&1 || die "coscli not found. Install at /usr/local/bin/coscli"
|
|
110
|
+
success "Required tools available (gh, coscli)"
|
|
111
|
+
|
|
112
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
113
|
+
# Step 2: Run tests
|
|
114
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
115
|
+
step 2 "Running test suite"
|
|
116
|
+
|
|
117
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
118
|
+
echo -e " ${YELLOW}[dry-run]${NC} bundle exec rspec"
|
|
119
|
+
else
|
|
120
|
+
bundle exec rspec || die "Tests failed — aborting release"
|
|
121
|
+
fi
|
|
122
|
+
success "All tests passed"
|
|
123
|
+
|
|
124
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
125
|
+
# Step 3: Bump version
|
|
126
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
127
|
+
step 3 "Bumping version to ${VERSION}"
|
|
128
|
+
|
|
129
|
+
run sed -i '' "s/VERSION = \"${CURRENT_VERSION}\"/VERSION = \"${VERSION}\"/" "$VERSION_FILE"
|
|
130
|
+
|
|
131
|
+
if [[ "$DRY_RUN" != true ]]; then
|
|
132
|
+
grep -q "VERSION = \"${VERSION}\"" "$VERSION_FILE" || die "Version bump failed"
|
|
133
|
+
fi
|
|
134
|
+
success "Updated ${VERSION_FILE}"
|
|
135
|
+
|
|
136
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
137
|
+
# Step 4: Update Gemfile.lock
|
|
138
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
139
|
+
step 4 "Updating Gemfile.lock"
|
|
140
|
+
|
|
141
|
+
run bundle install --quiet
|
|
142
|
+
success "Gemfile.lock updated"
|
|
143
|
+
|
|
144
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
145
|
+
# Step 5: Commit version bump
|
|
146
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
147
|
+
step 5 "Committing version bump"
|
|
148
|
+
|
|
149
|
+
run git add "$VERSION_FILE" Gemfile.lock
|
|
150
|
+
run git commit -m "chore: bump version to ${VERSION}"
|
|
151
|
+
success "Version bump committed"
|
|
152
|
+
|
|
153
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
154
|
+
# Step 6: Push and wait for CI
|
|
155
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
156
|
+
step 6 "Pushing to origin and checking CI"
|
|
157
|
+
|
|
158
|
+
run git push origin "$BRANCH"
|
|
159
|
+
success "Pushed to origin/${BRANCH}"
|
|
160
|
+
|
|
161
|
+
if [[ "$DRY_RUN" != true ]]; then
|
|
162
|
+
info "Waiting for CI to complete (this may take a few minutes)..."
|
|
163
|
+
if gh run list --branch "$BRANCH" --limit 1 --json status -q '.[0].status' 2>/dev/null | grep -q "completed"; then
|
|
164
|
+
success "CI already completed"
|
|
165
|
+
else
|
|
166
|
+
gh run watch --exit-status 2>/dev/null || warn "Could not watch CI run — verify manually at GitHub Actions"
|
|
167
|
+
fi
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
171
|
+
# Step 7: Build gem
|
|
172
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
173
|
+
step 7 "Building gem"
|
|
174
|
+
|
|
175
|
+
run gem build "$GEMSPEC"
|
|
176
|
+
|
|
177
|
+
if [[ "$DRY_RUN" != true ]]; then
|
|
178
|
+
[[ -f "$GEM_FILE" ]] || die "Gem file not found: $GEM_FILE"
|
|
179
|
+
fi
|
|
180
|
+
success "Built ${GEM_FILE}"
|
|
181
|
+
|
|
182
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
183
|
+
# Step 8: Publish to RubyGems
|
|
184
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
185
|
+
step 8 "Publishing to RubyGems"
|
|
186
|
+
|
|
187
|
+
run gem push "$GEM_FILE"
|
|
188
|
+
success "Published to RubyGems"
|
|
189
|
+
|
|
190
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
191
|
+
# Step 9: Git tag
|
|
192
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
193
|
+
step 9 "Creating git tag v${VERSION}"
|
|
194
|
+
|
|
195
|
+
run git tag "v${VERSION}"
|
|
196
|
+
run git push origin --tags
|
|
197
|
+
success "Tag v${VERSION} pushed"
|
|
198
|
+
|
|
199
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
200
|
+
# Step 10: GitHub Release
|
|
201
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
202
|
+
step 10 "Creating GitHub Release"
|
|
203
|
+
|
|
204
|
+
RELEASE_NOTES_FILE="/tmp/release_notes_${VERSION}.md"
|
|
205
|
+
|
|
206
|
+
if [[ "$DRY_RUN" != true ]]; then
|
|
207
|
+
if [[ -f "$CHANGELOG" ]]; then
|
|
208
|
+
# Extract section for this version from CHANGELOG
|
|
209
|
+
awk "/^## \\[${VERSION}\\]/{found=1; next} /^## \\[/{if(found) exit} found{print}" "$CHANGELOG" > "$RELEASE_NOTES_FILE"
|
|
210
|
+
if [[ ! -s "$RELEASE_NOTES_FILE" ]]; then
|
|
211
|
+
echo "Release v${VERSION}" > "$RELEASE_NOTES_FILE"
|
|
212
|
+
warn "No CHANGELOG entry found for ${VERSION} — using placeholder"
|
|
213
|
+
fi
|
|
214
|
+
else
|
|
215
|
+
echo "Release v${VERSION}" > "$RELEASE_NOTES_FILE"
|
|
216
|
+
warn "CHANGELOG.md not found — using placeholder"
|
|
217
|
+
fi
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
if [[ "$PRERELEASE" == true ]]; then
|
|
221
|
+
run gh release create "v${VERSION}" \
|
|
222
|
+
--title "v${VERSION}" \
|
|
223
|
+
--notes-file "$RELEASE_NOTES_FILE" \
|
|
224
|
+
--prerelease \
|
|
225
|
+
"$GEM_FILE"
|
|
226
|
+
else
|
|
227
|
+
run gh release create "v${VERSION}" \
|
|
228
|
+
--title "v${VERSION}" \
|
|
229
|
+
--notes-file "$RELEASE_NOTES_FILE" \
|
|
230
|
+
--latest \
|
|
231
|
+
"$GEM_FILE"
|
|
232
|
+
fi
|
|
233
|
+
success "GitHub Release created"
|
|
234
|
+
|
|
235
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
236
|
+
# Step 11: Upload to OSS CDN
|
|
237
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
238
|
+
step 11 "Syncing to Tencent Cloud OSS"
|
|
239
|
+
|
|
240
|
+
run coscli cp "$GEM_FILE" "${OSS_BUCKET}/octo/${GEM_FILE}"
|
|
241
|
+
success "Uploaded ${GEM_FILE} to OSS"
|
|
242
|
+
|
|
243
|
+
if [[ "$UPDATE_LATEST" == true ]]; then
|
|
244
|
+
if [[ "$DRY_RUN" != true ]]; then
|
|
245
|
+
echo "${VERSION}" > /tmp/latest.txt
|
|
246
|
+
fi
|
|
247
|
+
run coscli cp /tmp/latest.txt "${OSS_BUCKET}/octo/latest.txt"
|
|
248
|
+
success "Updated latest.txt → ${VERSION}"
|
|
249
|
+
|
|
250
|
+
if [[ "$DRY_RUN" != true ]]; then
|
|
251
|
+
VERIFY=$(curl -fsSL https://oss.1024code.com/octo/latest.txt 2>/dev/null || echo "FAILED")
|
|
252
|
+
if [[ "$VERIFY" == "$VERSION" ]]; then
|
|
253
|
+
success "Verified latest.txt = ${VERSION}"
|
|
254
|
+
else
|
|
255
|
+
warn "latest.txt verification returned: ${VERIFY}"
|
|
256
|
+
fi
|
|
257
|
+
fi
|
|
258
|
+
else
|
|
259
|
+
info "Skipping latest.txt update (pre-release or not requested)"
|
|
260
|
+
fi
|
|
261
|
+
|
|
262
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
263
|
+
# Step 12: Sync scripts to OSS
|
|
264
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
265
|
+
step 12 "Rebuilding and syncing scripts to OSS"
|
|
266
|
+
|
|
267
|
+
run bash scripts/build/build.sh
|
|
268
|
+
|
|
269
|
+
if [[ "$DRY_RUN" != true ]]; then
|
|
270
|
+
for script in scripts/*.sh scripts/*.ps1; do
|
|
271
|
+
[[ -f "$script" ]] || continue
|
|
272
|
+
coscli cp "$script" "${OSS_BUCKET}/octo-ai/octo/main/scripts/$(basename "$script")"
|
|
273
|
+
success "Uploaded $(basename "$script")"
|
|
274
|
+
done
|
|
275
|
+
else
|
|
276
|
+
echo -e " ${YELLOW}[dry-run]${NC} Upload scripts/*.sh and scripts/*.ps1 to OSS"
|
|
277
|
+
fi
|
|
278
|
+
success "Scripts synced to OSS"
|
|
279
|
+
|
|
280
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
281
|
+
# Step 13: Cleanup
|
|
282
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
283
|
+
step 13 "Cleanup"
|
|
284
|
+
|
|
285
|
+
[[ -f "$GEM_FILE" ]] && rm -f "$GEM_FILE" && info "Removed ${GEM_FILE}"
|
|
286
|
+
[[ -f "$RELEASE_NOTES_FILE" ]] && rm -f "$RELEASE_NOTES_FILE"
|
|
287
|
+
[[ -f "/tmp/latest.txt" ]] && rm -f /tmp/latest.txt
|
|
288
|
+
|
|
289
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
290
|
+
# Done
|
|
291
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
292
|
+
echo ""
|
|
293
|
+
echo "╔═══════════════════════════════════════════════════════════╗"
|
|
294
|
+
echo "║ ║"
|
|
295
|
+
echo -e "║ ${GREEN}🎉 v${VERSION} released successfully!${NC} ║"
|
|
296
|
+
echo "║ ║"
|
|
297
|
+
echo "╠═══════════════════════════════════════════════════════════╣"
|
|
298
|
+
echo "║ ║"
|
|
299
|
+
echo "║ 📦 RubyGems: rubygems.org/gems/octo ║"
|
|
300
|
+
echo "║ 🏷️ GitHub: github.com/octo-ai/octo/releases ║"
|
|
301
|
+
echo "║ ☁️ OSS CDN: oss.1024code.com/octo/ ║"
|
|
302
|
+
echo "║ ║"
|
|
303
|
+
echo "╚═══════════════════════════════════════════════════════════╝"
|
|
304
|
+
echo ""
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: oss-upload
|
|
3
|
+
description: Upload local files to Tencent COS (oss.1024code.com CDN) using coscli. Use when user wants to upload a file to CDN/OSS, or deploy static assets.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# OSS Upload Skill
|
|
7
|
+
|
|
8
|
+
Upload files to Tencent COS bucket `octoai-1258723534`, served via `https://oss.1024code.com`.
|
|
9
|
+
|
|
10
|
+
## Tool
|
|
11
|
+
`coscli` — config at `~/.cos.yaml`
|
|
12
|
+
|
|
13
|
+
## Bucket Info
|
|
14
|
+
- Bucket: `octoai-1258723534`
|
|
15
|
+
- Region: `ap-guangzhou`
|
|
16
|
+
- Endpoint: `cos.ap-guangzhou.myqcloud.com`
|
|
17
|
+
- Public CDN: `https://oss.1024code.com/<path>`
|
|
18
|
+
|
|
19
|
+
## Upload Command
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
coscli cp <local-file> cos://octoai-1258723534/<remote-path>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Examples
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Upload a single file to bucket root
|
|
29
|
+
coscli cp /tmp/wsl.2.6.3.0.arm64.msi cos://octoai-1258723534/wsl.2.6.3.0.arm64.msi
|
|
30
|
+
|
|
31
|
+
# Upload to a subdirectory
|
|
32
|
+
coscli cp /tmp/install.ps1 cos://octoai-1258723534/octo-ai/octo/main/scripts/install.ps1
|
|
33
|
+
|
|
34
|
+
# Upload entire directory recursively
|
|
35
|
+
coscli cp /tmp/dist/ cos://octoai-1258723534/dist/ -r
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Public URL
|
|
39
|
+
After upload, the file is accessible at:
|
|
40
|
+
```
|
|
41
|
+
https://oss.1024code.com/<remote-path>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Steps
|
|
45
|
+
1. Confirm local file exists
|
|
46
|
+
2. Run `coscli cp <local> cos://octoai-1258723534/<path>`
|
|
47
|
+
3. Return the public URL: `https://oss.1024code.com/<path>`
|
data/.octorules
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Octo Project Rules (.octorules)
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
This is the `octo` Ruby gem - an AI agent with three equal interfaces (CLI, Web UI, IM bridges) for interacting with AI models (Claude, OpenAI, DeepSeek, Bedrock, etc.).
|
|
5
|
+
It speaks three native API protocols — Anthropic Messages, OpenAI (Chat Completions + Responses), and AWS Bedrock — dispatched per-model in `lib/octo/providers.rb`. It provides chat functionality and autonomous AI agent capabilities with tool use.
|
|
6
|
+
|
|
7
|
+
## Project Structure
|
|
8
|
+
- `lib/octo/` - Main gem source code
|
|
9
|
+
- `cli.rb` - Command-line interface using Thor
|
|
10
|
+
- `agent.rb` - Core AI agent with tool execution
|
|
11
|
+
- `tools/` - Built-in tools (file operations, web search, shell, etc.)
|
|
12
|
+
- `client.rb` - API client for AI models
|
|
13
|
+
- `config.rb` - Configuration management
|
|
14
|
+
- `bin/` - Development executables
|
|
15
|
+
- `spec/` - RSpec test suite
|
|
16
|
+
- `octo.gemspec` - Gem specification
|
|
17
|
+
|
|
18
|
+
## Development Guidelines
|
|
19
|
+
|
|
20
|
+
### Code Style
|
|
21
|
+
- Follow Ruby conventions and best practices
|
|
22
|
+
- Use frozen string literals: `# frozen_string_literal: true`
|
|
23
|
+
- Keep classes focused and single-responsibility
|
|
24
|
+
- Use meaningful variable and method names
|
|
25
|
+
- **IMPORTANT**: All code comments must be written in English
|
|
26
|
+
- Add descriptive comments for complex logic
|
|
27
|
+
- Use clear, self-documenting code with English naming
|
|
28
|
+
- **IMPORTANT**: Always use inline `private` with instance method definitions (e.g., `private def method_name`). Do NOT use standalone `private` keyword
|
|
29
|
+
- **IMPORTANT**: For class methods (`def self.method_name`), do NOT use `private`. Class methods should be public
|
|
30
|
+
|
|
31
|
+
### Architecture Patterns
|
|
32
|
+
- Tools inherit from `Octo::Tools::Base`
|
|
33
|
+
- Each tool defines: `tool_name`, `tool_description`, `tool_category`, `tool_parameters`
|
|
34
|
+
- Agent uses React pattern (Reason-Act-Observe) for task execution
|
|
35
|
+
- Configuration is managed through `Octo::Config`
|
|
36
|
+
- CLI commands use Thor framework
|
|
37
|
+
|
|
38
|
+
### Testing
|
|
39
|
+
- Use RSpec for testing
|
|
40
|
+
- Test files in `spec/` directory
|
|
41
|
+
- **IMPORTANT**: Always run `bundle exec rspec` to verify tests pass after making changes
|
|
42
|
+
- All tests must pass before considering a task complete
|
|
43
|
+
- Maintain good test coverage
|
|
44
|
+
- When modifying existing functionality, ensure related tests still pass
|
|
45
|
+
- When adding new features, consider adding corresponding tests
|
|
46
|
+
- **IMPORTANT**: When developing new features, write RSpec tests as needed and ensure they pass
|
|
47
|
+
- **DO NOT** write custom test scripts unless explicitly requested by the user
|
|
48
|
+
- **DO NOT** create markdown documentation unless explicitly requested by the user
|
|
49
|
+
- **IMPORTANT**: When testing octo commands or debugging, always use `bundle exec ruby bin/octo` instead of the global `octo` command. The global command loads the system-installed gem version (e.g., `openocto-0.7.0`), not your local development code
|
|
50
|
+
|
|
51
|
+
### Tool Development
|
|
52
|
+
**IMPORTANT**: Do NOT add new Ruby Tool classes without careful consideration. Tools are low-level primitives (file I/O, shell, web search, etc.). Before creating a new Tool, always ask: can this capability be achieved with an existing Tool + a Skill (SKILL.md) instead? If yes, use a Skill.
|
|
53
|
+
|
|
54
|
+
Only add a new Tool when it requires capabilities that no existing tool can provide (e.g., a new API integration, a new system-level operation).
|
|
55
|
+
|
|
56
|
+
When a new Tool is truly necessary:
|
|
57
|
+
1. Create class in `lib/octo/tools/`
|
|
58
|
+
2. Inherit from `Octo::Tools::Base`
|
|
59
|
+
3. Define required class attributes
|
|
60
|
+
4. Implement `execute` method
|
|
61
|
+
5. Add optional `format_call` and `format_result` methods
|
|
62
|
+
6. Require in `lib/octo.rb`
|
|
63
|
+
|
|
64
|
+
### Skill Development
|
|
65
|
+
Skills are the preferred way to add new high-level capabilities. A skill is a Markdown instruction file (SKILL.md) that guides the Agent to accomplish a goal using existing Tools.
|
|
66
|
+
|
|
67
|
+
- Built-in default skills live in `lib/octo/default_skills/<skill-name>/SKILL.md` (shipped with the gem)
|
|
68
|
+
- Project-level skills live in `.octo/skills/<skill-name>/SKILL.md`
|
|
69
|
+
- User-level skills live in `~/.octo/skills/<skill-name>/SKILL.md`
|
|
70
|
+
- **Prefer Skills over new Tools** whenever the task can be composed from existing primitives (write, shell, read, etc.)
|
|
71
|
+
|
|
72
|
+
### Agent Behavior
|
|
73
|
+
- TODO manager is for planning only - must execute tasks after planning
|
|
74
|
+
- Always use tools to create/modify files, don't just return code
|
|
75
|
+
- Maintain conversation context across tasks
|
|
76
|
+
- Follow cost and iteration limits
|
|
77
|
+
- Support different permission modes (confirm_all, confirm_edits, auto_approve, plan_only)
|
|
78
|
+
|
|
79
|
+
## Dependencies
|
|
80
|
+
- Ruby >= 3.1.0
|
|
81
|
+
- faraday (~> 2.0) - HTTP client
|
|
82
|
+
- thor (~> 1.3) - CLI framework
|
|
83
|
+
- tty-prompt (~> 0.23) - Interactive prompts
|
|
84
|
+
- tty-spinner (~> 0.9) - Progress indicators
|
|
85
|
+
- diffy (~> 3.4) - Text diffs
|
|
86
|
+
|
|
87
|
+
## Important Notes
|
|
88
|
+
- This gem speaks Anthropic Messages, OpenAI (Chat Completions + Responses), and AWS Bedrock natively; provider-to-protocol mapping lives in `lib/octo/providers.rb` and message-format adapters in `lib/octo/message_format/`
|
|
89
|
+
- Security features include safe shell execution and path validation
|
|
90
|
+
- Agent includes cost control and message compression features
|
|
91
|
+
- Built-in tools cover file operations, web search, code execution, and project management
|
|
92
|
+
|
|
93
|
+
## Execution Binary
|
|
94
|
+
- Development: `bin/octo` (in repository)
|
|
95
|
+
- Installed gem: `octo` command globally available
|
|
96
|
+
|
|
97
|
+
## Configuration
|
|
98
|
+
- Stores API keys and settings in user's home directory
|
|
99
|
+
- Supports multiple AI model providers
|
|
100
|
+
- Configurable through `octo config set` command
|
|
101
|
+
|
|
102
|
+
## Personal Rules
|
|
103
|
+
1. 先想清楚,再动手 — 不确定就问,千万别猜。AI 最可怕的不是不会写,而是"自信乱写"。
|
|
104
|
+
2. 能简单,就别复杂 — 只写刚好够用的代码。过度抽象,大多数时候都是技术负债。
|
|
105
|
+
3. 外科手术式修改 — 需求没提到的地方,一行别碰。每次改动,都必须说得清理由。
|
|
106
|
+
4. 先定义"成功" — 写代码前,先明确什么叫"完成"。否则 AI 只是在随机输出。
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
This project is a hard fork of [clacky-ai/openclacky](https://github.com/clacky-ai/openclacky) at upstream **1.1.6**, renumbered as **0.10.0** in this fork's own SemVer line. Only changes made in this fork (0.11.x and later) are tracked here. For history prior to the fork, see the upstream repository.
|
|
9
|
+
|
|
10
|
+
## [0.11.2] - 2026-05-25
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Web UI: Skills panel (`/#skills`) could not scroll when the list of skill cards exceeded viewport height. Changed `#skills-body` from `overflow: hidden` to `overflow-y: auto` to match the Channels and Trash panels.
|
|
14
|
+
- Documentation: corrected Web UI port references from `7070` to `8888` in `what-is-octo.md` and `faq.md`.
|
|
15
|
+
- Documentation: fixed gem install commands from `gem install octo` to `gem install octo-agent` in `installation.md` and `windows-installation.md`.
|
|
16
|
+
- Documentation: updated CLI reference to include `--no-caching` and `--no-skill-evolution` flags.
|
|
17
|
+
- Documentation: removed stale `deploy` skill reference from `writing-tips.md`.
|
|
18
|
+
- `product-help` skill: fixed a Ruby rescue bug where `Gem::MissingSpecError` (inherits from `ScriptError`, not `StandardError`) caused the `rescue` modifier to fail when running from source. Switched to `begin/rescue Exception` with `Dir.pwd` fallback.
|
|
19
|
+
|
|
20
|
+
## [0.11.1] - 2026-05-25
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- Web UI: show a unified diff for the `edit` tool inline in its tool card
|
|
24
|
+
- Agent: take a checkpoint snapshot right after `think()` so the Time Machine has a clean pre-tool-use anchor
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- Web UI: a `diff` event emitted during `show_tool_preview` (before the matching `tool_call`) used to overwrite the previous tool card's stdout — typically a `read` card — making `Read(...)` look like it rendered a diff. The diff is now buffered until its owning `tool_call` creates the correct card.
|
|
28
|
+
- Web UI: tool card rendering, terminal error display, and todo progress consistency
|
|
29
|
+
- Web UI: keep tool groups expanded by default
|
|
30
|
+
- Terminal tool: pass `handle_id` into the `run_sync` polling loop so the right task is observed
|
|
31
|
+
- Terminal tool: drop the circular `max_duration` default that broke `bundle exec` startup on Ruby 3.3
|
|
32
|
+
- Providers: remove fake `octo` / `octoai-sea` provider stubs and update test fixtures accordingly
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
- Renamed the gem from `octo` to `octo-agent` (the `octo` name is already taken on RubyGems by an unrelated project). Repository, author, and email metadata updated to the Leihb fork.
|
|
36
|
+
- Attributed the upstream `clacky-ai/openclacky` project in `LICENSE.txt` (stacked copyright) and in both READMEs (fork notice under the language switcher).
|
|
37
|
+
- Documentation: README, `.octorules`, and gemspec description aligned around the "three interfaces (CLI / Web / IM), three native protocols (Anthropic Messages / OpenAI / AWS Bedrock)" framing.
|
|
38
|
+
|
|
39
|
+
### Removed
|
|
40
|
+
- Stopped tracking accidentally-committed gem-unpack artifacts (`data.tar.gz`, `metadata.gz`, `checksums.yaml.gz`); added anchored `.gitignore` entries so `gem unpack` at the repo root will not re-pollute the tree.
|
|
41
|
+
|
|
42
|
+
## [0.11.0] - 2026-05-25
|
|
43
|
+
|
|
44
|
+
First release of this fork. The hard fork happened because of philosophical disagreements with upstream over how the agent should treat human-in-the-loop interactions and long-running work; the three "headline" features below are the concrete expression of that disagreement and the reason this fork exists as a separate project. The rest of the release is rebranding and excising upstream subsystems that don't fit a non-commercial, single-brand tool.
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
- **Non-interrupting message inbox.** New user messages that arrive while the agent is mid-run land in a per-session inbox (`@inbox` in `agent.rb`) and are drained at the top of the next iteration, instead of preempting the in-flight tool call. This keeps tool execution atomic and ends the "user types a follow-up and the model loses its current goal" failure mode.
|
|
48
|
+
- **Next-message suggestion (ghost text).** After each agent turn, the agent emits a suggested next user prompt rendered as the textarea placeholder; pressing Tab on an empty input accepts it. Bias is toward "what would a power user type now?", not toward chatty continuation.
|
|
49
|
+
- **Background task notifications subsystem.** Long-running terminal tasks can be launched as background jobs; the agent is notified by the registry when they finish and resumes the conversation with the result, rather than blocking the run loop while a build/test/deploy executes.
|
|
50
|
+
- Command history for both CLI and Web UI
|
|
51
|
+
- `dedup_key` on background-terminal tasks to prevent the agent from spawning duplicates
|
|
52
|
+
- Customizable cancel reason for background tasks
|
|
53
|
+
- System-prompt guidance pushing the agent to STOP after starting an async task, and to refine async-task behavior (stop when blocked, continue when independent)
|
|
54
|
+
- Forceful anti-polling instruction in the terminal "still-running" status prompt
|
|
55
|
+
- Octo logo, channels panel styles, and other first-party visual assets to replace removed brand assets
|
|
56
|
+
|
|
57
|
+
### Fixed
|
|
58
|
+
- Anthropic thinking blocks now correctly extracted as `reasoning_content`
|
|
59
|
+
- `reasoning_content` converted to Anthropic thinking blocks when emitted through third-party endpoints, so the round-trip is lossless
|
|
60
|
+
- `bin/octo` entry point, banner methods, and lingering `{{BRAND_NAME}}` placeholders after rebrand
|
|
61
|
+
- Terminal tool: `__CLACKY_DONE__` marker renamed to `__OCTO_DONE__`
|
|
62
|
+
- Web UI: user image upload showing `[object Object]` and Analyzing-indicator ordering
|
|
63
|
+
- Web UI: shared CSS that was accidentally removed during the brand/creator cleanup restored
|
|
64
|
+
- CLI: logo typo corrected from `OOTO` to `OCTO`
|
|
65
|
+
- Server: broadcast the background-task count immediately after a terminal kill so badges stay in sync
|
|
66
|
+
- Test suite: resolved pre-existing RSpec failures in terminal and input-area specs
|
|
67
|
+
|
|
68
|
+
### Removed
|
|
69
|
+
- Upstream `openclacky` provider (replaced wholesale with the `octo` provider)
|
|
70
|
+
- Brand module and creator hub (this fork is not a commercial / multi-brand product)
|
|
71
|
+
- Billing module and the dead frontend code that fed it
|
|
72
|
+
- Cost-tracking pipeline (token-usage display in the UI is preserved)
|
|
73
|
+
|
|
74
|
+
## [0.10.0] - upstream baseline
|
|
75
|
+
|
|
76
|
+
Hard-fork point. This version corresponds to `clacky-ai/openclacky` at upstream **1.1.6**, renumbered to 0.10.0 to start a clean SemVer line in this fork. No changes from this project are included in 0.10.0; see the upstream repository for prior history.
|