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.
Files changed (319) hide show
  1. checksums.yaml +7 -0
  2. data/.clacky/skills/commit/SKILL.md +423 -0
  3. data/.clacky/skills/gem-release/SKILL.md +199 -0
  4. data/.clacky/skills/gem-release/scripts/release.sh +304 -0
  5. data/.clacky/skills/oss-upload/SKILL.md +47 -0
  6. data/.octorules +106 -0
  7. data/.rspec +3 -0
  8. data/.rubocop.yml +8 -0
  9. data/CHANGELOG.md +76 -0
  10. data/CODE_OF_CONDUCT.md +132 -0
  11. data/CONTRIBUTING.md +92 -0
  12. data/Dockerfile +28 -0
  13. data/LICENSE.txt +22 -0
  14. data/POSITIONING.md +46 -0
  15. data/README.md +134 -0
  16. data/README_CN.md +134 -0
  17. data/Rakefile +34 -0
  18. data/benchmark/fixtures/sample_project/Gemfile +3 -0
  19. data/benchmark/fixtures/sample_project/lib/api_handler.rb +32 -0
  20. data/benchmark/fixtures/sample_project/lib/order_calculator.rb +23 -0
  21. data/benchmark/fixtures/sample_project/lib/user_renderer.rb +20 -0
  22. data/benchmark/fixtures/sample_project/spec/order_calculator_spec.rb +20 -0
  23. data/benchmark/results/EVALUATION_REPORT.md +165 -0
  24. data/benchmark/results/baseline_20260511_174424.json +128 -0
  25. data/benchmark/results/report_20260511_175256.json +271 -0
  26. data/benchmark/results/report_20260511_175444.json +271 -0
  27. data/benchmark/results/treatment_20260511_175103.json +130 -0
  28. data/benchmark/runner.rb +441 -0
  29. data/bin/octo +7 -0
  30. data/docs/agent-first-ui-design.md +77 -0
  31. data/docs/billing-system.md +318 -0
  32. data/docs/channel-architecture.md +235 -0
  33. data/docs/engineering-article.md +343 -0
  34. data/docs/session-skill-invocation.md +69 -0
  35. data/docs/time_machine_design.md +247 -0
  36. data/docs/ui2-architecture.md +124 -0
  37. data/homebrew/README.md +96 -0
  38. data/homebrew/openocto.rb +24 -0
  39. data/lib/octo/agent/hook_manager.rb +61 -0
  40. data/lib/octo/agent/llm_caller.rb +800 -0
  41. data/lib/octo/agent/memory_updater.rb +246 -0
  42. data/lib/octo/agent/message_compressor.rb +225 -0
  43. data/lib/octo/agent/message_compressor_helper.rb +869 -0
  44. data/lib/octo/agent/next_message_suggester.rb +215 -0
  45. data/lib/octo/agent/session_serializer.rb +685 -0
  46. data/lib/octo/agent/skill_auto_creator.rb +114 -0
  47. data/lib/octo/agent/skill_evolution.rb +61 -0
  48. data/lib/octo/agent/skill_manager.rb +466 -0
  49. data/lib/octo/agent/skill_reflector.rb +89 -0
  50. data/lib/octo/agent/system_prompt_builder.rb +101 -0
  51. data/lib/octo/agent/time_machine.rb +214 -0
  52. data/lib/octo/agent/tool_executor.rb +454 -0
  53. data/lib/octo/agent/tool_registry.rb +150 -0
  54. data/lib/octo/agent.rb +2180 -0
  55. data/lib/octo/agent_config.rb +989 -0
  56. data/lib/octo/agent_profile.rb +112 -0
  57. data/lib/octo/anthropic_stream_aggregator.rb +137 -0
  58. data/lib/octo/background_task_registry.rb +324 -0
  59. data/lib/octo/banner.rb +34 -0
  60. data/lib/octo/bedrock_stream_aggregator.rb +137 -0
  61. data/lib/octo/block_font.rb +331 -0
  62. data/lib/octo/cli.rb +968 -0
  63. data/lib/octo/client.rb +623 -0
  64. data/lib/octo/default_agents/SOUL.md +3 -0
  65. data/lib/octo/default_agents/USER.md +1 -0
  66. data/lib/octo/default_agents/base_prompt.md +66 -0
  67. data/lib/octo/default_agents/coding/profile.yml +2 -0
  68. data/lib/octo/default_agents/coding/system_prompt.md +67 -0
  69. data/lib/octo/default_agents/general/profile.yml +2 -0
  70. data/lib/octo/default_agents/general/system_prompt.md +16 -0
  71. data/lib/octo/default_parsers/doc_parser.rb +69 -0
  72. data/lib/octo/default_parsers/docx_parser.rb +188 -0
  73. data/lib/octo/default_parsers/pdf_parser.rb +120 -0
  74. data/lib/octo/default_parsers/pdf_parser_ocr.py +103 -0
  75. data/lib/octo/default_parsers/pdf_parser_plumber.py +62 -0
  76. data/lib/octo/default_parsers/pptx_parser.rb +140 -0
  77. data/lib/octo/default_parsers/xlsx_parser.rb +121 -0
  78. data/lib/octo/default_skills/browser-setup/SKILL.md +426 -0
  79. data/lib/octo/default_skills/channel-manager/SKILL.md +623 -0
  80. data/lib/octo/default_skills/channel-manager/dingtalk_setup.rb +191 -0
  81. data/lib/octo/default_skills/channel-manager/discord_setup.rb +199 -0
  82. data/lib/octo/default_skills/channel-manager/feishu_setup.rb +574 -0
  83. data/lib/octo/default_skills/channel-manager/import_lark_skills.rb +97 -0
  84. data/lib/octo/default_skills/channel-manager/install_feishu_skills.rb +105 -0
  85. data/lib/octo/default_skills/channel-manager/weixin_setup.rb +274 -0
  86. data/lib/octo/default_skills/code-explorer/SKILL.md +36 -0
  87. data/lib/octo/default_skills/cron-task-creator/SKILL.md +257 -0
  88. data/lib/octo/default_skills/cron-task-creator/evals/evals.json +38 -0
  89. data/lib/octo/default_skills/onboard/SKILL.md +578 -0
  90. data/lib/octo/default_skills/onboard/scripts/import_external_skills.rb +413 -0
  91. data/lib/octo/default_skills/onboard/scripts/install_builtin_skills.rb +97 -0
  92. data/lib/octo/default_skills/persist-memory/SKILL.md +59 -0
  93. data/lib/octo/default_skills/personal-website/SKILL.md +113 -0
  94. data/lib/octo/default_skills/personal-website/publish.rb +235 -0
  95. data/lib/octo/default_skills/product-help/SKILL.md +123 -0
  96. data/lib/octo/default_skills/product-help/docs/agent-config.md +74 -0
  97. data/lib/octo/default_skills/product-help/docs/best-practices.md +49 -0
  98. data/lib/octo/default_skills/product-help/docs/browser-tool.md +53 -0
  99. data/lib/octo/default_skills/product-help/docs/built-in-skills.md +43 -0
  100. data/lib/octo/default_skills/product-help/docs/cli-reference.md +82 -0
  101. data/lib/octo/default_skills/product-help/docs/create-your-first-skill.md +47 -0
  102. data/lib/octo/default_skills/product-help/docs/faq.md +98 -0
  103. data/lib/octo/default_skills/product-help/docs/how-to-use-a-skill.md +58 -0
  104. data/lib/octo/default_skills/product-help/docs/installation.md +59 -0
  105. data/lib/octo/default_skills/product-help/docs/memory-system.md +61 -0
  106. data/lib/octo/default_skills/product-help/docs/octorules.md +62 -0
  107. data/lib/octo/default_skills/product-help/docs/session-management.md +63 -0
  108. data/lib/octo/default_skills/product-help/docs/skill-basics.md +55 -0
  109. data/lib/octo/default_skills/product-help/docs/skill-frontmatter.md +61 -0
  110. data/lib/octo/default_skills/product-help/docs/web-server.md +49 -0
  111. data/lib/octo/default_skills/product-help/docs/what-is-octo.md +37 -0
  112. data/lib/octo/default_skills/product-help/docs/windows-installation.md +36 -0
  113. data/lib/octo/default_skills/product-help/docs/writing-tips.md +53 -0
  114. data/lib/octo/default_skills/recall-memory/SKILL.md +65 -0
  115. data/lib/octo/default_skills/skill-add/SKILL.md +59 -0
  116. data/lib/octo/default_skills/skill-add/scripts/install_from_zip.rb +295 -0
  117. data/lib/octo/default_skills/skill-creator/SKILL.md +602 -0
  118. data/lib/octo/default_skills/skill-creator/agents/analyzer.md +274 -0
  119. data/lib/octo/default_skills/skill-creator/agents/comparator.md +202 -0
  120. data/lib/octo/default_skills/skill-creator/agents/grader.md +223 -0
  121. data/lib/octo/default_skills/skill-creator/eval-viewer/generate_review.py +471 -0
  122. data/lib/octo/default_skills/skill-creator/eval-viewer/viewer.html +1325 -0
  123. data/lib/octo/default_skills/skill-creator/references/schemas.md +430 -0
  124. data/lib/octo/default_skills/skill-creator/scripts/__init__.py +0 -0
  125. data/lib/octo/default_skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  126. data/lib/octo/default_skills/skill-creator/scripts/generate_report.py +326 -0
  127. data/lib/octo/default_skills/skill-creator/scripts/improve_description.py +310 -0
  128. data/lib/octo/default_skills/skill-creator/scripts/quick_validate.py +103 -0
  129. data/lib/octo/default_skills/skill-creator/scripts/run_eval.py +317 -0
  130. data/lib/octo/default_skills/skill-creator/scripts/run_loop.py +331 -0
  131. data/lib/octo/default_skills/skill-creator/scripts/utils.py +47 -0
  132. data/lib/octo/default_skills/skill-creator/scripts/validate_skill_frontmatter.rb +143 -0
  133. data/lib/octo/idle_compression_timer.rb +115 -0
  134. data/lib/octo/json_ui_controller.rb +204 -0
  135. data/lib/octo/message_format/anthropic.rb +409 -0
  136. data/lib/octo/message_format/bedrock.rb +361 -0
  137. data/lib/octo/message_format/open_ai.rb +222 -0
  138. data/lib/octo/message_history.rb +373 -0
  139. data/lib/octo/openai_stream_aggregator.rb +130 -0
  140. data/lib/octo/plain_ui_controller.rb +166 -0
  141. data/lib/octo/providers.rb +534 -0
  142. data/lib/octo/server/browser_manager.rb +397 -0
  143. data/lib/octo/server/channel/adapters/base.rb +82 -0
  144. data/lib/octo/server/channel/adapters/dingtalk/adapter.rb +314 -0
  145. data/lib/octo/server/channel/adapters/dingtalk/api_client.rb +391 -0
  146. data/lib/octo/server/channel/adapters/dingtalk/stream_client.rb +203 -0
  147. data/lib/octo/server/channel/adapters/discord/adapter.rb +229 -0
  148. data/lib/octo/server/channel/adapters/discord/api_client.rb +107 -0
  149. data/lib/octo/server/channel/adapters/discord/gateway_client.rb +270 -0
  150. data/lib/octo/server/channel/adapters/feishu/adapter.rb +320 -0
  151. data/lib/octo/server/channel/adapters/feishu/bot.rb +478 -0
  152. data/lib/octo/server/channel/adapters/feishu/file_processor.rb +36 -0
  153. data/lib/octo/server/channel/adapters/feishu/message_parser.rb +129 -0
  154. data/lib/octo/server/channel/adapters/feishu/ws_client.rb +423 -0
  155. data/lib/octo/server/channel/adapters/telegram/adapter.rb +375 -0
  156. data/lib/octo/server/channel/adapters/telegram/api_client.rb +205 -0
  157. data/lib/octo/server/channel/adapters/wecom/adapter.rb +148 -0
  158. data/lib/octo/server/channel/adapters/wecom/media_downloader.rb +115 -0
  159. data/lib/octo/server/channel/adapters/wecom/ws_client.rb +395 -0
  160. data/lib/octo/server/channel/adapters/weixin/adapter.rb +692 -0
  161. data/lib/octo/server/channel/adapters/weixin/api_client.rb +402 -0
  162. data/lib/octo/server/channel/channel_config.rb +178 -0
  163. data/lib/octo/server/channel/channel_manager.rb +468 -0
  164. data/lib/octo/server/channel/channel_ui_controller.rb +224 -0
  165. data/lib/octo/server/channel.rb +33 -0
  166. data/lib/octo/server/discover.rb +77 -0
  167. data/lib/octo/server/epipe_safe_io.rb +105 -0
  168. data/lib/octo/server/http_server.rb +3554 -0
  169. data/lib/octo/server/scheduler.rb +317 -0
  170. data/lib/octo/server/server_master.rb +325 -0
  171. data/lib/octo/server/session_registry.rb +431 -0
  172. data/lib/octo/server/web_ui_controller.rb +487 -0
  173. data/lib/octo/session_manager.rb +385 -0
  174. data/lib/octo/skill.rb +466 -0
  175. data/lib/octo/skill_loader.rb +328 -0
  176. data/lib/octo/tools/base.rb +118 -0
  177. data/lib/octo/tools/browser.rb +625 -0
  178. data/lib/octo/tools/edit.rb +165 -0
  179. data/lib/octo/tools/file_reader.rb +549 -0
  180. data/lib/octo/tools/glob.rb +162 -0
  181. data/lib/octo/tools/grep.rb +356 -0
  182. data/lib/octo/tools/invoke_skill.rb +96 -0
  183. data/lib/octo/tools/list_tasks.rb +54 -0
  184. data/lib/octo/tools/redo_task.rb +41 -0
  185. data/lib/octo/tools/request_user_feedback.rb +84 -0
  186. data/lib/octo/tools/security.rb +333 -0
  187. data/lib/octo/tools/terminal/output_cleaner.rb +63 -0
  188. data/lib/octo/tools/terminal/persistent_session.rb +268 -0
  189. data/lib/octo/tools/terminal/safe_rm.sh +106 -0
  190. data/lib/octo/tools/terminal/session_manager.rb +213 -0
  191. data/lib/octo/tools/terminal.rb +1828 -0
  192. data/lib/octo/tools/todo_manager.rb +374 -0
  193. data/lib/octo/tools/trash_manager.rb +388 -0
  194. data/lib/octo/tools/undo_task.rb +35 -0
  195. data/lib/octo/tools/web_fetch.rb +242 -0
  196. data/lib/octo/tools/web_search.rb +260 -0
  197. data/lib/octo/tools/write.rb +77 -0
  198. data/lib/octo/ui2/block_font.rb +10 -0
  199. data/lib/octo/ui2/components/base_component.rb +163 -0
  200. data/lib/octo/ui2/components/command_suggestions.rb +290 -0
  201. data/lib/octo/ui2/components/common_component.rb +96 -0
  202. data/lib/octo/ui2/components/inline_input.rb +226 -0
  203. data/lib/octo/ui2/components/input_area.rb +1338 -0
  204. data/lib/octo/ui2/components/message_component.rb +99 -0
  205. data/lib/octo/ui2/components/modal_component.rb +419 -0
  206. data/lib/octo/ui2/components/todo_area.rb +149 -0
  207. data/lib/octo/ui2/components/tool_component.rb +107 -0
  208. data/lib/octo/ui2/components/welcome_banner.rb +139 -0
  209. data/lib/octo/ui2/layout_manager.rb +807 -0
  210. data/lib/octo/ui2/line_editor.rb +363 -0
  211. data/lib/octo/ui2/markdown_renderer.rb +100 -0
  212. data/lib/octo/ui2/output_buffer.rb +370 -0
  213. data/lib/octo/ui2/progress_handle.rb +362 -0
  214. data/lib/octo/ui2/progress_indicator.rb +55 -0
  215. data/lib/octo/ui2/screen_buffer.rb +273 -0
  216. data/lib/octo/ui2/terminal_detector.rb +119 -0
  217. data/lib/octo/ui2/theme_manager.rb +85 -0
  218. data/lib/octo/ui2/themes/base_theme.rb +105 -0
  219. data/lib/octo/ui2/themes/hacker_theme.rb +62 -0
  220. data/lib/octo/ui2/themes/minimal_theme.rb +56 -0
  221. data/lib/octo/ui2/thinking_verbs.rb +26 -0
  222. data/lib/octo/ui2/ui_controller.rb +1625 -0
  223. data/lib/octo/ui2/view_renderer.rb +177 -0
  224. data/lib/octo/ui2.rb +40 -0
  225. data/lib/octo/ui_interface.rb +154 -0
  226. data/lib/octo/utils/arguments_parser.rb +191 -0
  227. data/lib/octo/utils/browser_detector.rb +195 -0
  228. data/lib/octo/utils/encoding.rb +92 -0
  229. data/lib/octo/utils/environment_detector.rb +140 -0
  230. data/lib/octo/utils/file_ignore_helper.rb +170 -0
  231. data/lib/octo/utils/file_processor.rb +601 -0
  232. data/lib/octo/utils/gitignore_parser.rb +154 -0
  233. data/lib/octo/utils/limit_stack.rb +152 -0
  234. data/lib/octo/utils/logger.rb +124 -0
  235. data/lib/octo/utils/login_shell.rb +72 -0
  236. data/lib/octo/utils/model_pricing.rb +646 -0
  237. data/lib/octo/utils/parser_manager.rb +165 -0
  238. data/lib/octo/utils/path_helper.rb +15 -0
  239. data/lib/octo/utils/scripts_manager.rb +59 -0
  240. data/lib/octo/utils/string_matcher.rb +158 -0
  241. data/lib/octo/utils/trash_directory.rb +112 -0
  242. data/lib/octo/utils/workspace_rules.rb +46 -0
  243. data/lib/octo/version.rb +5 -0
  244. data/lib/octo/web/app.css +7141 -0
  245. data/lib/octo/web/app.js +543 -0
  246. data/lib/octo/web/apple-touch-icon.png +0 -0
  247. data/lib/octo/web/auth.js +150 -0
  248. data/lib/octo/web/channels.js +276 -0
  249. data/lib/octo/web/datepicker.js +205 -0
  250. data/lib/octo/web/favicon.png +0 -0
  251. data/lib/octo/web/i18n.js +1073 -0
  252. data/lib/octo/web/icon-512.png +0 -0
  253. data/lib/octo/web/icon-dark.svg +25 -0
  254. data/lib/octo/web/icon.svg +29 -0
  255. data/lib/octo/web/index.html +871 -0
  256. data/lib/octo/web/marked.min.js +69 -0
  257. data/lib/octo/web/onboard.js +491 -0
  258. data/lib/octo/web/profile.js +442 -0
  259. data/lib/octo/web/sessions.js +4421 -0
  260. data/lib/octo/web/settings.js +913 -0
  261. data/lib/octo/web/sidebar.js +32 -0
  262. data/lib/octo/web/skills.js +885 -0
  263. data/lib/octo/web/tasks.js +297 -0
  264. data/lib/octo/web/theme.js +105 -0
  265. data/lib/octo/web/trash.js +343 -0
  266. data/lib/octo/web/vendor/hljs/highlight.min.js +1244 -0
  267. data/lib/octo/web/vendor/hljs/hljs-theme.css +95 -0
  268. data/lib/octo/web/vendor/katex/auto-render.min.js +1 -0
  269. data/lib/octo/web/vendor/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  270. data/lib/octo/web/vendor/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  271. data/lib/octo/web/vendor/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  272. data/lib/octo/web/vendor/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  273. data/lib/octo/web/vendor/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  274. data/lib/octo/web/vendor/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
  275. data/lib/octo/web/vendor/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  276. data/lib/octo/web/vendor/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
  277. data/lib/octo/web/vendor/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
  278. data/lib/octo/web/vendor/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  279. data/lib/octo/web/vendor/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
  280. data/lib/octo/web/vendor/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  281. data/lib/octo/web/vendor/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  282. data/lib/octo/web/vendor/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  283. data/lib/octo/web/vendor/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
  284. data/lib/octo/web/vendor/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  285. data/lib/octo/web/vendor/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  286. data/lib/octo/web/vendor/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  287. data/lib/octo/web/vendor/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  288. data/lib/octo/web/vendor/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  289. data/lib/octo/web/vendor/katex/katex.min.css +1 -0
  290. data/lib/octo/web/vendor/katex/katex.min.js +1 -0
  291. data/lib/octo/web/version.js +449 -0
  292. data/lib/octo/web/weixin-qr.html +209 -0
  293. data/lib/octo/web/ws-dispatcher.js +357 -0
  294. data/lib/octo/web/ws.js +128 -0
  295. data/lib/octo.rb +145 -0
  296. data/scripts/build/build.sh +329 -0
  297. data/scripts/build/lib/apt.sh +56 -0
  298. data/scripts/build/lib/brew.sh +89 -0
  299. data/scripts/build/lib/colors.sh +17 -0
  300. data/scripts/build/lib/gem.sh +95 -0
  301. data/scripts/build/lib/mise.sh +125 -0
  302. data/scripts/build/lib/network.sh +157 -0
  303. data/scripts/build/lib/os.sh +57 -0
  304. data/scripts/build/lib/shell.sh +37 -0
  305. data/scripts/build/src/install.sh.cc +174 -0
  306. data/scripts/build/src/install_browser.sh.cc +101 -0
  307. data/scripts/build/src/install_full.sh.cc +290 -0
  308. data/scripts/build/src/install_rails_deps.sh.cc +145 -0
  309. data/scripts/build/src/install_system_deps.sh.cc +123 -0
  310. data/scripts/build/src/uninstall.sh.cc +101 -0
  311. data/scripts/install.ps1 +532 -0
  312. data/scripts/install.sh +567 -0
  313. data/scripts/install_browser.sh +479 -0
  314. data/scripts/install_full.sh +838 -0
  315. data/scripts/install_rails_deps.sh +746 -0
  316. data/scripts/install_system_deps.sh +518 -0
  317. data/scripts/uninstall.sh +287 -0
  318. data/sig/octo.rbs +4 -0
  319. 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
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,8 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.1
3
+
4
+ Style/StringLiterals:
5
+ EnforcedStyle: double_quotes
6
+
7
+ Style/StringLiteralsInInterpolation:
8
+ EnforcedStyle: double_quotes
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.