@scemoon/cdh 1.0.6 → 1.0.7

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 (550) hide show
  1. package/package.json +2 -2
  2. package/ai-dlc-skill/SKILL.md +0 -77
  3. package/ai-dlc-skill/agents/deliver-agent.md +0 -24
  4. package/ai-dlc-skill/agents/master.md +0 -50
  5. package/ai-dlc-skill/agents/plan-agent.md +0 -23
  6. package/ai-dlc-skill/agents/understand-agent.md +0 -23
  7. package/ai-dlc-skill/agents/verify-agent.md +0 -27
  8. package/ai-dlc-skill/architecture/project-structure.md +0 -78
  9. package/ai-dlc-skill/brownfield/README.md +0 -30
  10. package/ai-dlc-skill/brownfield/generate-context.sh +0 -64
  11. package/ai-dlc-skill/brownfield/scripts/deps.sh +0 -27
  12. package/ai-dlc-skill/brownfield/scripts/discover.sh +0 -34
  13. package/ai-dlc-skill/brownfield/scripts/extract-api.sh +0 -45
  14. package/ai-dlc-skill/components/backend.md +0 -34
  15. package/ai-dlc-skill/components/desktop.md +0 -30
  16. package/ai-dlc-skill/components/mya.md +0 -29
  17. package/ai-dlc-skill/components/native.md +0 -30
  18. package/ai-dlc-skill/components/tta.md +0 -29
  19. package/ai-dlc-skill/components/web.md +0 -31
  20. package/ai-dlc-skill/components/wxa.md +0 -29
  21. package/ai-dlc-skill/contracts/README.md +0 -25
  22. package/ai-dlc-skill/core/adaptive-flow.md +0 -36
  23. package/ai-dlc-skill/core/security.md +0 -29
  24. package/ai-dlc-skill/cross-tool/cline/export.sh +0 -31
  25. package/ai-dlc-skill/cross-tool/copilot/export.sh +0 -47
  26. package/ai-dlc-skill/cross-tool/cursor/export.sh +0 -32
  27. package/ai-dlc-skill/cross-tool/export.sh +0 -22
  28. package/ai-dlc-skill/cross-tool/onecode/config.yaml.tpl +0 -17
  29. package/ai-dlc-skill/cross-tool/onecode/export-skills.sh +0 -35
  30. package/ai-dlc-skill/cross-tool/onecode/export.sh +0 -54
  31. package/ai-dlc-skill/phases/deliver/entry.md +0 -26
  32. package/ai-dlc-skill/phases/deliver/lifecycle.md +0 -185
  33. package/ai-dlc-skill/phases/deliver/prompt.md +0 -40
  34. package/ai-dlc-skill/phases/deliver/rules.md +0 -61
  35. package/ai-dlc-skill/phases/plan/entry.md +0 -25
  36. package/ai-dlc-skill/phases/plan/lifecycle.md +0 -204
  37. package/ai-dlc-skill/phases/plan/prompt.md +0 -38
  38. package/ai-dlc-skill/phases/plan/rules.md +0 -25
  39. package/ai-dlc-skill/phases/understand/entry.md +0 -26
  40. package/ai-dlc-skill/phases/understand/lifecycle.md +0 -184
  41. package/ai-dlc-skill/phases/understand/prompt.md +0 -41
  42. package/ai-dlc-skill/phases/understand/rules.md +0 -37
  43. package/ai-dlc-skill/phases/verify/entry.md +0 -26
  44. package/ai-dlc-skill/phases/verify/lifecycle.md +0 -192
  45. package/ai-dlc-skill/phases/verify/prompt.md +0 -43
  46. package/ai-dlc-skill/phases/verify/rules.md +0 -73
  47. package/ai-dlc-skill/practices/bdd.md +0 -91
  48. package/ai-dlc-skill/practices/sdd.md +0 -84
  49. package/ai-dlc-skill/practices/tdd.md +0 -95
  50. package/ai-dlc-skill/providers/README.md +0 -114
  51. package/ai-dlc-skill/providers/aliyun/deployment.yaml +0 -66
  52. package/ai-dlc-skill/providers/aliyun/preview.yaml +0 -84
  53. package/ai-dlc-skill/providers/aliyun/provider.yaml +0 -160
  54. package/ai-dlc-skill/providers/tcb/deployment.yaml +0 -69
  55. package/ai-dlc-skill/providers/tcb/preview.yaml +0 -83
  56. package/ai-dlc-skill/providers/tcb/provider.yaml +0 -172
  57. package/ai-dlc-skill/requirements.md +0 -140
  58. package/ai-dlc-skill/skill.yaml +0 -147
  59. package/ai-dlc-skill/templates/integration/CHANGELOG.md +0 -41
  60. package/ai-dlc-skill/templates/integration/asyncapi.yaml +0 -43
  61. package/ai-dlc-skill/templates/integration/contract-diff.md +0 -63
  62. package/ai-dlc-skill/templates/integration/contract-spec.md +0 -49
  63. package/ai-dlc-skill/templates/integration/openapi.yaml +0 -18
  64. package/ai-dlc-skill/templates/integration/runtime-contract.yaml +0 -36
  65. package/ai-dlc-skill/templates/plan/design.md +0 -49
  66. package/ai-dlc-skill/templates/plan/task-list.md +0 -32
  67. package/ai-dlc-skill/templates/project/README.md +0 -126
  68. package/ai-dlc-skill/templates/project/template.md +0 -119
  69. package/ai-dlc-skill/templates/understand/feature.feature +0 -23
  70. package/ai-dlc-skill/templates/understand/intent.md +0 -29
  71. package/ai-dlc-skill/templates/understand/spec-delta.md +0 -47
  72. package/ai-dlc-skill/templates/verify/test-unit.py +0 -27
  73. package/ai-dlc-skill/walkthrough/collect.sh +0 -50
  74. package/ai-dlc-skill/walkthrough/template.md +0 -54
  75. package/ai-dlc-skill/workflows/ai-dlc.yaml +0 -110
  76. package/ai-dlc-skill/workflows/deployment.yaml +0 -199
  77. package/cdh/__init__.py +0 -0
  78. package/cdh/__main__.py +0 -4
  79. package/cdh/__pycache__/__init__.cpython-314.pyc +0 -0
  80. package/cdh/__pycache__/cdh_mcp_injector.cpython-314.pyc +0 -0
  81. package/cdh/__pycache__/cdh_mcp_loader.cpython-314.pyc +0 -0
  82. package/cdh/__pycache__/cdh_mcp_manager.cpython-314.pyc +0 -0
  83. package/cdh/__pycache__/cdh_session_aggregator.cpython-314.pyc +0 -0
  84. package/cdh/__pycache__/cdh_skill_loader.cpython-314.pyc +0 -0
  85. package/cdh/__pycache__/cdh_skill_manager.cpython-314.pyc +0 -0
  86. package/cdh/__pycache__/cli.cpython-313.pyc +0 -0
  87. package/cdh/__pycache__/cli.cpython-314.pyc +0 -0
  88. package/cdh/__pycache__/scaffold.cpython-314.pyc +0 -0
  89. package/cdh/cdh_mcp_injector.py +0 -115
  90. package/cdh/cdh_mcp_loader.py +0 -67
  91. package/cdh/cdh_mcp_manager.py +0 -73
  92. package/cdh/cdh_session_aggregator.py +0 -258
  93. package/cdh/cdh_skill_manager.py +0 -105
  94. package/cdh/cli.py +0 -807
  95. package/cdh/scaffold.py +0 -728
  96. package/onecode/__init__.py +0 -1
  97. package/onecode/__main__.py +0 -4
  98. package/onecode/__pycache__/__init__.cpython-314.pyc +0 -0
  99. package/onecode/__pycache__/cli.cpython-314.pyc +0 -0
  100. package/onecode/__pycache__/commands.cpython-314.pyc +0 -0
  101. package/onecode/__pycache__/config.cpython-314.pyc +0 -0
  102. package/onecode/__pycache__/config_screen.cpython-314.pyc +0 -0
  103. package/onecode/__pycache__/migrate.cpython-314.pyc +0 -0
  104. package/onecode/agent/__init__.py +0 -0
  105. package/onecode/agent/__pycache__/__init__.cpython-314.pyc +0 -0
  106. package/onecode/agent/__pycache__/cdh_loader.cpython-314.pyc +0 -0
  107. package/onecode/agent/__pycache__/context.cpython-314.pyc +0 -0
  108. package/onecode/agent/__pycache__/engine.cpython-314.pyc +0 -0
  109. package/onecode/agent/__pycache__/hooks.cpython-314.pyc +0 -0
  110. package/onecode/agent/__pycache__/onecode_agent_acp.cpython-314.pyc +0 -0
  111. package/onecode/agent/__pycache__/permissions.cpython-314.pyc +0 -0
  112. package/onecode/agent/__pycache__/permissions_store.cpython-314.pyc +0 -0
  113. package/onecode/agent/__pycache__/project_doc.cpython-314.pyc +0 -0
  114. package/onecode/agent/__pycache__/session.cpython-314.pyc +0 -0
  115. package/onecode/agent/agents/__init__.py +0 -29
  116. package/onecode/agent/agents/__pycache__/__init__.cpython-314.pyc +0 -0
  117. package/onecode/agent/agents/__pycache__/types.cpython-314.pyc +0 -0
  118. package/onecode/agent/agents/types.py +0 -589
  119. package/onecode/agent/attachments.py +0 -112
  120. package/onecode/agent/cdh_loader.py +0 -267
  121. package/onecode/agent/context.py +0 -343
  122. package/onecode/agent/engine.py +0 -2700
  123. package/onecode/agent/hooks.py +0 -86
  124. package/onecode/agent/onecode_agent_acp.py +0 -2743
  125. package/onecode/agent/onecode_agent_acp.py.bak +0 -2447
  126. package/onecode/agent/permissions.py +0 -150
  127. package/onecode/agent/permissions_store.py +0 -62
  128. package/onecode/agent/project_doc.py +0 -19
  129. package/onecode/agent/session.py +0 -195
  130. package/onecode/agent/snapshot.py +0 -144
  131. package/onecode/agent/tools/__init__.py +0 -17
  132. package/onecode/agent/tools/__pycache__/__init__.cpython-314.pyc +0 -0
  133. package/onecode/agent/tools/__pycache__/agent_tools.cpython-314.pyc +0 -0
  134. package/onecode/agent/tools/__pycache__/apply_patch_tool.cpython-314.pyc +0 -0
  135. package/onecode/agent/tools/__pycache__/bash_tool.cpython-314.pyc +0 -0
  136. package/onecode/agent/tools/__pycache__/communication_tools.cpython-314.pyc +0 -0
  137. package/onecode/agent/tools/__pycache__/config_tool.cpython-314.pyc +0 -0
  138. package/onecode/agent/tools/__pycache__/cron_tools.cpython-314.pyc +0 -0
  139. package/onecode/agent/tools/__pycache__/errors.cpython-314.pyc +0 -0
  140. package/onecode/agent/tools/__pycache__/file_ops.cpython-314.pyc +0 -0
  141. package/onecode/agent/tools/__pycache__/file_tools.cpython-314.pyc +0 -0
  142. package/onecode/agent/tools/__pycache__/git_tools.cpython-314.pyc +0 -0
  143. package/onecode/agent/tools/__pycache__/lsp_tools.cpython-314.pyc +0 -0
  144. package/onecode/agent/tools/__pycache__/mcp_tools.cpython-314.pyc +0 -0
  145. package/onecode/agent/tools/__pycache__/permission_handler.cpython-314.pyc +0 -0
  146. package/onecode/agent/tools/__pycache__/permissions.cpython-314.pyc +0 -0
  147. package/onecode/agent/tools/__pycache__/protocol.cpython-314.pyc +0 -0
  148. package/onecode/agent/tools/__pycache__/registry.cpython-314.pyc +0 -0
  149. package/onecode/agent/tools/__pycache__/sandbox.cpython-314.pyc +0 -0
  150. package/onecode/agent/tools/__pycache__/schema_validation.cpython-314.pyc +0 -0
  151. package/onecode/agent/tools/__pycache__/skill_tools.cpython-314.pyc +0 -0
  152. package/onecode/agent/tools/__pycache__/todo_tools.cpython-314.pyc +0 -0
  153. package/onecode/agent/tools/__pycache__/web_tools.cpython-314.pyc +0 -0
  154. package/onecode/agent/tools/agent_tools.py +0 -132
  155. package/onecode/agent/tools/apply_patch_tool.py +0 -138
  156. package/onecode/agent/tools/bash_tool.py +0 -111
  157. package/onecode/agent/tools/communication_tools.py +0 -148
  158. package/onecode/agent/tools/config_tool.py +0 -130
  159. package/onecode/agent/tools/cron_tools.py +0 -178
  160. package/onecode/agent/tools/errors.py +0 -17
  161. package/onecode/agent/tools/file_ops.py +0 -221
  162. package/onecode/agent/tools/file_tools.py +0 -225
  163. package/onecode/agent/tools/git_tools.py +0 -88
  164. package/onecode/agent/tools/lsp_tools.py +0 -404
  165. package/onecode/agent/tools/mcp_tools.py +0 -127
  166. package/onecode/agent/tools/permission_handler.py +0 -46
  167. package/onecode/agent/tools/permissions.py +0 -77
  168. package/onecode/agent/tools/protocol.py +0 -20
  169. package/onecode/agent/tools/registry.py +0 -201
  170. package/onecode/agent/tools/sandbox.py +0 -358
  171. package/onecode/agent/tools/schema_validation.py +0 -100
  172. package/onecode/agent/tools/skill_tools.py +0 -52
  173. package/onecode/agent/tools/todo_tools.py +0 -207
  174. package/onecode/agent/tools/web_tools.py +0 -169
  175. package/onecode/builtin_skills/agent-browser/SKILL.md +0 -212
  176. package/onecode/builtin_skills/agent-browser/skill.yaml +0 -8
  177. package/onecode/builtin_skills/git/SKILL.md +0 -64
  178. package/onecode/builtin_skills/git/skill.yaml +0 -7
  179. package/onecode/builtin_skills/shell/SKILL.md +0 -58
  180. package/onecode/builtin_skills/shell/skill.yaml +0 -8
  181. package/onecode/builtin_skills/skill-creator/SKILL.md +0 -106
  182. package/onecode/builtin_skills/skill-creator/skill.yaml +0 -8
  183. package/onecode/cli.py +0 -935
  184. package/onecode/cloud/__init__.py +0 -0
  185. package/onecode/cloud/base.py +0 -20
  186. package/onecode/codebase/__init__.py +0 -69
  187. package/onecode/codebase/__pycache__/__init__.cpython-314.pyc +0 -0
  188. package/onecode/codebase/__pycache__/chunker.cpython-314.pyc +0 -0
  189. package/onecode/codebase/__pycache__/indexer.cpython-314.pyc +0 -0
  190. package/onecode/codebase/__pycache__/retriever.cpython-314.pyc +0 -0
  191. package/onecode/codebase/__pycache__/storage.cpython-314.pyc +0 -0
  192. package/onecode/codebase/__pycache__/tools.cpython-314.pyc +0 -0
  193. package/onecode/codebase/chunker.py +0 -125
  194. package/onecode/codebase/indexer.py +0 -149
  195. package/onecode/codebase/retriever.py +0 -203
  196. package/onecode/codebase/storage.py +0 -131
  197. package/onecode/codebase/tools.py +0 -59
  198. package/onecode/commands.py +0 -596
  199. package/onecode/config.py +0 -314
  200. package/onecode/config_screen.py +0 -600
  201. package/onecode/cron/__init__.py +0 -3
  202. package/onecode/lsp/__init__.py +0 -3
  203. package/onecode/mcp/__init__.py +0 -4
  204. package/onecode/mcp/__pycache__/__init__.cpython-314.pyc +0 -0
  205. package/onecode/mcp/__pycache__/client.cpython-314.pyc +0 -0
  206. package/onecode/mcp/__pycache__/manager.cpython-314.pyc +0 -0
  207. package/onecode/mcp/client.py +0 -193
  208. package/onecode/mcp/manager.py +0 -190
  209. package/onecode/memory/__init__.py +0 -49
  210. package/onecode/memory/__pycache__/__init__.cpython-314.pyc +0 -0
  211. package/onecode/memory/__pycache__/backend.cpython-314.pyc +0 -0
  212. package/onecode/memory/__pycache__/offload.cpython-314.pyc +0 -0
  213. package/onecode/memory/__pycache__/pyramid.cpython-314.pyc +0 -0
  214. package/onecode/memory/__pycache__/recall.cpython-314.pyc +0 -0
  215. package/onecode/memory/__pycache__/symbolic.cpython-314.pyc +0 -0
  216. package/onecode/memory/backend.py +0 -159
  217. package/onecode/memory/pyramid.py +0 -133
  218. package/onecode/memory/recall.py +0 -203
  219. package/onecode/migrate.py +0 -122
  220. package/onecode/models/__init__.py +0 -4
  221. package/onecode/models/__pycache__/__init__.cpython-314.pyc +0 -0
  222. package/onecode/models/__pycache__/errors.cpython-314.pyc +0 -0
  223. package/onecode/models/__pycache__/messages.cpython-314.pyc +0 -0
  224. package/onecode/models/__pycache__/provider.cpython-314.pyc +0 -0
  225. package/onecode/models/__pycache__/registry.cpython-314.pyc +0 -0
  226. package/onecode/models/errors.py +0 -104
  227. package/onecode/models/messages.py +0 -739
  228. package/onecode/models/provider.py +0 -699
  229. package/onecode/models/providers/__init__.py +0 -17
  230. package/onecode/models/providers/__pycache__/__init__.cpython-314.pyc +0 -0
  231. package/onecode/models/providers/__pycache__/anthropic_provider.cpython-314.pyc +0 -0
  232. package/onecode/models/providers/__pycache__/deepseek_provider.cpython-314.pyc +0 -0
  233. package/onecode/models/providers/__pycache__/glm_provider.cpython-314.pyc +0 -0
  234. package/onecode/models/providers/__pycache__/minimax_provider.cpython-314.pyc +0 -0
  235. package/onecode/models/providers/__pycache__/minimaxi_provider.cpython-314.pyc +0 -0
  236. package/onecode/models/providers/__pycache__/ollama_provider.cpython-314.pyc +0 -0
  237. package/onecode/models/providers/__pycache__/openai_provider.cpython-314.pyc +0 -0
  238. package/onecode/models/providers/anthropic_provider.py +0 -273
  239. package/onecode/models/providers/deepseek_provider.py +0 -212
  240. package/onecode/models/providers/glm_provider.py +0 -195
  241. package/onecode/models/providers/minimax_provider.py +0 -158
  242. package/onecode/models/providers/minimaxi_provider.py +0 -417
  243. package/onecode/models/providers/ollama_provider.py +0 -100
  244. package/onecode/models/providers/openai_provider.py +0 -237
  245. package/onecode/models/registry.py +0 -212
  246. package/onecode/server/__init__.py +0 -3
  247. package/onecode/server/app.py +0 -224
  248. package/onecode/skills/__init__.py +0 -11
  249. package/onecode/skills/__pycache__/__init__.cpython-314.pyc +0 -0
  250. package/onecode/skills/__pycache__/argument_substitution.cpython-314.pyc +0 -0
  251. package/onecode/skills/__pycache__/bootstrap.cpython-314.pyc +0 -0
  252. package/onecode/skills/__pycache__/create.cpython-314.pyc +0 -0
  253. package/onecode/skills/__pycache__/frontmatter.cpython-314.pyc +0 -0
  254. package/onecode/skills/__pycache__/loader.cpython-314.pyc +0 -0
  255. package/onecode/skills/__pycache__/manager.cpython-314.pyc +0 -0
  256. package/onecode/skills/__pycache__/model.cpython-314.pyc +0 -0
  257. package/onecode/skills/argument_substitution.py +0 -38
  258. package/onecode/skills/bootstrap.py +0 -124
  259. package/onecode/skills/create.py +0 -56
  260. package/onecode/skills/frontmatter.py +0 -33
  261. package/onecode/skills/loader.py +0 -139
  262. package/onecode/skills/manager.py +0 -75
  263. package/onecode/skills/model.py +0 -43
  264. package/onecode/storage/__init__.py +0 -0
  265. package/onecode/storage/activity.py +0 -63
  266. package/onecode/storage/project.py +0 -54
  267. package/onecode/storage/session.py +0 -112
  268. package/onecode/tasks/__init__.py +0 -26
  269. package/onecode/tasks/manager.py +0 -232
  270. package/onecode/tasks/models.py +0 -240
  271. package/onecode/trace/__init__.py +0 -0
  272. package/onecode/trace/tracer.py +0 -173
  273. package/onecode/utils/__init__.py +0 -0
  274. package/onecode/utils/helpers.py +0 -20
  275. package/pyproject.toml +0 -74
  276. package/tui/__init__.py +0 -46
  277. package/tui/__main__.py +0 -4
  278. package/tui/__pycache__/__init__.cpython-314.pyc +0 -0
  279. package/tui/__pycache__/_loop.cpython-314.pyc +0 -0
  280. package/tui/__pycache__/_path_fuzzy_search.cpython-314.pyc +0 -0
  281. package/tui/__pycache__/_path_match.cpython-314.pyc +0 -0
  282. package/tui/__pycache__/about.cpython-314.pyc +0 -0
  283. package/tui/__pycache__/agent.cpython-314.pyc +0 -0
  284. package/tui/__pycache__/agent_schema.cpython-314.pyc +0 -0
  285. package/tui/__pycache__/agents.cpython-314.pyc +0 -0
  286. package/tui/__pycache__/answer.cpython-314.pyc +0 -0
  287. package/tui/__pycache__/app.cpython-313.pyc +0 -0
  288. package/tui/__pycache__/app.cpython-314.pyc +0 -0
  289. package/tui/__pycache__/atomic.cpython-314.pyc +0 -0
  290. package/tui/__pycache__/complete.cpython-314.pyc +0 -0
  291. package/tui/__pycache__/constants.cpython-314.pyc +0 -0
  292. package/tui/__pycache__/conversation_markdown.cpython-314.pyc +0 -0
  293. package/tui/__pycache__/danger.cpython-314.pyc +0 -0
  294. package/tui/__pycache__/db.cpython-314.pyc +0 -0
  295. package/tui/__pycache__/dec.cpython-314.pyc +0 -0
  296. package/tui/__pycache__/directory.cpython-314.pyc +0 -0
  297. package/tui/__pycache__/directory_suggester.cpython-314.pyc +0 -0
  298. package/tui/__pycache__/directory_watcher.cpython-314.pyc +0 -0
  299. package/tui/__pycache__/format_path.cpython-314.pyc +0 -0
  300. package/tui/__pycache__/fuzzy.cpython-314.pyc +0 -0
  301. package/tui/__pycache__/fuzzy_index.cpython-314.pyc +0 -0
  302. package/tui/__pycache__/history.cpython-314.pyc +0 -0
  303. package/tui/__pycache__/jsonrpc.cpython-314.pyc +0 -0
  304. package/tui/__pycache__/menus.cpython-314.pyc +0 -0
  305. package/tui/__pycache__/message_log.cpython-314.pyc +0 -0
  306. package/tui/__pycache__/messages.cpython-314.pyc +0 -0
  307. package/tui/__pycache__/path_complete.cpython-314.pyc +0 -0
  308. package/tui/__pycache__/path_filter.cpython-314.pyc +0 -0
  309. package/tui/__pycache__/paths.cpython-314.pyc +0 -0
  310. package/tui/__pycache__/pill.cpython-314.pyc +0 -0
  311. package/tui/__pycache__/platform_commands.cpython-314.pyc +0 -0
  312. package/tui/__pycache__/protocol.cpython-314.pyc +0 -0
  313. package/tui/__pycache__/session_tracker.cpython-314.pyc +0 -0
  314. package/tui/__pycache__/settings.cpython-314.pyc +0 -0
  315. package/tui/__pycache__/settings_schema.cpython-314.pyc +0 -0
  316. package/tui/__pycache__/shell.cpython-314.pyc +0 -0
  317. package/tui/__pycache__/shell_read.cpython-314.pyc +0 -0
  318. package/tui/__pycache__/slash_command.cpython-314.pyc +0 -0
  319. package/tui/__pycache__/version.cpython-314.pyc +0 -0
  320. package/tui/_loop.py +0 -86
  321. package/tui/_path_fuzzy_search.py +0 -48
  322. package/tui/_path_match.py +0 -141
  323. package/tui/about.py +0 -95
  324. package/tui/acp/__pycache__/agent.cpython-314.pyc +0 -0
  325. package/tui/acp/__pycache__/api.cpython-314.pyc +0 -0
  326. package/tui/acp/__pycache__/encode_tool_call_id.cpython-314.pyc +0 -0
  327. package/tui/acp/__pycache__/messages.cpython-314.pyc +0 -0
  328. package/tui/acp/__pycache__/prompt.cpython-314.pyc +0 -0
  329. package/tui/acp/__pycache__/protocol.cpython-314.pyc +0 -0
  330. package/tui/acp/agent.py +0 -1002
  331. package/tui/acp/api.py +0 -73
  332. package/tui/acp/encode_tool_call_id.py +0 -12
  333. package/tui/acp/messages.py +0 -203
  334. package/tui/acp/prompt.py +0 -53
  335. package/tui/acp/protocol.py +0 -499
  336. package/tui/agent.py +0 -70
  337. package/tui/agent_schema.py +0 -76
  338. package/tui/agents.py +0 -46
  339. package/tui/ansi/__init__.py +0 -1
  340. package/tui/ansi/__pycache__/__init__.cpython-314.pyc +0 -0
  341. package/tui/ansi/__pycache__/_ansi.cpython-314.pyc +0 -0
  342. package/tui/ansi/__pycache__/_ansi_colors.cpython-314.pyc +0 -0
  343. package/tui/ansi/__pycache__/_control_codes.cpython-314.pyc +0 -0
  344. package/tui/ansi/__pycache__/_keys.cpython-314.pyc +0 -0
  345. package/tui/ansi/__pycache__/_sgr_styles.cpython-314.pyc +0 -0
  346. package/tui/ansi/__pycache__/_stream_parser.cpython-314.pyc +0 -0
  347. package/tui/ansi/_ansi.py +0 -1689
  348. package/tui/ansi/_ansi_colors.py +0 -264
  349. package/tui/ansi/_control_codes.py +0 -37
  350. package/tui/ansi/_keys.py +0 -251
  351. package/tui/ansi/_sgr_styles.py +0 -64
  352. package/tui/ansi/_stream_parser.py +0 -418
  353. package/tui/answer.py +0 -12
  354. package/tui/app.py +0 -1266
  355. package/tui/atomic.py +0 -37
  356. package/tui/cli.py +0 -313
  357. package/tui/code_analyze.py +0 -27
  358. package/tui/complete.py +0 -38
  359. package/tui/constants.py +0 -61
  360. package/tui/conversation_markdown.py +0 -30
  361. package/tui/danger.py +0 -372
  362. package/tui/data/agents/ampcode.com.toml +0 -52
  363. package/tui/data/agents/augmentcode.com.toml +0 -41
  364. package/tui/data/agents/cdh.cloud-dev-harness.toml +0 -23
  365. package/tui/data/agents/claude.com.toml +0 -41
  366. package/tui/data/agents/copilot.github.com.toml +0 -29
  367. package/tui/data/agents/crowai.dev.toml +0 -36
  368. package/tui/data/agents/cursor.com.toml +0 -38
  369. package/tui/data/agents/deepagents.langchain.com +0 -34
  370. package/tui/data/agents/docker.com.toml +0 -60
  371. package/tui/data/agents/geminicli.com.toml +0 -28
  372. package/tui/data/agents/goose.ai.toml +0 -52
  373. package/tui/data/agents/inference.huggingface.co.toml +0 -41
  374. package/tui/data/agents/kimi.com.toml +0 -35
  375. package/tui/data/agents/kiro.dev.toml +0 -43
  376. package/tui/data/agents/onecode.dev.toml +0 -22
  377. package/tui/data/agents/openai.com.toml +0 -53
  378. package/tui/data/agents/openclaw.ai.toml +0 -37
  379. package/tui/data/agents/opencode.ai.toml +0 -39
  380. package/tui/data/agents/openhands.dev.toml +0 -46
  381. package/tui/data/agents/stakpak.dev.toml +0 -62
  382. package/tui/data/agents/vibe.mistral.ai.toml +0 -31
  383. package/tui/data/agents/vtcode.dev.toml +0 -63
  384. package/tui/data/images/frog.png +0 -0
  385. package/tui/data/sounds/question.wav +0 -0
  386. package/tui/data/sounds/turn-over.wav +0 -0
  387. package/tui/db.py +0 -213
  388. package/tui/dec.py +0 -332
  389. package/tui/directory.py +0 -234
  390. package/tui/directory_suggester.py +0 -93
  391. package/tui/directory_watcher.py +0 -231
  392. package/tui/format_path.py +0 -25
  393. package/tui/fuzzy.py +0 -140
  394. package/tui/fuzzy_index.py +0 -275
  395. package/tui/gist.py +0 -33
  396. package/tui/history.py +0 -138
  397. package/tui/jsonrpc.py +0 -578
  398. package/tui/menus.py +0 -14
  399. package/tui/message_log.py +0 -69
  400. package/tui/messages.py +0 -144
  401. package/tui/option_content.py +0 -51
  402. package/tui/os.py +0 -0
  403. package/tui/path_complete.py +0 -217
  404. package/tui/path_filter.py +0 -124
  405. package/tui/paths.py +0 -87
  406. package/tui/pill.py +0 -23
  407. package/tui/platform_commands.py +0 -52
  408. package/tui/prompt/__pycache__/extract.cpython-314.pyc +0 -0
  409. package/tui/prompt/__pycache__/resource.cpython-314.pyc +0 -0
  410. package/tui/prompt/extract.py +0 -19
  411. package/tui/prompt/resource.py +0 -68
  412. package/tui/protocol.py +0 -28
  413. package/tui/screens/__init__.py +0 -0
  414. package/tui/screens/__pycache__/__init__.cpython-314.pyc +0 -0
  415. package/tui/screens/__pycache__/agent_modal.cpython-314.pyc +0 -0
  416. package/tui/screens/__pycache__/component_picker.cpython-314.pyc +0 -0
  417. package/tui/screens/__pycache__/diff_screen.cpython-314.pyc +0 -0
  418. package/tui/screens/__pycache__/log.cpython-314.pyc +0 -0
  419. package/tui/screens/__pycache__/main.cpython-313.pyc +0 -0
  420. package/tui/screens/__pycache__/main.cpython-314.pyc +0 -0
  421. package/tui/screens/__pycache__/permissions.cpython-314.pyc +0 -0
  422. package/tui/screens/__pycache__/projects_app.cpython-314.pyc +0 -0
  423. package/tui/screens/__pycache__/projects_screen.cpython-314.pyc +0 -0
  424. package/tui/screens/__pycache__/sessions.cpython-314.pyc +0 -0
  425. package/tui/screens/__pycache__/store.cpython-314.pyc +0 -0
  426. package/tui/screens/__pycache__/tool_content_screen.cpython-314.pyc +0 -0
  427. package/tui/screens/action_modal.py +0 -94
  428. package/tui/screens/agent_modal.py +0 -175
  429. package/tui/screens/command_edit_modal.py +0 -74
  430. package/tui/screens/component_picker.py +0 -168
  431. package/tui/screens/diff_screen.py +0 -84
  432. package/tui/screens/log.py +0 -553
  433. package/tui/screens/main.py +0 -385
  434. package/tui/screens/main.tcss +0 -655
  435. package/tui/screens/permissions.py +0 -404
  436. package/tui/screens/permissions.tcss +0 -72
  437. package/tui/screens/projects.tcss +0 -80
  438. package/tui/screens/projects_app.py +0 -347
  439. package/tui/screens/projects_screen.py +0 -284
  440. package/tui/screens/session_resume_modal.py +0 -172
  441. package/tui/screens/session_resume_modal.tcss +0 -35
  442. package/tui/screens/sessions.py +0 -164
  443. package/tui/screens/sessions.tcss +0 -119
  444. package/tui/screens/settings.py +0 -254
  445. package/tui/screens/settings.tcss +0 -101
  446. package/tui/screens/store.py +0 -500
  447. package/tui/screens/store.tcss +0 -274
  448. package/tui/screens/tool_content_screen.py +0 -59
  449. package/tui/session_tracker.py +0 -123
  450. package/tui/settings.py +0 -353
  451. package/tui/settings_schema.py +0 -431
  452. package/tui/shell.py +0 -304
  453. package/tui/shell_read.py +0 -42
  454. package/tui/slash_command.py +0 -34
  455. package/tui/tui.tcss +0 -246
  456. package/tui/twitter.py +0 -38
  457. package/tui/version.py +0 -80
  458. package/tui/visuals/__init__.py +0 -0
  459. package/tui/visuals/__pycache__/__init__.cpython-314.pyc +0 -0
  460. package/tui/visuals/__pycache__/columns.cpython-314.pyc +0 -0
  461. package/tui/visuals/columns.py +0 -272
  462. package/tui/widgets/__init__.py +0 -0
  463. package/tui/widgets/__pycache__/__init__.cpython-314.pyc +0 -0
  464. package/tui/widgets/__pycache__/acp_content.cpython-314.pyc +0 -0
  465. package/tui/widgets/__pycache__/agent_response.cpython-314.pyc +0 -0
  466. package/tui/widgets/__pycache__/agent_thought.cpython-314.pyc +0 -0
  467. package/tui/widgets/__pycache__/ask_user.cpython-314.pyc +0 -0
  468. package/tui/widgets/__pycache__/condensed_path.cpython-314.pyc +0 -0
  469. package/tui/widgets/__pycache__/context_stats.cpython-314.pyc +0 -0
  470. package/tui/widgets/__pycache__/conversation.cpython-314.pyc +0 -0
  471. package/tui/widgets/__pycache__/diff_view.cpython-314.pyc +0 -0
  472. package/tui/widgets/__pycache__/directory_input.cpython-314.pyc +0 -0
  473. package/tui/widgets/__pycache__/flash.cpython-314.pyc +0 -0
  474. package/tui/widgets/__pycache__/future_text.cpython-314.pyc +0 -0
  475. package/tui/widgets/__pycache__/grid_select.cpython-314.pyc +0 -0
  476. package/tui/widgets/__pycache__/highlighted_textarea.cpython-314.pyc +0 -0
  477. package/tui/widgets/__pycache__/load_more.cpython-314.pyc +0 -0
  478. package/tui/widgets/__pycache__/mandelbrot.cpython-314.pyc +0 -0
  479. package/tui/widgets/__pycache__/markdown_note.cpython-314.pyc +0 -0
  480. package/tui/widgets/__pycache__/menu.cpython-314.pyc +0 -0
  481. package/tui/widgets/__pycache__/modified_files.cpython-314.pyc +0 -0
  482. package/tui/widgets/__pycache__/non_selectable_label.cpython-314.pyc +0 -0
  483. package/tui/widgets/__pycache__/note.cpython-314.pyc +0 -0
  484. package/tui/widgets/__pycache__/path_search.cpython-314.pyc +0 -0
  485. package/tui/widgets/__pycache__/plan.cpython-314.pyc +0 -0
  486. package/tui/widgets/__pycache__/project_directory_tree.cpython-314.pyc +0 -0
  487. package/tui/widgets/__pycache__/project_grid_select.cpython-314.pyc +0 -0
  488. package/tui/widgets/__pycache__/project_summary.cpython-314.pyc +0 -0
  489. package/tui/widgets/__pycache__/prompt.cpython-314.pyc +0 -0
  490. package/tui/widgets/__pycache__/question.cpython-314.pyc +0 -0
  491. package/tui/widgets/__pycache__/session_grid_select.cpython-314.pyc +0 -0
  492. package/tui/widgets/__pycache__/session_summary.cpython-314.pyc +0 -0
  493. package/tui/widgets/__pycache__/session_tabs.cpython-314.pyc +0 -0
  494. package/tui/widgets/__pycache__/shell_result.cpython-314.pyc +0 -0
  495. package/tui/widgets/__pycache__/shell_terminal.cpython-314.pyc +0 -0
  496. package/tui/widgets/__pycache__/side_bar.cpython-314.pyc +0 -0
  497. package/tui/widgets/__pycache__/slash_complete.cpython-314.pyc +0 -0
  498. package/tui/widgets/__pycache__/strike_text.cpython-314.pyc +0 -0
  499. package/tui/widgets/__pycache__/subagent.cpython-314.pyc +0 -0
  500. package/tui/widgets/__pycache__/subagent_screen.cpython-314.pyc +0 -0
  501. package/tui/widgets/__pycache__/terminal.cpython-314.pyc +0 -0
  502. package/tui/widgets/__pycache__/throbber.cpython-314.pyc +0 -0
  503. package/tui/widgets/__pycache__/tool_call.cpython-314.pyc +0 -0
  504. package/tui/widgets/__pycache__/user_input.cpython-314.pyc +0 -0
  505. package/tui/widgets/acp_content.py +0 -70
  506. package/tui/widgets/agent_response.py +0 -76
  507. package/tui/widgets/agent_thought.py +0 -167
  508. package/tui/widgets/ask_user.py +0 -264
  509. package/tui/widgets/command_pane.py +0 -223
  510. package/tui/widgets/condensed_path.py +0 -115
  511. package/tui/widgets/context_stats.py +0 -66
  512. package/tui/widgets/conversation.py +0 -2641
  513. package/tui/widgets/danger_warning.py +0 -65
  514. package/tui/widgets/diff_view.py +0 -69
  515. package/tui/widgets/directory_input.py +0 -8
  516. package/tui/widgets/flash.py +0 -81
  517. package/tui/widgets/future_text.py +0 -126
  518. package/tui/widgets/grid_select.py +0 -234
  519. package/tui/widgets/highlighted_textarea.py +0 -180
  520. package/tui/widgets/load_more.py +0 -24
  521. package/tui/widgets/mandelbrot.py +0 -294
  522. package/tui/widgets/markdown_note.py +0 -13
  523. package/tui/widgets/menu.py +0 -147
  524. package/tui/widgets/modified_files.py +0 -306
  525. package/tui/widgets/non_selectable_label.py +0 -5
  526. package/tui/widgets/note.py +0 -18
  527. package/tui/widgets/path_search.py +0 -492
  528. package/tui/widgets/plan.py +0 -285
  529. package/tui/widgets/project_directory_tree.py +0 -102
  530. package/tui/widgets/project_grid_select.py +0 -64
  531. package/tui/widgets/project_summary.py +0 -33
  532. package/tui/widgets/prompt.py +0 -795
  533. package/tui/widgets/question.py +0 -360
  534. package/tui/widgets/session_grid_select.py +0 -230
  535. package/tui/widgets/session_summary.py +0 -115
  536. package/tui/widgets/session_tabs.py +0 -188
  537. package/tui/widgets/shell_result.py +0 -35
  538. package/tui/widgets/shell_terminal.py +0 -40
  539. package/tui/widgets/side_bar.py +0 -124
  540. package/tui/widgets/slash_complete.py +0 -235
  541. package/tui/widgets/strike_text.py +0 -70
  542. package/tui/widgets/subagent.py +0 -287
  543. package/tui/widgets/subagent_screen.py +0 -709
  544. package/tui/widgets/terminal.py +0 -576
  545. package/tui/widgets/terminal_tool.py +0 -360
  546. package/tui/widgets/throbber.py +0 -100
  547. package/tui/widgets/tool_call.py +0 -398
  548. package/tui/widgets/user_input.py +0 -23
  549. package/tui/widgets/version.py +0 -5
  550. package/tui/widgets/welcome.py +0 -31
