@scemoon/cdh 1.0.0

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 (528) hide show
  1. package/ai-dlc-skill/SKILL.md +75 -0
  2. package/ai-dlc-skill/agents/deliver-agent.md +24 -0
  3. package/ai-dlc-skill/agents/master.md +44 -0
  4. package/ai-dlc-skill/agents/plan-agent.md +23 -0
  5. package/ai-dlc-skill/agents/understand-agent.md +23 -0
  6. package/ai-dlc-skill/agents/verify-agent.md +27 -0
  7. package/ai-dlc-skill/architecture/project-structure.md +78 -0
  8. package/ai-dlc-skill/brownfield/README.md +30 -0
  9. package/ai-dlc-skill/brownfield/generate-context.sh +64 -0
  10. package/ai-dlc-skill/brownfield/scripts/deps.sh +27 -0
  11. package/ai-dlc-skill/brownfield/scripts/discover.sh +34 -0
  12. package/ai-dlc-skill/brownfield/scripts/extract-api.sh +45 -0
  13. package/ai-dlc-skill/components/backend.md +34 -0
  14. package/ai-dlc-skill/components/desktop.md +30 -0
  15. package/ai-dlc-skill/components/mya.md +29 -0
  16. package/ai-dlc-skill/components/native.md +30 -0
  17. package/ai-dlc-skill/components/tta.md +29 -0
  18. package/ai-dlc-skill/components/web.md +31 -0
  19. package/ai-dlc-skill/components/wxa.md +29 -0
  20. package/ai-dlc-skill/contracts/README.md +25 -0
  21. package/ai-dlc-skill/core/adaptive-flow.md +36 -0
  22. package/ai-dlc-skill/core/security.md +29 -0
  23. package/ai-dlc-skill/cross-tool/cline/export.sh +31 -0
  24. package/ai-dlc-skill/cross-tool/copilot/export.sh +47 -0
  25. package/ai-dlc-skill/cross-tool/cursor/export.sh +32 -0
  26. package/ai-dlc-skill/cross-tool/export.sh +22 -0
  27. package/ai-dlc-skill/cross-tool/onecode/config.yaml.tpl +17 -0
  28. package/ai-dlc-skill/cross-tool/onecode/export-skills.sh +31 -0
  29. package/ai-dlc-skill/cross-tool/onecode/export.sh +48 -0
  30. package/ai-dlc-skill/phases/deliver/entry.md +26 -0
  31. package/ai-dlc-skill/phases/deliver/lifecycle.md +185 -0
  32. package/ai-dlc-skill/phases/deliver/prompt.md +40 -0
  33. package/ai-dlc-skill/phases/deliver/rules.md +61 -0
  34. package/ai-dlc-skill/phases/plan/entry.md +25 -0
  35. package/ai-dlc-skill/phases/plan/lifecycle.md +204 -0
  36. package/ai-dlc-skill/phases/plan/prompt.md +38 -0
  37. package/ai-dlc-skill/phases/plan/rules.md +25 -0
  38. package/ai-dlc-skill/phases/understand/entry.md +26 -0
  39. package/ai-dlc-skill/phases/understand/lifecycle.md +184 -0
  40. package/ai-dlc-skill/phases/understand/prompt.md +41 -0
  41. package/ai-dlc-skill/phases/understand/rules.md +37 -0
  42. package/ai-dlc-skill/phases/verify/entry.md +26 -0
  43. package/ai-dlc-skill/phases/verify/lifecycle.md +192 -0
  44. package/ai-dlc-skill/phases/verify/prompt.md +43 -0
  45. package/ai-dlc-skill/phases/verify/rules.md +73 -0
  46. package/ai-dlc-skill/practices/bdd.md +91 -0
  47. package/ai-dlc-skill/practices/sdd.md +84 -0
  48. package/ai-dlc-skill/practices/tdd.md +95 -0
  49. package/ai-dlc-skill/providers/README.md +114 -0
  50. package/ai-dlc-skill/providers/aliyun/deployment.yaml +66 -0
  51. package/ai-dlc-skill/providers/aliyun/preview.yaml +84 -0
  52. package/ai-dlc-skill/providers/aliyun/provider.yaml +160 -0
  53. package/ai-dlc-skill/providers/tcb/deployment.yaml +69 -0
  54. package/ai-dlc-skill/providers/tcb/preview.yaml +83 -0
  55. package/ai-dlc-skill/providers/tcb/provider.yaml +172 -0
  56. package/ai-dlc-skill/requirements.md +140 -0
  57. package/ai-dlc-skill/skill.yaml +147 -0
  58. package/ai-dlc-skill/templates/integration/CHANGELOG.md +41 -0
  59. package/ai-dlc-skill/templates/integration/asyncapi.yaml +43 -0
  60. package/ai-dlc-skill/templates/integration/contract-diff.md +63 -0
  61. package/ai-dlc-skill/templates/integration/contract-spec.md +49 -0
  62. package/ai-dlc-skill/templates/integration/openapi.yaml +18 -0
  63. package/ai-dlc-skill/templates/integration/runtime-contract.yaml +36 -0
  64. package/ai-dlc-skill/templates/plan/design.md +49 -0
  65. package/ai-dlc-skill/templates/plan/task-list.md +32 -0
  66. package/ai-dlc-skill/templates/project/README.md +127 -0
  67. package/ai-dlc-skill/templates/project/template.md +119 -0
  68. package/ai-dlc-skill/templates/understand/feature.feature +23 -0
  69. package/ai-dlc-skill/templates/understand/intent.md +29 -0
  70. package/ai-dlc-skill/templates/understand/spec-delta.md +47 -0
  71. package/ai-dlc-skill/templates/verify/test-unit.py +27 -0
  72. package/ai-dlc-skill/walkthrough/collect.sh +50 -0
  73. package/ai-dlc-skill/walkthrough/template.md +54 -0
  74. package/ai-dlc-skill/workflows/ai-dlc.yaml +110 -0
  75. package/ai-dlc-skill/workflows/deployment.yaml +199 -0
  76. package/cdh/__init__.py +0 -0
  77. package/cdh/__main__.py +4 -0
  78. package/cdh/__pycache__/__init__.cpython-313.pyc +0 -0
  79. package/cdh/__pycache__/__init__.cpython-314.pyc +0 -0
  80. package/cdh/__pycache__/cli.cpython-314.pyc +0 -0
  81. package/cdh/__pycache__/scaffold.cpython-313.pyc +0 -0
  82. package/cdh/__pycache__/scaffold.cpython-314.pyc +0 -0
  83. package/cdh/cli.py +361 -0
  84. package/cdh/scaffold.py +312 -0
  85. package/cli.js +2 -0
  86. package/onecode/__init__.py +1 -0
  87. package/onecode/__main__.py +4 -0
  88. package/onecode/__pycache__/__init__.cpython-314.pyc +0 -0
  89. package/onecode/__pycache__/cli.cpython-314.pyc +0 -0
  90. package/onecode/__pycache__/commands.cpython-314.pyc +0 -0
  91. package/onecode/__pycache__/config.cpython-314.pyc +0 -0
  92. package/onecode/__pycache__/config_screen.cpython-314.pyc +0 -0
  93. package/onecode/__pycache__/mock_data.cpython-314.pyc +0 -0
  94. package/onecode/agent/__init__.py +0 -0
  95. package/onecode/agent/__pycache__/__init__.cpython-314.pyc +0 -0
  96. package/onecode/agent/__pycache__/cdh_agent_acp.cpython-313.pyc +0 -0
  97. package/onecode/agent/__pycache__/cdh_agent_acp.cpython-314.pyc +0 -0
  98. package/onecode/agent/__pycache__/cdh_loader.cpython-314.pyc +0 -0
  99. package/onecode/agent/__pycache__/context.cpython-314.pyc +0 -0
  100. package/onecode/agent/__pycache__/engine.cpython-314.pyc +0 -0
  101. package/onecode/agent/__pycache__/harness_skill.cpython-314.pyc +0 -0
  102. package/onecode/agent/__pycache__/hooks.cpython-314.pyc +0 -0
  103. package/onecode/agent/__pycache__/onecode_agent_acp.cpython-314.pyc +0 -0
  104. package/onecode/agent/__pycache__/permissions.cpython-314.pyc +0 -0
  105. package/onecode/agent/__pycache__/permissions_store.cpython-314.pyc +0 -0
  106. package/onecode/agent/__pycache__/session.cpython-314.pyc +0 -0
  107. package/onecode/agent/agents/__init__.py +29 -0
  108. package/onecode/agent/agents/__pycache__/__init__.cpython-314.pyc +0 -0
  109. package/onecode/agent/agents/__pycache__/types.cpython-314.pyc +0 -0
  110. package/onecode/agent/agents/types.py +662 -0
  111. package/onecode/agent/attachments.py +113 -0
  112. package/onecode/agent/cdh_loader.py +262 -0
  113. package/onecode/agent/context.py +338 -0
  114. package/onecode/agent/engine.py +1894 -0
  115. package/onecode/agent/hooks.py +86 -0
  116. package/onecode/agent/onecode_agent_acp.py +2203 -0
  117. package/onecode/agent/permissions.py +151 -0
  118. package/onecode/agent/permissions_store.py +62 -0
  119. package/onecode/agent/session.py +186 -0
  120. package/onecode/agent/snapshot.py +145 -0
  121. package/onecode/agent/tools/__init__.py +17 -0
  122. package/onecode/agent/tools/__pycache__/__init__.cpython-314.pyc +0 -0
  123. package/onecode/agent/tools/__pycache__/agent_tools.cpython-314.pyc +0 -0
  124. package/onecode/agent/tools/__pycache__/apply_patch_tool.cpython-314.pyc +0 -0
  125. package/onecode/agent/tools/__pycache__/bash_tool.cpython-314.pyc +0 -0
  126. package/onecode/agent/tools/__pycache__/communication_tools.cpython-314.pyc +0 -0
  127. package/onecode/agent/tools/__pycache__/config_tool.cpython-314.pyc +0 -0
  128. package/onecode/agent/tools/__pycache__/cron_tools.cpython-314.pyc +0 -0
  129. package/onecode/agent/tools/__pycache__/errors.cpython-314.pyc +0 -0
  130. package/onecode/agent/tools/__pycache__/file_ops.cpython-314.pyc +0 -0
  131. package/onecode/agent/tools/__pycache__/file_tools.cpython-314.pyc +0 -0
  132. package/onecode/agent/tools/__pycache__/git_tools.cpython-314.pyc +0 -0
  133. package/onecode/agent/tools/__pycache__/lsp_tools.cpython-314.pyc +0 -0
  134. package/onecode/agent/tools/__pycache__/mcp_tools.cpython-314.pyc +0 -0
  135. package/onecode/agent/tools/__pycache__/permission_handler.cpython-314.pyc +0 -0
  136. package/onecode/agent/tools/__pycache__/permissions.cpython-314.pyc +0 -0
  137. package/onecode/agent/tools/__pycache__/protocol.cpython-314.pyc +0 -0
  138. package/onecode/agent/tools/__pycache__/registry.cpython-314.pyc +0 -0
  139. package/onecode/agent/tools/__pycache__/sandbox.cpython-314.pyc +0 -0
  140. package/onecode/agent/tools/__pycache__/schema_validation.cpython-314.pyc +0 -0
  141. package/onecode/agent/tools/__pycache__/skill_tools.cpython-314.pyc +0 -0
  142. package/onecode/agent/tools/__pycache__/task_tools.cpython-314.pyc +0 -0
  143. package/onecode/agent/tools/__pycache__/web_tools.cpython-314.pyc +0 -0
  144. package/onecode/agent/tools/agent_tools.py +134 -0
  145. package/onecode/agent/tools/apply_patch_tool.py +144 -0
  146. package/onecode/agent/tools/bash_tool.py +91 -0
  147. package/onecode/agent/tools/communication_tools.py +149 -0
  148. package/onecode/agent/tools/config_tool.py +130 -0
  149. package/onecode/agent/tools/cron_tools.py +179 -0
  150. package/onecode/agent/tools/errors.py +17 -0
  151. package/onecode/agent/tools/file_ops.py +187 -0
  152. package/onecode/agent/tools/file_tools.py +226 -0
  153. package/onecode/agent/tools/git_tools.py +88 -0
  154. package/onecode/agent/tools/lsp_tools.py +404 -0
  155. package/onecode/agent/tools/mcp_tools.py +129 -0
  156. package/onecode/agent/tools/permission_handler.py +46 -0
  157. package/onecode/agent/tools/permissions.py +77 -0
  158. package/onecode/agent/tools/protocol.py +20 -0
  159. package/onecode/agent/tools/registry.py +134 -0
  160. package/onecode/agent/tools/sandbox.py +264 -0
  161. package/onecode/agent/tools/schema_validation.py +100 -0
  162. package/onecode/agent/tools/skill_tools.py +52 -0
  163. package/onecode/agent/tools/task_tools.py +249 -0
  164. package/onecode/agent/tools/web_tools.py +170 -0
  165. package/onecode/builtin_skills/git/SKILL.md +64 -0
  166. package/onecode/builtin_skills/git/skill.yaml +7 -0
  167. package/onecode/builtin_skills/shell/SKILL.md +58 -0
  168. package/onecode/builtin_skills/shell/skill.yaml +8 -0
  169. package/onecode/cli.py +755 -0
  170. package/onecode/cloud/__init__.py +0 -0
  171. package/onecode/cloud/base.py +20 -0
  172. package/onecode/codebase/__init__.py +69 -0
  173. package/onecode/codebase/__pycache__/__init__.cpython-314.pyc +0 -0
  174. package/onecode/codebase/__pycache__/chunker.cpython-314.pyc +0 -0
  175. package/onecode/codebase/__pycache__/config.cpython-314.pyc +0 -0
  176. package/onecode/codebase/__pycache__/indexer.cpython-314.pyc +0 -0
  177. package/onecode/codebase/__pycache__/retriever.cpython-314.pyc +0 -0
  178. package/onecode/codebase/__pycache__/storage.cpython-314.pyc +0 -0
  179. package/onecode/codebase/__pycache__/tools.cpython-314.pyc +0 -0
  180. package/onecode/codebase/chunker.py +130 -0
  181. package/onecode/codebase/indexer.py +136 -0
  182. package/onecode/codebase/retriever.py +192 -0
  183. package/onecode/codebase/storage.py +130 -0
  184. package/onecode/codebase/tools.py +59 -0
  185. package/onecode/commands.py +276 -0
  186. package/onecode/config.py +285 -0
  187. package/onecode/config_screen.py +594 -0
  188. package/onecode/cron/__init__.py +3 -0
  189. package/onecode/lsp/__init__.py +3 -0
  190. package/onecode/mcp/__init__.py +4 -0
  191. package/onecode/mcp/__pycache__/__init__.cpython-314.pyc +0 -0
  192. package/onecode/mcp/__pycache__/client.cpython-314.pyc +0 -0
  193. package/onecode/mcp/__pycache__/manager.cpython-314.pyc +0 -0
  194. package/onecode/mcp/client.py +193 -0
  195. package/onecode/mcp/manager.py +191 -0
  196. package/onecode/memory/__init__.py +95 -0
  197. package/onecode/memory/__pycache__/__init__.cpython-314.pyc +0 -0
  198. package/onecode/memory/__pycache__/backend.cpython-314.pyc +0 -0
  199. package/onecode/memory/__pycache__/offload.cpython-314.pyc +0 -0
  200. package/onecode/memory/__pycache__/pyramid.cpython-314.pyc +0 -0
  201. package/onecode/memory/__pycache__/recall.cpython-314.pyc +0 -0
  202. package/onecode/memory/__pycache__/symbolic.cpython-314.pyc +0 -0
  203. package/onecode/memory/backend.py +185 -0
  204. package/onecode/memory/offload.py +114 -0
  205. package/onecode/memory/pyramid.py +202 -0
  206. package/onecode/memory/recall.py +168 -0
  207. package/onecode/memory/symbolic.py +164 -0
  208. package/onecode/models/__init__.py +4 -0
  209. package/onecode/models/__pycache__/__init__.cpython-314.pyc +0 -0
  210. package/onecode/models/__pycache__/errors.cpython-314.pyc +0 -0
  211. package/onecode/models/__pycache__/messages.cpython-314.pyc +0 -0
  212. package/onecode/models/__pycache__/provider.cpython-314.pyc +0 -0
  213. package/onecode/models/__pycache__/registry.cpython-314.pyc +0 -0
  214. package/onecode/models/errors.py +94 -0
  215. package/onecode/models/messages.py +662 -0
  216. package/onecode/models/provider.py +450 -0
  217. package/onecode/models/providers/__init__.py +17 -0
  218. package/onecode/models/providers/__pycache__/__init__.cpython-314.pyc +0 -0
  219. package/onecode/models/providers/__pycache__/anthropic_provider.cpython-314.pyc +0 -0
  220. package/onecode/models/providers/__pycache__/deepseek_provider.cpython-314.pyc +0 -0
  221. package/onecode/models/providers/__pycache__/glm_provider.cpython-314.pyc +0 -0
  222. package/onecode/models/providers/__pycache__/minimax_provider.cpython-314.pyc +0 -0
  223. package/onecode/models/providers/__pycache__/minimaxi_provider.cpython-314.pyc +0 -0
  224. package/onecode/models/providers/__pycache__/mock_provider.cpython-314.pyc +0 -0
  225. package/onecode/models/providers/__pycache__/ollama_provider.cpython-314.pyc +0 -0
  226. package/onecode/models/providers/__pycache__/openai_provider.cpython-314.pyc +0 -0
  227. package/onecode/models/providers/anthropic_provider.py +224 -0
  228. package/onecode/models/providers/deepseek_provider.py +210 -0
  229. package/onecode/models/providers/glm_provider.py +154 -0
  230. package/onecode/models/providers/minimax_provider.py +154 -0
  231. package/onecode/models/providers/minimaxi_provider.py +363 -0
  232. package/onecode/models/providers/ollama_provider.py +96 -0
  233. package/onecode/models/providers/openai_provider.py +233 -0
  234. package/onecode/models/registry.py +212 -0
  235. package/onecode/server/__init__.py +3 -0
  236. package/onecode/server/app.py +224 -0
  237. package/onecode/skills/__init__.py +11 -0
  238. package/onecode/skills/__pycache__/__init__.cpython-314.pyc +0 -0
  239. package/onecode/skills/__pycache__/argument_substitution.cpython-314.pyc +0 -0
  240. package/onecode/skills/__pycache__/create.cpython-314.pyc +0 -0
  241. package/onecode/skills/__pycache__/frontmatter.cpython-314.pyc +0 -0
  242. package/onecode/skills/__pycache__/loader.cpython-314.pyc +0 -0
  243. package/onecode/skills/__pycache__/manager.cpython-314.pyc +0 -0
  244. package/onecode/skills/__pycache__/model.cpython-314.pyc +0 -0
  245. package/onecode/skills/argument_substitution.py +39 -0
  246. package/onecode/skills/create.py +56 -0
  247. package/onecode/skills/frontmatter.py +33 -0
  248. package/onecode/skills/loader.py +157 -0
  249. package/onecode/skills/manager.py +75 -0
  250. package/onecode/skills/model.py +43 -0
  251. package/onecode/storage/__init__.py +0 -0
  252. package/onecode/storage/activity.py +64 -0
  253. package/onecode/storage/project.py +54 -0
  254. package/onecode/storage/session.py +113 -0
  255. package/onecode/tasks/__init__.py +26 -0
  256. package/onecode/tasks/manager.py +219 -0
  257. package/onecode/tasks/models.py +240 -0
  258. package/onecode/trace/__init__.py +0 -0
  259. package/onecode/trace/tracer.py +174 -0
  260. package/onecode/utils/__init__.py +0 -0
  261. package/onecode/utils/helpers.py +20 -0
  262. package/onecode-cli.js +2 -0
  263. package/package.json +32 -0
  264. package/pyproject.toml +60 -0
  265. package/run.js +86 -0
  266. package/tui/__init__.py +46 -0
  267. package/tui/__main__.py +4 -0
  268. package/tui/__pycache__/__init__.cpython-314.pyc +0 -0
  269. package/tui/__pycache__/_loop.cpython-314.pyc +0 -0
  270. package/tui/__pycache__/_path_fuzzy_search.cpython-314.pyc +0 -0
  271. package/tui/__pycache__/_path_match.cpython-314.pyc +0 -0
  272. package/tui/__pycache__/agent.cpython-314.pyc +0 -0
  273. package/tui/__pycache__/agent_schema.cpython-314.pyc +0 -0
  274. package/tui/__pycache__/agents.cpython-314.pyc +0 -0
  275. package/tui/__pycache__/answer.cpython-314.pyc +0 -0
  276. package/tui/__pycache__/app.cpython-314.pyc +0 -0
  277. package/tui/__pycache__/atomic.cpython-314.pyc +0 -0
  278. package/tui/__pycache__/complete.cpython-314.pyc +0 -0
  279. package/tui/__pycache__/constants.cpython-314.pyc +0 -0
  280. package/tui/__pycache__/conversation_markdown.cpython-314.pyc +0 -0
  281. package/tui/__pycache__/danger.cpython-314.pyc +0 -0
  282. package/tui/__pycache__/db.cpython-314.pyc +0 -0
  283. package/tui/__pycache__/dec.cpython-314.pyc +0 -0
  284. package/tui/__pycache__/directory.cpython-314.pyc +0 -0
  285. package/tui/__pycache__/directory_suggester.cpython-314.pyc +0 -0
  286. package/tui/__pycache__/directory_watcher.cpython-314.pyc +0 -0
  287. package/tui/__pycache__/format_path.cpython-314.pyc +0 -0
  288. package/tui/__pycache__/fuzzy.cpython-314.pyc +0 -0
  289. package/tui/__pycache__/fuzzy_index.cpython-314.pyc +0 -0
  290. package/tui/__pycache__/history.cpython-314.pyc +0 -0
  291. package/tui/__pycache__/jsonrpc.cpython-314.pyc +0 -0
  292. package/tui/__pycache__/menus.cpython-314.pyc +0 -0
  293. package/tui/__pycache__/message_log.cpython-314.pyc +0 -0
  294. package/tui/__pycache__/messages.cpython-314.pyc +0 -0
  295. package/tui/__pycache__/path_complete.cpython-314.pyc +0 -0
  296. package/tui/__pycache__/path_filter.cpython-314.pyc +0 -0
  297. package/tui/__pycache__/paths.cpython-314.pyc +0 -0
  298. package/tui/__pycache__/pill.cpython-314.pyc +0 -0
  299. package/tui/__pycache__/platform_commands.cpython-314.pyc +0 -0
  300. package/tui/__pycache__/protocol.cpython-314.pyc +0 -0
  301. package/tui/__pycache__/session_tracker.cpython-314.pyc +0 -0
  302. package/tui/__pycache__/settings.cpython-314.pyc +0 -0
  303. package/tui/__pycache__/settings_schema.cpython-314.pyc +0 -0
  304. package/tui/__pycache__/shell.cpython-314.pyc +0 -0
  305. package/tui/__pycache__/shell_read.cpython-314.pyc +0 -0
  306. package/tui/__pycache__/slash_command.cpython-314.pyc +0 -0
  307. package/tui/__pycache__/version.cpython-314.pyc +0 -0
  308. package/tui/_loop.py +86 -0
  309. package/tui/_path_fuzzy_search.py +48 -0
  310. package/tui/_path_match.py +141 -0
  311. package/tui/about.py +95 -0
  312. package/tui/acp/__pycache__/agent.cpython-314.pyc +0 -0
  313. package/tui/acp/__pycache__/api.cpython-314.pyc +0 -0
  314. package/tui/acp/__pycache__/encode_tool_call_id.cpython-314.pyc +0 -0
  315. package/tui/acp/__pycache__/messages.cpython-314.pyc +0 -0
  316. package/tui/acp/__pycache__/prompt.cpython-314.pyc +0 -0
  317. package/tui/acp/__pycache__/protocol.cpython-314.pyc +0 -0
  318. package/tui/acp/agent.py +886 -0
  319. package/tui/acp/api.py +55 -0
  320. package/tui/acp/encode_tool_call_id.py +12 -0
  321. package/tui/acp/messages.py +190 -0
  322. package/tui/acp/prompt.py +110 -0
  323. package/tui/acp/protocol.py +462 -0
  324. package/tui/agent.py +70 -0
  325. package/tui/agent_schema.py +76 -0
  326. package/tui/agents.py +45 -0
  327. package/tui/ansi/__init__.py +1 -0
  328. package/tui/ansi/__pycache__/__init__.cpython-314.pyc +0 -0
  329. package/tui/ansi/__pycache__/_ansi.cpython-314.pyc +0 -0
  330. package/tui/ansi/__pycache__/_ansi_colors.cpython-314.pyc +0 -0
  331. package/tui/ansi/__pycache__/_control_codes.cpython-314.pyc +0 -0
  332. package/tui/ansi/__pycache__/_keys.cpython-314.pyc +0 -0
  333. package/tui/ansi/__pycache__/_sgr_styles.cpython-314.pyc +0 -0
  334. package/tui/ansi/__pycache__/_stream_parser.cpython-314.pyc +0 -0
  335. package/tui/ansi/_ansi.py +1689 -0
  336. package/tui/ansi/_ansi_colors.py +264 -0
  337. package/tui/ansi/_control_codes.py +37 -0
  338. package/tui/ansi/_keys.py +251 -0
  339. package/tui/ansi/_sgr_styles.py +64 -0
  340. package/tui/ansi/_stream_parser.py +418 -0
  341. package/tui/answer.py +12 -0
  342. package/tui/app.py +1236 -0
  343. package/tui/atomic.py +37 -0
  344. package/tui/cli.py +313 -0
  345. package/tui/code_analyze.py +27 -0
  346. package/tui/complete.py +38 -0
  347. package/tui/constants.py +61 -0
  348. package/tui/conversation_markdown.py +30 -0
  349. package/tui/danger.py +372 -0
  350. package/tui/data/agents/ampcode.com.toml +51 -0
  351. package/tui/data/agents/augmentcode.com.toml +40 -0
  352. package/tui/data/agents/cdh.cloud-dev-harness.toml +22 -0
  353. package/tui/data/agents/claude.com.toml +41 -0
  354. package/tui/data/agents/copilot.github.com.toml +29 -0
  355. package/tui/data/agents/crowai.dev.toml +35 -0
  356. package/tui/data/agents/cursor.com.toml +38 -0
  357. package/tui/data/agents/deepagents.langchain.com +33 -0
  358. package/tui/data/agents/docker.com.toml +59 -0
  359. package/tui/data/agents/geminicli.com.toml +28 -0
  360. package/tui/data/agents/goose.ai.toml +51 -0
  361. package/tui/data/agents/inference.huggingface.co.toml +41 -0
  362. package/tui/data/agents/kimi.com.toml +35 -0
  363. package/tui/data/agents/kiro.dev.toml +42 -0
  364. package/tui/data/agents/openai.com.toml +53 -0
  365. package/tui/data/agents/openclaw.ai.toml +37 -0
  366. package/tui/data/agents/opencode.ai.toml +39 -0
  367. package/tui/data/agents/openhands.dev.toml +45 -0
  368. package/tui/data/agents/stakpak.dev.toml +61 -0
  369. package/tui/data/agents/vibe.mistral.ai.toml +30 -0
  370. package/tui/data/agents/vtcode.dev.toml +62 -0
  371. package/tui/data/images/frog.png +0 -0
  372. package/tui/data/sounds/question.wav +0 -0
  373. package/tui/data/sounds/turn-over.wav +0 -0
  374. package/tui/db.py +190 -0
  375. package/tui/dec.py +332 -0
  376. package/tui/directory.py +234 -0
  377. package/tui/directory_suggester.py +93 -0
  378. package/tui/directory_watcher.py +197 -0
  379. package/tui/format_path.py +25 -0
  380. package/tui/fuzzy.py +140 -0
  381. package/tui/fuzzy_index.py +275 -0
  382. package/tui/gist.py +33 -0
  383. package/tui/history.py +138 -0
  384. package/tui/jsonrpc.py +578 -0
  385. package/tui/menus.py +14 -0
  386. package/tui/message_log.py +69 -0
  387. package/tui/messages.py +139 -0
  388. package/tui/option_content.py +51 -0
  389. package/tui/os.py +0 -0
  390. package/tui/path_complete.py +217 -0
  391. package/tui/path_filter.py +124 -0
  392. package/tui/paths.py +71 -0
  393. package/tui/pill.py +23 -0
  394. package/tui/platform_commands.py +52 -0
  395. package/tui/prompt/__pycache__/extract.cpython-314.pyc +0 -0
  396. package/tui/prompt/__pycache__/resource.cpython-314.pyc +0 -0
  397. package/tui/prompt/extract.py +19 -0
  398. package/tui/prompt/resource.py +68 -0
  399. package/tui/protocol.py +28 -0
  400. package/tui/screens/__init__.py +0 -0
  401. package/tui/screens/__pycache__/__init__.cpython-314.pyc +0 -0
  402. package/tui/screens/__pycache__/log.cpython-314.pyc +0 -0
  403. package/tui/screens/__pycache__/main.cpython-314.pyc +0 -0
  404. package/tui/screens/__pycache__/projects_screen.cpython-314.pyc +0 -0
  405. package/tui/screens/__pycache__/sessions.cpython-314.pyc +0 -0
  406. package/tui/screens/__pycache__/settings.cpython-314.pyc +0 -0
  407. package/tui/screens/__pycache__/store.cpython-314.pyc +0 -0
  408. package/tui/screens/action_modal.py +94 -0
  409. package/tui/screens/agent_modal.py +175 -0
  410. package/tui/screens/command_edit_modal.py +74 -0
  411. package/tui/screens/log.py +553 -0
  412. package/tui/screens/main.py +411 -0
  413. package/tui/screens/main.tcss +655 -0
  414. package/tui/screens/permissions.py +404 -0
  415. package/tui/screens/permissions.tcss +72 -0
  416. package/tui/screens/projects.tcss +66 -0
  417. package/tui/screens/projects_app.py +319 -0
  418. package/tui/screens/projects_screen.py +142 -0
  419. package/tui/screens/session_resume_modal.py +172 -0
  420. package/tui/screens/session_resume_modal.tcss +35 -0
  421. package/tui/screens/sessions.py +166 -0
  422. package/tui/screens/sessions.tcss +119 -0
  423. package/tui/screens/settings.py +254 -0
  424. package/tui/screens/settings.tcss +101 -0
  425. package/tui/screens/store.py +500 -0
  426. package/tui/screens/store.tcss +274 -0
  427. package/tui/screens/tool_content_screen.py +59 -0
  428. package/tui/session_tracker.py +120 -0
  429. package/tui/settings.py +353 -0
  430. package/tui/settings_schema.py +431 -0
  431. package/tui/shell.py +304 -0
  432. package/tui/shell_read.py +42 -0
  433. package/tui/slash_command.py +34 -0
  434. package/tui/tui.tcss +246 -0
  435. package/tui/twitter.py +38 -0
  436. package/tui/version.py +80 -0
  437. package/tui/visuals/__init__.py +0 -0
  438. package/tui/visuals/__pycache__/__init__.cpython-314.pyc +0 -0
  439. package/tui/visuals/__pycache__/columns.cpython-314.pyc +0 -0
  440. package/tui/visuals/columns.py +273 -0
  441. package/tui/widgets/__init__.py +0 -0
  442. package/tui/widgets/__pycache__/__init__.cpython-314.pyc +0 -0
  443. package/tui/widgets/__pycache__/acp_content.cpython-314.pyc +0 -0
  444. package/tui/widgets/__pycache__/agent_response.cpython-314.pyc +0 -0
  445. package/tui/widgets/__pycache__/agent_thought.cpython-314.pyc +0 -0
  446. package/tui/widgets/__pycache__/ask_user.cpython-314.pyc +0 -0
  447. package/tui/widgets/__pycache__/condensed_path.cpython-314.pyc +0 -0
  448. package/tui/widgets/__pycache__/context_stats.cpython-314.pyc +0 -0
  449. package/tui/widgets/__pycache__/conversation.cpython-313.pyc +0 -0
  450. package/tui/widgets/__pycache__/conversation.cpython-314.pyc +0 -0
  451. package/tui/widgets/__pycache__/diff_view.cpython-314.pyc +0 -0
  452. package/tui/widgets/__pycache__/directory_input.cpython-314.pyc +0 -0
  453. package/tui/widgets/__pycache__/flash.cpython-314.pyc +0 -0
  454. package/tui/widgets/__pycache__/future_text.cpython-314.pyc +0 -0
  455. package/tui/widgets/__pycache__/grid_select.cpython-314.pyc +0 -0
  456. package/tui/widgets/__pycache__/highlighted_textarea.cpython-314.pyc +0 -0
  457. package/tui/widgets/__pycache__/mandelbrot.cpython-314.pyc +0 -0
  458. package/tui/widgets/__pycache__/markdown_note.cpython-314.pyc +0 -0
  459. package/tui/widgets/__pycache__/menu.cpython-314.pyc +0 -0
  460. package/tui/widgets/__pycache__/modified_files.cpython-314.pyc +0 -0
  461. package/tui/widgets/__pycache__/non_selectable_label.cpython-314.pyc +0 -0
  462. package/tui/widgets/__pycache__/note.cpython-314.pyc +0 -0
  463. package/tui/widgets/__pycache__/path_search.cpython-314.pyc +0 -0
  464. package/tui/widgets/__pycache__/plan.cpython-314.pyc +0 -0
  465. package/tui/widgets/__pycache__/project_directory_tree.cpython-314.pyc +0 -0
  466. package/tui/widgets/__pycache__/project_grid_select.cpython-314.pyc +0 -0
  467. package/tui/widgets/__pycache__/project_summary.cpython-314.pyc +0 -0
  468. package/tui/widgets/__pycache__/prompt.cpython-314.pyc +0 -0
  469. package/tui/widgets/__pycache__/question.cpython-314.pyc +0 -0
  470. package/tui/widgets/__pycache__/session_grid_select.cpython-314.pyc +0 -0
  471. package/tui/widgets/__pycache__/session_summary.cpython-314.pyc +0 -0
  472. package/tui/widgets/__pycache__/session_tabs.cpython-314.pyc +0 -0
  473. package/tui/widgets/__pycache__/shell_result.cpython-314.pyc +0 -0
  474. package/tui/widgets/__pycache__/shell_terminal.cpython-314.pyc +0 -0
  475. package/tui/widgets/__pycache__/side_bar.cpython-314.pyc +0 -0
  476. package/tui/widgets/__pycache__/slash_complete.cpython-314.pyc +0 -0
  477. package/tui/widgets/__pycache__/strike_text.cpython-314.pyc +0 -0
  478. package/tui/widgets/__pycache__/subagent.cpython-314.pyc +0 -0
  479. package/tui/widgets/__pycache__/terminal.cpython-313.pyc +0 -0
  480. package/tui/widgets/__pycache__/terminal.cpython-314.pyc +0 -0
  481. package/tui/widgets/__pycache__/throbber.cpython-314.pyc +0 -0
  482. package/tui/widgets/__pycache__/tool_call.cpython-313.pyc +0 -0
  483. package/tui/widgets/__pycache__/tool_call.cpython-314.pyc +0 -0
  484. package/tui/widgets/__pycache__/user_input.cpython-314.pyc +0 -0
  485. package/tui/widgets/acp_content.py +70 -0
  486. package/tui/widgets/agent_response.py +77 -0
  487. package/tui/widgets/agent_thought.py +168 -0
  488. package/tui/widgets/ask_user.py +264 -0
  489. package/tui/widgets/command_pane.py +223 -0
  490. package/tui/widgets/condensed_path.py +115 -0
  491. package/tui/widgets/context_stats.py +66 -0
  492. package/tui/widgets/conversation.py +2441 -0
  493. package/tui/widgets/danger_warning.py +65 -0
  494. package/tui/widgets/diff_view.py +59 -0
  495. package/tui/widgets/directory_input.py +8 -0
  496. package/tui/widgets/flash.py +81 -0
  497. package/tui/widgets/future_text.py +126 -0
  498. package/tui/widgets/grid_select.py +234 -0
  499. package/tui/widgets/highlighted_textarea.py +180 -0
  500. package/tui/widgets/mandelbrot.py +294 -0
  501. package/tui/widgets/markdown_note.py +13 -0
  502. package/tui/widgets/menu.py +147 -0
  503. package/tui/widgets/modified_files.py +106 -0
  504. package/tui/widgets/non_selectable_label.py +5 -0
  505. package/tui/widgets/note.py +18 -0
  506. package/tui/widgets/path_search.py +492 -0
  507. package/tui/widgets/plan.py +263 -0
  508. package/tui/widgets/project_directory_tree.py +90 -0
  509. package/tui/widgets/project_grid_select.py +35 -0
  510. package/tui/widgets/project_summary.py +33 -0
  511. package/tui/widgets/prompt.py +795 -0
  512. package/tui/widgets/question.py +360 -0
  513. package/tui/widgets/session_grid_select.py +224 -0
  514. package/tui/widgets/session_summary.py +115 -0
  515. package/tui/widgets/session_tabs.py +188 -0
  516. package/tui/widgets/shell_result.py +35 -0
  517. package/tui/widgets/shell_terminal.py +40 -0
  518. package/tui/widgets/side_bar.py +114 -0
  519. package/tui/widgets/slash_complete.py +235 -0
  520. package/tui/widgets/strike_text.py +70 -0
  521. package/tui/widgets/subagent.py +87 -0
  522. package/tui/widgets/terminal.py +577 -0
  523. package/tui/widgets/terminal_tool.py +351 -0
  524. package/tui/widgets/throbber.py +100 -0
  525. package/tui/widgets/tool_call.py +368 -0
  526. package/tui/widgets/user_input.py +23 -0
  527. package/tui/widgets/version.py +5 -0
  528. package/tui/widgets/welcome.py +31 -0
