@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,360 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from dataclasses import dataclass
4
- from typing import Any, Callable
5
-
6
- from textual.app import ComposeResult
7
- from textual import getters
8
- from textual import events, on
9
- from textual.binding import Binding
10
- from textual import containers
11
- from textual.content import Content
12
- from textual.reactive import var, reactive
13
- from textual.message import Message
14
- from textual.widget import Widget
15
-
16
- from textual import widgets
17
-
18
- from tui.answer import Answer
19
-
20
- type Options = list[Answer]
21
-
22
-
23
- @dataclass
24
- class Ask:
25
- """Data for Question."""
26
-
27
- question: str
28
- options: Options
29
- get_content: Callable[[], Widget] | None = None
30
- callback: Callable[[Answer], Any] | None = None
31
-
32
-
33
- class NonSelectableLabel(widgets.Label):
34
- ALLOW_SELECT = False
35
-
36
-
37
- class Option(containers.HorizontalGroup):
38
- ALLOW_SELECT = False
39
- DEFAULT_CSS = """
40
- Option {
41
-
42
- &:hover {
43
- background: $boost;
44
- }
45
- color: $text-muted;
46
- #caret {
47
- visibility: hidden;
48
- padding: 0 1;
49
- }
50
- #index {
51
- padding-right: 1;
52
- }
53
- #label {
54
- width: 1fr;
55
- }
56
- &.-active {
57
- color: $text-accent;
58
- #caret {
59
- visibility: visible;
60
- }
61
- }
62
- &.-selected {
63
- opacity: 0.5;
64
- }
65
- &.-active.-selected {
66
- opacity: 1.0;
67
- background: transparent;
68
- color: $text-accent;
69
- #label {
70
- text-style: underline;
71
- }
72
- #caret {
73
- visibility: hidden;
74
- }
75
- }
76
- }
77
- """
78
-
79
- @dataclass
80
- class Selected(Message):
81
- """The option was selected."""
82
-
83
- index: int
84
-
85
- selected: reactive[bool] = reactive(False, toggle_class="-selected")
86
-
87
- def __init__(
88
- self, index: int, content: Content, key: str | None, classes: str = ""
89
- ) -> None:
90
- super().__init__(classes=classes)
91
- self.index = index
92
- self.content = content
93
- self.key = key
94
-
95
- def compose(self) -> ComposeResult:
96
- key = self.key
97
- yield NonSelectableLabel("❯", id="caret")
98
- if key:
99
- yield NonSelectableLabel(Content.styled(f"{key}", "b"), id="index")
100
- else:
101
- yield NonSelectableLabel(Content(" "), id="index")
102
-
103
- yield NonSelectableLabel(self.content, id="label")
104
-
105
- def on_click(self, event: events.Click) -> None:
106
- event.stop()
107
- self.post_message(self.Selected(self.index))
108
-
109
-
110
- class Question(containers.VerticalGroup, can_focus=True):
111
- """A text question with a menu of responses."""
112
-
113
- BINDING_GROUP_TITLE = "Question"
114
- ALLOW_SELECT = False
115
- CURSOR_GROUP = Binding.Group("Cursor", compact=True)
116
- ALLOW_GROUP = Binding.Group("Allow once/always", compact=True)
117
- REJECT_GROUP = Binding.Group("Reject once/always", compact=True)
118
- BINDINGS = [
119
- Binding(
120
- "up",
121
- "selection_up",
122
- "Up",
123
- group=CURSOR_GROUP,
124
- ),
125
- Binding(
126
- "down",
127
- "selection_down",
128
- "Down",
129
- group=CURSOR_GROUP,
130
- ),
131
- Binding(
132
- "enter",
133
- "select",
134
- "Select",
135
- ),
136
- Binding(
137
- "a",
138
- "select_kind(('allow_once', 'allow'))",
139
- "Allow once",
140
- group=ALLOW_GROUP,
141
- ),
142
- Binding(
143
- "A",
144
- "select_kind('allow_always')",
145
- "Allow always",
146
- group=ALLOW_GROUP,
147
- ),
148
- Binding(
149
- "r",
150
- "select_kind(('reject_once', 'reject'))",
151
- "Reject once",
152
- group=REJECT_GROUP,
153
- ),
154
- Binding(
155
- "R",
156
- "select_kind('reject_always')",
157
- "Reject always",
158
- group=REJECT_GROUP,
159
- ),
160
- ]
161
-
162
- DEFAULT_CSS = """
163
- Question {
164
- width: 1fr;
165
- height: auto;
166
- padding: 0 1;
167
- background: transparent;
168
- #title {
169
- margin-bottom: 1;
170
- color: $text-primary;
171
- }
172
- #question-container {
173
- margin-bottom: 1;
174
- }
175
-
176
-
177
-
178
- #option-container.-blink Option.-active #caret {
179
- opacity: 0.2;
180
- }
181
-
182
- &:blur {
183
- #index {
184
- opacity: 0.3;
185
- }
186
- #caret {
187
- opacity: 0.3;
188
- }
189
- }
190
- }
191
- """
192
-
193
- title: var[str] = var("")
194
- options: var[Options] = var(list)
195
-
196
- selection: reactive[int] = reactive(0, init=False)
197
- selected: var[bool] = var(False, toggle_class="-selected")
198
- blink: var[bool] = var(False)
199
-
200
- option_container = getters.query_one("#option-container", containers.VerticalGroup)
201
-
202
- DEFAULT_KINDS = {
203
- "allow_once": "a",
204
- "allow_always": "A",
205
- "reject_once": "r",
206
- "reject_always": "R",
207
- }
208
-
209
- @dataclass
210
- class Answer(Message):
211
- """User selected a response."""
212
-
213
- index: int
214
- answer: Answer
215
-
216
- def __init__(
217
- self,
218
- title: str = "Ask and you will receive",
219
- get_content: Callable[[], Widget] | None = None,
220
- options: Options | None = None,
221
- name: str | None = None,
222
- id: str | None = None,
223
- classes: str | None = None,
224
- disabled: bool = False,
225
- ):
226
- super().__init__(name=name, id=id, classes=classes, disabled=disabled)
227
- self.set_reactive(Question.title, title)
228
- self._get_content = get_content
229
- self.set_reactive(Question.options, options or [])
230
-
231
- def on_mount(self) -> None:
232
- def toggle_blink() -> None:
233
- if self.has_focus:
234
- self.blink = not self.blink
235
- else:
236
- self.blink = False
237
-
238
- self._blink_timer = self.set_interval(0.5, toggle_blink)
239
-
240
- def _reset_blink(self) -> None:
241
- self.blink = False
242
- self._blink_timer.reset()
243
-
244
- def update(self, ask: Ask) -> None:
245
- self.title = ask.question
246
- self._get_content = ask.get_content
247
- self.options = ask.options
248
- self.selection = 0
249
- self.selected = False
250
- self.refresh(recompose=True)
251
-
252
- def compose(self) -> ComposeResult:
253
-
254
- with containers.VerticalGroup(id="contents"):
255
- if self.title:
256
- yield widgets.Label(self.title, id="title", markup=False)
257
- if self._get_content is not None:
258
- yield self._get_content()
259
-
260
- with containers.VerticalGroup(id="option-container"):
261
- kinds: set[str] = set()
262
- for index, answer in enumerate(self.options):
263
- active = index == self.selection
264
- key = (
265
- answer.kind
266
- if (answer.kind and answer.kind not in kinds
267
- and answer.kind not in self.DEFAULT_KINDS)
268
- else (
269
- self.DEFAULT_KINDS.get(answer.kind)
270
- if (answer.kind and answer.kind not in kinds)
271
- else None
272
- )
273
- )
274
- yield Option(
275
- index,
276
- Content(answer.text),
277
- key,
278
- classes="-active" if active else "",
279
- ).data_bind(Question.selected)
280
- if answer.kind is not None:
281
- kinds.add(answer.kind)
282
-
283
- def watch_selection(self, old_selection: int, new_selection: int) -> None:
284
- self.query("#option-container > .-active").remove_class("-active")
285
- if new_selection >= 0:
286
- self.query_one("#option-container").children[new_selection].add_class(
287
- "-active"
288
- )
289
-
290
- def check_action(self, action: str, parameters: tuple[object, ...]) -> bool | None:
291
- if self.selected and action in ("selection_up", "selection_down"):
292
- return False
293
- if action == "select_kind":
294
- kinds = {answer.kind for answer in self.options if answer.kind is not None}
295
- check_kinds = set()
296
- for parameter in parameters:
297
- if isinstance(parameter, str):
298
- check_kinds.add(parameter)
299
- elif isinstance(parameter, tuple):
300
- check_kinds.update(parameter)
301
-
302
- return any(kind in kinds for kind in check_kinds)
303
-
304
- return True
305
-
306
- def watch_blink(self, blink: bool) -> None:
307
- self.option_container.set_class(blink, "-blink")
308
-
309
- def action_selection_up(self) -> None:
310
- self._reset_blink()
311
- self.selection = max(0, self.selection - 1)
312
-
313
- def action_selection_down(self) -> None:
314
- self._reset_blink()
315
- self.selection = min(len(self.options) - 1, self.selection + 1)
316
-
317
- def action_select(self) -> None:
318
- self._reset_blink()
319
- self.post_message(
320
- self.Answer(
321
- index=self.selection,
322
- answer=self.options[self.selection],
323
- )
324
- )
325
- self.selected = True
326
-
327
- def action_select_kind(self, kind: str | tuple[str]) -> None:
328
- kinds = kind if isinstance(kind, tuple) else (kind,)
329
- for kind in kinds:
330
- for index, answer in enumerate(self.options):
331
- if answer.kind == kind:
332
- self.selection = index
333
- self.action_select()
334
- break
335
-
336
- @on(Option.Selected)
337
- def on_option_selected(self, event: Option.Selected) -> None:
338
- event.stop()
339
- self._reset_blink()
340
- if not self.selected:
341
- self.selection = event.index
342
-
343
-
344
- if __name__ == "__main__":
345
- from textual.app import App
346
- from textual.widgets import Footer
347
-
348
- OPTIONS = [
349
- Answer("Yes, allow once", "proceed_always", kind="allow_once"),
350
- Answer("Yes, allow always", "allow_always", kind="allow_always"),
351
- Answer("Modify with external editor", "modify", kind="allow_once"),
352
- Answer("No, suggest changes (esc)", "reject"),
353
- ]
354
-
355
- class QuestionApp(App):
356
- def compose(self) -> ComposeResult:
357
- yield Question("Apply this change?", OPTIONS)
358
- yield Footer()
359
-
360
- QuestionApp().run()
@@ -1,230 +0,0 @@
1
- from textual.app import ComposeResult
2
- from textual import getters
3
- from textual.binding import Binding
4
-
5
- from tui.app import A2TUIApp
6
- from tui.constants import SESSION_GRID_PAGE_SIZE
7
- from tui.widgets.grid_select import GridSelect
8
- from tui.widgets.session_summary import SessionSummary
9
- from tui.session_tracker import SessionTracker, SessionDetails
10
-
11
-
12
- PAGE_INDICATOR_ID = "session-grid-page-indicator"
13
-
14
-
15
- class SessionGridSelect(GridSelect):
16
- FOCUS_ON_CLICK = True
17
- CURSOR_GROUP = Binding.Group("Select")
18
- BINDINGS = [
19
- Binding("]", "next_page", "Next page"),
20
- Binding("[", "prev_page", "Prev page"),
21
- ]
22
- app: getters.app[A2TUIApp] = getters.app(A2TUIApp)
23
-
24
- def __init__(
25
- self,
26
- session_tracker: SessionTracker,
27
- id: str | None = None,
28
- classes: str | None = None,
29
- ) -> None:
30
- self.session_tracker = session_tracker
31
- self._all_sessions: list[SessionDetails] = []
32
- self._current_page: int = 0
33
- super().__init__(
34
- id=id,
35
- classes=classes,
36
- min_column_width=36,
37
- )
38
-
39
- @property
40
- def page_size(self) -> int:
41
- return SESSION_GRID_PAGE_SIZE
42
-
43
- @property
44
- def page_count(self) -> int:
45
- total = len(self._all_sessions)
46
- if total == 0:
47
- return 0
48
- return (total + self.page_size - 1) // self.page_size
49
-
50
- @property
51
- def current_page(self) -> int:
52
- return self._current_page
53
-
54
- def allow_focus(self) -> bool:
55
- return True
56
-
57
- def on_mount(self) -> None:
58
- self.app.session_update_signal.subscribe(
59
- self, self.handle_session_update_signal
60
- )
61
- if self._all_sessions:
62
- self._render_page()
63
- self.call_after_refresh(self._ensure_focus)
64
-
65
- def _ensure_focus(self) -> None:
66
- if (
67
- self.is_mounted
68
- and not self._closing
69
- and self.focusable
70
- and self.screen is not None
71
- and self.screen.is_mounted
72
- ):
73
- self.focus()
74
-
75
- def update_current(self, current_mode: str) -> None:
76
- for index, child in enumerate(self.query_children(SessionSummary)):
77
- if child.session_details is None:
78
- continue
79
- is_current = child.session_details.mode_name == current_mode
80
- child.current = is_current
81
- if is_current:
82
- self.highlighted = index
83
-
84
- async def handle_session_update_signal(
85
- self, update: tuple[str, SessionDetails | None]
86
- ) -> None:
87
- mode_name, details = update
88
- if details is None:
89
- if session_summary := self.query_one_optional(
90
- f"#{mode_name}", SessionSummary
91
- ):
92
- await session_summary.remove()
93
- for i, existing in enumerate(self._all_sessions):
94
- if existing.mode_name == mode_name:
95
- self._all_sessions.pop(i)
96
- break
97
- self._clamp_page()
98
- self._render_page()
99
- return
100
-
101
- if session_summary := self.query_one_optional(
102
- f"#{mode_name}", SessionSummary
103
- ):
104
- session_summary.session_details = details
105
- for existing in self._all_sessions:
106
- if existing.mode_name == mode_name:
107
- existing.title = details.title
108
- existing.subtitle = details.subtitle
109
- existing.path = details.path
110
- existing.state = details.state
111
- break
112
- return
113
-
114
- for i, existing in enumerate(self._all_sessions):
115
- if existing.mode_name == mode_name:
116
- self._all_sessions[i] = details
117
- self._render_page()
118
- return
119
-
120
- if details.session_pk is not None:
121
- for i, existing in enumerate(self._all_sessions):
122
- if existing.session_pk == details.session_pk:
123
- self._all_sessions[i] = details
124
- self._render_page()
125
- return
126
-
127
- self._all_sessions.append(details)
128
- self._render_page()
129
-
130
- def compose(self) -> ComposeResult:
131
- yield from ()
132
-
133
- def set_sessions(self, sessions: list[SessionDetails]) -> None:
134
- deduped: list[SessionDetails] = []
135
- seen: set[int] = set()
136
- for session in sessions:
137
- if session.session_pk is not None:
138
- if session.session_pk in seen:
139
- continue
140
- seen.add(session.session_pk)
141
- deduped.append(session)
142
- self._all_sessions = deduped
143
- self._current_page = 0
144
- if self.is_mounted:
145
- self._render_page()
146
-
147
- def _current_page_items(self) -> list[SessionDetails]:
148
- if not self._all_sessions:
149
- return []
150
- start = self._current_page * self.page_size
151
- end = start + self.page_size
152
- return self._all_sessions[start:end]
153
-
154
- def _clamp_page(self) -> None:
155
- if self._current_page >= self.page_count and self.page_count > 0:
156
- self._current_page = self.page_count - 1
157
-
158
- def _render_page(self) -> None:
159
- if not self.is_mounted or self._closing or self._closed:
160
- return
161
- if self.screen is None or not self.screen.is_mounted:
162
- return
163
-
164
- current_items = self._current_page_items()
165
- seen: dict[str, SessionDetails] = {}
166
- for session in current_items:
167
- seen[session.mode_name] = session
168
- unique_items = list(seen.values())
169
-
170
- for child in list(self.query_children(SessionSummary)):
171
- if child.id not in seen:
172
- try:
173
- child.remove()
174
- except Exception:
175
- pass
176
-
177
- existing_ids = {c.id for c in self.query_children(SessionSummary)}
178
- for session in unique_items:
179
- if session.mode_name not in existing_ids:
180
- try:
181
- self.mount(SessionSummary(session, id=session.mode_name))
182
- except Exception:
183
- pass
184
-
185
- self._apply_current()
186
- self._update_page_indicator()
187
- self.highlighted = 0 if unique_items else None
188
-
189
- if unique_items:
190
- self.call_later(self._ensure_focus)
191
-
192
- def _apply_current(self) -> None:
193
- current_mode = self._current_screen_mode_name()
194
- for index, child in enumerate(self.query_children(SessionSummary)):
195
- if child.session_details is None:
196
- continue
197
- is_current = child.session_details.mode_name == current_mode
198
- child.current = is_current
199
- if is_current:
200
- self.highlighted = index
201
-
202
- def _current_screen_mode_name(self) -> str | None:
203
- try:
204
- screen = self.app.screen_stack[0]
205
- except (IndexError, AttributeError):
206
- return None
207
- return getattr(screen, "id", None)
208
-
209
- def _update_page_indicator(self) -> None:
210
- try:
211
- indicator = self.app.query_one(f"#{PAGE_INDICATOR_ID}")
212
- except Exception:
213
- return
214
- total = len(self._all_sessions)
215
- if total == 0:
216
- indicator.update("")
217
- return
218
- indicator.update(
219
- f"Page {self._current_page + 1} / {self.page_count} · 共 {total} 项"
220
- )
221
-
222
- def action_next_page(self) -> None:
223
- if self._current_page + 1 < self.page_count:
224
- self._current_page += 1
225
- self._render_page()
226
-
227
- def action_prev_page(self) -> None:
228
- if self._current_page > 0:
229
- self._current_page -= 1
230
- self._render_page()
@@ -1,115 +0,0 @@
1
- from textual.app import ComposeResult
2
- from textual import getters
3
- from textual import containers
4
- from textual import widgets
5
- from textual.reactive import reactive
6
- from textual.timer import Timer
7
-
8
-
9
- from tui.widgets.condensed_path import CondensedPath
10
- from tui.widgets.throbber import ThrobberVisual
11
- from tui.session_tracker import SessionDetails
12
-
13
-
14
- class BusyIndicator(widgets.Static):
15
- def render(self) -> ThrobberVisual:
16
- return ThrobberVisual("▔")
17
-
18
- def on_mount(self) -> None:
19
- self.auto_refresh = 1 / 4
20
-
21
-
22
- class SessionSummary(containers.VerticalGroup):
23
- session_details: reactive[SessionDetails | None] = reactive(
24
- None, always_update=True, recompose=True
25
- )
26
-
27
- title = getters.query_one(".title", widgets.Label)
28
- subtitle = getters.query_one(".subtitle", widgets.Label)
29
- current = reactive(False, toggle_class="-current", init=False, recompose=True)
30
- blink = reactive(False, toggle_class="-blink")
31
-
32
- def __init__(
33
- self,
34
- session_details: SessionDetails | None,
35
- id: str | None = None,
36
- classes: str | None = None,
37
- ) -> None:
38
- super().__init__(id=id, classes=classes)
39
- self.blink_timer: Timer | None = None
40
- self.set_reactive(SessionSummary.session_details, session_details)
41
-
42
- def on_mount(self) -> None:
43
-
44
- def do_blink() -> None:
45
- self.blink = not self.blink
46
-
47
- self.blink_timer = self.set_interval(0.5, do_blink, pause=False)
48
-
49
- def watch_current(self, current: bool) -> None:
50
- if (session_details := self.session_details) is not None:
51
- if current:
52
- self.title.update(f"✱{session_details.title}")
53
- else:
54
- self.title.update(session_details.title)
55
-
56
- def compose(self) -> ComposeResult:
57
- if (session_details := self.session_details) is not None:
58
- self.remove_class(
59
- "-state-notready",
60
- "-state-busy",
61
- "-state-asking",
62
- "-state-idle",
63
- update=False,
64
- )
65
- self.add_class(f"-state-{session_details.state}")
66
-
67
- yield BusyIndicator()
68
- # yield widgets.Rule(line_style="heavy")
69
- with containers.HorizontalGroup():
70
- yield widgets.Label("❯", classes="icon")
71
- with containers.VerticalGroup():
72
- if session_details is not None:
73
- yield widgets.Label(
74
- (
75
- f"✱{session_details.title}"
76
- if self.current
77
- else session_details.title
78
- ),
79
- classes="title",
80
- markup=False,
81
- )
82
- yield widgets.Label(
83
- session_details.subtitle,
84
- classes="subtitle",
85
- markup=False,
86
- )
87
- with containers.HorizontalGroup():
88
- yield widgets.Label("📁 ")
89
- yield CondensedPath(session_details.path)
90
-
91
-
92
- if __name__ == "__main__":
93
- from textual.app import App
94
-
95
- session_details = SessionDetails(
96
- 0,
97
- "mode",
98
- title="Building BMI calculator",
99
- subtitle="Claude Code",
100
- )
101
-
102
- class SessionApp(App):
103
- CSS_PATH = "../tui.tcss"
104
- CSS = """
105
- Screen {
106
- layout: horizontal;
107
- }
108
- """
109
-
110
- def compose(self) -> ComposeResult:
111
- yield SessionSummary(session_details, classes="-state-busy")
112
- yield SessionSummary(session_details, classes="-state-asking")
113
- yield SessionSummary(session_details, classes="-state-idle")
114
-
115
- SessionApp().run()