@@ -1,188 +0,0 @@
1
- import asyncio
2
- from functools import partial
3
- from rich.style import Style as RichStyle
4
-
5
- from textual import work
6
- from textual.app import ComposeResult, RenderResult
7
-
8
- from textual import events
9
- from textual.content import Content
10
- from textual.geometry import Offset
11
- from textual.reactive import reactive
12
- from textual.renderables.bar import Bar
13
- from textual.widget import Widget
14
- from textual import containers
15
- from textual import widgets
16
- from textual import getters
17
- from textual.message import Message
18
-
19
- from tui.app import A2TUIApp
20
- from tui.session_tracker import SessionDetails
21
- from tui import messages
22
-
23
-
24
- class SessionLabel(widgets.Label):
25
- ALLOW_SELECT = False
26
-
27
- def on_click(self) -> None:
28
- if self.id is not None:
29
- self.post_message(messages.SessionSwitch(self.id))
30
-
31
-
32
- class Underline(Widget):
33
- """The animated underline beneath tabs."""
34
-
35
- COMPONENT_CLASSES = {"underline--bar"}
36
- """
37
- | Class | Description |
38
- | :- | :- |
39
- | `underline--bar` | Style of the bar (may be used to change the color). |
40
- """
41
-
42
- highlight_start = reactive(0)
43
- """First cell in highlight."""
44
- highlight_end = reactive(0)
45
- """Last cell (inclusive) in highlight."""
46
- show_highlight: reactive[bool] = reactive(True)
47
- """Flag to indicate if a highlight should be shown at all."""
48
-
49
- class Clicked(Message):
50
- """Inform ancestors the underline was clicked."""
51
-
52
- offset: Offset
53
- """The offset of the click, relative to the origin of the bar."""
54
-
55
- def __init__(self, offset: Offset) -> None:
56
- self.offset = offset
57
- super().__init__()
58
-
59
- @property
60
- def _highlight_range(self) -> tuple[int, int]:
61
- """Highlighted range for underline bar."""
62
- return (
63
- (self.highlight_start, self.highlight_end)
64
- if self.show_highlight
65
- else (0, 0)
66
- )
67
-
68
- def render(self) -> RenderResult:
69
- """Render the bar."""
70
- bar_style = self.get_component_rich_style("underline--bar")
71
- return Bar(
72
- highlight_range=self._highlight_range,
73
- highlight_style=RichStyle.from_color(bar_style.color),
74
- background_style=RichStyle.from_color(bar_style.bgcolor),
75
- )
76
-
77
- def _on_click(self, event: events.Click):
78
- """Catch clicks, so that the underline can activate the tabs."""
79
- event.stop()
80
- self.post_message(self.Clicked(event.screen_offset))
81
-
82
-
83
- class SessionsTabs(Widget):
84
-
85
- ALLOW_SELECT = False
86
- app: getters.app[A2TUIApp] = getters.app(A2TUIApp)
87
-
88
- title_container = getters.query_one("#title-container", Widget)
89
-
90
- current_session = reactive("", init=False)
91
-
92
- def on_mount(self) -> None:
93
- self.current_session = self.app.current_mode
94
- self.app.mode_change_signal.subscribe(self, self.handle_mode_change)
95
- self.app.session_update_signal.subscribe(
96
- self, self.handle_session_update_signal, immediate=True
97
- )
98
- self.update_underline(self.current_session, animate=False)
99
- self.call_after_refresh(self.update_underline, self.current_session)
100
-
101
- def handle_mode_change(self, mode: str) -> None:
102
- self.current_session = mode
103
-
104
- def watch_current_session(self, old_session: str, new_session: str) -> None:
105
- self.query(".-current").remove_class("-current")
106
- self.query(f"#{new_session}").add_class("-current")
107
- if old_session:
108
- self.update_underline(old_session, animate=False)
109
-
110
- self.update_underline(new_session, animate=True)
111
-
112
- def update_underline(self, session: str | None = None, animate: bool = True):
113
- if not self.is_mounted or not self.is_attached:
114
- return
115
- if session is None:
116
- session = self.current_session
117
- if not session:
118
- return
119
- if current_label := self.query_one_optional(f"#{session}", SessionLabel):
120
- tab_region = current_label.virtual_region.shrink((0, 1, 0, 1))
121
- if not tab_region:
122
- return
123
- start, end = tab_region.column_span
124
- underline = self.query_one(Underline)
125
- if animate:
126
- underline.animate("highlight_start", start, duration=0.3)
127
- underline.animate(
128
- "highlight_end",
129
- end,
130
- duration=0.3,
131
- on_complete=partial(self.scroll_to_center, current_label),
132
- )
133
- else:
134
- underline.highlight_start = start
135
- underline.highlight_end = end
136
- self.scroll_to_center(current_label, animate=False)
137
-
138
- def render_session_label(self, session: SessionDetails) -> Content:
139
- match session.state:
140
- case "asking":
141
- return Content.assemble(
142
- ("❯ ", "not dim $text-secondary"), session.title
143
- )
144
- case "busy":
145
- return Content(f"⌛ {session.title}")
146
- return Content(session.title)
147
-
148
- def compose(self) -> ComposeResult:
149
- with containers.HorizontalGroup(id="title-container"):
150
- for session in self.app.session_tracker.ordered_sessions:
151
- yield SessionLabel(
152
- self.render_session_label(session),
153
- id=session.mode_name,
154
- classes="-current" if session.mode_name == self.screen.id else "",
155
- )
156
- yield Underline()
157
-
158
- @work(exit_on_error=False)
159
- async def handle_session_update_signal(
160
- self, update: tuple[str, SessionDetails | None]
161
- ) -> None:
162
- mode, details = update
163
- if details is None:
164
- removed_mode = mode
165
- await self.query(f"#{mode}").remove()
166
- if self.current_session == removed_mode:
167
- remaining = list(self.query(SessionLabel))
168
- if remaining:
169
- new_current = remaining[0].id or ""
170
- else:
171
- new_current = ""
172
- self.current_session = new_current
173
- else:
174
- if tab_label := self.query_one_optional(f"#{mode}", SessionLabel):
175
- tab_label.update(self.render_session_label(details))
176
- else:
177
- self.query(SessionLabel).remove_class("-current")
178
- await self.title_container.mount(
179
- SessionLabel(
180
- self.render_session_label(details),
181
- id=details.mode_name,
182
- classes=(
183
- "-current" if details.mode_name == self.screen.id else ""
184
- ),
185
- )
186
- )
187
- await asyncio.sleep(0.05)
188
- self.call_after_refresh(self.update_underline, self.current_session)
@@ -1,35 +0,0 @@
1
- from __future__ import annotations
2
- from typing import Iterable
3
-
4
- from textual.app import ComposeResult
5
- from textual import containers
6
- from textual.highlight import highlight
7
- from textual.widgets import Static
8
-
9
-
10
- from tui.menus import MenuItem
11
- from tui.widgets.non_selectable_label import NonSelectableLabel
12
-
13
-
14
- class ShellResult(containers.HorizontalGroup):
15
- def __init__(
16
- self,
17
- command: str,
18
- *,
19
- name: str | None = None,
20
- id: str | None = None,
21
- classes: str | None = None,
22
- disabled: bool = False,
23
- ) -> None:
24
- self._command = command
25
- super().__init__(name=name, id=id, classes=classes, disabled=disabled)
26
-
27
- def compose(self) -> ComposeResult:
28
- yield NonSelectableLabel("$", id="prompt", markup=False)
29
- yield Static(highlight(self._command, language="sh"))
30
-
31
- def get_block_menu(self) -> Iterable[MenuItem]:
32
- yield from ()
33
-
34
- def get_block_content(self, destination: str) -> str | None:
35
- return self._command
@@ -1,40 +0,0 @@
1
- from dataclasses import dataclass
2
- from typing import Iterable
3
-
4
- from textual.content import Content
5
- from textual.dom import DOMNode
6
- from textual.message import Message
7
-
8
- from tui.menus import MenuItem
9
- from tui.widgets.terminal import Terminal
10
-
11
-
12
- class ShellTerminal(Terminal):
13
- """Subclass of Terminal used in the Shell view."""
14
-
15
- @dataclass
16
- class Terminate(Message):
17
- teminal: ShellTerminal
18
-
19
- @property
20
- def control(self) -> DOMNode:
21
- return self.terminal
22
-
23
- @dataclass
24
- class Interrupt(Message):
25
- teminal: ShellTerminal
26
-
27
- @property
28
- def control(self) -> DOMNode:
29
- return self.terminal
30
-
31
- def get_block_menu(self) -> Iterable[MenuItem]:
32
- if not self.is_finalized:
33
- yield MenuItem("Interrupt", "interrupt", "i")
34
- yield MenuItem("Focus", f"focus_block({self.id!r})", "f")
35
-
36
- def get_block_content(self, destination: str) -> str | None:
37
- return "\n".join(line.content.plain for line in self.state.buffer.lines)
38
-
39
- def on_mount(self) -> None:
40
- self.border_title = Content(self.name)
@@ -1,124 +0,0 @@
1
- from dataclasses import dataclass
2
-
3
- from textual.app import ComposeResult
4
- from textual.binding import Binding
5
- from textual.widget import Widget
6
- from textual import containers
7
- from textual import widgets
8
- from textual.message import Message
9
-
10
-
11
- class SideBarCollapsible(widgets.Collapsible):
12
- BINDING_GROUP_TITLE = "Sidebar collapsible"
13
- BINDINGS = [
14
- Binding("down", "focus_content", "Focus content", show=False),
15
- ]
16
- HELP = """\
17
- ## Sidebar
18
-
19
- This is your sidebar.
20
-
21
- The Sidebar contains additonal information associated with the conversation.
22
-
23
- - **tab / shift+tab** Navigate sections
24
- - **enter** expand or collapse secions
25
- """
26
-
27
- def action_focus_content(self) -> None:
28
- """Move focus into the content area when expanded."""
29
- if self.collapsed:
30
- return
31
- self.screen.focus_next()
32
-
33
-
34
- class SideBar(containers.Vertical):
35
- BINDING_GROUP_TITLE = "Sidebar"
36
- BINDINGS = [("escape", "dismiss", "Dismiss sidebar")]
37
-
38
- class Dismiss(Message):
39
- pass
40
-
41
- @dataclass(frozen=True)
42
- class Panel:
43
- title: str
44
- widget: Widget
45
- flex: bool = False
46
- collapsed: bool = False
47
- id: str | None = None
48
-
49
- def __init__(
50
- self,
51
- *panels: Panel,
52
- name: str | None = None,
53
- id: str | None = None,
54
- classes: str | None = None,
55
- disabled: bool = False,
56
- hide: bool = False,
57
- ) -> None:
58
- super().__init__(name=name, id=id, classes=classes, disabled=disabled)
59
- self.panels: list[SideBar.Panel] = [*panels]
60
- self.hide = hide
61
-
62
- def on_mount(self) -> None:
63
- self.trap_focus()
64
-
65
- def compose(self) -> ComposeResult:
66
- for panel in self.panels:
67
- yield SideBarCollapsible(
68
- panel.widget,
69
- title=panel.title,
70
- collapsed=panel.collapsed,
71
- classes="-flex" if panel.flex else "-fixed",
72
- id=panel.id,
73
- )
74
-
75
- def action_dismiss(self) -> None:
76
- self.post_message(self.Dismiss())
77
-
78
- def has_panel(self, panel_id: str) -> bool:
79
- return self.query_one_optional(f"#{panel_id}") is not None
80
-
81
- async def add_panel(self, panel: Panel) -> SideBarCollapsible:
82
- collapsible = SideBarCollapsible(
83
- panel.widget,
84
- title=panel.title,
85
- collapsed=panel.collapsed,
86
- classes="-flex" if panel.flex else "-fixed",
87
- id=panel.id,
88
- )
89
- await self.mount(collapsible)
90
- self.panels.append(panel)
91
- return collapsible
92
-
93
- def remove_panel(self, panel_id: str) -> bool:
94
- for i, p in enumerate(self.panels):
95
- if p.id == panel_id:
96
- widget = self.query_one_optional(f"#{panel_id}")
97
- if widget is not None:
98
- widget.remove()
99
- self.panels.pop(i)
100
- return True
101
- return False
102
-
103
-
104
- if __name__ == "__main__":
105
- from textual.app import App, ComposeResult
106
-
107
- class SApp(App):
108
- def compose(self) -> ComposeResult:
109
- yield SideBar(
110
- SideBar.Panel("Hello", widgets.Label("Hello, World!")),
111
- SideBar.Panel(
112
- "Files",
113
- widgets.DirectoryTree(
114
- "~/",
115
- ),
116
- flex=True,
117
- ),
118
- SideBar.Panel(
119
- "Hello",
120
- widgets.Static("Where there is a Will! " * 10),
121
- ),
122
- )
123
-
124
- SApp().run()
@@ -1,235 +0,0 @@
1
- from dataclasses import dataclass
2
- from operator import itemgetter
3
- from typing import Iterable, Self, Sequence
4
-
5
- from textual import on
6
- from textual.app import ComposeResult
7
- from textual.binding import Binding
8
- from textual.content import Content, Span
9
-
10
- from textual import getters
11
- from textual.message import Message
12
- from textual.reactive import var
13
- from textual import containers
14
- from textual import widgets
15
- from textual.widgets.option_list import Option
16
-
17
- from tui.fuzzy import FuzzySearch
18
- from tui.messages import Dismiss
19
- from tui.slash_command import SlashCommand
20
- from tui.visuals.columns import Columns
21
-
22
-
23
- class SlashCompleteInput(widgets.Input):
24
- BINDING_GROUP_TITLE = "Fuzzy search slash commands"
25
- HELP = """\
26
- ## Slash command fuzzy search
27
-
28
- Search for slash commands by typing a few characters from the command.
29
-
30
- - **cursor keys** Navigate list
31
- - **enter** Add command to prompt
32
- - **escape** Dismiss fuzzy search
33
- """
34
-
35
-
36
- class SlashComplete(containers.VerticalGroup):
37
- """A widget to auto-complete slash commands."""
38
-
39
- CURSOR_BINDING_GROUP = Binding.Group(description="Select")
40
- BINDINGS = [
41
- Binding(
42
- "up",
43
- "cursor_up",
44
- "Cursor up",
45
- group=CURSOR_BINDING_GROUP,
46
- priority=True,
47
- ),
48
- Binding(
49
- "down",
50
- "cursor_down",
51
- "Cursor down",
52
- group=CURSOR_BINDING_GROUP,
53
- priority=True,
54
- ),
55
- Binding("enter", "submit", "Insert /command", priority=True),
56
- Binding("escape", "dismiss", "Dismiss", priority=True),
57
- ]
58
-
59
- DEFAULT_CSS = """
60
- SlashComplete {
61
- OptionList {
62
- height: auto;
63
- }
64
- }
65
- """
66
-
67
- input = getters.query_one(widgets.Input)
68
- option_list = getters.query_one(widgets.OptionList)
69
-
70
- slash_commands: var[list[SlashCommand]] = var(list)
71
-
72
- @dataclass
73
- class Completed(Message):
74
- command: str
75
-
76
- def __init__(
77
- self,
78
- slash_commands: Iterable[SlashCommand] | None = None,
79
- id: str | None = None,
80
- classes: str | None = None,
81
- ) -> None:
82
- super().__init__(id=id, classes=classes)
83
- self.slash_commands = list(slash_commands) if slash_commands else []
84
- self.hints = {
85
- slash_command.command: slash_command.hint
86
- for slash_command in self.slash_commands
87
- if slash_command.hint
88
- }
89
-
90
- self.fuzzy_search = FuzzySearch(case_sensitive=False)
91
-
92
- def compose(self) -> ComposeResult:
93
- yield SlashCompleteInput(compact=True, placeholder="fuzzy search")
94
- yield widgets.OptionList()
95
-
96
- def focus(self, scroll_visible: bool = False) -> Self:
97
- self.filter_slash_commands("")
98
- self.input.focus(scroll_visible)
99
- return self
100
-
101
- def on_mount(self) -> None:
102
- self.filter_slash_commands("")
103
-
104
- def on_descendant_blur(self) -> None:
105
- self.post_message(Dismiss(self))
106
-
107
- @on(widgets.Input.Changed)
108
- def on_input_changed(self, event: widgets.Input.Changed) -> None:
109
- event.stop()
110
- self.filter_slash_commands(event.value)
111
-
112
- async def watch_slash_commands(self, slash_commands: list[SlashCommand]) -> None:
113
- self.hints = {
114
- slash_command.command: slash_command.hint
115
- for slash_command in slash_commands
116
- if slash_command.hint
117
- }
118
- self.filter_slash_commands(self.input.value)
119
-
120
- def filter_slash_commands(self, prompt: str) -> None:
121
- """Filter slash commands by the given prompt.
122
-
123
- Args:
124
- prompt: Text prompt.
125
- """
126
- prompt = prompt.lstrip("/").casefold().rstrip()
127
- columns = self.columns = Columns("auto", "flex")
128
-
129
- slash_commands = sorted(
130
- self.slash_commands,
131
- key=lambda slash_command: slash_command.command.casefold(),
132
- )
133
- deduplicated_slash_commands = {
134
- slash_command.command: slash_command for slash_command in slash_commands
135
- }
136
- self.fuzzy_search.cache.grow(len(deduplicated_slash_commands))
137
-
138
- if prompt:
139
- slash_prompt = f"/{prompt}"
140
- scores: list[tuple[float, Sequence[int], SlashCommand]] = [
141
- (
142
- *self.fuzzy_search.match(prompt, slash_command.command[1:]),
143
- slash_command,
144
- )
145
- for slash_command in slash_commands
146
- ]
147
-
148
- scores = sorted(
149
- [
150
- (
151
- (
152
- score * 2
153
- if slash_command.command.casefold().startswith(slash_prompt)
154
- else score
155
- ),
156
- highlights,
157
- slash_command,
158
- )
159
- for score, highlights, slash_command in scores
160
- if score
161
- ],
162
- key=itemgetter(0),
163
- reverse=True,
164
- )
165
- else:
166
- scores = [(1.0, [], slash_command) for slash_command in slash_commands]
167
-
168
- def make_row(
169
- slash_command: SlashCommand, indices: Iterable[int]
170
- ) -> tuple[Content, ...]:
171
- """Make a row for the Columns display.
172
-
173
- Args:
174
- slash_command: The slash command instance.
175
- indices: Indices of matching characters.
176
-
177
- Returns:
178
- A tuple of `Content` instances for use as a column row.
179
- """
180
- command = Content.styled(slash_command.command, "$text-success")
181
- command = command.add_spans(
182
- [Span(index + 1, index + 2, "underline not dim") for index in indices]
183
- )
184
- return (command, Content.styled(slash_command.help, "dim"))
185
-
186
- rows = [
187
- (
188
- columns.add_row(
189
- *make_row(slash_command, indices),
190
- ),
191
- slash_command.command,
192
- )
193
- for _, indices, slash_command in scores
194
- ]
195
- self.option_list.set_options(
196
- Option(row, id=command_name) for row, command_name in rows
197
- )
198
- if self.display:
199
- self.option_list.highlighted = 0
200
- else:
201
- with self.option_list.prevent(widgets.OptionList.OptionHighlighted):
202
- self.option_list.highlighted = 0
203
-
204
- def action_cursor_down(self) -> None:
205
- self.option_list.action_cursor_down()
206
-
207
- def action_cursor_up(self) -> None:
208
- self.option_list.action_cursor_up()
209
-
210
- def action_dismiss(self) -> None:
211
- self.post_message(Dismiss(self))
212
-
213
- def action_submit(self) -> None:
214
- option_list = self.option_list
215
- if (option := option_list.highlighted_option) is not None:
216
- with self.input.prevent(widgets.Input.Changed):
217
- self.input.clear()
218
- self.post_message(self.Completed(option.id or ""))
219
-
220
-
221
- if __name__ == "__main__":
222
- from textual.app import App, ComposeResult
223
-
224
- COMMANDS = [
225
- SlashCommand("/help", "Help with slash commands"),
226
- SlashCommand("/foo", "This is FOO"),
227
- SlashCommand("/bar", "This is BAR"),
228
- SlashCommand("/baz", "This is BAZ"),
229
- ]
230
-
231
- class SlashApp(App):
232
- def compose(self) -> ComposeResult:
233
- yield SlashComplete(COMMANDS)
234
-
235
- SlashApp().run()
@@ -1,70 +0,0 @@
1
- from time import monotonic
2
-
3
- from textual.widget import Widget
4
-
5
- from textual.content import Content
6
- from textual.reactive import reactive
7
-
8
-
9
- class StrikeText(Widget):
10
- DEFAULT_CSS = """
11
- StrikeText {
12
- height: auto;
13
- &.-complete {
14
- text-style: strike;
15
- color: $text-primary;
16
- }
17
- }
18
- """
19
-
20
- strike_time: reactive[float | None] = reactive(None)
21
-
22
- def __init__(
23
- self,
24
- content: Content,
25
- name: str | None = None,
26
- id: str | None = None,
27
- classes: str | None = None,
28
- ):
29
- self.content = content
30
- super().__init__(name=name, id=id, classes=classes)
31
-
32
- def strike(self) -> None:
33
- self.strike_time = monotonic()
34
- self.auto_refresh = 1 / 30
35
-
36
- def render(self) -> Content:
37
- content = self.content
38
- if self.strike_time is not None:
39
- position = int((monotonic() - self.strike_time) * 70)
40
- content = content.stylize("strike $text-primary", 0, position)
41
- if position > len(content):
42
- self.auto_refresh = None
43
- return content
44
-
45
-
46
- if __name__ == "__main__":
47
- from textual.app import App, ComposeResult
48
- from textual.widgets import Static
49
-
50
- class StrikeApp(App):
51
- CSS = """
52
- Screen {
53
- overflow: auto;
54
- }
55
-
56
- """
57
- BINDINGS = [("space", "strike", "Strike")]
58
-
59
- def compose(self) -> ComposeResult:
60
- for n in range(20):
61
- yield Static("HELLO")
62
- yield StrikeText(Content("Where there is a Will, there is a way"))
63
- for n in range(200):
64
- yield Static("World")
65
-
66
- def action_strike(self):
67
- self.query_one(StrikeText).strike()
68
-
69
- app = StrikeApp()
70
- app.run()