@@ -0,0 +1,249 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from onecode.agent.tools.protocol import ToolResult
6
+ from onecode.agent.tools.registry import ToolSpec
7
+
8
+
9
+ class TaskCreateTool:
10
+ def __init__(self, task_manager):
11
+ self._tm = task_manager
12
+
13
+ def spec(self) -> ToolSpec:
14
+ return ToolSpec(
15
+ name="TaskCreate",
16
+ description="Create a fine-grained task (1-3 tool calls each). For large work, split into multiple smaller tasks with dependencies. Returns task id.",
17
+ input_schema={
18
+ "type": "object",
19
+ "properties": {
20
+ "subject": {"type": "string", "description": "Short, action-oriented title (verb + noun, e.g. 'Create User model')"},
21
+ "description": {"type": "string", "description": "What needs to be done + acceptance criteria"},
22
+ "activeForm": {"type": "string", "description": "Active form description"},
23
+ "metadata": {"type": "object", "description": 'Optional metadata. Supports priority (high/medium/low) and effort (small/medium/large)'},
24
+ },
25
+ "required": ["subject", "description"],
26
+ },
27
+ )
28
+
29
+ def run(self, tool_input: dict[str, Any]) -> ToolResult:
30
+ task = self._tm.create_task(
31
+ subject=tool_input.get("subject", ""),
32
+ description=tool_input.get("description", ""),
33
+ active_form=tool_input.get("activeForm", ""),
34
+ metadata=tool_input.get("metadata"),
35
+ )
36
+ return ToolResult(name="TaskCreate", output={"task": {"id": task["id"], "subject": task["subject"]}})
37
+
38
+
39
+
40
+ class TaskGetTool:
41
+ def __init__(self, task_manager):
42
+ self._tm = task_manager
43
+
44
+ def spec(self) -> ToolSpec:
45
+ return ToolSpec(
46
+ name="TaskGet",
47
+ description="Retrieve a task by ID.",
48
+ input_schema={
49
+ "type": "object",
50
+ "properties": {
51
+ "taskId": {"type": "string", "description": "Task id to retrieve"},
52
+ },
53
+ "required": ["taskId"],
54
+ },
55
+ )
56
+
57
+ def run(self, tool_input: dict[str, Any]) -> ToolResult:
58
+ task_id = tool_input.get("taskId", "")
59
+ task = self._tm.get_task(task_id)
60
+ if task is None:
61
+ return ToolResult(name="TaskGet", output={"task": None})
62
+ info = {k: task[k] for k in ("id", "subject", "description", "status", "blocks", "blockedBy")}
63
+ return ToolResult(name="TaskGet", output={"task": info})
64
+
65
+
66
+
67
+ class TaskListTool:
68
+ def __init__(self, task_manager):
69
+ self._tm = task_manager
70
+
71
+ def spec(self) -> ToolSpec:
72
+ return ToolSpec(
73
+ name="TaskList",
74
+ description="List all tasks with their current status and dependencies.",
75
+ input_schema={"type": "object", "properties": {}, "required": []},
76
+ )
77
+
78
+ def run(self, tool_input: dict[str, Any]) -> ToolResult:
79
+ tasks = self._tm.list_tasks()
80
+ if not tasks:
81
+ return ToolResult(name="TaskList", output={"tasks": []})
82
+ summaries = []
83
+ for t in tasks:
84
+ s = {"id": t["id"], "subject": t["subject"], "status": t["status"]}
85
+ if t.get("owner"):
86
+ s["owner"] = t["owner"]
87
+ s["blockedBy"] = list(t.get("blockedBy") or [])
88
+ summaries.append(s)
89
+ return ToolResult(name="TaskList", output={"tasks": summaries})
90
+
91
+
92
+
93
+ class TaskUpdateTool:
94
+ def __init__(self, task_manager):
95
+ self._tm = task_manager
96
+
97
+ def spec(self) -> ToolSpec:
98
+ return ToolSpec(
99
+ name="TaskUpdate",
100
+ description="Update a task: subject, description, status, owner, dependencies, output.",
101
+ input_schema={
102
+ "type": "object",
103
+ "properties": {
104
+ "taskId": {"type": "string", "description": "Task id to update"},
105
+ "subject": {"type": "string"},
106
+ "description": {"type": "string"},
107
+ "activeForm": {"type": "string"},
108
+ "status": {"type": "string", "description": "pending|in_progress|completed|deleted"},
109
+ "owner": {"type": "string"},
110
+ "addBlocks": {"type": "array", "items": {"type": "string"}, "description": "Task IDs this task blocks"},
111
+ "addBlockedBy": {"type": "array", "items": {"type": "string"}, "description": "Task IDs that block this"},
112
+ "metadata": {"type": "object"},
113
+ "output": {"type": "string", "description": "Key results to pass to downstream tasks"},
114
+ },
115
+ "required": ["taskId"],
116
+ },
117
+ )
118
+
119
+ def run(self, tool_input: dict[str, Any]) -> ToolResult:
120
+ task_id = tool_input.get("taskId", "")
121
+ updates = {k: v for k, v in tool_input.items() if k != "taskId" and v is not None}
122
+ if "subject" not in updates and "title" in updates:
123
+ updates["subject"] = updates.pop("title")
124
+ if "addBlocks" not in updates and "blocks" in updates and isinstance(updates.get("blocks"), list):
125
+ updates["addBlocks"] = updates.pop("blocks")
126
+ result = self._tm.update_task(task_id, **updates)
127
+ if result is None:
128
+ return ToolResult(name="TaskUpdate", output={"success": False, "taskId": task_id, "error": "Task not found"}, is_error=True)
129
+ if result.get("deleted"):
130
+ return ToolResult(name="TaskUpdate", output={"success": True, "taskId": task_id, "updatedFields": ["deleted"]})
131
+ return ToolResult(name="TaskUpdate", output={"success": True, "taskId": task_id, "task": {"id": result["id"], "subject": result["subject"], "status": result["status"]}})
132
+
133
+
134
+
135
+ class TaskOutputTool:
136
+ def __init__(self, task_manager):
137
+ self._tm = task_manager
138
+
139
+ def spec(self) -> ToolSpec:
140
+ return ToolSpec(
141
+ name="TaskOutput",
142
+ description="Get output for a task.",
143
+ input_schema={
144
+ "type": "object",
145
+ "properties": {
146
+ "task_id": {"type": "string", "description": "Task id to get output for"},
147
+ },
148
+ "required": ["task_id"],
149
+ },
150
+ )
151
+
152
+ def run(self, tool_input: dict[str, Any]) -> ToolResult:
153
+ task_id = tool_input.get("task_id", "")
154
+ result = self._tm.get_task_output(task_id)
155
+ return ToolResult(name="TaskOutput", output=result)
156
+
157
+
158
+
159
+ class TaskStopTool:
160
+ def __init__(self, task_manager):
161
+ self._tm = task_manager
162
+
163
+ def spec(self) -> ToolSpec:
164
+ return ToolSpec(
165
+ name="TaskStop",
166
+ description="Stop/cancel a running task.",
167
+ input_schema={
168
+ "type": "object",
169
+ "properties": {
170
+ "task_id": {"type": "string", "description": "Task id to stop"},
171
+ },
172
+ "required": ["task_id"],
173
+ },
174
+ )
175
+
176
+ def run(self, tool_input: dict[str, Any]) -> ToolResult:
177
+ task_id = tool_input.get("task_id", "")
178
+ result = self._tm.update_task(task_id, status="completed")
179
+ if result is None:
180
+ return ToolResult(name="TaskStop", output={"success": False, "stopped": False, "error": "Task not found"}, is_error=True)
181
+ if result.get("deleted"):
182
+ return ToolResult(name="TaskStop", output={"success": True, "stopped": True, "task_id": task_id})
183
+ return ToolResult(name="TaskStop", output={"success": True, "stopped": True, "task_id": task_id})
184
+
185
+
186
+
187
+ class TodoCreateTool:
188
+ def __init__(self, task_manager):
189
+ self._tm = task_manager
190
+
191
+ def spec(self) -> ToolSpec:
192
+ return ToolSpec(
193
+ name="TodoCreate",
194
+ description="Create a todo item. Returns todo id.",
195
+ input_schema={
196
+ "type": "object",
197
+ "properties": {
198
+ "text": {"type": "string", "description": "Todo item text"},
199
+ },
200
+ "required": ["text"],
201
+ },
202
+ )
203
+
204
+ def run(self, tool_input: dict[str, Any]) -> ToolResult:
205
+ text = tool_input.get("text", "")
206
+ todo_id = self._tm.add_todo(text)
207
+ return ToolResult(name="TodoCreate", output={"id": todo_id, "text": text})
208
+
209
+
210
+
211
+ class TodoListTool:
212
+ def __init__(self, task_manager):
213
+ self._tm = task_manager
214
+
215
+ def spec(self) -> ToolSpec:
216
+ return ToolSpec(
217
+ name="TodoList",
218
+ description="List all todo items.",
219
+ input_schema={"type": "object", "properties": {}, "required": []},
220
+ )
221
+
222
+ def run(self, tool_input: dict[str, Any]) -> ToolResult:
223
+ todos = self._tm.list_todos()
224
+ return ToolResult(name="TodoList", output=todos)
225
+
226
+
227
+
228
+ class TodoCompleteTool:
229
+ def __init__(self, task_manager):
230
+ self._tm = task_manager
231
+
232
+ def spec(self) -> ToolSpec:
233
+ return ToolSpec(
234
+ name="TodoComplete",
235
+ description="Mark a todo as completed.",
236
+ input_schema={
237
+ "type": "object",
238
+ "properties": {
239
+ "todo_id": {"type": "string", "description": "Todo id to complete"},
240
+ },
241
+ "required": ["todo_id"],
242
+ },
243
+ )
244
+
245
+ def run(self, tool_input: dict[str, Any]) -> ToolResult:
246
+ todo_id = tool_input.get("todo_id", tool_input.get("id", ""))
247
+ ok = self._tm.complete_todo(str(todo_id))
248
+ return ToolResult(name="TodoComplete", output={"success": ok, "todo_id": todo_id}, is_error=not ok)
249
+
@@ -0,0 +1,170 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ import html
5
+ from dataclasses import dataclass
6
+ from typing import Any, Optional
7
+
8
+ import httpx
9
+
10
+ from onecode.agent.tools.protocol import ToolResult
11
+ from onecode.agent.tools.registry import ToolSpec
12
+
13
+
14
+ @dataclass
15
+ class WebResult:
16
+ url: str
17
+ title: str
18
+ snippet: str
19
+ content: Optional[str] = None
20
+
21
+
22
+ class WebFetcher:
23
+ def __init__(self, timeout: int = 30):
24
+ self.timeout = timeout
25
+
26
+ def fetch(self, url: str, prompt: Optional[str] = None) -> str:
27
+ try:
28
+ with httpx.Client(timeout=self.timeout, follow_redirects=True) as client:
29
+ resp = client.get(url)
30
+ resp.raise_for_status()
31
+
32
+ content_type = resp.headers.get("content-type", "").lower()
33
+ if "text/html" in content_type:
34
+ text = self._extract_text_from_html(resp.text)
35
+ else:
36
+ text = resp.text[:5000]
37
+
38
+ if prompt:
39
+ return f"URL: {url}\nContent (relevant to '{prompt}'):\n{text[:3000]}"
40
+ return f"URL: {url}\nContent:\n{text[:3000]}"
41
+
42
+ except httpx.TimeoutException:
43
+ return f"Error: Timeout fetching {url}"
44
+ except httpx.HTTPStatusError as e:
45
+ return f"Error: HTTP {e.response.status_code} for {url}"
46
+ except Exception as e:
47
+ return f"Error: {str(e)} for {url}"
48
+
49
+ def _extract_text_from_html(self, html_content: str) -> str:
50
+ text = re.sub(r"<script[^>]*>.*?</script>", "", html_content, flags=re.DOTALL | re.IGNORECASE)
51
+ text = re.sub(r"<style[^>]*>.*?</style>", "", text, flags=re.DOTALL | re.IGNORECASE)
52
+ text = re.sub(r"<[^>]+>", " ", text)
53
+ text = html.unescape(text)
54
+ text = re.sub(r"\s+", " ", text).strip()
55
+ return text[:5000]
56
+
57
+
58
+ class WebSearch:
59
+ def __init__(self, timeout: int = 30):
60
+ self.timeout = timeout
61
+ self._fetcher = WebFetcher(timeout)
62
+
63
+ def search(self, query: str, num_results: int = 5) -> str:
64
+ search_urls = [
65
+ f"https://duckduckgo.com/html/?q={self._quote(query)}",
66
+ f"https://html.duckduckgo.com/html/?q={self._quote(query)}",
67
+ ]
68
+
69
+ for url in search_urls:
70
+ try:
71
+ results = self._search_duckduckgo(url, num_results)
72
+ if results:
73
+ return results
74
+ except Exception:
75
+ continue
76
+
77
+ return self._search_fallback(query, num_results)
78
+
79
+ def _search_duckduckgo(self, url: str, num_results: int) -> str:
80
+ with httpx.Client(timeout=self.timeout, follow_redirects=True) as client:
81
+ resp = client.get(url)
82
+ resp.raise_for_status()
83
+
84
+ html_content = resp.text
85
+ results = []
86
+
87
+ result_pattern = re.compile(r'<a class="result__a" href="([^"]+)">([^<]+)</a>.*?<a class="result__snippet"[^>]*>([^<]+)</a>', re.DOTALL)
88
+ snippets = re.findall(r'<a class="result__a" href="([^"]+)">([^<]+)</a>', html_content)
89
+ snippet_pattern = re.compile(r'<a class="result__a" href="[^"]+">[^<]+</a>.*?(?:<p class="result__snippet">([^<]+)</p>)?', re.DOTALL)
90
+
91
+ for i, (url, title) in enumerate(snippets[:num_results]):
92
+ snippet_match = re.search(rf'<a class="result__a" href="{re.escape(url)}"[^>]*>[^<]+</a>.*?(?:<p class="result__snippet">([^<]+)</p>|(?:<a class="result__snippet"[^>]*>([^<]+)</a>))?', html_content, re.DOTALL)
93
+ snippet = ""
94
+ if snippet_match:
95
+ snippet = snippet_match.group(1) or snippet_match.group(2) or ""
96
+
97
+ title = re.sub(r'<[^>]+>', '', title)
98
+ snippet = re.sub(r'<[^>]+>', '', snippet)
99
+ results.append(f"{i+1}. {title}\n URL: {url}\n {snippet[:200]}")
100
+
101
+ if results:
102
+ return f"Search results for '{query}':\n\n" + "\n\n".join(results)
103
+
104
+ return f"No results found for '{query}'"
105
+
106
+ def _search_fallback(self, query: str, num_results: int) -> str:
107
+ return f"Web search for '{query}' returned no results. Try using WebFetch to directly access a URL."
108
+
109
+ def _quote(self, query: str) -> str:
110
+ import urllib.parse
111
+ return urllib.parse.quote_plus(query)
112
+
113
+
114
+ def webfetch(url: str, prompt: Optional[str] = None) -> str:
115
+ fetcher = WebFetcher()
116
+ return fetcher.fetch(url, prompt)
117
+
118
+
119
+ def websearch(query: str, num_results: int = 5) -> str:
120
+ searcher = WebSearch()
121
+ return searcher.search(query, num_results)
122
+
123
+
124
+ class WebFetchTool:
125
+ def spec(self) -> ToolSpec:
126
+ return ToolSpec(
127
+ name="WebFetch",
128
+ description="Fetch a URL and extract information.",
129
+ input_schema={
130
+ "type": "object",
131
+ "properties": {
132
+ "url": {"type": "string", "description": "URL to fetch"},
133
+ "prompt": {"type": "string", "description": "What to extract from the page"},
134
+ },
135
+ "required": ["url"],
136
+ },
137
+ is_read_only=True,
138
+ )
139
+
140
+ def run(self, tool_input: dict[str, Any]) -> ToolResult:
141
+ url = tool_input.get("url", "")
142
+ prompt = tool_input.get("prompt")
143
+ content = webfetch(url, prompt)
144
+ is_error = str(content).startswith("Error:")
145
+ return ToolResult(name="WebFetch", output=str(content), is_error=is_error)
146
+
147
+
148
+
149
+ class WebSearchTool:
150
+ def spec(self) -> ToolSpec:
151
+ return ToolSpec(
152
+ name="WebSearch",
153
+ description="Search the web and return results.",
154
+ input_schema={
155
+ "type": "object",
156
+ "properties": {
157
+ "query": {"type": "string", "description": "Search query"},
158
+ "num_results": {"type": "integer", "description": "Number of results", "default": 5},
159
+ },
160
+ "required": ["query"],
161
+ },
162
+ is_read_only=True,
163
+ )
164
+
165
+ def run(self, tool_input: dict[str, Any]) -> ToolResult:
166
+ query = tool_input.get("query", "")
167
+ num_results = tool_input.get("num_results", 5)
168
+ content = websearch(query, num_results)
169
+ is_error = "Error" in str(content) and str(content).startswith("Error")
170
+ return ToolResult(name="WebSearch", output=str(content), is_error=is_error)
@@ -0,0 +1,64 @@
1
+ # Git Skill
2
+
3
+ Provides Git version control and GitHub integration capabilities.
4
+
5
+ ## Agent Tools
6
+
7
+ | Operation | Tool |
8
+ |-----------|------|
9
+ | Clone repo | `exec_shell("git clone ...")` |
10
+ | Commit | `exec_shell("git commit ...")` |
11
+ | Push/Pull | `exec_shell("git push/pull")` |
12
+ | Branch | `exec_shell("git checkout/branch ...")` |
13
+ | GitHub API | via `gh` command |
14
+
15
+ ## Common Commands
16
+
17
+ ### Basic Workflow
18
+ ```bash
19
+ git init # Initialize repo
20
+ git clone <url> # Clone repository
21
+ git add . # Stage all changes
22
+ git commit -m "message" # Commit with message
23
+ git push # Push to remote
24
+ git pull # Pull from remote
25
+ ```
26
+
27
+ ### Branching
28
+ ```bash
29
+ git branch # List branches
30
+ git branch -b new-branch # Create and switch
31
+ git checkout <branch> # Switch branch
32
+ git merge <branch> # Merge branch
33
+ ```
34
+
35
+ ### Inspection
36
+ ```bash
37
+ git status # Show working tree status
38
+ git log --oneline -10 # Recent commits
39
+ git diff # Show changes
40
+ git diff --staged # Staged changes
41
+ git show <commit> # Commit details
42
+ ```
43
+
44
+ ### GitHub CLI (`gh`)
45
+ ```bash
46
+ gh repo clone owner/repo # Clone via gh
47
+ gh pr create # Create pull request
48
+ gh pr list # List PRs
49
+ gh issue list # List issues
50
+ gh repo view # View repo info
51
+ ```
52
+
53
+ ## Agent Integration
54
+
55
+ When this skill is active, the agent can:
56
+ 1. Clone repos to local via `git clone`
57
+ 2. Commit changes with structured messages
58
+ 3. Create and manage branches
59
+ 4. Interact with GitHub via `gh` CLI
60
+ 5. Pull/push code during development
61
+
62
+ ## GitHub Token
63
+
64
+ Store token at `~/.cloud-harness-tokens.json` or set `GITHUB_TOKEN` env var.
@@ -0,0 +1,7 @@
1
+ name: git
2
+ description: >-
3
+ Git skill for version control operations, GitHub integration,
4
+ and code repository management.
5
+ version: 1.0.0
6
+ enabled: true
7
+ entry: SKILL.md
@@ -0,0 +1,58 @@
1
+ # Shell Skill
2
+
3
+ Provides shell command execution capabilities and common operations.
4
+
5
+ ## Agent Tools
6
+
7
+ | Operation | Command |
8
+ |-----------|---------|
9
+ | Execute command | `exec_shell("command")` |
10
+ | Check output | read from command result |
11
+ | Working directory | defaults to current workspace |
12
+
13
+ ## Common Commands
14
+
15
+ ### File Operations
16
+ ```bash
17
+ ls -la # List files with details
18
+ mkdir -p path # Create directory
19
+ rm -rf path # Remove directory recursively
20
+ cp -r src dst # Copy recursively
21
+ mv src dst # Move/rename
22
+ find . -name "*.py" # Find files
23
+ ```
24
+
25
+ ### Git Operations (see git skill)
26
+ ```bash
27
+ git status
28
+ git add .
29
+ git commit -m "message"
30
+ git push
31
+ ```
32
+
33
+ ### npm/Node
34
+ ```bash
35
+ npm install
36
+ npm run build
37
+ npm test
38
+ ```
39
+
40
+ ### Python
41
+ ```bash
42
+ python3 -m pip install <package>
43
+ python3 script.py
44
+ ```
45
+
46
+ ## Safety
47
+
48
+ - Agent should confirm destructive commands (rm -rf, etc.) with user
49
+ - Shell whitelist configurable in cdh.config.yaml
50
+ - Interactive commands (vim, less, etc.) may not work in agent mode
51
+
52
+ ## Agent Integration
53
+
54
+ When this skill is active, the agent can:
55
+ 1. Execute commands via `exec_shell` tool
56
+ 2. Parse command output for decision making
57
+ 3. Chain commands with pipes
58
+ 4. Run background tasks with `&`
@@ -0,0 +1,8 @@
1
+ name: shell
2
+ description: >-
3
+ Shell skill for executing system commands, managing processes,
4
+ and performing file operations. Integrates with the agent's
5
+ exec_shell tool and provides command templates.
6
+ version: 1.0.0
7
+ enabled: true
8
+ entry: SKILL.md