illusion-code 0.2.5__tar.gz → 0.2.7__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 (526) hide show
  1. {illusion_code-0.2.5 → illusion_code-0.2.7}/.github/workflows/publish.yml +2 -4
  2. {illusion_code-0.2.5 → illusion_code-0.2.7}/PKG-INFO +1 -1
  3. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/package-lock.json +2 -2
  4. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/package.json +1 -1
  5. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/ConversationView.tsx +6 -3
  6. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/TodoPanel.tsx +6 -5
  7. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/version.ts +1 -1
  8. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/index.html +1 -1
  9. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/package-lock.json +2 -2
  10. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/package.json +1 -1
  11. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/src/App.tsx +134 -17
  12. illusion_code-0.2.7/frontend/web/src/components/ChatArea.tsx +428 -0
  13. illusion_code-0.2.7/frontend/web/src/components/MessageBubble.tsx +496 -0
  14. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/src/components/ModalCard.tsx +16 -16
  15. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/src/components/PromptInput.tsx +49 -12
  16. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/src/components/RightPanel.tsx +19 -17
  17. illusion_code-0.2.7/frontend/web/src/components/Sidebar.tsx +216 -0
  18. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/src/components/TodoPanel.tsx +2 -2
  19. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/src/components/Toolbar.tsx +14 -12
  20. illusion_code-0.2.7/frontend/web/src/components/WelcomeScreen.tsx +76 -0
  21. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/src/i18n.ts +34 -0
  22. illusion_code-0.2.7/frontend/web/src/index.css +722 -0
  23. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/src/version.ts +1 -1
  24. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/tailwind.config.js +25 -0
  25. {illusion_code-0.2.5 → illusion_code-0.2.7}/pyproject.toml +1 -1
  26. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/__init__.py +1 -1
  27. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/__init__.py +61 -6
  28. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/base.py +11 -0
  29. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/config.py +3 -2
  30. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/feishu/adapter.py +27 -0
  31. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/feishu/messaging.py +7 -5
  32. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/feishu/session_map.py +2 -1
  33. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/pid.py +2 -1
  34. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/qq/adapter.py +35 -0
  35. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/qq/session_map.py +13 -11
  36. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/weixin/adapter.py +27 -2
  37. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/weixin/session_map.py +17 -1
  38. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/config/settings.py +3 -2
  39. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/engine/query.py +4 -0
  40. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/engine/query_engine.py +6 -1
  41. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/memory/manager.py +4 -3
  42. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/cron.py +2 -1
  43. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/session_storage.py +4 -3
  44. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/file_edit_tool.py +102 -26
  45. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/file_read_tool.py +86 -12
  46. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/file_write_tool.py +54 -12
  47. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/lsp_tool.py +29 -11
  48. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/notebook_edit_tool.py +58 -5
  49. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/web_fetch_tool.py +39 -7
  50. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/permission_store.py +3 -1
  51. illusion_code-0.2.7/src/illusion/utils/__init__.py +1 -0
  52. illusion_code-0.2.7/src/illusion/utils/atomic_write.py +92 -0
  53. illusion_code-0.2.7/src/illusion/utils/file_state_cache.py +289 -0
  54. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_tools/test_core_tools.py +16 -5
  55. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_tools/test_integration_flows.py +16 -9
  56. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_tools/test_web_fetch_tool.py +5 -1
  57. illusion_code-0.2.5/frontend/web/src/components/ChatArea.tsx +0 -179
  58. illusion_code-0.2.5/frontend/web/src/components/MessageBubble.tsx +0 -277
  59. illusion_code-0.2.5/frontend/web/src/components/Sidebar.tsx +0 -164
  60. illusion_code-0.2.5/frontend/web/src/components/WelcomeScreen.tsx +0 -49
  61. illusion_code-0.2.5/frontend/web/src/index.css +0 -419
  62. illusion_code-0.2.5/tests/test_ui/__init__.py +0 -0
  63. {illusion_code-0.2.5 → illusion_code-0.2.7}/.gitignore +0 -0
  64. {illusion_code-0.2.5 → illusion_code-0.2.7}/.python-version +0 -0
  65. {illusion_code-0.2.5 → illusion_code-0.2.7}/LICENSE +0 -0
  66. {illusion_code-0.2.5 → illusion_code-0.2.7}/README.md +0 -0
  67. {illusion_code-0.2.5 → illusion_code-0.2.7}/README.zh-CN.md +0 -0
  68. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/en/architecture.md +0 -0
  69. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/en/channels.md +0 -0
  70. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/en/commands.md +0 -0
  71. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/en/extensions.md +0 -0
  72. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/en/getting-started.md +0 -0
  73. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/en/introduction.md +0 -0
  74. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/en/project-files.md +0 -0
  75. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/en/settings.md +0 -0
  76. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/images/IllusionCode.png +0 -0
  77. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/images/image1.png +0 -0
  78. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/images/image2.png +0 -0
  79. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/zh-CN/architecture.md +0 -0
  80. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/zh-CN/channels.md +0 -0
  81. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/zh-CN/commands.md +0 -0
  82. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/zh-CN/extensions.md +0 -0
  83. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/zh-CN/getting-started.md +0 -0
  84. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/zh-CN/introduction.md +0 -0
  85. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/zh-CN/project-files.md +0 -0
  86. {illusion_code-0.2.5 → illusion_code-0.2.7}/docs/zh-CN/settings.md +0 -0
  87. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/build.mjs +0 -0
  88. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/App.tsx +0 -0
  89. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/CommandPicker.tsx +0 -0
  90. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/Composer.tsx +0 -0
  91. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/ComposerController.tsx +0 -0
  92. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/Footer.tsx +0 -0
  93. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/MarkdownContent.tsx +0 -0
  94. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/MarkdownTable.tsx +0 -0
  95. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/ModalHost.tsx +0 -0
  96. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/MultilineTextInput.tsx +0 -0
  97. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/PromptInput.tsx +0 -0
  98. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/QuestionNavigationBar.tsx +0 -0
  99. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/QuestionPreviewBox.tsx +0 -0
  100. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/SelectModal.tsx +0 -0
  101. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/SidePanel.tsx +0 -0
  102. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/Spinner.tsx +0 -0
  103. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/StatusBar.tsx +0 -0
  104. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/SwarmPanel.tsx +0 -0
  105. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/ToolCallDisplay.tsx +0 -0
  106. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/TranscriptPane.tsx +0 -0
  107. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/components/WelcomeBanner.tsx +0 -0
  108. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/hooks/useAnimationFrame.ts +0 -0
  109. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/hooks/useBackendSession.ts +0 -0
  110. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/hooks/useBlink.ts +0 -0
  111. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/hooks/useQuestionState.ts +0 -0
  112. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/hooks/useTerminalSize.ts +0 -0
  113. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/i18n.ts +0 -0
  114. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/index.tsx +0 -0
  115. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/theme/ThemeContext.tsx +0 -0
  116. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/theme/builtinThemes.ts +0 -0
  117. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/ToolInterface.ts +0 -0
  118. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/AgentTool.ts +0 -0
  119. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/BashTool.ts +0 -0
  120. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/CronTool.ts +0 -0
  121. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/EditTool.ts +0 -0
  122. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/GenericTool.ts +0 -0
  123. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/LspTool.ts +0 -0
  124. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/McpTool.ts +0 -0
  125. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/NotebookTool.ts +0 -0
  126. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/PlanTool.ts +0 -0
  127. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/ReadTool.ts +0 -0
  128. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/SearchTool.ts +0 -0
  129. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/SkillTool.ts +0 -0
  130. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/TaskTool.ts +0 -0
  131. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/WebTool.ts +0 -0
  132. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/WorktreeTool.ts +0 -0
  133. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/implementations/WriteTool.ts +0 -0
  134. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/tools/registry.ts +0 -0
  135. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/types.ts +0 -0
  136. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/utils/markdown.ts +0 -0
  137. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/src/utils/thinking.ts +0 -0
  138. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/terminal/tsconfig.json +0 -0
  139. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/postcss.config.js +0 -0
  140. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/src/components/ErrorBoundary.tsx +0 -0
  141. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/src/hooks/useWebSocketSession.ts +0 -0
  142. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/src/main.tsx +0 -0
  143. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/src/remarkSuperscript.ts +0 -0
  144. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/src/types/protocol.ts +0 -0
  145. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/src/vite-env.d.ts +0 -0
  146. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/tsconfig.json +0 -0
  147. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/tsconfig.node.json +0 -0
  148. {illusion_code-0.2.5 → illusion_code-0.2.7}/frontend/web/vite.config.ts +0 -0
  149. {illusion_code-0.2.5 → illusion_code-0.2.7}/scripts/build_frontend.py +0 -0
  150. {illusion_code-0.2.5 → illusion_code-0.2.7}/scripts/hatch_build.py +0 -0
  151. {illusion_code-0.2.5 → illusion_code-0.2.7}/scripts/publish.py +0 -0
  152. {illusion_code-0.2.5 → illusion_code-0.2.7}/scripts/sync_version.py +0 -0
  153. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/__main__.py +0 -0
  154. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/api/__init__.py +0 -0
  155. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/api/client.py +0 -0
  156. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/api/codex_client.py +0 -0
  157. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/api/compat.py +0 -0
  158. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/api/effort.py +0 -0
  159. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/api/errors.py +0 -0
  160. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/api/openai_client.py +0 -0
  161. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/api/provider.py +0 -0
  162. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/api/registry.py +0 -0
  163. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/api/usage.py +0 -0
  164. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/auth/__init__.py +0 -0
  165. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/auth/codex_oauth.py +0 -0
  166. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/auth/copilot.py +0 -0
  167. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/auth/external.py +0 -0
  168. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/auth/flows.py +0 -0
  169. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/auth/manager.py +0 -0
  170. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/auth/storage.py +0 -0
  171. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/bridge/__init__.py +0 -0
  172. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/bridge/manager.py +0 -0
  173. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/bridge/session_runner.py +0 -0
  174. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/bridge/types.py +0 -0
  175. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/bridge/work_secret.py +0 -0
  176. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/base_commands.py +0 -0
  177. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/feishu/__init__.py +0 -0
  178. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/feishu/commands.py +0 -0
  179. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/feishu/ws_client.py +0 -0
  180. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/qq/__init__.py +0 -0
  181. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/qq/api.py +0 -0
  182. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/qq/commands.py +0 -0
  183. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/qq/ws_client.py +0 -0
  184. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/serve.py +0 -0
  185. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/tools/__init__.py +0 -0
  186. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/tools/feishu_doc.py +0 -0
  187. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/tools/feishu_drive.py +0 -0
  188. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/weixin/__init__.py +0 -0
  189. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/weixin/commands.py +0 -0
  190. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/channels/weixin/ilink_api.py +0 -0
  191. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/cli.py +0 -0
  192. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/__init__.py +0 -0
  193. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/auth.py +0 -0
  194. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/bridge.py +0 -0
  195. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/context.py +0 -0
  196. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/git.py +0 -0
  197. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/helpers.py +0 -0
  198. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/__init__.py +0 -0
  199. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/analysis/__init__.py +0 -0
  200. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/analysis/architecture.py +0 -0
  201. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/analysis/conventions.py +0 -0
  202. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/analysis/dependencies.py +0 -0
  203. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/analysis/key_modules.py +0 -0
  204. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/extraction/__init__.py +0 -0
  205. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/extraction/lsp_symbols.py +0 -0
  206. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/extraction/readme.py +0 -0
  207. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/extraction/scanner.py +0 -0
  208. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/generation/__init__.py +0 -0
  209. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/generation/claudemd.py +0 -0
  210. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/generation/illusionmd.py +0 -0
  211. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/generation/memory_template.py +0 -0
  212. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/generation/rules.py +0 -0
  213. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/generation/sections.py +0 -0
  214. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/orchestrator.py +0 -0
  215. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/init/types.py +0 -0
  216. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/mcp.py +0 -0
  217. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/memory.py +0 -0
  218. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/misc.py +0 -0
  219. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/model.py +0 -0
  220. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/plugin.py +0 -0
  221. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/registry.py +0 -0
  222. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/rules.py +0 -0
  223. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/sandbox.py +0 -0
  224. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/session.py +0 -0
  225. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/settings.py +0 -0
  226. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/commands/types.py +0 -0
  227. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/config/__init__.py +0 -0
  228. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/config/i18n.py +0 -0
  229. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/config/paths.py +0 -0
  230. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/config/plan_file.py +0 -0
  231. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/coordinator/__init__.py +0 -0
  232. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/coordinator/agent_definitions.py +0 -0
  233. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/coordinator/coordinator_mode.py +0 -0
  234. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/engine/__init__.py +0 -0
  235. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/engine/cost_tracker.py +0 -0
  236. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/engine/messages.py +0 -0
  237. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/engine/stream_events.py +0 -0
  238. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/hooks/__init__.py +0 -0
  239. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/hooks/events.py +0 -0
  240. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/hooks/executor.py +0 -0
  241. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/hooks/hot_reload.py +0 -0
  242. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/hooks/loader.py +0 -0
  243. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/hooks/register_hooks.py +0 -0
  244. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/hooks/schemas.py +0 -0
  245. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/hooks/session_hooks.py +0 -0
  246. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/hooks/types.py +0 -0
  247. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/hooks/utils.py +0 -0
  248. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/mcp/__init__.py +0 -0
  249. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/mcp/client.py +0 -0
  250. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/mcp/config.py +0 -0
  251. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/mcp/types.py +0 -0
  252. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/memory/__init__.py +0 -0
  253. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/memory/memdir.py +0 -0
  254. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/memory/paths.py +0 -0
  255. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/memory/scan.py +0 -0
  256. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/memory/search.py +0 -0
  257. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/memory/types.py +0 -0
  258. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/output_styles/__init__.py +0 -0
  259. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/output_styles/loader.py +0 -0
  260. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/permissions/__init__.py +0 -0
  261. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/permissions/checker.py +0 -0
  262. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/permissions/loader.py +0 -0
  263. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/permissions/modes.py +0 -0
  264. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/permissions/schemas.py +0 -0
  265. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/platforms.py +0 -0
  266. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/plugins/__init__.py +0 -0
  267. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/plugins/installer.py +0 -0
  268. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/plugins/loader.py +0 -0
  269. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/plugins/options.py +0 -0
  270. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/plugins/schemas.py +0 -0
  271. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/plugins/types.py +0 -0
  272. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/prompts/__init__.py +0 -0
  273. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/prompts/claudemd.py +0 -0
  274. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/prompts/context.py +0 -0
  275. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/prompts/environment.py +0 -0
  276. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/prompts/system_prompt.py +0 -0
  277. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/sandbox/__init__.py +0 -0
  278. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/sandbox/adapter.py +0 -0
  279. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/sandbox/platforms/__init__.py +0 -0
  280. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/sandbox/platforms/base.py +0 -0
  281. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/sandbox/platforms/linux.py +0 -0
  282. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/sandbox/platforms/macos.py +0 -0
  283. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/sandbox/platforms/windows.py +0 -0
  284. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/sandbox/proxy/__init__.py +0 -0
  285. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/sandbox/proxy/env_vars.py +0 -0
  286. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/sandbox/runtime.py +0 -0
  287. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/sandbox/symlink_protection.py +0 -0
  288. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/sandbox/utils.py +0 -0
  289. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/sandbox/violation_store.py +0 -0
  290. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/__init__.py +0 -0
  291. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/compact/__init__.py +0 -0
  292. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/compact/auto_compact.py +0 -0
  293. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/compact/compact_core.py +0 -0
  294. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/compact/compact_prompt.py +0 -0
  295. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/compact/constants.py +0 -0
  296. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/compact/message_ops.py +0 -0
  297. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/compact/microcompact.py +0 -0
  298. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/compact/models.py +0 -0
  299. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/compact/token_utils.py +0 -0
  300. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/cron_scheduler.py +0 -0
  301. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/file_history.py +0 -0
  302. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/lsp/__init__.py +0 -0
  303. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/lsp/client.py +0 -0
  304. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/lsp/config.py +0 -0
  305. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/lsp/manager.py +0 -0
  306. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/lsp/types.py +0 -0
  307. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/services/token_estimation.py +0 -0
  308. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/skills/__init__.py +0 -0
  309. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/skills/bundled/__init__.py +0 -0
  310. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/skills/bundled/content/batch.md +0 -0
  311. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/skills/bundled/content/debug.md +0 -0
  312. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/skills/bundled/content/loop.md +0 -0
  313. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/skills/bundled/content/remember.md +0 -0
  314. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/skills/bundled/content/simplify.md +0 -0
  315. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/skills/bundled/content/skillify.md +0 -0
  316. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/skills/bundled/content/stuck.md +0 -0
  317. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/skills/bundled/content/update-config.md +0 -0
  318. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/skills/bundled/content/verify.md +0 -0
  319. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/skills/loader.py +0 -0
  320. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/skills/registry.py +0 -0
  321. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/skills/types.py +0 -0
  322. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/state/__init__.py +0 -0
  323. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/state/app_state.py +0 -0
  324. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/state/store.py +0 -0
  325. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/swarm/__init__.py +0 -0
  326. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/swarm/agent_executor.py +0 -0
  327. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/swarm/in_process.py +0 -0
  328. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/swarm/subprocess_backend.py +0 -0
  329. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/swarm/team_helpers.py +0 -0
  330. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/swarm/types.py +0 -0
  331. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/swarm/worktree.py +0 -0
  332. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tasks/__init__.py +0 -0
  333. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tasks/local_agent_task.py +0 -0
  334. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tasks/local_shell_task.py +0 -0
  335. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tasks/manager.py +0 -0
  336. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tasks/stop_task.py +0 -0
  337. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tasks/types.py +0 -0
  338. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/__init__.py +0 -0
  339. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/agent_tool.py +0 -0
  340. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/ask_user_question_tool.py +0 -0
  341. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/base.py +0 -0
  342. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/bash_tool.py +0 -0
  343. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/config_tool.py +0 -0
  344. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/cron_tool.py +0 -0
  345. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/enter_plan_mode_tool.py +0 -0
  346. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/enter_worktree_tool.py +0 -0
  347. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/exit_plan_mode_tool.py +0 -0
  348. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/exit_worktree_tool.py +0 -0
  349. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/glob_tool.py +0 -0
  350. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/grep_tool.py +0 -0
  351. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/list_mcp_resources_tool.py +0 -0
  352. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/lsp_formatters.py +0 -0
  353. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/lsp_schemas.py +0 -0
  354. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/mcp_auth_tool.py +0 -0
  355. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/mcp_tool.py +0 -0
  356. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/powershell_tool.py +0 -0
  357. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/read_mcp_resource_tool.py +0 -0
  358. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/repl_tool.py +0 -0
  359. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/send_message_tool.py +0 -0
  360. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/shell_common.py +0 -0
  361. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/skill_tool.py +0 -0
  362. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/sleep_tool.py +0 -0
  363. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/structured_output_tool.py +0 -0
  364. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/task_create_tool.py +0 -0
  365. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/task_get_tool.py +0 -0
  366. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/task_list_tool.py +0 -0
  367. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/task_output_tool.py +0 -0
  368. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/task_stop_tool.py +0 -0
  369. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/task_update_tool.py +0 -0
  370. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/team_create_tool.py +0 -0
  371. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/team_delete_tool.py +0 -0
  372. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/todo_write_tool.py +0 -0
  373. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/tool_search_tool.py +0 -0
  374. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/tools/web_search_tool.py +0 -0
  375. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/__init__.py +0 -0
  376. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/app.py +0 -0
  377. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/backend_host.py +0 -0
  378. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/input.py +0 -0
  379. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/output.py +0 -0
  380. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/permission_dialog.py +0 -0
  381. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/protocol.py +0 -0
  382. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/react_launcher.py +0 -0
  383. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/runtime.py +0 -0
  384. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/textual_app.py +0 -0
  385. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/web/__init__.py +0 -0
  386. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/web/server.py +0 -0
  387. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/web/ws_host.py +0 -0
  388. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/ui/web/ws_web_api.py +0 -0
  389. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/utils/ripgrep.py +0 -0
  390. {illusion_code-0.2.5 → illusion_code-0.2.7}/src/illusion/utils/shell.py +0 -0
  391. {illusion_code-0.2.5/src/illusion/utils → illusion_code-0.2.7/tests}/__init__.py +0 -0
  392. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/api/test_anthropic_client.py +0 -0
  393. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/api/test_client.py +0 -0
  394. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/api/test_codex_client.py +0 -0
  395. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/api/test_effort.py +0 -0
  396. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/api/test_fallback/346/217/220/347/244/272.py" +0 -0
  397. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/api/test_openai_client.py +0 -0
  398. {illusion_code-0.2.5/tests → illusion_code-0.2.7/tests/channels}/__init__.py +0 -0
  399. {illusion_code-0.2.5/tests/channels → illusion_code-0.2.7/tests/channels/feishu}/__init__.py +0 -0
  400. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/channels/feishu/test_adapter.py +0 -0
  401. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/channels/feishu/test_commands.py +0 -0
  402. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/channels/feishu/test_session_map.py +0 -0
  403. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/channels/test_base.py +0 -0
  404. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/channels/test_base_commands.py +0 -0
  405. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/channels/test_config.py +0 -0
  406. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/channels/test_pid.py +0 -0
  407. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/channels/test_tool_registration.py +0 -0
  408. {illusion_code-0.2.5/tests/channels/feishu → illusion_code-0.2.7/tests/channels/tools}/__init__.py +0 -0
  409. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/channels/tools/test_feishu_doc.py +0 -0
  410. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/channels/tools/test_feishu_drive.py +0 -0
  411. {illusion_code-0.2.5/tests/channels/tools → illusion_code-0.2.7/tests/channels/weixin}/__init__.py +0 -0
  412. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/channels/weixin/test_adapter.py +0 -0
  413. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/channels/weixin/test_config.py +0 -0
  414. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/channels/weixin/test_ilink_api.py +0 -0
  415. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/channels/weixin/test_session_map.py +0 -0
  416. {illusion_code-0.2.5/tests/channels/weixin → illusion_code-0.2.7/tests/commands/init}/__init__.py +0 -0
  417. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/commands/init/test_claudemd.py +0 -0
  418. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/commands/init/test_orchestrator.py +0 -0
  419. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/commands/init/test_scanner.py +0 -0
  420. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/commands/init/test_sections.py +0 -0
  421. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/commands/test_effort_command.py +0 -0
  422. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/config/test_i18n.py +0 -0
  423. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/config/test_settings.py +0 -0
  424. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/conftest.py +0 -0
  425. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/engine/test_query_engine.py +0 -0
  426. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/fixtures/fake_mcp_server.py +0 -0
  427. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/integration/test_effort_integration.py +0 -0
  428. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/services/lsp/test_lsp_client.py +0 -0
  429. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/services/lsp/test_lsp_config.py +0 -0
  430. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/services/lsp/test_lsp_manager.py +0 -0
  431. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/services/lsp/test_lsp_types.py +0 -0
  432. {illusion_code-0.2.5/tests/commands/init → illusion_code-0.2.7/tests/test_api}/__init__.py +0 -0
  433. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_api/test_client.py +0 -0
  434. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_api/test_codex_client.py +0 -0
  435. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_api/test_compat.py +0 -0
  436. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_api/test_openai_client.py +0 -0
  437. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_auth/test_external.py +0 -0
  438. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_bridge/test_core.py +0 -0
  439. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_bridge/test_session_flow.py +0 -0
  440. {illusion_code-0.2.5/tests/test_api → illusion_code-0.2.7/tests/test_commands}/__init__.py +0 -0
  441. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_commands/test_cli.py +0 -0
  442. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_commands/test_command_flows.py +0 -0
  443. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_commands/test_registry.py +0 -0
  444. {illusion_code-0.2.5/tests/test_commands → illusion_code-0.2.7/tests/test_config}/__init__.py +0 -0
  445. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_config/test_paths.py +0 -0
  446. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_config/test_settings.py +0 -0
  447. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_coordinator/test_agent_definitions.py +0 -0
  448. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_coordinator/test_coordinator_mode.py +0 -0
  449. {illusion_code-0.2.5/tests/test_config → illusion_code-0.2.7/tests/test_engine}/__init__.py +0 -0
  450. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_engine/test_media_block.py +0 -0
  451. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_engine/test_query_engine.py +0 -0
  452. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_engine/test_tool_result_media.py +0 -0
  453. {illusion_code-0.2.5/tests/test_engine → illusion_code-0.2.7/tests/test_hooks}/__init__.py +0 -0
  454. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_hooks/test_executor.py +0 -0
  455. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_hooks/test_loader_permissions.py +0 -0
  456. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_hooks_skills_plugins_real.py +0 -0
  457. {illusion_code-0.2.5/tests/test_hooks → illusion_code-0.2.7/tests/test_mcp}/__init__.py +0 -0
  458. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_mcp/test_config_permissions.py +0 -0
  459. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_mcp/test_integration.py +0 -0
  460. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_mcp/test_stdio_flow.py +0 -0
  461. {illusion_code-0.2.5/tests/test_mcp → illusion_code-0.2.7/tests/test_memory}/__init__.py +0 -0
  462. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_memory/test_manager_permissions.py +0 -0
  463. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_memory/test_memdir.py +0 -0
  464. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_merged_prs_on_autoagent.py +0 -0
  465. {illusion_code-0.2.5/tests/test_memory → illusion_code-0.2.7/tests/test_permissions}/__init__.py +0 -0
  466. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_permissions/test_checker.py +0 -0
  467. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_permissions/test_loader.py +0 -0
  468. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_permissions/test_project_permissions.py +0 -0
  469. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_platforms.py +0 -0
  470. {illusion_code-0.2.5/tests/test_permissions → illusion_code-0.2.7/tests/test_plugins}/__init__.py +0 -0
  471. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_plugins/test_lifecycle_flow.py +0 -0
  472. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_plugins/test_loader.py +0 -0
  473. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_plugins/test_loader_permissions.py +0 -0
  474. {illusion_code-0.2.5/tests/test_plugins → illusion_code-0.2.7/tests/test_prompts}/__init__.py +0 -0
  475. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_prompts/test_claudemd.py +0 -0
  476. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_prompts/test_claudemd_permissions.py +0 -0
  477. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_prompts/test_environment.py +0 -0
  478. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_prompts/test_system_prompt.py +0 -0
  479. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_qq_channel.py +0 -0
  480. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_real_large_tasks.py +0 -0
  481. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_sandbox/test_adapter.py +0 -0
  482. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_sandbox/test_config_schema.py +0 -0
  483. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_sandbox/test_platform_linux.py +0 -0
  484. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_sandbox/test_platform_macos.py +0 -0
  485. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_sandbox/test_platform_windows.py +0 -0
  486. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_sandbox/test_proxy_env_vars.py +0 -0
  487. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_sandbox/test_runtime.py +0 -0
  488. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_sandbox/test_symlink_protection.py +0 -0
  489. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_sandbox/test_utils.py +0 -0
  490. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_sandbox/test_violation_store.py +0 -0
  491. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_scripts/test_sync_version.py +0 -0
  492. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_services/test_compact.py +0 -0
  493. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_services/test_cron.py +0 -0
  494. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_services/test_cron_scheduler.py +0 -0
  495. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_services/test_session_storage.py +0 -0
  496. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_skills/test_loader.py +0 -0
  497. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_skills/test_loader_permissions.py +0 -0
  498. {illusion_code-0.2.5/tests/test_prompts → illusion_code-0.2.7/tests/test_swarm}/__init__.py +0 -0
  499. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_swarm/test_agent_executor.py +0 -0
  500. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_swarm/test_imports.py +0 -0
  501. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_swarm/test_in_process.py +0 -0
  502. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_swarm/test_types.py +0 -0
  503. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_swarm/test_worktree.py +0 -0
  504. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_tasks/test_manager.py +0 -0
  505. {illusion_code-0.2.5/tests/test_swarm → illusion_code-0.2.7/tests/test_tools}/__init__.py +0 -0
  506. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_tools/test_agent_tool.py +0 -0
  507. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_tools/test_file_read_media.py +0 -0
  508. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_tools/test_glob_tool.py +0 -0
  509. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_tools/test_grep_tool.py +0 -0
  510. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_tools/test_integration.py +0 -0
  511. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_tools/test_mcp_auth_tool.py +0 -0
  512. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_tools/test_ripgrep.py +0 -0
  513. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_tools/test_shell_common.py +0 -0
  514. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_tools/test_task_tools.py +0 -0
  515. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_tools/test_team_tools.py +0 -0
  516. {illusion_code-0.2.5/tests/test_tools → illusion_code-0.2.7/tests/test_ui}/__init__.py +0 -0
  517. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_ui/test_modes.py +0 -0
  518. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_ui/test_permission_store.py +0 -0
  519. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_ui/test_react_backend.py +0 -0
  520. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_ui/test_react_launcher.py +0 -0
  521. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_ui/test_textual_app.py +0 -0
  522. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_untested_features.py +0 -0
  523. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/test_utils/test_shell.py +0 -0
  524. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/ui/test_backend_host.py +0 -0
  525. {illusion_code-0.2.5 → illusion_code-0.2.7}/tests/ui/test_protocol_web.py +0 -0
  526. {illusion_code-0.2.5 → illusion_code-0.2.7}/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.7
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.7",
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.7",
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.7"
28
28
  }
