@scemoon/cdh 1.0.5 → 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 (551) hide show
  1. package/package.json +2 -2
  2. package/run.js +68 -14
  3. package/ai-dlc-skill/SKILL.md +0 -77
  4. package/ai-dlc-skill/agents/deliver-agent.md +0 -24
  5. package/ai-dlc-skill/agents/master.md +0 -50
  6. package/ai-dlc-skill/agents/plan-agent.md +0 -23
  7. package/ai-dlc-skill/agents/understand-agent.md +0 -23
  8. package/ai-dlc-skill/agents/verify-agent.md +0 -27
  9. package/ai-dlc-skill/architecture/project-structure.md +0 -78
  10. package/ai-dlc-skill/brownfield/README.md +0 -30
  11. package/ai-dlc-skill/brownfield/generate-context.sh +0 -64
  12. package/ai-dlc-skill/brownfield/scripts/deps.sh +0 -27
  13. package/ai-dlc-skill/brownfield/scripts/discover.sh +0 -34
  14. package/ai-dlc-skill/brownfield/scripts/extract-api.sh +0 -45
  15. package/ai-dlc-skill/components/backend.md +0 -34
  16. package/ai-dlc-skill/components/desktop.md +0 -30
  17. package/ai-dlc-skill/components/mya.md +0 -29
  18. package/ai-dlc-skill/components/native.md +0 -30
  19. package/ai-dlc-skill/components/tta.md +0 -29
  20. package/ai-dlc-skill/components/web.md +0 -31
  21. package/ai-dlc-skill/components/wxa.md +0 -29
  22. package/ai-dlc-skill/contracts/README.md +0 -25
  23. package/ai-dlc-skill/core/adaptive-flow.md +0 -36
  24. package/ai-dlc-skill/core/security.md +0 -29
  25. package/ai-dlc-skill/cross-tool/cline/export.sh +0 -31
  26. package/ai-dlc-skill/cross-tool/copilot/export.sh +0 -47
  27. package/ai-dlc-skill/cross-tool/cursor/export.sh +0 -32
  28. package/ai-dlc-skill/cross-tool/export.sh +0 -22
  29. package/ai-dlc-skill/cross-tool/onecode/config.yaml.tpl +0 -17
  30. package/ai-dlc-skill/cross-tool/onecode/export-skills.sh +0 -35
  31. package/ai-dlc-skill/cross-tool/onecode/export.sh +0 -54
  32. package/ai-dlc-skill/phases/deliver/entry.md +0 -26
  33. package/ai-dlc-skill/phases/deliver/lifecycle.md +0 -185
  34. package/ai-dlc-skill/phases/deliver/prompt.md +0 -40
  35. package/ai-dlc-skill/phases/deliver/rules.md +0 -61
  36. package/ai-dlc-skill/phases/plan/entry.md +0 -25
  37. package/ai-dlc-skill/phases/plan/lifecycle.md +0 -204
  38. package/ai-dlc-skill/phases/plan/prompt.md +0 -38
  39. package/ai-dlc-skill/phases/plan/rules.md +0 -25
  40. package/ai-dlc-skill/phases/understand/entry.md +0 -26
  41. package/ai-dlc-skill/phases/understand/lifecycle.md +0 -184
  42. package/ai-dlc-skill/phases/understand/prompt.md +0 -41
  43. package/ai-dlc-skill/phases/understand/rules.md +0 -37
  44. package/ai-dlc-skill/phases/verify/entry.md +0 -26
  45. package/ai-dlc-skill/phases/verify/lifecycle.md +0 -192
  46. package/ai-dlc-skill/phases/verify/prompt.md +0 -43
  47. package/ai-dlc-skill/phases/verify/rules.md +0 -73
  48. package/ai-dlc-skill/practices/bdd.md +0 -91
  49. package/ai-dlc-skill/practices/sdd.md +0 -84
  50. package/ai-dlc-skill/practices/tdd.md +0 -95
  51. package/ai-dlc-skill/providers/README.md +0 -114
  52. package/ai-dlc-skill/providers/aliyun/deployment.yaml +0 -66
  53. package/ai-dlc-skill/providers/aliyun/preview.yaml +0 -84
  54. package/ai-dlc-skill/providers/aliyun/provider.yaml +0 -160
  55. package/ai-dlc-skill/providers/tcb/deployment.yaml +0 -69
  56. package/ai-dlc-skill/providers/tcb/preview.yaml +0 -83
  57. package/ai-dlc-skill/providers/tcb/provider.yaml +0 -172
  58. package/ai-dlc-skill/requirements.md +0 -140
  59. package/ai-dlc-skill/skill.yaml +0 -147
  60. package/ai-dlc-skill/templates/integration/CHANGELOG.md +0 -41
  61. package/ai-dlc-skill/templates/integration/asyncapi.yaml +0 -43
  62. package/ai-dlc-skill/templates/integration/contract-diff.md +0 -63
  63. package/ai-dlc-skill/templates/integration/contract-spec.md +0 -49
  64. package/ai-dlc-skill/templates/integration/openapi.yaml +0 -18
  65. package/ai-dlc-skill/templates/integration/runtime-contract.yaml +0 -36
  66. package/ai-dlc-skill/templates/plan/design.md +0 -49
  67. package/ai-dlc-skill/templates/plan/task-list.md +0 -32
  68. package/ai-dlc-skill/templates/project/README.md +0 -126
  69. package/ai-dlc-skill/templates/project/template.md +0 -119
  70. package/ai-dlc-skill/templates/understand/feature.feature +0 -23
  71. package/ai-dlc-skill/templates/understand/intent.md +0 -29
  72. package/ai-dlc-skill/templates/understand/spec-delta.md +0 -47
  73. package/ai-dlc-skill/templates/verify/test-unit.py +0 -27
  74. package/ai-dlc-skill/walkthrough/collect.sh +0 -50
  75. package/ai-dlc-skill/walkthrough/template.md +0 -54
  76. package/ai-dlc-skill/workflows/ai-dlc.yaml +0 -110
  77. package/ai-dlc-skill/workflows/deployment.yaml +0 -199
  78. package/cdh/__init__.py +0 -0
  79. package/cdh/__main__.py +0 -4
  80. package/cdh/__pycache__/__init__.cpython-314.pyc +0 -0
  81. package/cdh/__pycache__/cdh_mcp_injector.cpython-314.pyc +0 -0
  82. package/cdh/__pycache__/cdh_mcp_loader.cpython-314.pyc +0 -0
  83. package/cdh/__pycache__/cdh_mcp_manager.cpython-314.pyc +0 -0
  84. package/cdh/__pycache__/cdh_session_aggregator.cpython-314.pyc +0 -0
  85. package/cdh/__pycache__/cdh_skill_loader.cpython-314.pyc +0 -0
  86. package/cdh/__pycache__/cdh_skill_manager.cpython-314.pyc +0 -0
  87. package/cdh/__pycache__/cli.cpython-313.pyc +0 -0
  88. package/cdh/__pycache__/cli.cpython-314.pyc +0 -0
  89. package/cdh/__pycache__/scaffold.cpython-314.pyc +0 -0
  90. package/cdh/cdh_mcp_injector.py +0 -115
  91. package/cdh/cdh_mcp_loader.py +0 -67
  92. package/cdh/cdh_mcp_manager.py +0 -73
  93. package/cdh/cdh_session_aggregator.py +0 -258
  94. package/cdh/cdh_skill_manager.py +0 -105
  95. package/cdh/cli.py +0 -758
  96. package/cdh/scaffold.py +0 -728
  97. package/onecode/__init__.py +0 -1
  98. package/onecode/__main__.py +0 -4
  99. package/onecode/__pycache__/__init__.cpython-314.pyc +0 -0
  100. package/onecode/__pycache__/cli.cpython-314.pyc +0 -0
  101. package/onecode/__pycache__/commands.cpython-314.pyc +0 -0
  102. package/onecode/__pycache__/config.cpython-314.pyc +0 -0
  103. package/onecode/__pycache__/config_screen.cpython-314.pyc +0 -0
  104. package/onecode/__pycache__/migrate.cpython-314.pyc +0 -0
  105. package/onecode/agent/__init__.py +0 -0
  106. package/onecode/agent/__pycache__/__init__.cpython-314.pyc +0 -0
  107. package/onecode/agent/__pycache__/cdh_loader.cpython-314.pyc +0 -0
  108. package/onecode/agent/__pycache__/context.cpython-314.pyc +0 -0
  109. package/onecode/agent/__pycache__/engine.cpython-314.pyc +0 -0
  110. package/onecode/agent/__pycache__/hooks.cpython-314.pyc +0 -0
  111. package/onecode/agent/__pycache__/onecode_agent_acp.cpython-314.pyc +0 -0
  112. package/onecode/agent/__pycache__/permissions.cpython-314.pyc +0 -0
  113. package/onecode/agent/__pycache__/permissions_store.cpython-314.pyc +0 -0
  114. package/onecode/agent/__pycache__/project_doc.cpython-314.pyc +0 -0
  115. package/onecode/agent/__pycache__/session.cpython-314.pyc +0 -0
  116. package/onecode/agent/agents/__init__.py +0 -29
  117. package/onecode/agent/agents/__pycache__/__init__.cpython-314.pyc +0 -0
  118. package/onecode/agent/agents/__pycache__/types.cpython-314.pyc +0 -0
  119. package/onecode/agent/agents/types.py +0 -589
  120. package/onecode/agent/attachments.py +0 -112
  121. package/onecode/agent/cdh_loader.py +0 -267
  122. package/onecode/agent/context.py +0 -343
  123. package/onecode/agent/engine.py +0 -2700
  124. package/onecode/agent/hooks.py +0 -86
  125. package/onecode/agent/onecode_agent_acp.py +0 -2743
  126. package/onecode/agent/onecode_agent_acp.py.bak +0 -2447
  127. package/onecode/agent/permissions.py +0 -150
  128. package/onecode/agent/permissions_store.py +0 -62
  129. package/onecode/agent/project_doc.py +0 -19
  130. package/onecode/agent/session.py +0 -195
  131. package/onecode/agent/snapshot.py +0 -144
  132. package/onecode/agent/tools/__init__.py +0 -17
  133. package/onecode/agent/tools/__pycache__/__init__.cpython-314.pyc +0 -0
  134. package/onecode/agent/tools/__pycache__/agent_tools.cpython-314.pyc +0 -0
  135. package/onecode/agent/tools/__pycache__/apply_patch_tool.cpython-314.pyc +0 -0
  136. package/onecode/agent/tools/__pycache__/bash_tool.cpython-314.pyc +0 -0
  137. package/onecode/agent/tools/__pycache__/communication_tools.cpython-314.pyc +0 -0
  138. package/onecode/agent/tools/__pycache__/config_tool.cpython-314.pyc +0 -0
  139. package/onecode/agent/tools/__pycache__/cron_tools.cpython-314.pyc +0 -0
  140. package/onecode/agent/tools/__pycache__/errors.cpython-314.pyc +0 -0
  141. package/onecode/agent/tools/__pycache__/file_ops.cpython-314.pyc +0 -0
  142. package/onecode/agent/tools/__pycache__/file_tools.cpython-314.pyc +0 -0
  143. package/onecode/agent/tools/__pycache__/git_tools.cpython-314.pyc +0 -0
  144. package/onecode/agent/tools/__pycache__/lsp_tools.cpython-314.pyc +0 -0
  145. package/onecode/agent/tools/__pycache__/mcp_tools.cpython-314.pyc +0 -0
  146. package/onecode/agent/tools/__pycache__/permission_handler.cpython-314.pyc +0 -0
  147. package/onecode/agent/tools/__pycache__/permissions.cpython-314.pyc +0 -0
  148. package/onecode/agent/tools/__pycache__/protocol.cpython-314.pyc +0 -0
  149. package/onecode/agent/tools/__pycache__/registry.cpython-314.pyc +0 -0
  150. package/onecode/agent/tools/__pycache__/sandbox.cpython-314.pyc +0 -0
  151. package/onecode/agent/tools/__pycache__/schema_validation.cpython-314.pyc +0 -0
  152. package/onecode/agent/tools/__pycache__/skill_tools.cpython-314.pyc +0 -0
  153. package/onecode/agent/tools/__pycache__/todo_tools.cpython-314.pyc +0 -0
  154. package/onecode/agent/tools/__pycache__/web_tools.cpython-314.pyc +0 -0
  155. package/onecode/agent/tools/agent_tools.py +0 -132
  156. package/onecode/agent/tools/apply_patch_tool.py +0 -138
  157. package/onecode/agent/tools/bash_tool.py +0 -111
  158. package/onecode/agent/tools/communication_tools.py +0 -148
  159. package/onecode/agent/tools/config_tool.py +0 -130
  160. package/onecode/agent/tools/cron_tools.py +0 -178
  161. package/onecode/agent/tools/errors.py +0 -17
  162. package/onecode/agent/tools/file_ops.py +0 -221
  163. package/onecode/agent/tools/file_tools.py +0 -225
  164. package/onecode/agent/tools/git_tools.py +0 -88
  165. package/onecode/agent/tools/lsp_tools.py +0 -404
  166. package/onecode/agent/tools/mcp_tools.py +0 -127
  167. package/onecode/agent/tools/permission_handler.py +0 -46
  168. package/onecode/agent/tools/permissions.py +0 -77
  169. package/onecode/agent/tools/protocol.py +0 -20
  170. package/onecode/agent/tools/registry.py +0 -201
  171. package/onecode/agent/tools/sandbox.py +0 -358
  172. package/onecode/agent/tools/schema_validation.py +0 -100
  173. package/onecode/agent/tools/skill_tools.py +0 -52
  174. package/onecode/agent/tools/todo_tools.py +0 -207
  175. package/onecode/agent/tools/web_tools.py +0 -169
  176. package/onecode/builtin_skills/agent-browser/SKILL.md +0 -212
  177. package/onecode/builtin_skills/agent-browser/skill.yaml +0 -8
  178. package/onecode/builtin_skills/git/SKILL.md +0 -64
  179. package/onecode/builtin_skills/git/skill.yaml +0 -7
  180. package/onecode/builtin_skills/shell/SKILL.md +0 -58
  181. package/onecode/builtin_skills/shell/skill.yaml +0 -8
  182. package/onecode/builtin_skills/skill-creator/SKILL.md +0 -106
  183. package/onecode/builtin_skills/skill-creator/skill.yaml +0 -8
  184. package/onecode/cli.py +0 -935
  185. package/onecode/cloud/__init__.py +0 -0
  186. package/onecode/cloud/base.py +0 -20
  187. package/onecode/codebase/__init__.py +0 -69
  188. package/onecode/codebase/__pycache__/__init__.cpython-314.pyc +0 -0
  189. package/onecode/codebase/__pycache__/chunker.cpython-314.pyc +0 -0
  190. package/onecode/codebase/__pycache__/indexer.cpython-314.pyc +0 -0
  191. package/onecode/codebase/__pycache__/retriever.cpython-314.pyc +0 -0
  192. package/onecode/codebase/__pycache__/storage.cpython-314.pyc +0 -0
  193. package/onecode/codebase/__pycache__/tools.cpython-314.pyc +0 -0
  194. package/onecode/codebase/chunker.py +0 -125
  195. package/onecode/codebase/indexer.py +0 -149
  196. package/onecode/codebase/retriever.py +0 -203
  197. package/onecode/codebase/storage.py +0 -131
  198. package/onecode/codebase/tools.py +0 -59
  199. package/onecode/commands.py +0 -596
  200. package/onecode/config.py +0 -314
  201. package/onecode/config_screen.py +0 -600
  202. package/onecode/cron/__init__.py +0 -3
  203. package/onecode/lsp/__init__.py +0 -3
  204. package/onecode/mcp/__init__.py +0 -4
  205. package/onecode/mcp/__pycache__/__init__.cpython-314.pyc +0 -0
  206. package/onecode/mcp/__pycache__/client.cpython-314.pyc +0 -0
  207. package/onecode/mcp/__pycache__/manager.cpython-314.pyc +0 -0
  208. package/onecode/mcp/client.py +0 -193
  209. package/onecode/mcp/manager.py +0 -190
  210. package/onecode/memory/__init__.py +0 -49
  211. package/onecode/memory/__pycache__/__init__.cpython-314.pyc +0 -0
  212. package/onecode/memory/__pycache__/backend.cpython-314.pyc +0 -0
  213. package/onecode/memory/__pycache__/offload.cpython-314.pyc +0 -0
  214. package/onecode/memory/__pycache__/pyramid.cpython-314.pyc +0 -0
  215. package/onecode/memory/__pycache__/recall.cpython-314.pyc +0 -0
  216. package/onecode/memory/__pycache__/symbolic.cpython-314.pyc +0 -0
  217. package/onecode/memory/backend.py +0 -159
  218. package/onecode/memory/pyramid.py +0 -133
  219. package/onecode/memory/recall.py +0 -203
  220. package/onecode/migrate.py +0 -122
  221. package/onecode/models/__init__.py +0 -4
  222. package/onecode/models/__pycache__/__init__.cpython-314.pyc +0 -0
  223. package/onecode/models/__pycache__/errors.cpython-314.pyc +0 -0
  224. package/onecode/models/__pycache__/messages.cpython-314.pyc +0 -0
  225. package/onecode/models/__pycache__/provider.cpython-314.pyc +0 -0
  226. package/onecode/models/__pycache__/registry.cpython-314.pyc +0 -0
  227. package/onecode/models/errors.py +0 -104
  228. package/onecode/models/messages.py +0 -739
  229. package/onecode/models/provider.py +0 -699
  230. package/onecode/models/providers/__init__.py +0 -17
  231. package/onecode/models/providers/__pycache__/__init__.cpython-314.pyc +0 -0
  232. package/onecode/models/providers/__pycache__/anthropic_provider.cpython-314.pyc +0 -0
  233. package/onecode/models/providers/__pycache__/deepseek_provider.cpython-314.pyc +0 -0
  234. package/onecode/models/providers/__pycache__/glm_provider.cpython-314.pyc +0 -0
  235. package/onecode/models/providers/__pycache__/minimax_provider.cpython-314.pyc +0 -0
  236. package/onecode/models/providers/__pycache__/minimaxi_provider.cpython-314.pyc +0 -0
  237. package/onecode/models/providers/__pycache__/ollama_provider.cpython-314.pyc +0 -0
  238. package/onecode/models/providers/__pycache__/openai_provider.cpython-314.pyc +0 -0
  239. package/onecode/models/providers/anthropic_provider.py +0 -273
  240. package/onecode/models/providers/deepseek_provider.py +0 -212
  241. package/onecode/models/providers/glm_provider.py +0 -195
  242. package/onecode/models/providers/minimax_provider.py +0 -158
  243. package/onecode/models/providers/minimaxi_provider.py +0 -417
  244. package/onecode/models/providers/ollama_provider.py +0 -100
  245. package/onecode/models/providers/openai_provider.py +0 -237
  246. package/onecode/models/registry.py +0 -212
  247. package/onecode/server/__init__.py +0 -3
  248. package/onecode/server/app.py +0 -224
  249. package/onecode/skills/__init__.py +0 -11
  250. package/onecode/skills/__pycache__/__init__.cpython-314.pyc +0 -0
  251. package/onecode/skills/__pycache__/argument_substitution.cpython-314.pyc +0 -0
  252. package/onecode/skills/__pycache__/bootstrap.cpython-314.pyc +0 -0
  253. package/onecode/skills/__pycache__/create.cpython-314.pyc +0 -0
  254. package/onecode/skills/__pycache__/frontmatter.cpython-314.pyc +0 -0
  255. package/onecode/skills/__pycache__/loader.cpython-314.pyc +0 -0
  256. package/onecode/skills/__pycache__/manager.cpython-314.pyc +0 -0
  257. package/onecode/skills/__pycache__/model.cpython-314.pyc +0 -0
  258. package/onecode/skills/argument_substitution.py +0 -38
  259. package/onecode/skills/bootstrap.py +0 -124
  260. package/onecode/skills/create.py +0 -56
  261. package/onecode/skills/frontmatter.py +0 -33
  262. package/onecode/skills/loader.py +0 -139
  263. package/onecode/skills/manager.py +0 -75
  264. package/onecode/skills/model.py +0 -43
  265. package/onecode/storage/__init__.py +0 -0
  266. package/onecode/storage/activity.py +0 -63
  267. package/onecode/storage/project.py +0 -54
  268. package/onecode/storage/session.py +0 -112
  269. package/onecode/tasks/__init__.py +0 -26
  270. package/onecode/tasks/manager.py +0 -232
  271. package/onecode/tasks/models.py +0 -240
  272. package/onecode/trace/__init__.py +0 -0
  273. package/onecode/trace/tracer.py +0 -173
  274. package/onecode/utils/__init__.py +0 -0
  275. package/onecode/utils/helpers.py +0 -20
  276. package/pyproject.toml +0 -74
  277. package/tui/__init__.py +0 -46
  278. package/tui/__main__.py +0 -4
  279. package/tui/__pycache__/__init__.cpython-314.pyc +0 -0
  280. package/tui/__pycache__/_loop.cpython-314.pyc +0 -0
  281. package/tui/__pycache__/_path_fuzzy_search.cpython-314.pyc +0 -0
  282. package/tui/__pycache__/_path_match.cpython-314.pyc +0 -0
  283. package/tui/__pycache__/about.cpython-314.pyc +0 -0
  284. package/tui/__pycache__/agent.cpython-314.pyc +0 -0
  285. package/tui/__pycache__/agent_schema.cpython-314.pyc +0 -0
  286. package/tui/__pycache__/agents.cpython-314.pyc +0 -0
  287. package/tui/__pycache__/answer.cpython-314.pyc +0 -0
  288. package/tui/__pycache__/app.cpython-313.pyc +0 -0
  289. package/tui/__pycache__/app.cpython-314.pyc +0 -0
  290. package/tui/__pycache__/atomic.cpython-314.pyc +0 -0
  291. package/tui/__pycache__/complete.cpython-314.pyc +0 -0
  292. package/tui/__pycache__/constants.cpython-314.pyc +0 -0
  293. package/tui/__pycache__/conversation_markdown.cpython-314.pyc +0 -0
  294. package/tui/__pycache__/danger.cpython-314.pyc +0 -0
  295. package/tui/__pycache__/db.cpython-314.pyc +0 -0
  296. package/tui/__pycache__/dec.cpython-314.pyc +0 -0
  297. package/tui/__pycache__/directory.cpython-314.pyc +0 -0
  298. package/tui/__pycache__/directory_suggester.cpython-314.pyc +0 -0
  299. package/tui/__pycache__/directory_watcher.cpython-314.pyc +0 -0
  300. package/tui/__pycache__/format_path.cpython-314.pyc +0 -0
  301. package/tui/__pycache__/fuzzy.cpython-314.pyc +0 -0
  302. package/tui/__pycache__/fuzzy_index.cpython-314.pyc +0 -0
  303. package/tui/__pycache__/history.cpython-314.pyc +0 -0
  304. package/tui/__pycache__/jsonrpc.cpython-314.pyc +0 -0
  305. package/tui/__pycache__/menus.cpython-314.pyc +0 -0
  306. package/tui/__pycache__/message_log.cpython-314.pyc +0 -0
  307. package/tui/__pycache__/messages.cpython-314.pyc +0 -0
  308. package/tui/__pycache__/path_complete.cpython-314.pyc +0 -0
  309. package/tui/__pycache__/path_filter.cpython-314.pyc +0 -0
  310. package/tui/__pycache__/paths.cpython-314.pyc +0 -0
  311. package/tui/__pycache__/pill.cpython-314.pyc +0 -0
  312. package/tui/__pycache__/platform_commands.cpython-314.pyc +0 -0
  313. package/tui/__pycache__/protocol.cpython-314.pyc +0 -0
  314. package/tui/__pycache__/session_tracker.cpython-314.pyc +0 -0
  315. package/tui/__pycache__/settings.cpython-314.pyc +0 -0
  316. package/tui/__pycache__/settings_schema.cpython-314.pyc +0 -0
  317. package/tui/__pycache__/shell.cpython-314.pyc +0 -0
  318. package/tui/__pycache__/shell_read.cpython-314.pyc +0 -0
  319. package/tui/__pycache__/slash_command.cpython-314.pyc +0 -0
  320. package/tui/__pycache__/version.cpython-314.pyc +0 -0
  321. package/tui/_loop.py +0 -86
  322. package/tui/_path_fuzzy_search.py +0 -48
  323. package/tui/_path_match.py +0 -141
  324. package/tui/about.py +0 -95
  325. package/tui/acp/__pycache__/agent.cpython-314.pyc +0 -0
  326. package/tui/acp/__pycache__/api.cpython-314.pyc +0 -0
  327. package/tui/acp/__pycache__/encode_tool_call_id.cpython-314.pyc +0 -0
  328. package/tui/acp/__pycache__/messages.cpython-314.pyc +0 -0
  329. package/tui/acp/__pycache__/prompt.cpython-314.pyc +0 -0
  330. package/tui/acp/__pycache__/protocol.cpython-314.pyc +0 -0
  331. package/tui/acp/agent.py +0 -1002
  332. package/tui/acp/api.py +0 -73
  333. package/tui/acp/encode_tool_call_id.py +0 -12
  334. package/tui/acp/messages.py +0 -203
  335. package/tui/acp/prompt.py +0 -53
  336. package/tui/acp/protocol.py +0 -499
  337. package/tui/agent.py +0 -70
  338. package/tui/agent_schema.py +0 -76
  339. package/tui/agents.py +0 -46
  340. package/tui/ansi/__init__.py +0 -1
  341. package/tui/ansi/__pycache__/__init__.cpython-314.pyc +0 -0
  342. package/tui/ansi/__pycache__/_ansi.cpython-314.pyc +0 -0
  343. package/tui/ansi/__pycache__/_ansi_colors.cpython-314.pyc +0 -0
  344. package/tui/ansi/__pycache__/_control_codes.cpython-314.pyc +0 -0
  345. package/tui/ansi/__pycache__/_keys.cpython-314.pyc +0 -0
  346. package/tui/ansi/__pycache__/_sgr_styles.cpython-314.pyc +0 -0
  347. package/tui/ansi/__pycache__/_stream_parser.cpython-314.pyc +0 -0
  348. package/tui/ansi/_ansi.py +0 -1689
  349. package/tui/ansi/_ansi_colors.py +0 -264
  350. package/tui/ansi/_control_codes.py +0 -37
  351. package/tui/ansi/_keys.py +0 -251
  352. package/tui/ansi/_sgr_styles.py +0 -64
  353. package/tui/ansi/_stream_parser.py +0 -418
  354. package/tui/answer.py +0 -12
  355. package/tui/app.py +0 -1266
  356. package/tui/atomic.py +0 -37
  357. package/tui/cli.py +0 -313
  358. package/tui/code_analyze.py +0 -27
  359. package/tui/complete.py +0 -38
  360. package/tui/constants.py +0 -61
  361. package/tui/conversation_markdown.py +0 -30
  362. package/tui/danger.py +0 -372
  363. package/tui/data/agents/ampcode.com.toml +0 -52
  364. package/tui/data/agents/augmentcode.com.toml +0 -41
  365. package/tui/data/agents/cdh.cloud-dev-harness.toml +0 -23
  366. package/tui/data/agents/claude.com.toml +0 -41
  367. package/tui/data/agents/copilot.github.com.toml +0 -29
  368. package/tui/data/agents/crowai.dev.toml +0 -36
  369. package/tui/data/agents/cursor.com.toml +0 -38
  370. package/tui/data/agents/deepagents.langchain.com +0 -34
  371. package/tui/data/agents/docker.com.toml +0 -60
  372. package/tui/data/agents/geminicli.com.toml +0 -28
  373. package/tui/data/agents/goose.ai.toml +0 -52
  374. package/tui/data/agents/inference.huggingface.co.toml +0 -41
  375. package/tui/data/agents/kimi.com.toml +0 -35
  376. package/tui/data/agents/kiro.dev.toml +0 -43
  377. package/tui/data/agents/onecode.dev.toml +0 -22
  378. package/tui/data/agents/openai.com.toml +0 -53
  379. package/tui/data/agents/openclaw.ai.toml +0 -37
  380. package/tui/data/agents/opencode.ai.toml +0 -39
  381. package/tui/data/agents/openhands.dev.toml +0 -46
  382. package/tui/data/agents/stakpak.dev.toml +0 -62
  383. package/tui/data/agents/vibe.mistral.ai.toml +0 -31
  384. package/tui/data/agents/vtcode.dev.toml +0 -63
  385. package/tui/data/images/frog.png +0 -0
  386. package/tui/data/sounds/question.wav +0 -0
  387. package/tui/data/sounds/turn-over.wav +0 -0
  388. package/tui/db.py +0 -213
  389. package/tui/dec.py +0 -332
  390. package/tui/directory.py +0 -234
  391. package/tui/directory_suggester.py +0 -93
  392. package/tui/directory_watcher.py +0 -231
  393. package/tui/format_path.py +0 -25
  394. package/tui/fuzzy.py +0 -140
  395. package/tui/fuzzy_index.py +0 -275
  396. package/tui/gist.py +0 -33
  397. package/tui/history.py +0 -138
  398. package/tui/jsonrpc.py +0 -578
  399. package/tui/menus.py +0 -14
  400. package/tui/message_log.py +0 -69
  401. package/tui/messages.py +0 -144
  402. package/tui/option_content.py +0 -51
  403. package/tui/os.py +0 -0
  404. package/tui/path_complete.py +0 -217
  405. package/tui/path_filter.py +0 -124
  406. package/tui/paths.py +0 -87
  407. package/tui/pill.py +0 -23
  408. package/tui/platform_commands.py +0 -52
  409. package/tui/prompt/__pycache__/extract.cpython-314.pyc +0 -0
  410. package/tui/prompt/__pycache__/resource.cpython-314.pyc +0 -0
  411. package/tui/prompt/extract.py +0 -19
  412. package/tui/prompt/resource.py +0 -68
  413. package/tui/protocol.py +0 -28
  414. package/tui/screens/__init__.py +0 -0
  415. package/tui/screens/__pycache__/__init__.cpython-314.pyc +0 -0
  416. package/tui/screens/__pycache__/agent_modal.cpython-314.pyc +0 -0
  417. package/tui/screens/__pycache__/component_picker.cpython-314.pyc +0 -0
  418. package/tui/screens/__pycache__/diff_screen.cpython-314.pyc +0 -0
  419. package/tui/screens/__pycache__/log.cpython-314.pyc +0 -0
  420. package/tui/screens/__pycache__/main.cpython-313.pyc +0 -0
  421. package/tui/screens/__pycache__/main.cpython-314.pyc +0 -0
  422. package/tui/screens/__pycache__/permissions.cpython-314.pyc +0 -0
  423. package/tui/screens/__pycache__/projects_app.cpython-314.pyc +0 -0
  424. package/tui/screens/__pycache__/projects_screen.cpython-314.pyc +0 -0
  425. package/tui/screens/__pycache__/sessions.cpython-314.pyc +0 -0
  426. package/tui/screens/__pycache__/store.cpython-314.pyc +0 -0
  427. package/tui/screens/__pycache__/tool_content_screen.cpython-314.pyc +0 -0
  428. package/tui/screens/action_modal.py +0 -94
  429. package/tui/screens/agent_modal.py +0 -175
  430. package/tui/screens/command_edit_modal.py +0 -74
  431. package/tui/screens/component_picker.py +0 -168
  432. package/tui/screens/diff_screen.py +0 -84
  433. package/tui/screens/log.py +0 -553
  434. package/tui/screens/main.py +0 -385
  435. package/tui/screens/main.tcss +0 -655
  436. package/tui/screens/permissions.py +0 -404
  437. package/tui/screens/permissions.tcss +0 -72
  438. package/tui/screens/projects.tcss +0 -80
  439. package/tui/screens/projects_app.py +0 -347
  440. package/tui/screens/projects_screen.py +0 -284
  441. package/tui/screens/session_resume_modal.py +0 -172
  442. package/tui/screens/session_resume_modal.tcss +0 -35
  443. package/tui/screens/sessions.py +0 -164
  444. package/tui/screens/sessions.tcss +0 -119
  445. package/tui/screens/settings.py +0 -254
  446. package/tui/screens/settings.tcss +0 -101
  447. package/tui/screens/store.py +0 -500
  448. package/tui/screens/store.tcss +0 -274
  449. package/tui/screens/tool_content_screen.py +0 -59
  450. package/tui/session_tracker.py +0 -123
  451. package/tui/settings.py +0 -353
  452. package/tui/settings_schema.py +0 -431
  453. package/tui/shell.py +0 -304
  454. package/tui/shell_read.py +0 -42
  455. package/tui/slash_command.py +0 -34
  456. package/tui/tui.tcss +0 -246
  457. package/tui/twitter.py +0 -38
  458. package/tui/version.py +0 -80
  459. package/tui/visuals/__init__.py +0 -0
  460. package/tui/visuals/__pycache__/__init__.cpython-314.pyc +0 -0
  461. package/tui/visuals/__pycache__/columns.cpython-314.pyc +0 -0
  462. package/tui/visuals/columns.py +0 -272
  463. package/tui/widgets/__init__.py +0 -0
  464. package/tui/widgets/__pycache__/__init__.cpython-314.pyc +0 -0
  465. package/tui/widgets/__pycache__/acp_content.cpython-314.pyc +0 -0
  466. package/tui/widgets/__pycache__/agent_response.cpython-314.pyc +0 -0
  467. package/tui/widgets/__pycache__/agent_thought.cpython-314.pyc +0 -0
  468. package/tui/widgets/__pycache__/ask_user.cpython-314.pyc +0 -0
  469. package/tui/widgets/__pycache__/condensed_path.cpython-314.pyc +0 -0
  470. package/tui/widgets/__pycache__/context_stats.cpython-314.pyc +0 -0
  471. package/tui/widgets/__pycache__/conversation.cpython-314.pyc +0 -0
  472. package/tui/widgets/__pycache__/diff_view.cpython-314.pyc +0 -0
  473. package/tui/widgets/__pycache__/directory_input.cpython-314.pyc +0 -0
  474. package/tui/widgets/__pycache__/flash.cpython-314.pyc +0 -0
  475. package/tui/widgets/__pycache__/future_text.cpython-314.pyc +0 -0
  476. package/tui/widgets/__pycache__/grid_select.cpython-314.pyc +0 -0
  477. package/tui/widgets/__pycache__/highlighted_textarea.cpython-314.pyc +0 -0
  478. package/tui/widgets/__pycache__/load_more.cpython-314.pyc +0 -0
  479. package/tui/widgets/__pycache__/mandelbrot.cpython-314.pyc +0 -0
  480. package/tui/widgets/__pycache__/markdown_note.cpython-314.pyc +0 -0
  481. package/tui/widgets/__pycache__/menu.cpython-314.pyc +0 -0
  482. package/tui/widgets/__pycache__/modified_files.cpython-314.pyc +0 -0
  483. package/tui/widgets/__pycache__/non_selectable_label.cpython-314.pyc +0 -0
  484. package/tui/widgets/__pycache__/note.cpython-314.pyc +0 -0
  485. package/tui/widgets/__pycache__/path_search.cpython-314.pyc +0 -0
  486. package/tui/widgets/__pycache__/plan.cpython-314.pyc +0 -0
  487. package/tui/widgets/__pycache__/project_directory_tree.cpython-314.pyc +0 -0
  488. package/tui/widgets/__pycache__/project_grid_select.cpython-314.pyc +0 -0
  489. package/tui/widgets/__pycache__/project_summary.cpython-314.pyc +0 -0
  490. package/tui/widgets/__pycache__/prompt.cpython-314.pyc +0 -0
  491. package/tui/widgets/__pycache__/question.cpython-314.pyc +0 -0
  492. package/tui/widgets/__pycache__/session_grid_select.cpython-314.pyc +0 -0
  493. package/tui/widgets/__pycache__/session_summary.cpython-314.pyc +0 -0
  494. package/tui/widgets/__pycache__/session_tabs.cpython-314.pyc +0 -0
  495. package/tui/widgets/__pycache__/shell_result.cpython-314.pyc +0 -0
  496. package/tui/widgets/__pycache__/shell_terminal.cpython-314.pyc +0 -0
  497. package/tui/widgets/__pycache__/side_bar.cpython-314.pyc +0 -0
  498. package/tui/widgets/__pycache__/slash_complete.cpython-314.pyc +0 -0
  499. package/tui/widgets/__pycache__/strike_text.cpython-314.pyc +0 -0
  500. package/tui/widgets/__pycache__/subagent.cpython-314.pyc +0 -0
  501. package/tui/widgets/__pycache__/subagent_screen.cpython-314.pyc +0 -0
  502. package/tui/widgets/__pycache__/terminal.cpython-314.pyc +0 -0
  503. package/tui/widgets/__pycache__/throbber.cpython-314.pyc +0 -0
  504. package/tui/widgets/__pycache__/tool_call.cpython-314.pyc +0 -0
  505. package/tui/widgets/__pycache__/user_input.cpython-314.pyc +0 -0
  506. package/tui/widgets/acp_content.py +0 -70
  507. package/tui/widgets/agent_response.py +0 -76
  508. package/tui/widgets/agent_thought.py +0 -167
  509. package/tui/widgets/ask_user.py +0 -264
  510. package/tui/widgets/command_pane.py +0 -223
  511. package/tui/widgets/condensed_path.py +0 -115
  512. package/tui/widgets/context_stats.py +0 -66
  513. package/tui/widgets/conversation.py +0 -2641
  514. package/tui/widgets/danger_warning.py +0 -65
  515. package/tui/widgets/diff_view.py +0 -69
  516. package/tui/widgets/directory_input.py +0 -8
  517. package/tui/widgets/flash.py +0 -81
  518. package/tui/widgets/future_text.py +0 -126
  519. package/tui/widgets/grid_select.py +0 -234
  520. package/tui/widgets/highlighted_textarea.py +0 -180
  521. package/tui/widgets/load_more.py +0 -24
  522. package/tui/widgets/mandelbrot.py +0 -294
  523. package/tui/widgets/markdown_note.py +0 -13
  524. package/tui/widgets/menu.py +0 -147
  525. package/tui/widgets/modified_files.py +0 -306
  526. package/tui/widgets/non_selectable_label.py +0 -5
  527. package/tui/widgets/note.py +0 -18
  528. package/tui/widgets/path_search.py +0 -492
  529. package/tui/widgets/plan.py +0 -285
  530. package/tui/widgets/project_directory_tree.py +0 -102
  531. package/tui/widgets/project_grid_select.py +0 -64
  532. package/tui/widgets/project_summary.py +0 -33
  533. package/tui/widgets/prompt.py +0 -795
  534. package/tui/widgets/question.py +0 -360
  535. package/tui/widgets/session_grid_select.py +0 -230
  536. package/tui/widgets/session_summary.py +0 -115
  537. package/tui/widgets/session_tabs.py +0 -188
  538. package/tui/widgets/shell_result.py +0 -35
  539. package/tui/widgets/shell_terminal.py +0 -40
  540. package/tui/widgets/side_bar.py +0 -124
  541. package/tui/widgets/slash_complete.py +0 -235
  542. package/tui/widgets/strike_text.py +0 -70
  543. package/tui/widgets/subagent.py +0 -287
  544. package/tui/widgets/subagent_screen.py +0 -709
  545. package/tui/widgets/terminal.py +0 -576
  546. package/tui/widgets/terminal_tool.py +0 -360
  547. package/tui/widgets/throbber.py +0 -100
  548. package/tui/widgets/tool_call.py +0 -398
  549. package/tui/widgets/user_input.py +0 -23
  550. package/tui/widgets/version.py +0 -5
  551. 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()