illusion-code 0.2.5__tar.gz → 0.2.6__tar.gz

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 (523) hide show
  1. {illusion_code-0.2.5 → illusion_code-0.2.6}/.github/workflows/publish.yml +2 -4
  2. {illusion_code-0.2.5 → illusion_code-0.2.6}/PKG-INFO +1 -1
  3. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/package-lock.json +2 -2
  4. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/package.json +1 -1
  5. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/TodoPanel.tsx +6 -5
  6. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/version.ts +1 -1
  7. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/index.html +1 -1
  8. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/package-lock.json +2 -2
  9. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/package.json +1 -1
  10. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/App.tsx +37 -16
  11. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/components/ChatArea.tsx +2 -2
  12. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/components/MessageBubble.tsx +1 -1
  13. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/components/ModalCard.tsx +16 -16
  14. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/components/PromptInput.tsx +40 -12
  15. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/components/RightPanel.tsx +19 -17
  16. illusion_code-0.2.6/frontend/web/src/components/Sidebar.tsx +202 -0
  17. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/components/TodoPanel.tsx +2 -2
  18. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/components/Toolbar.tsx +14 -12
  19. illusion_code-0.2.6/frontend/web/src/components/WelcomeScreen.tsx +76 -0
  20. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/index.css +226 -1
  21. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/version.ts +1 -1
  22. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/tailwind.config.js +25 -0
  23. {illusion_code-0.2.5 → illusion_code-0.2.6}/pyproject.toml +1 -1
  24. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/__init__.py +1 -1
  25. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/__init__.py +61 -6
  26. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/base.py +11 -0
  27. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/config.py +3 -2
  28. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/feishu/adapter.py +27 -0
  29. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/feishu/messaging.py +7 -5
  30. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/feishu/session_map.py +2 -1
  31. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/pid.py +2 -1
  32. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/qq/adapter.py +35 -0
  33. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/qq/session_map.py +13 -11
  34. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/weixin/adapter.py +27 -2
  35. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/weixin/session_map.py +17 -1
  36. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/config/settings.py +3 -2
  37. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/engine/query.py +4 -0
  38. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/engine/query_engine.py +6 -1
  39. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/memory/manager.py +4 -3
  40. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/cron.py +2 -1
  41. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/session_storage.py +4 -3
  42. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/file_edit_tool.py +102 -26
  43. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/file_read_tool.py +86 -12
  44. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/file_write_tool.py +54 -12
  45. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/lsp_tool.py +29 -11
  46. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/notebook_edit_tool.py +58 -5
  47. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/web_fetch_tool.py +39 -7
  48. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/permission_store.py +3 -1
  49. illusion_code-0.2.6/src/illusion/utils/__init__.py +1 -0
  50. illusion_code-0.2.6/src/illusion/utils/atomic_write.py +92 -0
  51. illusion_code-0.2.6/src/illusion/utils/file_state_cache.py +289 -0
  52. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_tools/test_core_tools.py +16 -5
  53. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_tools/test_integration_flows.py +16 -9
  54. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_tools/test_web_fetch_tool.py +5 -1
  55. illusion_code-0.2.5/frontend/web/src/components/Sidebar.tsx +0 -164
  56. illusion_code-0.2.5/frontend/web/src/components/WelcomeScreen.tsx +0 -49
  57. illusion_code-0.2.5/tests/test_ui/__init__.py +0 -0
  58. {illusion_code-0.2.5 → illusion_code-0.2.6}/.gitignore +0 -0
  59. {illusion_code-0.2.5 → illusion_code-0.2.6}/.python-version +0 -0
  60. {illusion_code-0.2.5 → illusion_code-0.2.6}/LICENSE +0 -0
  61. {illusion_code-0.2.5 → illusion_code-0.2.6}/README.md +0 -0
  62. {illusion_code-0.2.5 → illusion_code-0.2.6}/README.zh-CN.md +0 -0
  63. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/en/architecture.md +0 -0
  64. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/en/channels.md +0 -0
  65. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/en/commands.md +0 -0
  66. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/en/extensions.md +0 -0
  67. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/en/getting-started.md +0 -0
  68. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/en/introduction.md +0 -0
  69. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/en/project-files.md +0 -0
  70. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/en/settings.md +0 -0
  71. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/images/IllusionCode.png +0 -0
  72. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/images/image1.png +0 -0
  73. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/images/image2.png +0 -0
  74. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/zh-CN/architecture.md +0 -0
  75. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/zh-CN/channels.md +0 -0
  76. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/zh-CN/commands.md +0 -0
  77. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/zh-CN/extensions.md +0 -0
  78. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/zh-CN/getting-started.md +0 -0
  79. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/zh-CN/introduction.md +0 -0
  80. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/zh-CN/project-files.md +0 -0
  81. {illusion_code-0.2.5 → illusion_code-0.2.6}/docs/zh-CN/settings.md +0 -0
  82. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/build.mjs +0 -0
  83. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/App.tsx +0 -0
  84. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/CommandPicker.tsx +0 -0
  85. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/Composer.tsx +0 -0
  86. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/ComposerController.tsx +0 -0
  87. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/ConversationView.tsx +0 -0
  88. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/Footer.tsx +0 -0
  89. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/MarkdownContent.tsx +0 -0
  90. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/MarkdownTable.tsx +0 -0
  91. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/ModalHost.tsx +0 -0
  92. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/MultilineTextInput.tsx +0 -0
  93. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/PromptInput.tsx +0 -0
  94. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/QuestionNavigationBar.tsx +0 -0
  95. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/QuestionPreviewBox.tsx +0 -0
  96. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/SelectModal.tsx +0 -0
  97. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/SidePanel.tsx +0 -0
  98. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/Spinner.tsx +0 -0
  99. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/StatusBar.tsx +0 -0
  100. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/SwarmPanel.tsx +0 -0
  101. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/ToolCallDisplay.tsx +0 -0
  102. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/TranscriptPane.tsx +0 -0
  103. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/components/WelcomeBanner.tsx +0 -0
  104. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/hooks/useAnimationFrame.ts +0 -0
  105. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/hooks/useBackendSession.ts +0 -0
  106. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/hooks/useBlink.ts +0 -0
  107. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/hooks/useQuestionState.ts +0 -0
  108. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/hooks/useTerminalSize.ts +0 -0
  109. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/i18n.ts +0 -0
  110. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/index.tsx +0 -0
  111. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/theme/ThemeContext.tsx +0 -0
  112. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/theme/builtinThemes.ts +0 -0
  113. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/ToolInterface.ts +0 -0
  114. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/AgentTool.ts +0 -0
  115. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/BashTool.ts +0 -0
  116. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/CronTool.ts +0 -0
  117. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/EditTool.ts +0 -0
  118. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/GenericTool.ts +0 -0
  119. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/LspTool.ts +0 -0
  120. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/McpTool.ts +0 -0
  121. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/NotebookTool.ts +0 -0
  122. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/PlanTool.ts +0 -0
  123. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/ReadTool.ts +0 -0
  124. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/SearchTool.ts +0 -0
  125. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/SkillTool.ts +0 -0
  126. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/TaskTool.ts +0 -0
  127. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/WebTool.ts +0 -0
  128. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/WorktreeTool.ts +0 -0
  129. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/implementations/WriteTool.ts +0 -0
  130. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/tools/registry.ts +0 -0
  131. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/types.ts +0 -0
  132. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/utils/markdown.ts +0 -0
  133. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/src/utils/thinking.ts +0 -0
  134. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/terminal/tsconfig.json +0 -0
  135. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/postcss.config.js +0 -0
  136. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/components/ErrorBoundary.tsx +0 -0
  137. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/hooks/useWebSocketSession.ts +0 -0
  138. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/i18n.ts +0 -0
  139. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/main.tsx +0 -0
  140. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/remarkSuperscript.ts +0 -0
  141. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/types/protocol.ts +0 -0
  142. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/src/vite-env.d.ts +0 -0
  143. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/tsconfig.json +0 -0
  144. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/tsconfig.node.json +0 -0
  145. {illusion_code-0.2.5 → illusion_code-0.2.6}/frontend/web/vite.config.ts +0 -0
  146. {illusion_code-0.2.5 → illusion_code-0.2.6}/scripts/build_frontend.py +0 -0
  147. {illusion_code-0.2.5 → illusion_code-0.2.6}/scripts/hatch_build.py +0 -0
  148. {illusion_code-0.2.5 → illusion_code-0.2.6}/scripts/publish.py +0 -0
  149. {illusion_code-0.2.5 → illusion_code-0.2.6}/scripts/sync_version.py +0 -0
  150. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/__main__.py +0 -0
  151. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/api/__init__.py +0 -0
  152. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/api/client.py +0 -0
  153. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/api/codex_client.py +0 -0
  154. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/api/compat.py +0 -0
  155. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/api/effort.py +0 -0
  156. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/api/errors.py +0 -0
  157. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/api/openai_client.py +0 -0
  158. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/api/provider.py +0 -0
  159. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/api/registry.py +0 -0
  160. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/api/usage.py +0 -0
  161. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/auth/__init__.py +0 -0
  162. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/auth/codex_oauth.py +0 -0
  163. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/auth/copilot.py +0 -0
  164. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/auth/external.py +0 -0
  165. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/auth/flows.py +0 -0
  166. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/auth/manager.py +0 -0
  167. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/auth/storage.py +0 -0
  168. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/bridge/__init__.py +0 -0
  169. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/bridge/manager.py +0 -0
  170. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/bridge/session_runner.py +0 -0
  171. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/bridge/types.py +0 -0
  172. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/bridge/work_secret.py +0 -0
  173. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/base_commands.py +0 -0
  174. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/feishu/__init__.py +0 -0
  175. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/feishu/commands.py +0 -0
  176. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/feishu/ws_client.py +0 -0
  177. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/qq/__init__.py +0 -0
  178. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/qq/api.py +0 -0
  179. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/qq/commands.py +0 -0
  180. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/qq/ws_client.py +0 -0
  181. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/serve.py +0 -0
  182. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/tools/__init__.py +0 -0
  183. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/tools/feishu_doc.py +0 -0
  184. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/tools/feishu_drive.py +0 -0
  185. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/weixin/__init__.py +0 -0
  186. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/weixin/commands.py +0 -0
  187. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/channels/weixin/ilink_api.py +0 -0
  188. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/cli.py +0 -0
  189. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/__init__.py +0 -0
  190. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/auth.py +0 -0
  191. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/bridge.py +0 -0
  192. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/context.py +0 -0
  193. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/git.py +0 -0
  194. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/helpers.py +0 -0
  195. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/__init__.py +0 -0
  196. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/analysis/__init__.py +0 -0
  197. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/analysis/architecture.py +0 -0
  198. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/analysis/conventions.py +0 -0
  199. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/analysis/dependencies.py +0 -0
  200. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/analysis/key_modules.py +0 -0
  201. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/extraction/__init__.py +0 -0
  202. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/extraction/lsp_symbols.py +0 -0
  203. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/extraction/readme.py +0 -0
  204. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/extraction/scanner.py +0 -0
  205. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/generation/__init__.py +0 -0
  206. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/generation/claudemd.py +0 -0
  207. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/generation/illusionmd.py +0 -0
  208. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/generation/memory_template.py +0 -0
  209. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/generation/rules.py +0 -0
  210. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/generation/sections.py +0 -0
  211. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/orchestrator.py +0 -0
  212. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/init/types.py +0 -0
  213. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/mcp.py +0 -0
  214. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/memory.py +0 -0
  215. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/misc.py +0 -0
  216. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/model.py +0 -0
  217. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/plugin.py +0 -0
  218. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/registry.py +0 -0
  219. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/rules.py +0 -0
  220. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/sandbox.py +0 -0
  221. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/session.py +0 -0
  222. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/settings.py +0 -0
  223. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/commands/types.py +0 -0
  224. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/config/__init__.py +0 -0
  225. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/config/i18n.py +0 -0
  226. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/config/paths.py +0 -0
  227. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/config/plan_file.py +0 -0
  228. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/coordinator/__init__.py +0 -0
  229. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/coordinator/agent_definitions.py +0 -0
  230. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/coordinator/coordinator_mode.py +0 -0
  231. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/engine/__init__.py +0 -0
  232. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/engine/cost_tracker.py +0 -0
  233. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/engine/messages.py +0 -0
  234. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/engine/stream_events.py +0 -0
  235. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/hooks/__init__.py +0 -0
  236. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/hooks/events.py +0 -0
  237. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/hooks/executor.py +0 -0
  238. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/hooks/hot_reload.py +0 -0
  239. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/hooks/loader.py +0 -0
  240. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/hooks/register_hooks.py +0 -0
  241. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/hooks/schemas.py +0 -0
  242. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/hooks/session_hooks.py +0 -0
  243. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/hooks/types.py +0 -0
  244. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/hooks/utils.py +0 -0
  245. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/mcp/__init__.py +0 -0
  246. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/mcp/client.py +0 -0
  247. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/mcp/config.py +0 -0
  248. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/mcp/types.py +0 -0
  249. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/memory/__init__.py +0 -0
  250. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/memory/memdir.py +0 -0
  251. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/memory/paths.py +0 -0
  252. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/memory/scan.py +0 -0
  253. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/memory/search.py +0 -0
  254. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/memory/types.py +0 -0
  255. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/output_styles/__init__.py +0 -0
  256. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/output_styles/loader.py +0 -0
  257. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/permissions/__init__.py +0 -0
  258. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/permissions/checker.py +0 -0
  259. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/permissions/loader.py +0 -0
  260. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/permissions/modes.py +0 -0
  261. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/permissions/schemas.py +0 -0
  262. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/platforms.py +0 -0
  263. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/plugins/__init__.py +0 -0
  264. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/plugins/installer.py +0 -0
  265. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/plugins/loader.py +0 -0
  266. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/plugins/options.py +0 -0
  267. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/plugins/schemas.py +0 -0
  268. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/plugins/types.py +0 -0
  269. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/prompts/__init__.py +0 -0
  270. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/prompts/claudemd.py +0 -0
  271. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/prompts/context.py +0 -0
  272. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/prompts/environment.py +0 -0
  273. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/prompts/system_prompt.py +0 -0
  274. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/sandbox/__init__.py +0 -0
  275. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/sandbox/adapter.py +0 -0
  276. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/sandbox/platforms/__init__.py +0 -0
  277. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/sandbox/platforms/base.py +0 -0
  278. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/sandbox/platforms/linux.py +0 -0
  279. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/sandbox/platforms/macos.py +0 -0
  280. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/sandbox/platforms/windows.py +0 -0
  281. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/sandbox/proxy/__init__.py +0 -0
  282. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/sandbox/proxy/env_vars.py +0 -0
  283. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/sandbox/runtime.py +0 -0
  284. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/sandbox/symlink_protection.py +0 -0
  285. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/sandbox/utils.py +0 -0
  286. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/sandbox/violation_store.py +0 -0
  287. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/__init__.py +0 -0
  288. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/compact/__init__.py +0 -0
  289. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/compact/auto_compact.py +0 -0
  290. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/compact/compact_core.py +0 -0
  291. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/compact/compact_prompt.py +0 -0
  292. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/compact/constants.py +0 -0
  293. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/compact/message_ops.py +0 -0
  294. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/compact/microcompact.py +0 -0
  295. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/compact/models.py +0 -0
  296. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/compact/token_utils.py +0 -0
  297. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/cron_scheduler.py +0 -0
  298. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/file_history.py +0 -0
  299. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/lsp/__init__.py +0 -0
  300. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/lsp/client.py +0 -0
  301. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/lsp/config.py +0 -0
  302. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/lsp/manager.py +0 -0
  303. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/lsp/types.py +0 -0
  304. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/services/token_estimation.py +0 -0
  305. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/skills/__init__.py +0 -0
  306. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/skills/bundled/__init__.py +0 -0
  307. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/skills/bundled/content/batch.md +0 -0
  308. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/skills/bundled/content/debug.md +0 -0
  309. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/skills/bundled/content/loop.md +0 -0
  310. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/skills/bundled/content/remember.md +0 -0
  311. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/skills/bundled/content/simplify.md +0 -0
  312. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/skills/bundled/content/skillify.md +0 -0
  313. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/skills/bundled/content/stuck.md +0 -0
  314. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/skills/bundled/content/update-config.md +0 -0
  315. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/skills/bundled/content/verify.md +0 -0
  316. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/skills/loader.py +0 -0
  317. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/skills/registry.py +0 -0
  318. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/skills/types.py +0 -0
  319. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/state/__init__.py +0 -0
  320. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/state/app_state.py +0 -0
  321. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/state/store.py +0 -0
  322. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/swarm/__init__.py +0 -0
  323. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/swarm/agent_executor.py +0 -0
  324. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/swarm/in_process.py +0 -0
  325. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/swarm/subprocess_backend.py +0 -0
  326. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/swarm/team_helpers.py +0 -0
  327. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/swarm/types.py +0 -0
  328. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/swarm/worktree.py +0 -0
  329. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tasks/__init__.py +0 -0
  330. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tasks/local_agent_task.py +0 -0
  331. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tasks/local_shell_task.py +0 -0
  332. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tasks/manager.py +0 -0
  333. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tasks/stop_task.py +0 -0
  334. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tasks/types.py +0 -0
  335. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/__init__.py +0 -0
  336. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/agent_tool.py +0 -0
  337. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/ask_user_question_tool.py +0 -0
  338. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/base.py +0 -0
  339. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/bash_tool.py +0 -0
  340. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/config_tool.py +0 -0
  341. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/cron_tool.py +0 -0
  342. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/enter_plan_mode_tool.py +0 -0
  343. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/enter_worktree_tool.py +0 -0
  344. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/exit_plan_mode_tool.py +0 -0
  345. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/exit_worktree_tool.py +0 -0
  346. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/glob_tool.py +0 -0
  347. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/grep_tool.py +0 -0
  348. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/list_mcp_resources_tool.py +0 -0
  349. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/lsp_formatters.py +0 -0
  350. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/lsp_schemas.py +0 -0
  351. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/mcp_auth_tool.py +0 -0
  352. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/mcp_tool.py +0 -0
  353. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/powershell_tool.py +0 -0
  354. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/read_mcp_resource_tool.py +0 -0
  355. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/repl_tool.py +0 -0
  356. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/send_message_tool.py +0 -0
  357. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/shell_common.py +0 -0
  358. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/skill_tool.py +0 -0
  359. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/sleep_tool.py +0 -0
  360. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/structured_output_tool.py +0 -0
  361. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/task_create_tool.py +0 -0
  362. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/task_get_tool.py +0 -0
  363. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/task_list_tool.py +0 -0
  364. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/task_output_tool.py +0 -0
  365. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/task_stop_tool.py +0 -0
  366. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/task_update_tool.py +0 -0
  367. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/team_create_tool.py +0 -0
  368. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/team_delete_tool.py +0 -0
  369. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/todo_write_tool.py +0 -0
  370. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/tool_search_tool.py +0 -0
  371. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/tools/web_search_tool.py +0 -0
  372. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/__init__.py +0 -0
  373. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/app.py +0 -0
  374. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/backend_host.py +0 -0
  375. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/input.py +0 -0
  376. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/output.py +0 -0
  377. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/permission_dialog.py +0 -0
  378. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/protocol.py +0 -0
  379. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/react_launcher.py +0 -0
  380. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/runtime.py +0 -0
  381. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/textual_app.py +0 -0
  382. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/web/__init__.py +0 -0
  383. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/web/server.py +0 -0
  384. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/web/ws_host.py +0 -0
  385. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/ui/web/ws_web_api.py +0 -0
  386. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/utils/ripgrep.py +0 -0
  387. {illusion_code-0.2.5 → illusion_code-0.2.6}/src/illusion/utils/shell.py +0 -0
  388. {illusion_code-0.2.5/src/illusion/utils → illusion_code-0.2.6/tests}/__init__.py +0 -0
  389. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/api/test_anthropic_client.py +0 -0
  390. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/api/test_client.py +0 -0
  391. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/api/test_codex_client.py +0 -0
  392. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/api/test_effort.py +0 -0
  393. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/api/test_fallback/346/217/220/347/244/272.py" +0 -0
  394. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/api/test_openai_client.py +0 -0
  395. {illusion_code-0.2.5/tests → illusion_code-0.2.6/tests/channels}/__init__.py +0 -0
  396. {illusion_code-0.2.5/tests/channels → illusion_code-0.2.6/tests/channels/feishu}/__init__.py +0 -0
  397. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/channels/feishu/test_adapter.py +0 -0
  398. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/channels/feishu/test_commands.py +0 -0
  399. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/channels/feishu/test_session_map.py +0 -0
  400. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/channels/test_base.py +0 -0
  401. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/channels/test_base_commands.py +0 -0
  402. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/channels/test_config.py +0 -0
  403. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/channels/test_pid.py +0 -0
  404. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/channels/test_tool_registration.py +0 -0
  405. {illusion_code-0.2.5/tests/channels/feishu → illusion_code-0.2.6/tests/channels/tools}/__init__.py +0 -0
  406. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/channels/tools/test_feishu_doc.py +0 -0
  407. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/channels/tools/test_feishu_drive.py +0 -0
  408. {illusion_code-0.2.5/tests/channels/tools → illusion_code-0.2.6/tests/channels/weixin}/__init__.py +0 -0
  409. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/channels/weixin/test_adapter.py +0 -0
  410. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/channels/weixin/test_config.py +0 -0
  411. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/channels/weixin/test_ilink_api.py +0 -0
  412. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/channels/weixin/test_session_map.py +0 -0
  413. {illusion_code-0.2.5/tests/channels/weixin → illusion_code-0.2.6/tests/commands/init}/__init__.py +0 -0
  414. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/commands/init/test_claudemd.py +0 -0
  415. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/commands/init/test_orchestrator.py +0 -0
  416. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/commands/init/test_scanner.py +0 -0
  417. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/commands/init/test_sections.py +0 -0
  418. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/commands/test_effort_command.py +0 -0
  419. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/config/test_i18n.py +0 -0
  420. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/config/test_settings.py +0 -0
  421. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/conftest.py +0 -0
  422. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/engine/test_query_engine.py +0 -0
  423. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/fixtures/fake_mcp_server.py +0 -0
  424. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/integration/test_effort_integration.py +0 -0
  425. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/services/lsp/test_lsp_client.py +0 -0
  426. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/services/lsp/test_lsp_config.py +0 -0
  427. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/services/lsp/test_lsp_manager.py +0 -0
  428. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/services/lsp/test_lsp_types.py +0 -0
  429. {illusion_code-0.2.5/tests/commands/init → illusion_code-0.2.6/tests/test_api}/__init__.py +0 -0
  430. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_api/test_client.py +0 -0
  431. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_api/test_codex_client.py +0 -0
  432. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_api/test_compat.py +0 -0
  433. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_api/test_openai_client.py +0 -0
  434. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_auth/test_external.py +0 -0
  435. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_bridge/test_core.py +0 -0
  436. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_bridge/test_session_flow.py +0 -0
  437. {illusion_code-0.2.5/tests/test_api → illusion_code-0.2.6/tests/test_commands}/__init__.py +0 -0
  438. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_commands/test_cli.py +0 -0
  439. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_commands/test_command_flows.py +0 -0
  440. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_commands/test_registry.py +0 -0
  441. {illusion_code-0.2.5/tests/test_commands → illusion_code-0.2.6/tests/test_config}/__init__.py +0 -0
  442. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_config/test_paths.py +0 -0
  443. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_config/test_settings.py +0 -0
  444. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_coordinator/test_agent_definitions.py +0 -0
  445. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_coordinator/test_coordinator_mode.py +0 -0
  446. {illusion_code-0.2.5/tests/test_config → illusion_code-0.2.6/tests/test_engine}/__init__.py +0 -0
  447. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_engine/test_media_block.py +0 -0
  448. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_engine/test_query_engine.py +0 -0
  449. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_engine/test_tool_result_media.py +0 -0
  450. {illusion_code-0.2.5/tests/test_engine → illusion_code-0.2.6/tests/test_hooks}/__init__.py +0 -0
  451. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_hooks/test_executor.py +0 -0
  452. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_hooks/test_loader_permissions.py +0 -0
  453. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_hooks_skills_plugins_real.py +0 -0
  454. {illusion_code-0.2.5/tests/test_hooks → illusion_code-0.2.6/tests/test_mcp}/__init__.py +0 -0
  455. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_mcp/test_config_permissions.py +0 -0
  456. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_mcp/test_integration.py +0 -0
  457. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_mcp/test_stdio_flow.py +0 -0
  458. {illusion_code-0.2.5/tests/test_mcp → illusion_code-0.2.6/tests/test_memory}/__init__.py +0 -0
  459. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_memory/test_manager_permissions.py +0 -0
  460. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_memory/test_memdir.py +0 -0
  461. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_merged_prs_on_autoagent.py +0 -0
  462. {illusion_code-0.2.5/tests/test_memory → illusion_code-0.2.6/tests/test_permissions}/__init__.py +0 -0
  463. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_permissions/test_checker.py +0 -0
  464. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_permissions/test_loader.py +0 -0
  465. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_permissions/test_project_permissions.py +0 -0
  466. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_platforms.py +0 -0
  467. {illusion_code-0.2.5/tests/test_permissions → illusion_code-0.2.6/tests/test_plugins}/__init__.py +0 -0
  468. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_plugins/test_lifecycle_flow.py +0 -0
  469. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_plugins/test_loader.py +0 -0
  470. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_plugins/test_loader_permissions.py +0 -0
  471. {illusion_code-0.2.5/tests/test_plugins → illusion_code-0.2.6/tests/test_prompts}/__init__.py +0 -0
  472. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_prompts/test_claudemd.py +0 -0
  473. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_prompts/test_claudemd_permissions.py +0 -0
  474. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_prompts/test_environment.py +0 -0
  475. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_prompts/test_system_prompt.py +0 -0
  476. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_qq_channel.py +0 -0
  477. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_real_large_tasks.py +0 -0
  478. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_sandbox/test_adapter.py +0 -0
  479. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_sandbox/test_config_schema.py +0 -0
  480. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_sandbox/test_platform_linux.py +0 -0
  481. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_sandbox/test_platform_macos.py +0 -0
  482. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_sandbox/test_platform_windows.py +0 -0
  483. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_sandbox/test_proxy_env_vars.py +0 -0
  484. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_sandbox/test_runtime.py +0 -0
  485. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_sandbox/test_symlink_protection.py +0 -0
  486. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_sandbox/test_utils.py +0 -0
  487. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_sandbox/test_violation_store.py +0 -0
  488. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_scripts/test_sync_version.py +0 -0
  489. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_services/test_compact.py +0 -0
  490. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_services/test_cron.py +0 -0
  491. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_services/test_cron_scheduler.py +0 -0
  492. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_services/test_session_storage.py +0 -0
  493. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_skills/test_loader.py +0 -0
  494. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_skills/test_loader_permissions.py +0 -0
  495. {illusion_code-0.2.5/tests/test_prompts → illusion_code-0.2.6/tests/test_swarm}/__init__.py +0 -0
  496. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_swarm/test_agent_executor.py +0 -0
  497. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_swarm/test_imports.py +0 -0
  498. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_swarm/test_in_process.py +0 -0
  499. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_swarm/test_types.py +0 -0
  500. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_swarm/test_worktree.py +0 -0
  501. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_tasks/test_manager.py +0 -0
  502. {illusion_code-0.2.5/tests/test_swarm → illusion_code-0.2.6/tests/test_tools}/__init__.py +0 -0
  503. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_tools/test_agent_tool.py +0 -0
  504. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_tools/test_file_read_media.py +0 -0
  505. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_tools/test_glob_tool.py +0 -0
  506. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_tools/test_grep_tool.py +0 -0
  507. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_tools/test_integration.py +0 -0
  508. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_tools/test_mcp_auth_tool.py +0 -0
  509. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_tools/test_ripgrep.py +0 -0
  510. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_tools/test_shell_common.py +0 -0
  511. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_tools/test_task_tools.py +0 -0
  512. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_tools/test_team_tools.py +0 -0
  513. {illusion_code-0.2.5/tests/test_tools → illusion_code-0.2.6/tests/test_ui}/__init__.py +0 -0
  514. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_ui/test_modes.py +0 -0
  515. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_ui/test_permission_store.py +0 -0
  516. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_ui/test_react_backend.py +0 -0
  517. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_ui/test_react_launcher.py +0 -0
  518. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_ui/test_textual_app.py +0 -0
  519. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_untested_features.py +0 -0
  520. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/test_utils/test_shell.py +0 -0
  521. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/ui/test_backend_host.py +0 -0
  522. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/ui/test_protocol_web.py +0 -0
  523. {illusion_code-0.2.5 → illusion_code-0.2.6}/tests/ui/test_web_api.py +0 -0