@@ -680,12 +680,15 @@ function wrapForPrefix(text: string, terminalWidth: number, prefix: string): str
680
680
  }
681
681
 
682
682
  function truncateToDisplayWidth(text: string, maxWidth: number): string {
683
- if (stringWidth(text) <= maxWidth) {
684
- return text;
683
+ // tab 替换为空格,因为 string-width 将 tab 算作1字符宽度,
684
+ // 但终端中 tab 会展开为多个空格,导致宽度计算偏小、截断不足
685
+ const expanded = text.replace(/\t/g, ' ');
686
+ if (stringWidth(expanded) <= maxWidth) {
687
+ return expanded;
685
688
  }
686
689
  let result = '';
687
690
  let width = 0;
688
- for (const ch of text) {
691
+ for (const ch of expanded) {
689
692
  const charWidth = stringWidth(ch);
690
693
  if (width + charWidth > Math.max(1, maxWidth - 1)) {
691
694
  break;
@@ -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.7';
@@ -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.7",
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.7",
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.7",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -53,20 +53,35 @@ export default function App() {
53
53
  // 内联选项状态
54
54
  const [inlineOptions, setInlineOptions] = useState<SelectRequestPayload | null>(null);
55
55
 
56
+ // 回退确认弹窗状态
57
+ const [rewindConfirm, setRewindConfirm] = useState<{ turns: number } | null>(null);
58
+ // 重新生成:存储待重发的 user 消息文本,rewind 完成后自动重发
59
+ const pendingRegenerateRef = useRef<string | null>(null);
60
+ const prevBusyRef = useRef(false);
61
+
56
62
  // Toast 状态
57
63
  const [toastMessage, setToastMessage] = useState<{ text: string; type: 'success' | 'error' | 'info' } | null>(null);
64
+ const [toastExiting, setToastExiting] = useState(false);
58
65
  const toastTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
59
66
  const toastHoverRef = useRef(false);
67
+ const toastKeyRef = useRef(0);
68
+
69
+ const closeToast = useCallback(() => {
70
+ setToastExiting(true);
71
+ setTimeout(() => { setToastMessage(null); setToastExiting(false); }, 200);
72
+ }, []);
60
73
 
61
74
  const showToast = useCallback((text: string, type: string) => {
62
75
  if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
76
+ toastKeyRef.current += 1;
77
+ setToastExiting(false);
63
78
  setToastMessage({ text, type: type as 'success' | 'error' | 'info' });
64
79
  toastHoverRef.current = false;
65
80
  toastTimerRef.current = setTimeout(() => {
66
- if (!toastHoverRef.current) { setToastMessage(null); }
81
+ if (!toastHoverRef.current) { closeToast(); }
67
82
  toastTimerRef.current = null;
68
83
  }, TOAST_DURATION);
69
- }, []);
84
+ }, [closeToast]);
70
85
 
71
86
  const handleToastMouseEnter = useCallback(() => {
72
87
  toastHoverRef.current = true;
@@ -75,8 +90,8 @@ export default function App() {
75
90
 
76
91
  const handleToastMouseLeave = useCallback(() => {
77
92
  toastHoverRef.current = false;
78
- toastTimerRef.current = setTimeout(() => { setToastMessage(null); toastTimerRef.current = null; }, TOAST_DURATION);
79
- }, []);
93
+ toastTimerRef.current = setTimeout(() => { closeToast(); toastTimerRef.current = null; }, TOAST_DURATION);
94
+ }, [closeToast]);
80
95
 
81
96
  /**
82
97
  * 注册回调函数
@@ -222,6 +237,57 @@ export default function App() {
222
237
  /** 处理停止当前任务 */
223
238
  const handleStop = () => { session.sendRequest({ type: 'stop' }); };
224
239
 
240
+ /**
241
+ * 处理回退到指定轮次
242
+ *
243
+ * 由 ChatArea 中 user 消息的撤销按钮触发,弹出模式选择弹窗。
244
+ *
245
+ * @param turnsToRewind - 需要回退的轮次数
246
+ */
247
+ const handleRewindToTurn = useCallback((turnsToRewind: number) => {
248
+ setRewindConfirm({ turns: turnsToRewind });
249
+ }, []);
250
+
251
+ /**
252
+ * 确认回退 —— 根据用户选择的模式执行 /rewind N mode
253
+ *
254
+ * 通过 submit_line 通道(treat_as_text 缺省=false)直接走命令注册表,
255
+ * 绕过 web_query 的多步弹窗流程。
256
+ *
257
+ * @param mode - 回退模式:code / conversation / both
258
+ */
259
+ const handleConfirmRewind = useCallback((mode: string) => {
260
+ const turns = rewindConfirm?.turns ?? 1;
261
+ setRewindConfirm(null);
262
+ session.setBusyTrue();
263
+ session.sendRequest({ type: 'submit_line', line: `/rewind ${turns} ${mode}` });
264
+ }, [rewindConfirm, session]);
265
+
266
+ /**
267
+ * 处理重新生成
268
+ *
269
+ * 找到最后一条 user 消息文本,先 /rewind 1 both 回退一轮,
270
+ * rewind 完成后(busy→false)自动重发 user 消息。
271
+ */
272
+ const handleRegenerate = useCallback(() => {
273
+ const lastUserMsg = [...session.staticItems].reverse().find((i) => i.role === 'user' && !i.text.startsWith('/'));
274
+ if (!lastUserMsg) return;
275
+ pendingRegenerateRef.current = lastUserMsg.text;
276
+ session.setBusyTrue();
277
+ session.sendRequest({ type: 'submit_line', line: '/rewind 1 both' });
278
+ }, [session]);
279
+
280
+ // 监听 busy 状态变化:rewind 完成后自动重发 user 消息(重新生成)
281
+ useEffect(() => {
282
+ if (prevBusyRef.current && !session.busy && pendingRegenerateRef.current) {
283
+ const text = pendingRegenerateRef.current;
284
+ pendingRegenerateRef.current = null;
285
+ session.setBusyTrue();
286
+ session.sendRequest({ type: 'submit_line', line: text, treat_as_text: true });
287
+ }
288
+ prevBusyRef.current = session.busy;
289
+ }, [session.busy, session]);
290
+
225
291
  /** 处理新建会话 */
226
292
  const handleNewSession = () => {
227
293
  session.sendRequest({ type: 'web_new_session' });
@@ -317,7 +383,7 @@ export default function App() {
317
383
  };
318
384
 
319
385
  return (
320
- <div className="flex h-screen bg-surface-main">
386
+ <div className="flex h-screen">
321
387
  <Sidebar lang={lang} connected={session.connected} sessions={session.sessions}
322
388
  onNewSession={handleNewSession} onSelectSession={handleSelectSession}
323
389
  onListSessions={handleListSessions}
@@ -336,7 +402,8 @@ export default function App() {
336
402
  streamingReasoning={session.streamingReasoning} pendingToolCalls={session.pendingToolCalls}
337
403
  busy={session.busy} connected={session.connected}
338
404
  modal={session.modal} onPermissionResponse={handlePermissionResponse}
339
- onQuestionResponse={handleQuestionResponse} restoringSessionId={session.restoringSessionId} />
405
+ onQuestionResponse={handleQuestionResponse} restoringSessionId={session.restoringSessionId}
406
+ onRewindToTurn={handleRewindToTurn} onRegenerate={handleRegenerate} />
340
407
  <PromptInput lang={lang} busy={session.busy} connected={session.connected}
341
408
  commands={session.commands} onSubmit={handleSubmit} onStop={handleStop}
342
409
  inlineOptions={inlineOptions} onInlineSelect={handleInlineSelect} onInlineClose={handleInlineClose} />
@@ -363,8 +430,8 @@ export default function App() {
363
430
  {/* 删除会话弹窗(仅 sidebar 触发) */}
364
431
  {showDeleteModal && (
365
432
  <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">
433
+ <div className="absolute inset-0 bg-black/35 backdrop-blur-md animate-fade-in" onClick={handleCloseDeleteModal} />
434
+ <div className="relative glass-overlay rounded-2xl w-[420px] max-h-[70vh] flex flex-col animate-scale-in modal-origin-center">
368
435
  <div className="px-6 py-4 border-b border-border-light">
369
436
  <h3 className="text-lg font-semibold text-content-primary">{t(lang, 'delete_session')}</h3>
370
437
  </div>
@@ -372,7 +439,7 @@ export default function App() {
372
439
  {regularSessions.length === 0 ? (
373
440
  <div className="px-6 py-8 text-center text-sm text-content-disabled">{t(lang, 'no_sessions')}</div>
374
441
  ) : 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">
442
+ <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
443
  <input type="checkbox" checked={deleteSelected.has(s.value)} onChange={() => toggleDeleteItem(s.value)} className="w-4 h-4 rounded accent-danger" />
377
444
  <span className="text-sm text-content-secondary truncate flex-1">{s.label}</span>
378
445
  </label>
@@ -384,10 +451,10 @@ export default function App() {
384
451
  // 直接删除全部;后端会原子化地新建空会话,避免两阶段竞态
385
452
  session.deleteSessions([], true);
386
453
  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>
454
+ }} className="danger-action px-4 py-2 text-sm text-danger rounded-lg cursor-pointer">{t(lang, 'delete_all')}</button>
388
455
  )}</div>
389
456
  <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>
457
+ <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
458
  <button onClick={handleConfirmDelete} disabled={deleteSelected.size === 0}
392
459
  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
460
  {t(lang, 'confirm_delete')} ({deleteSelected.size})
@@ -398,18 +465,68 @@ export default function App() {
398
465
  </div>
399
466
  )}
400
467
 
468
+ {/* 回退确认弹窗(选择回退范围) */}
469
+ {rewindConfirm && (
470
+ <div className="fixed inset-0 z-50 flex items-center justify-center">
471
+ <div className="absolute inset-0 bg-black/35 backdrop-blur-md animate-fade-in" onClick={() => setRewindConfirm(null)} />
472
+ <div className="relative glass-overlay rounded-2xl w-[380px] flex flex-col animate-scale-in modal-origin-center">
473
+ <div className="px-6 py-4 border-b border-border-light">
474
+ <h3 className="text-lg font-semibold text-content-primary">{t(lang, 'rewind_confirm_title')}</h3>
475
+ </div>
476
+ <div className="py-2 px-1">
477
+ {([
478
+ { mode: 'both', label: t(lang, 'rewind_both'), desc: t(lang, 'rewind_both_desc') },
479
+ { mode: 'conversation', label: t(lang, 'rewind_conversation'), desc: t(lang, 'rewind_conversation_desc') },
480
+ { mode: 'code', label: t(lang, 'rewind_code'), desc: t(lang, 'rewind_code_desc') },
481
+ ] as const).map((opt) => (
482
+ <button
483
+ key={opt.mode}
484
+ onClick={() => handleConfirmRewind(opt.mode)}
485
+ className="w-full text-left px-6 py-3 cursor-pointer glass-option-hover transition-colors rounded-lg flex items-center justify-between group"
486
+ >
487
+ <div>
488
+ <div className="text-sm font-medium text-content-primary">{opt.label}</div>
489
+ <div className="text-xs text-content-disabled mt-0.5">{opt.desc}</div>
490
+ </div>
491
+ <svg className="w-4 h-4 text-content-disabled opacity-0 group-hover:opacity-100 transition-opacity" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
492
+ <path d="M6 3l5 5-5 5" />
493
+ </svg>
494
+ </button>
495
+ ))}
496
+ </div>
497
+ <div className="px-6 py-4 border-t border-border-light flex justify-end">
498
+ <button onClick={() => setRewindConfirm(null)} className="px-4 py-2 text-sm text-content-secondary glass-option-hover rounded-lg transition-colors cursor-pointer border border-white/40">
499
+ {t(lang, 'cancel')}
500
+ </button>
501
+ </div>
502
+ </div>
503
+ </div>
504
+ )}
505
+
401
506
  {/* Toast 通知 */}
402
507
  {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">
508
+ <div
509
+ key={toastKeyRef.current}
510
+ className={`fixed bottom-20 right-6 z-50 ${toastExiting ? 'animate-toast-out' : 'animate-toast-in'}`}
511
+ onMouseEnter={handleToastMouseEnter} onMouseLeave={handleToastMouseLeave}
512
+ >
513
+ <div className="glass-surface border border-black/10 rounded-2xl max-w-sm overflow-hidden">
514
+ <div className="flex items-start gap-3 px-4 py-3">
407
515
  <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">
516
+ <button onClick={closeToast}
517
+ 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
518
  <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
519
  </button>
412
520
  </div>
521
+ <div className="h-0.5 bg-black/10">
522
+ <div
523
+ key={toastKeyRef.current}
524
+ className={`h-full animate-progress-shrink ${
525
+ toastMessage.type === 'error' ? 'bg-danger/80' : toastMessage.type === 'success' ? 'bg-success/80' : 'bg-primary/80'
526
+ }`}
527
+ style={{ animationDuration: `${TOAST_DURATION}ms` }}
528
+ />
529
+ </div>
413
530
  </div>
414
531
  </div>
415
532
  )}