@@ -10,6 +10,7 @@ jobs:
10
10
  runs-on: ubuntu-latest
11
11
  permissions:
12
12
  contents: read
13
+ id-token: write
13
14
 
14
15
  steps:
15
16
  - uses: actions/checkout@v4
@@ -43,7 +44,4 @@ jobs:
43
44
  run: twine check dist/*
44
45
 
45
46
  - name: Publish to PyPI
46
- env:
47
- TWINE_USERNAME: __token__
48
- TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
49
- run: twine upload dist/*
47
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: illusion-code
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: Open-source Python port of Claude Code - an AI-powered CLI coding assistant
5
5
  Project-URL: Homepage, https://github.com/YunTaiHua/illusion-code
6
6
  Project-URL: Repository, https://github.com/YunTaiHua/illusion-code
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@illusion/terminal",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@illusion/terminal",
9
- "version": "0.2.5",
9
+ "version": "0.2.6",
10
10
  "dependencies": {
11
11
  "chalk": "^5.6.2",
12
12
  "ink": "^5.1.0",
@@ -24,5 +24,5 @@
24
24
  "tsx": "^4.19.2",
25
25
  "typescript": "^5.7.3"
26
26
  },
27
- "version": "0.2.5"
27
+ "version": "0.2.6"
28
28
  }
@@ -41,10 +41,6 @@ export function TodoPanel({items}: {items: TodoItemSnapshot[]}): React.JSX.Eleme
41
41
  const hideTimerRef = useRef<NodeJS.Timeout | null>(null);
42
42
  const completionTimeRef = useRef<Record<string, number>>({});
43
43
 
44
- if (items.length === 0 || hidden) {
45
- return <></>;
46
- }
47
-
48
44
  const completed = items.filter((t) => t.status === 'completed').length;
49
45
  const inProgress = items.filter((t) => t.status === 'in_progress').length;
50
46
  const pending = items.filter((t) => t.status === 'pending').length;
@@ -58,7 +54,7 @@ export function TodoPanel({items}: {items: TodoItemSnapshot[]}): React.JSX.Eleme
58
54
  }
59
55
  }
60
56
 
61
- // 所有任务完成后延迟隐藏
57
+ // 所有任务完成后延迟隐藏(必须在所有条件 return 之前,遵守 Hooks 规则)
62
58
  useEffect(() => {
63
59
  if (allDone) {
64
60
  if (hideTimerRef.current === null) {
@@ -82,6 +78,11 @@ export function TodoPanel({items}: {items: TodoItemSnapshot[]}): React.JSX.Eleme
82
78
  };
83
79
  }, [allDone]);
84
80
 
81
+ // 条件 return 放在 useEffect 之后,避免违反 React Hooks 规则
82
+ if (items.length === 0 || hidden) {
83
+ return <></>;
84
+ }
85
+
85
86
  // 排序:最近完成 > in_progress > pending > 较早完成
86
87
  const sorted = [...items].sort((a, b) => {
87
88
  const aRecent = a.status === 'completed' && (now - (completionTimeRef.current[a.content] ?? 0)) < RECENT_COMPLETED_TTL_MS;
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  /** 当前版本号 */
9
- export const VERSION = '0.2.5';
9
+ export const VERSION = '0.2.6';
@@ -8,7 +8,7 @@
8
8
  <link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,100..900&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap" rel="stylesheet" />
9
9
  <title>Illusion Code</title>
10
10
  </head>
11
- <body class="bg-white">
11
+ <body>
12
12
  <div id="root"></div>
13
13
  <script type="module" src="/src/main.tsx"></script>
14
14
  </body>
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@illusion/web",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@illusion/web",
9
- "version": "0.2.5",
9
+ "version": "0.2.6",
10
10
  "dependencies": {
11
11
  "highlight.js": "^11.11.0",
12
12
  "react": "^18.3.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@illusion/web",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -55,18 +55,27 @@ export default function App() {
55
55
 
56
56
  // Toast 状态
57
57
  const [toastMessage, setToastMessage] = useState<{ text: string; type: 'success' | 'error' | 'info' } | null>(null);
58
+ const [toastExiting, setToastExiting] = useState(false);
58
59
  const toastTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
59
60
  const toastHoverRef = useRef(false);
61
+ const toastKeyRef = useRef(0);
62
+
63
+ const closeToast = useCallback(() => {
64
+ setToastExiting(true);
65
+ setTimeout(() => { setToastMessage(null); setToastExiting(false); }, 200);
66
+ }, []);
60
67
 
61
68
  const showToast = useCallback((text: string, type: string) => {
62
69
  if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
70
+ toastKeyRef.current += 1;
71
+ setToastExiting(false);
63
72
  setToastMessage({ text, type: type as 'success' | 'error' | 'info' });
64
73
  toastHoverRef.current = false;
65
74
  toastTimerRef.current = setTimeout(() => {
66
- if (!toastHoverRef.current) { setToastMessage(null); }
75
+ if (!toastHoverRef.current) { closeToast(); }
67
76
  toastTimerRef.current = null;
68
77
  }, TOAST_DURATION);
69
- }, []);
78
+ }, [closeToast]);
70
79
 
71
80
  const handleToastMouseEnter = useCallback(() => {
72
81
  toastHoverRef.current = true;
@@ -75,8 +84,8 @@ export default function App() {
75
84
 
76
85
  const handleToastMouseLeave = useCallback(() => {
77
86
  toastHoverRef.current = false;
78
- toastTimerRef.current = setTimeout(() => { setToastMessage(null); toastTimerRef.current = null; }, TOAST_DURATION);
79
- }, []);
87
+ toastTimerRef.current = setTimeout(() => { closeToast(); toastTimerRef.current = null; }, TOAST_DURATION);
88
+ }, [closeToast]);
80
89
 
81
90
  /**
82
91
  * 注册回调函数
@@ -317,7 +326,7 @@ export default function App() {
317
326
  };
318
327
 
319
328
  return (
320
- <div className="flex h-screen bg-surface-main">
329
+ <div className="flex h-screen">
321
330
  <Sidebar lang={lang} connected={session.connected} sessions={session.sessions}
322
331
  onNewSession={handleNewSession} onSelectSession={handleSelectSession}
323
332
  onListSessions={handleListSessions}
@@ -363,8 +372,8 @@ export default function App() {
363
372
  {/* 删除会话弹窗(仅 sidebar 触发) */}
364
373
  {showDeleteModal && (
365
374
  <div className="fixed inset-0 z-50 flex items-center justify-center">
366
- <div className="absolute inset-0 bg-black/30 backdrop-blur-sm" onClick={handleCloseDeleteModal} />
367
- <div className="relative bg-white rounded-xl shadow-2xl border border-border-light w-[420px] max-h-[70vh] flex flex-col">
375
+ <div className="absolute inset-0 bg-black/35 backdrop-blur-md animate-fade-in" onClick={handleCloseDeleteModal} />
376
+ <div className="relative glass-overlay rounded-2xl w-[420px] max-h-[70vh] flex flex-col animate-scale-in modal-origin-center">
368
377
  <div className="px-6 py-4 border-b border-border-light">
369
378
  <h3 className="text-lg font-semibold text-content-primary">{t(lang, 'delete_session')}</h3>
370
379
  </div>
@@ -372,7 +381,7 @@ export default function App() {
372
381
  {regularSessions.length === 0 ? (
373
382
  <div className="px-6 py-8 text-center text-sm text-content-disabled">{t(lang, 'no_sessions')}</div>
374
383
  ) : regularSessions.map((s) => (
375
- <label key={s.value} className="flex items-center gap-3 px-6 py-3 cursor-pointer hover:bg-surface-hover transition-colors">
384
+ <label key={s.value} className="flex items-center gap-3 px-6 py-3 cursor-pointer glass-option-hover transition-colors rounded-lg mx-1">
376
385
  <input type="checkbox" checked={deleteSelected.has(s.value)} onChange={() => toggleDeleteItem(s.value)} className="w-4 h-4 rounded accent-danger" />
377
386
  <span className="text-sm text-content-secondary truncate flex-1">{s.label}</span>
378
387
  </label>
@@ -384,10 +393,10 @@ export default function App() {
384
393
  // 直接删除全部;后端会原子化地新建空会话,避免两阶段竞态
385
394
  session.deleteSessions([], true);
386
395
  setDeleteModalOpen(false); setDeleteSelected(new Set());
387
- }} className="px-4 py-2 text-sm text-danger hover:bg-red-50 rounded-lg transition-colors cursor-pointer">{t(lang, 'delete_all')}</button>
396
+ }} className="danger-action px-4 py-2 text-sm text-danger rounded-lg cursor-pointer">{t(lang, 'delete_all')}</button>
388
397
  )}</div>
389
398
  <div className="flex gap-2">
390
- <button onClick={handleCloseDeleteModal} className="px-4 py-2 text-sm text-content-secondary hover:bg-surface-hover rounded-lg transition-colors cursor-pointer border border-border-light">{t(lang, 'cancel')}</button>
399
+ <button onClick={handleCloseDeleteModal} className="px-4 py-2 text-sm text-content-secondary glass-option-hover rounded-lg transition-colors cursor-pointer border border-white/40">{t(lang, 'cancel')}</button>
391
400
  <button onClick={handleConfirmDelete} disabled={deleteSelected.size === 0}
392
401
  className="px-4 py-2 text-sm text-white bg-danger hover:bg-danger-hover rounded-lg transition-colors cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed">
393
402
  {t(lang, 'confirm_delete')} ({deleteSelected.size})
@@ -400,16 +409,28 @@ export default function App() {
400
409
 
401
410
  {/* Toast 通知 */}
402
411
  {toastMessage && (
403
- <div className="fixed bottom-20 right-6 z-50 animate-fade-in"
404
- onMouseEnter={handleToastMouseEnter} onMouseLeave={handleToastMouseLeave}>
405
- <div className="bg-white rounded-lg shadow-lg px-4 py-3 max-w-sm">
406
- <div className="flex items-start gap-3">
412
+ <div
413
+ key={toastKeyRef.current}
414
+ className={`fixed bottom-20 right-6 z-50 ${toastExiting ? 'animate-toast-out' : 'animate-toast-in'}`}
415
+ onMouseEnter={handleToastMouseEnter} onMouseLeave={handleToastMouseLeave}
416
+ >
417
+ <div className="glass-surface border border-black/10 rounded-2xl max-w-sm overflow-hidden">
418
+ <div className="flex items-start gap-3 px-4 py-3">
407
419
  <pre className="text-sm text-content-primary whitespace-pre-wrap font-mono leading-relaxed flex-1 max-h-40 overflow-y-auto">{toastMessage.text}</pre>
408
- <button onClick={() => setToastMessage(null)}
409
- className="shrink-0 w-5 h-5 flex items-center justify-center rounded text-content-disabled hover:text-content-primary hover:bg-surface-hover transition-colors cursor-pointer">
420
+ <button onClick={closeToast}
421
+ className="shrink-0 w-5 h-5 flex items-center justify-center rounded text-content-disabled hover:text-content-primary glass-option-hover transition-colors cursor-pointer">
410
422
  <svg width="10" height="10" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M2 2l8 8M10 2l-8 8" /></svg>
411
423
  </button>
412
424
  </div>
425
+ <div className="h-0.5 bg-black/10">
426
+ <div
427
+ key={toastKeyRef.current}
428
+ className={`h-full animate-progress-shrink ${
429
+ toastMessage.type === 'error' ? 'bg-danger/80' : toastMessage.type === 'success' ? 'bg-success/80' : 'bg-primary/80'
430
+ }`}
431
+ style={{ animationDuration: `${TOAST_DURATION}ms` }}
432
+ />
433
+ </div>
413
434
  </div>
414
435
  </div>
415
436
  )}
@@ -103,7 +103,7 @@ export default function ChatArea({
103
103
  // 此条件返回在所有 hooks 之后,不违反 React Rules of Hooks
104
104
  if (restoringSessionId) {
105
105
  return (
106
- <div className="flex-1 flex items-center justify-center bg-surface-main">
106
+ <div className="flex-1 flex items-center justify-center">
107
107
  <div className="flex flex-col items-center gap-3">
108
108
  <svg className="animate-spin w-8 h-8 text-primary" viewBox="0 0 24 24" fill="none">
109
109
  <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
@@ -116,7 +116,7 @@ export default function ChatArea({
116
116
  }
117
117
 
118
118
  return (
119
- <div className="flex-1 overflow-y-auto bg-surface-main">
119
+ <div className="flex-1 overflow-y-auto">
120
120
  {!connected && !hasContent && (
121
121
  <div className="flex items-center justify-center h-full text-content-disabled text-sm font-medium">
122
122
  {t(lang, 'connecting')}
@@ -51,7 +51,7 @@ export default function MessageBubble({ item, toolInputMap }: MessageBubbleProps
51
51
 
52
52
  if (item.role === 'assistant') {
53
53
  return (
54
- <div className="py-1.5">
54
+ <div className="py-1.5 animate-fade-in-up">
55
55
  {item.reasoning && <ThinkingBlock text={item.reasoning} />}
56
56
  <div className="text-content-primary text-sm prose max-w-full select-text">
57
57
  <ReactMarkdown remarkPlugins={[remarkGfm, remarkSuperscript]} rehypePlugins={[rehypeHighlight, rehypeRaw]}>
@@ -65,8 +65,8 @@ export function PermissionCard({ modal, lang, onRespond }: PermissionCardProps)
65
65
  const requestId = String(modal.request_id ?? '');
66
66
 
67
67
  return (
68
- <div className="my-3 rounded-xl border border-border-light overflow-hidden shadow-soft">
69
- <div className="bg-surface-main px-4 py-3 flex items-center gap-2">
68
+ <div className="my-3 rounded-2xl glass-surface overflow-hidden">
69
+ <div className="px-4 py-3 flex items-center gap-2 border-b border-white/30">
70
70
  <svg className="w-4 h-4 text-amber-500 shrink-0" viewBox="0 0 16 16" fill="currentColor">
71
71
  <path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z" />
72
72
  </svg>
@@ -82,16 +82,16 @@ export function PermissionCard({ modal, lang, onRespond }: PermissionCardProps)
82
82
  <div className="text-xs text-content-secondary mt-1 leading-relaxed">{reason}</div>
83
83
  )}
84
84
  </div>
85
- <div className="px-4 py-3 border-t border-border-light flex items-center justify-end gap-2">
85
+ <div className="px-4 py-3 border-t border-white/30 flex items-center justify-end gap-2">
86
86
  <button
87
87
  onClick={() => onRespond(requestId, false, false, toolName)}
88
- className="px-3 py-1.5 text-xs font-medium text-content-secondary hover:bg-surface-hover rounded-md transition-colors cursor-pointer"
88
+ className="px-3 py-1.5 text-xs font-medium text-content-secondary glass-option-hover rounded-md transition-colors cursor-pointer"
89
89
  >
90
90
  {t(lang, 'deny')}
91
91
  </button>
92
92
  <button
93
93
  onClick={() => onRespond(requestId, true, true, toolName)}
94
- className="px-3 py-1.5 text-xs font-medium text-content-primary border border-border-light hover:bg-surface-hover rounded-md transition-colors cursor-pointer"
94
+ className="px-3 py-1.5 text-xs font-medium text-content-primary border border-white/40 glass-option-hover rounded-md transition-colors cursor-pointer"
95
95
  >
96
96
  {t(lang, 'always_allow')}
97
97
  </button>
@@ -319,11 +319,11 @@ export function QuestionCard({ modal, lang, onRespond }: QuestionCardProps) {
319
319
  if (next && cardRef.current?.contains(next)) return;
320
320
  submitSingleMultiSelect();
321
321
  }}
322
- className={`my-3 rounded-xl border border-border-light overflow-hidden shadow-soft ${
322
+ className={`my-3 rounded-2xl glass-surface overflow-hidden ${
323
323
  isMultiSelect && !isMultiQuestion ? 'outline-none' : ''
324
324
  }`}
325
325
  >
326
- <div className="bg-surface-main px-4 py-3">
326
+ <div className="px-4 py-3">
327
327
  {/* Tab 导航栏 — 仅多问题时显示 */}
328
328
  {isMultiQuestion && (
329
329
  <div className="flex items-center gap-1 mb-2 overflow-x-auto">
@@ -340,7 +340,7 @@ export function QuestionCard({ modal, lang, onRespond }: QuestionCardProps) {
340
340
  ? 'bg-primary text-white'
341
341
  : isAnswered
342
342
  ? 'bg-primary-light text-primary border border-primary/20'
343
- : 'bg-surface-hover text-content-secondary hover:bg-surface-main'
343
+ : 'glass-option-hover text-content-secondary'
344
344
  }`}
345
345
  >
346
346
  {isAnswered && !isActive && <span className="mr-1">✓</span>}
@@ -376,8 +376,8 @@ export function QuestionCard({ modal, lang, onRespond }: QuestionCardProps) {
376
376
  onClick={() => handleOptionClick(i, opt.label)}
377
377
  className={`w-full text-left px-3 py-2.5 rounded-lg text-sm transition-colors cursor-pointer flex items-start gap-2.5 ${
378
378
  isSelected
379
- ? 'bg-primary-light border border-primary/20'
380
- : 'bg-white border border-border-light hover:bg-surface-hover'
379
+ ? 'glass-option-active'
380
+ : 'border border-transparent glass-option-hover'
381
381
  }`}
382
382
  >
383
383
  {isMultiSelect ? (
@@ -407,10 +407,10 @@ export function QuestionCard({ modal, lang, onRespond }: QuestionCardProps) {
407
407
  <div
408
408
  className={`w-full text-left px-3 py-2.5 rounded-lg text-sm transition-colors cursor-pointer flex items-start gap-2.5 ${
409
409
  isMultiSelect && selectedIndices.has(otherIdx)
410
- ? 'bg-primary-light border border-primary/20'
410
+ ? 'glass-option-active'
411
411
  : isOtherFocused
412
- ? 'bg-white border border-primary/30'
413
- : 'text-content-disabled hover:bg-surface-hover border border-border-light border-dashed'
412
+ ? 'glass-option-active'
413
+ : 'text-content-disabled glass-option-hover border border-black/[0.06] border-dashed'
414
414
  }`}
415
415
  onClick={() => handleOptionClick(otherIdx, lang === 'zh-CN' ? '其他' : 'Other')}
416
416
  >
@@ -501,7 +501,7 @@ export function QuestionCard({ modal, lang, onRespond }: QuestionCardProps) {
501
501
  }}
502
502
  placeholder={lang === 'zh-CN' ? '输入你的回答...' : 'Type your answer...'}
503
503
  rows={1}
504
- className="flex-1 resize-none bg-white border border-border-light rounded-lg px-3 py-2 text-sm outline-none focus:border-content-disabled transition-colors"
504
+ className="flex-1 resize-none bg-white/60 border border-white/40 rounded-lg px-3 py-2 text-sm outline-none focus:border-primary/40 transition-colors"
505
505
  />
506
506
  <button
507
507
  onClick={() => {
@@ -523,7 +523,7 @@ export function QuestionCard({ modal, lang, onRespond }: QuestionCardProps) {
523
523
  )}
524
524
  </div>
525
525
 
526
- <div className="px-4 py-3 border-t border-border-light flex items-center justify-between">
526
+ <div className="px-4 py-3 border-t border-white/30 flex items-center justify-between">
527
527
  {/* 左侧:重置按钮(多问题时) */}
528
528
  <div>
529
529
  {isMultiQuestion && Object.keys(multiAnswers).length > 0 && (
@@ -534,7 +534,7 @@ export function QuestionCard({ modal, lang, onRespond }: QuestionCardProps) {
534
534
  setAllOtherText({});
535
535
  setCurrentIndex(0);
536
536
  }}
537
- className="px-3 py-1.5 text-xs font-medium text-content-secondary hover:bg-surface-hover rounded-md transition-colors cursor-pointer"
537
+ className="px-3 py-1.5 text-xs font-medium text-content-secondary glass-option-hover rounded-md transition-colors cursor-pointer"
538
538
  >
539
539
  {lang === 'zh-CN' ? '重置' : 'Reset'}
540
540
  </button>
@@ -88,6 +88,31 @@ export default function PromptInput({ lang, busy, connected, commands, onSubmit,
88
88
  const [showCommands, setShowCommands] = useState(false);
89
89
  const [selectedIndex, setSelectedIndex] = useState(0);
90
90
  const listRef = useRef<HTMLDivElement>(null);
91
+ const containerRef = useRef<HTMLDivElement>(null);
92
+
93
+ // 点击外部关闭内联选项
94
+ useEffect(() => {
95
+ if (!inlineOptions || inlineOptions.options.length === 0) return;
96
+ const handler = (e: MouseEvent) => {
97
+ if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
98
+ onInlineClose?.();
99
+ }
100
+ };
101
+ document.addEventListener('mousedown', handler);
102
+ return () => document.removeEventListener('mousedown', handler);
103
+ }, [inlineOptions, onInlineClose]);
104
+
105
+ // 点击外部关闭命令补全
106
+ useEffect(() => {
107
+ if (!showCommands) return;
108
+ const handler = (e: MouseEvent) => {
109
+ if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
110
+ setShowCommands(false);
111
+ }
112
+ };
113
+ document.addEventListener('mousedown', handler);
114
+ return () => document.removeEventListener('mousedown', handler);
115
+ }, [showCommands]);
91
116
 
92
117
  // 自动补全仅显示 B 类指令(与后端 ready 推送的完整命令列表取交集,无交集则用静态集合)
93
118
  const webCommands = useMemo(() => {
@@ -225,18 +250,19 @@ export default function PromptInput({ lang, busy, connected, commands, onSubmit,
225
250
  const showAutocomplete = showCommands && filteredCommands.length > 0 && !showInline;
226
251
 
227
252
  return (
228
- <div className="px-4 md:px-5 pb-4 pt-2 relative">
253
+ <div className="px-4 md:px-5 pb-4 pt-2 relative" ref={containerRef}>
229
254
  {/* 内联选项 */}
230
255
  {showInline && (
231
- <div className="absolute bottom-full left-4 right-4 md:left-5 md:right-5 mb-1 bg-white border border-border-light rounded-xl shadow-lg max-h-64 overflow-y-auto py-1 z-20">
232
- <div className="px-3 py-1.5 text-xs text-content-disabled font-medium">{inlineOptions.title}</div>
256
+ <div className="absolute bottom-full left-4 right-4 md:left-5 md:right-5 mb-1 glass-surface rounded-xl max-h-64 overflow-y-auto py-1.5 z-20 animate-fade-in-up">
257
+ <div className="px-3 py-1.5 text-[10px] text-content-disabled font-semibold uppercase tracking-widest">{inlineOptions.title}</div>
233
258
  {inlineOptions.options.map((opt, idx) => (
234
259
  <button
235
260
  key={opt.value}
236
261
  onClick={() => onInlineSelect?.(inlineOptions.command, opt.value)}
237
- className={`w-full text-left px-3 py-2 text-sm transition-colors cursor-pointer flex flex-col gap-0.5 ${
238
- idx === selectedIndex ? 'bg-primary-light text-primary' : opt.active ? 'bg-surface-hover text-content-primary' : 'text-content-secondary hover:bg-surface-hover'
262
+ className={`w-full text-left px-3 py-2 text-sm transition-colors cursor-pointer flex flex-col gap-0.5 animate-fade-in-up rounded-md ${
263
+ idx === selectedIndex ? 'glass-option-active text-content-primary' : opt.active ? 'text-primary/70 glass-option-hover' : 'text-content-secondary glass-option-hover'
239
264
  }`}
265
+ style={{ animationDelay: `${(idx + 1) * 30}ms` }}
240
266
  >
241
267
  <span className="font-medium">{opt.label}</span>
242
268
  {opt.description && <span className="text-xs text-content-disabled">{opt.description}</span>}
@@ -249,15 +275,17 @@ export default function PromptInput({ lang, busy, connected, commands, onSubmit,
249
275
  {showAutocomplete && (
250
276
  <div
251
277
  ref={listRef}
252
- className="absolute bottom-full left-4 right-4 md:left-5 md:right-5 mb-1 bg-white border border-border-light rounded-xl shadow-lg max-h-56 overflow-y-auto py-1 z-20"
278
+ className="absolute bottom-full left-4 right-4 md:left-5 md:right-5 mb-1 glass-surface rounded-xl max-h-56 overflow-y-auto py-1.5 z-20 animate-fade-in-up"
253
279
  >
280
+ <div className="px-3 py-1.5 text-[10px] text-content-disabled font-semibold uppercase tracking-widest">Commands</div>
254
281
  {filteredCommands.map((cmd, idx) => (
255
282
  <button
256
283
  key={cmd}
257
284
  onClick={() => selectCommand(cmd)}
258
- className={`w-full text-left px-3 py-2 text-sm transition-colors cursor-pointer ${
259
- idx === selectedIndex ? 'bg-primary-light text-primary' : 'text-content-secondary hover:bg-surface-hover'
285
+ className={`w-full text-left px-3 py-2 text-sm transition-colors cursor-pointer animate-fade-in-up rounded-md ${
286
+ idx === selectedIndex ? 'glass-option-active text-content-primary' : 'text-content-secondary glass-option-hover'
260
287
  }`}
288
+ style={{ animationDelay: `${idx * 30}ms` }}
261
289
  >
262
290
  <span className="font-mono">{cmd}</span>
263
291
  </button>
@@ -265,7 +293,7 @@ export default function PromptInput({ lang, busy, connected, commands, onSubmit,
265
293
  </div>
266
294
  )}
267
295
 
268
- <div className="flex items-end bg-surface-card rounded-md border border-border-light shadow-soft focus-within:border-primary focus-within:ring-1 focus-within:ring-primary">
296
+ <div className="flex items-end glass-surface rounded-lg transition-all duration-200 focus-within:shadow-glow">
269
297
  <textarea
270
298
  value={value}
271
299
  onChange={handleChange}
@@ -284,14 +312,14 @@ export default function PromptInput({ lang, busy, connected, commands, onSubmit,
284
312
  <button
285
313
  onClick={handleSend}
286
314
  disabled={!connected && !busy}
287
- className={`shrink-0 m-1.5 w-8 h-8 flex items-center justify-center rounded-full transition-colors cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed ${
315
+ className={`shrink-0 m-1.5 w-8 h-8 flex items-center justify-center rounded-full transition-all duration-150 cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed hover:scale-105 active:scale-90 ${
288
316
  busy
289
317
  ? 'bg-danger/10 text-danger hover:bg-danger/20 animate-pulse'
290
- : 'bg-primary text-white hover:bg-primary-hover'
318
+ : 'bg-primary text-white hover:bg-primary-hover hover:shadow-glow'
291
319
  }`}
292
320
  title={busy ? t(lang, 'task_stopped') : t(lang, 'send')}
293
321
  >
294
- {busy ? '■' : '↑'}
322
+ {busy ? <svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><rect width="10" height="10" rx="1.5" /></svg> : '↑'}
295
323
  </button>
296
324
  </div>
297
325
  </div>
@@ -67,15 +67,15 @@ export default function RightPanel({
67
67
  // 折叠态
68
68
  if (collapsed) {
69
69
  return (
70
- <aside className="w-12 bg-surface-main border-l border-border-light flex flex-col items-center py-4 shrink-0 select-none">
70
+ <aside className="w-12 glass-panel border-l border-white/30 flex flex-col items-center py-4 shrink-0 select-none">
71
71
  <button onClick={onToggle} title={t(lang, 'expand_panel')}
72
- className="w-8 h-8 flex items-center justify-center rounded-lg text-content-secondary hover:bg-surface-hover hover:text-content-primary transition-colors cursor-pointer">
72
+ className="w-8 h-8 flex items-center justify-center rounded-lg text-content-secondary glass-option-hover hover:text-content-primary transition-colors cursor-pointer">
73
73
  <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
74
74
  <path d="M10 3l-5 5 5 5" />
75
75
  </svg>
76
76
  </button>
77
77
  <div className="mt-auto mb-2">
78
- <span className={`block w-2.5 h-2.5 rounded-full ${connected ? (busy ? 'bg-warning animate-pulse' : 'bg-success') : 'bg-danger'}`} />
78
+ <span className={`block w-2.5 h-2.5 rounded-full ${connected ? (busy ? 'bg-warning animate-pulse' : 'bg-success') : 'bg-danger'}`} style={connected && !busy ? { boxShadow: '0 0 6px rgba(76, 175, 125, 0.5)' } : busy ? { boxShadow: '0 0 6px rgba(232, 168, 76, 0.5)' } : { boxShadow: '0 0 6px rgba(212, 91, 91, 0.4)' }} />
79
79
  </div>
80
80
  </aside>
81
81
  );
@@ -87,11 +87,11 @@ export default function RightPanel({
87
87
  const projectRules = rules.filter((r) => r.source === 'project');
88
88
 
89
89
  return (
90
- <aside className="bg-surface-main border-l border-border-light flex flex-col h-full shrink-0 overflow-y-auto select-none" style={{ width: `${width}px` }}>
90
+ <aside className="glass-panel border-l border-white/30 flex flex-col h-full shrink-0 overflow-y-auto select-none" style={{ width: `${width}px` }}>
91
91
  {/* 折叠按钮 */}
92
92
  <div className="px-5 pt-3 pb-1 flex justify-end">
93
93
  <button onClick={onToggle} title={t(lang, 'collapse_panel')}
94
- className="w-7 h-7 flex items-center justify-center rounded-lg text-content-secondary hover:bg-surface-hover hover:text-content-primary transition-colors cursor-pointer">
94
+ className="w-7 h-7 flex items-center justify-center rounded-lg text-content-secondary glass-option-hover hover:text-content-primary transition-colors cursor-pointer">
95
95
  <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
96
96
  <path d="M6 3l5 5-5 5" />
97
97
  </svg>
@@ -164,9 +164,9 @@ export default function RightPanel({
164
164
  <div className="text-xs text-content-secondary font-medium mb-1.5">{t(lang, 'context_window')}</div>
165
165
  <div className="flex items-center gap-3">
166
166
  <span className="text-sm text-content-primary whitespace-nowrap tabular-nums">~{formatTokens(contextTokens)}/{formatTokens(contextWindow)}</span>
167
- <div className="flex-1 h-2 bg-surface-hover rounded-full overflow-hidden">
167
+ <div className="flex-1 h-1.5 bg-black/10 rounded-full overflow-hidden">
168
168
  <div
169
- className={`h-full rounded-full transition-all duration-500 ${contextPercent >= 95 ? 'bg-danger' : contextPercent >= 80 ? 'bg-warning' : 'bg-primary'}`}
169
+ className={`h-full rounded-full transition-all duration-500 ${contextPercent >= 95 ? 'bg-gradient-to-r from-warning to-danger' : contextPercent >= 80 ? 'bg-gradient-to-r from-primary to-warning' : 'bg-primary'}`}
170
170
  style={{ width: `${contextPercent}%` }}
171
171
  />
172
172
  </div>
@@ -199,23 +199,25 @@ function CollapsibleSection({
199
199
  <div className="border-t border-border-light">
200
200
  <button
201
201
  onClick={() => setCollapsed((c) => !c)}
202
- className="w-full px-5 py-2.5 flex items-center gap-2 hover:bg-surface-hover transition-colors cursor-pointer"
202
+ className="w-full px-5 py-2.5 flex items-center gap-2 glass-option-hover transition-colors cursor-pointer"
203
203
  >
204
204
  <svg
205
- className={`w-3 h-3 text-content-disabled shrink-0 transition-transform duration-150 ${collapsed ? '' : 'rotate-90'}`}
205
+ className={`w-3 h-3 text-content-disabled shrink-0 transition-transform duration-200 ${collapsed ? '' : 'rotate-90'}`}
206
206
  viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
207
207
  >
208
208
  <path d="M6 3l5 5-5 5" />
209
209
  </svg>
210
- <span className="text-xs font-medium text-content-primary">{title}</span>
211
- <span className="text-xs text-content-disabled tabular-nums">{count}</span>
210
+ <span className="text-xs font-semibold text-content-primary tracking-wide">{title}</span>
211
+ <span className="text-[10px] text-content-secondary bg-white/50 px-1.5 py-0.5 rounded-full tabular-nums">{count}</span>
212
212
  {subtitle && <span className="text-xs text-content-disabled ml-auto">{subtitle}</span>}
213
213
  </button>
214
- {!collapsed && (
215
- <div className="px-5 pb-2.5 flex flex-col gap-0.5 max-h-[50vh] overflow-y-auto">
216
- {children}
214
+ <div className="grid transition-[grid-template-rows] duration-200 ease-out" style={{ gridTemplateRows: collapsed ? '0fr' : '1fr' }}>
215
+ <div className="overflow-hidden">
216
+ <div className={`px-5 pb-2.5 flex flex-col gap-0.5 max-h-[50vh] overflow-y-auto ${collapsed ? '' : 'animate-fade-in-up'}`} style={{ animationDelay: '80ms' }}>
217
+ {children}
218
+ </div>
217
219
  </div>
218
- )}
220
+ </div>
219
221
  </div>
220
222
  );
221
223
  }
@@ -230,12 +232,12 @@ function ItemRow({ name, description, tag }: { name: string; description: string
230
232
  <div>
231
233
  <button
232
234
  onClick={() => hasDesc && setExpanded((e) => !e)}
233
- className={`w-full flex items-center gap-2 px-2 py-1 rounded text-xs transition-colors ${hasDesc ? 'hover:bg-surface-hover cursor-pointer' : 'cursor-default'}`}
235
+ className={`w-full flex items-center gap-2 px-2 py-1 rounded text-xs transition-colors ${hasDesc ? 'glass-option-hover cursor-pointer' : 'cursor-default'}`}
234
236
  title={hasDesc ? description : name}
235
237
  >
236
238
  <span className="text-content-primary font-medium truncate flex-1 text-left">{name}</span>
237
239
  {tag && (
238
- <span className="text-[10px] text-content-disabled bg-surface-main px-1.5 py-0.5 rounded shrink-0">{tag}</span>
240
+ <span className="text-[10px] text-primary/80 bg-white/50 px-1.5 py-0.5 rounded-full font-medium shrink-0">{tag}</span>
239
241
  )}
240
242
  </button>
241
243
  {expanded && hasDesc && (