illusion-code 0.2.10__tar.gz → 0.2.11__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 (545) hide show
  1. {illusion_code-0.2.10 → illusion_code-0.2.11}/PKG-INFO +1 -1
  2. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/package-lock.json +2 -2
  3. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/package.json +1 -1
  4. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/version.ts +1 -1
  5. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/package-lock.json +2 -2
  6. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/package.json +1 -1
  7. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/version.ts +1 -1
  8. {illusion_code-0.2.10 → illusion_code-0.2.11}/pyproject.toml +1 -1
  9. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/__init__.py +1 -1
  10. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/__init__.py +35 -78
  11. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/config.py +17 -7
  12. illusion_code-0.2.11/src/illusion/channels/exit_handler.py +83 -0
  13. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/feishu/session_map.py +25 -15
  14. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/qq/adapter.py +39 -34
  15. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/qq/session_map.py +22 -12
  16. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/qq/ws_client.py +73 -18
  17. illusion_code-0.2.11/src/illusion/channels/registry.py +253 -0
  18. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/serve.py +117 -90
  19. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/tools/feishu_doc.py +6 -6
  20. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/tools/feishu_drive.py +9 -9
  21. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/tools/media.py +5 -1
  22. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/weixin/ilink_api.py +93 -14
  23. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/weixin/session_map.py +22 -12
  24. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/cli.py +10 -51
  25. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/session.py +2 -18
  26. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/config/i18n.py +24 -4
  27. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/hooks/__init__.py +1 -1
  28. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/mcp/__init__.py +1 -0
  29. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/plugins/__init__.py +7 -0
  30. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/skills/__init__.py +6 -0
  31. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tasks/todo_sync.py +2 -2
  32. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/runtime.py +1 -1
  33. illusion_code-0.2.11/tests/channels/test_exit_handler.py +192 -0
  34. illusion_code-0.2.11/tests/channels/test_registry.py +248 -0
  35. illusion_code-0.2.11/tests/channels/test_session_persist.py +72 -0
  36. illusion_code-0.2.11/tests/channels/test_supervise.py +71 -0
  37. illusion_code-0.2.11/tests/channels/weixin/test_ilink_retry.py +65 -0
  38. illusion_code-0.2.11/tests/test_cli_exit_handler.py +66 -0
  39. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/unit/test_qq_streaming.py +2 -2
  40. {illusion_code-0.2.10 → illusion_code-0.2.11}/.github/workflows/publish.yml +0 -0
  41. {illusion_code-0.2.10 → illusion_code-0.2.11}/.gitignore +0 -0
  42. {illusion_code-0.2.10 → illusion_code-0.2.11}/.python-version +0 -0
  43. {illusion_code-0.2.10 → illusion_code-0.2.11}/LICENSE +0 -0
  44. {illusion_code-0.2.10 → illusion_code-0.2.11}/README.md +0 -0
  45. {illusion_code-0.2.10 → illusion_code-0.2.11}/README.zh-CN.md +0 -0
  46. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/en/architecture.md +0 -0
  47. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/en/channels.md +0 -0
  48. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/en/commands.md +0 -0
  49. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/en/extensions.md +0 -0
  50. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/en/getting-started.md +0 -0
  51. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/en/introduction.md +0 -0
  52. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/en/project-files.md +0 -0
  53. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/en/settings.md +0 -0
  54. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/images/IllusionCode.png +0 -0
  55. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/images/image1.png +0 -0
  56. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/images/image2.png +0 -0
  57. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/zh-CN/architecture.md +0 -0
  58. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/zh-CN/channels.md +0 -0
  59. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/zh-CN/commands.md +0 -0
  60. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/zh-CN/extensions.md +0 -0
  61. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/zh-CN/getting-started.md +0 -0
  62. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/zh-CN/introduction.md +0 -0
  63. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/zh-CN/project-files.md +0 -0
  64. {illusion_code-0.2.10 → illusion_code-0.2.11}/docs/zh-CN/settings.md +0 -0
  65. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/build.mjs +0 -0
  66. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/App.tsx +0 -0
  67. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/CommandPicker.tsx +0 -0
  68. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/Composer.tsx +0 -0
  69. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/ComposerController.tsx +0 -0
  70. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/ConversationView.tsx +0 -0
  71. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/Footer.tsx +0 -0
  72. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/MarkdownContent.tsx +0 -0
  73. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/MarkdownTable.tsx +0 -0
  74. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/ModalHost.tsx +0 -0
  75. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/MultilineTextInput.tsx +0 -0
  76. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/PromptInput.tsx +0 -0
  77. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/QuestionNavigationBar.tsx +0 -0
  78. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/QuestionPreviewBox.tsx +0 -0
  79. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/SelectModal.tsx +0 -0
  80. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/SidePanel.tsx +0 -0
  81. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/Spinner.tsx +0 -0
  82. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/StatusBar.tsx +0 -0
  83. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/SwarmPanel.tsx +0 -0
  84. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/TodoPanel.tsx +0 -0
  85. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/ToolCallDisplay.tsx +0 -0
  86. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/TranscriptPane.tsx +0 -0
  87. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/components/WelcomeBanner.tsx +0 -0
  88. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/hooks/useAnimationFrame.ts +0 -0
  89. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/hooks/useBackendSession.ts +0 -0
  90. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/hooks/useBlink.ts +0 -0
  91. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/hooks/useQuestionState.ts +0 -0
  92. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/hooks/useTerminalSize.ts +0 -0
  93. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/i18n.ts +0 -0
  94. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/index.tsx +0 -0
  95. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/theme/ThemeContext.tsx +0 -0
  96. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/theme/builtinThemes.ts +0 -0
  97. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/ToolInterface.ts +0 -0
  98. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/AgentTool.ts +0 -0
  99. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/BashTool.ts +0 -0
  100. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/CronTool.ts +0 -0
  101. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/EditTool.ts +0 -0
  102. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/GenericTool.ts +0 -0
  103. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/LspTool.ts +0 -0
  104. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/McpTool.ts +0 -0
  105. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/NotebookTool.ts +0 -0
  106. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/PlanTool.ts +0 -0
  107. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/ReadTool.ts +0 -0
  108. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/SearchTool.ts +0 -0
  109. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/SkillTool.ts +0 -0
  110. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/TaskTool.ts +0 -0
  111. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/WebTool.ts +0 -0
  112. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/WorktreeTool.ts +0 -0
  113. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/WriteTool.ts +0 -0
  114. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/tools/registry.ts +0 -0
  115. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/types.ts +0 -0
  116. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/utils/markdown.ts +0 -0
  117. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/src/utils/thinking.ts +0 -0
  118. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/terminal/tsconfig.json +0 -0
  119. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/index.html +0 -0
  120. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/postcss.config.js +0 -0
  121. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/App.tsx +0 -0
  122. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/components/ChatArea.tsx +0 -0
  123. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/components/ErrorBoundary.tsx +0 -0
  124. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/components/MessageBubble.tsx +0 -0
  125. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/components/ModalCard.tsx +0 -0
  126. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/components/PromptInput.tsx +0 -0
  127. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/components/RightPanel.tsx +0 -0
  128. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/components/Sidebar.tsx +0 -0
  129. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/components/TodoPanel.tsx +0 -0
  130. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/components/Toolbar.tsx +0 -0
  131. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/components/WelcomeScreen.tsx +0 -0
  132. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/hooks/useTheme.ts +0 -0
  133. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/hooks/useWebSocketSession.ts +0 -0
  134. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/i18n.ts +0 -0
  135. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/index.css +0 -0
  136. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/main.tsx +0 -0
  137. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/remarkSuperscript.ts +0 -0
  138. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/types/protocol.ts +0 -0
  139. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/utils/toolDisplayName.ts +0 -0
  140. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/src/vite-env.d.ts +0 -0
  141. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/tailwind.config.js +0 -0
  142. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/tsconfig.json +0 -0
  143. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/tsconfig.node.json +0 -0
  144. {illusion_code-0.2.10 → illusion_code-0.2.11}/frontend/web/vite.config.ts +0 -0
  145. {illusion_code-0.2.10 → illusion_code-0.2.11}/scripts/build_frontend.py +0 -0
  146. {illusion_code-0.2.10 → illusion_code-0.2.11}/scripts/hatch_build.py +0 -0
  147. {illusion_code-0.2.10 → illusion_code-0.2.11}/scripts/publish.py +0 -0
  148. {illusion_code-0.2.10 → illusion_code-0.2.11}/scripts/sync_version.py +0 -0
  149. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/__main__.py +0 -0
  150. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/api/__init__.py +0 -0
  151. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/api/client.py +0 -0
  152. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/api/codex_client.py +0 -0
  153. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/api/compat.py +0 -0
  154. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/api/effort.py +0 -0
  155. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/api/errors.py +0 -0
  156. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/api/openai_client.py +0 -0
  157. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/api/provider.py +0 -0
  158. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/api/registry.py +0 -0
  159. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/api/usage.py +0 -0
  160. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/auth/__init__.py +0 -0
  161. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/auth/codex_oauth.py +0 -0
  162. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/auth/copilot.py +0 -0
  163. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/auth/external.py +0 -0
  164. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/auth/flows.py +0 -0
  165. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/auth/manager.py +0 -0
  166. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/auth/storage.py +0 -0
  167. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/bridge/__init__.py +0 -0
  168. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/bridge/manager.py +0 -0
  169. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/bridge/session_runner.py +0 -0
  170. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/bridge/types.py +0 -0
  171. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/bridge/work_secret.py +0 -0
  172. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/base.py +0 -0
  173. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/base_commands.py +0 -0
  174. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/delivery.py +0 -0
  175. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/feishu/__init__.py +0 -0
  176. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/feishu/adapter.py +0 -0
  177. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/feishu/commands.py +0 -0
  178. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/feishu/messaging.py +0 -0
  179. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/feishu/streaming.py +0 -0
  180. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/feishu/ws_client.py +0 -0
  181. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/pid.py +0 -0
  182. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/qq/__init__.py +0 -0
  183. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/qq/api.py +0 -0
  184. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/qq/commands.py +0 -0
  185. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/qq/streaming.py +0 -0
  186. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/tools/__init__.py +0 -0
  187. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/tools/cross_channel.py +0 -0
  188. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/weixin/__init__.py +0 -0
  189. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/weixin/adapter.py +0 -0
  190. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/channels/weixin/commands.py +0 -0
  191. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/__init__.py +0 -0
  192. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/auth.py +0 -0
  193. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/bridge.py +0 -0
  194. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/context.py +0 -0
  195. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/git.py +0 -0
  196. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/helpers.py +0 -0
  197. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/__init__.py +0 -0
  198. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/analysis/__init__.py +0 -0
  199. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/analysis/architecture.py +0 -0
  200. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/analysis/conventions.py +0 -0
  201. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/analysis/dependencies.py +0 -0
  202. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/analysis/key_modules.py +0 -0
  203. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/extraction/__init__.py +0 -0
  204. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/extraction/lsp_symbols.py +0 -0
  205. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/extraction/readme.py +0 -0
  206. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/extraction/scanner.py +0 -0
  207. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/generation/__init__.py +0 -0
  208. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/generation/claudemd.py +0 -0
  209. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/generation/illusionmd.py +0 -0
  210. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/generation/memory_template.py +0 -0
  211. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/generation/rules.py +0 -0
  212. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/generation/sections.py +0 -0
  213. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/orchestrator.py +0 -0
  214. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/init/types.py +0 -0
  215. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/mcp.py +0 -0
  216. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/memory.py +0 -0
  217. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/misc.py +0 -0
  218. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/model.py +0 -0
  219. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/plugin.py +0 -0
  220. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/registry.py +0 -0
  221. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/rules.py +0 -0
  222. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/sandbox.py +0 -0
  223. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/settings.py +0 -0
  224. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/commands/types.py +0 -0
  225. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/config/__init__.py +0 -0
  226. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/config/paths.py +0 -0
  227. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/config/plan_file.py +0 -0
  228. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/config/settings.py +0 -0
  229. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/coordinator/__init__.py +0 -0
  230. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/coordinator/agent_definitions.py +0 -0
  231. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/coordinator/coordinator_mode.py +0 -0
  232. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/engine/__init__.py +0 -0
  233. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/engine/cost_tracker.py +0 -0
  234. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/engine/messages.py +0 -0
  235. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/engine/query.py +0 -0
  236. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/engine/query_engine.py +0 -0
  237. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/engine/stream_events.py +0 -0
  238. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/hooks/events.py +0 -0
  239. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/hooks/executor.py +0 -0
  240. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/hooks/hot_reload.py +0 -0
  241. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/hooks/loader.py +0 -0
  242. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/hooks/register_hooks.py +0 -0
  243. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/hooks/schemas.py +0 -0
  244. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/hooks/session_hooks.py +0 -0
  245. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/hooks/types.py +0 -0
  246. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/hooks/utils.py +0 -0
  247. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/mcp/client.py +0 -0
  248. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/mcp/config.py +0 -0
  249. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/mcp/types.py +0 -0
  250. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/memory/__init__.py +0 -0
  251. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/memory/manager.py +0 -0
  252. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/memory/memdir.py +0 -0
  253. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/memory/paths.py +0 -0
  254. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/memory/scan.py +0 -0
  255. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/memory/search.py +0 -0
  256. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/memory/types.py +0 -0
  257. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/output_styles/__init__.py +0 -0
  258. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/output_styles/loader.py +0 -0
  259. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/permissions/__init__.py +0 -0
  260. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/permissions/checker.py +0 -0
  261. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/permissions/loader.py +0 -0
  262. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/permissions/modes.py +0 -0
  263. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/permissions/schemas.py +0 -0
  264. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/platforms.py +0 -0
  265. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/plugins/installer.py +0 -0
  266. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/plugins/loader.py +0 -0
  267. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/plugins/options.py +0 -0
  268. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/plugins/schemas.py +0 -0
  269. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/plugins/types.py +0 -0
  270. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/prompts/__init__.py +0 -0
  271. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/prompts/channel_hints.py +0 -0
  272. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/prompts/claudemd.py +0 -0
  273. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/prompts/context.py +0 -0
  274. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/prompts/environment.py +0 -0
  275. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/prompts/system_prompt.py +0 -0
  276. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/sandbox/__init__.py +0 -0
  277. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/sandbox/adapter.py +0 -0
  278. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/sandbox/platforms/__init__.py +0 -0
  279. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/sandbox/platforms/base.py +0 -0
  280. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/sandbox/platforms/linux.py +0 -0
  281. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/sandbox/platforms/macos.py +0 -0
  282. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/sandbox/platforms/windows.py +0 -0
  283. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/sandbox/proxy/__init__.py +0 -0
  284. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/sandbox/proxy/env_vars.py +0 -0
  285. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/sandbox/runtime.py +0 -0
  286. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/sandbox/symlink_protection.py +0 -0
  287. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/sandbox/utils.py +0 -0
  288. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/sandbox/violation_store.py +0 -0
  289. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/__init__.py +0 -0
  290. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/compact/__init__.py +0 -0
  291. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/compact/auto_compact.py +0 -0
  292. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/compact/compact_core.py +0 -0
  293. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/compact/compact_prompt.py +0 -0
  294. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/compact/constants.py +0 -0
  295. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/compact/message_ops.py +0 -0
  296. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/compact/microcompact.py +0 -0
  297. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/compact/models.py +0 -0
  298. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/compact/token_utils.py +0 -0
  299. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/cron.py +0 -0
  300. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/cron_scheduler.py +0 -0
  301. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/file_history.py +0 -0
  302. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/lsp/__init__.py +0 -0
  303. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/lsp/client.py +0 -0
  304. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/lsp/config.py +0 -0
  305. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/lsp/manager.py +0 -0
  306. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/lsp/types.py +0 -0
  307. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/session_storage.py +0 -0
  308. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/services/token_estimation.py +0 -0
  309. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/skills/bundled/__init__.py +0 -0
  310. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/batch.md +0 -0
  311. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/debug.md +0 -0
  312. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/loop.md +0 -0
  313. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/remember.md +0 -0
  314. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/simplify.md +0 -0
  315. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/skillify.md +0 -0
  316. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/stuck.md +0 -0
  317. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/update-config.md +0 -0
  318. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/verify.md +0 -0
  319. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/skills/loader.py +0 -0
  320. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/skills/registry.py +0 -0
  321. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/skills/types.py +0 -0
  322. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/state/__init__.py +0 -0
  323. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/state/app_state.py +0 -0
  324. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/state/store.py +0 -0
  325. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/swarm/__init__.py +0 -0
  326. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/swarm/agent_executor.py +0 -0
  327. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/swarm/in_process.py +0 -0
  328. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/swarm/subprocess_backend.py +0 -0
  329. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/swarm/team_helpers.py +0 -0
  330. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/swarm/types.py +0 -0
  331. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/swarm/worktree.py +0 -0
  332. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tasks/__init__.py +0 -0
  333. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tasks/local_agent_task.py +0 -0
  334. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tasks/local_shell_task.py +0 -0
  335. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tasks/manager.py +0 -0
  336. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tasks/stop_task.py +0 -0
  337. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tasks/types.py +0 -0
  338. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/__init__.py +0 -0
  339. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/agent_tool.py +0 -0
  340. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/ask_user_question_tool.py +0 -0
  341. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/base.py +0 -0
  342. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/bash_tool.py +0 -0
  343. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/config_tool.py +0 -0
  344. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/cron_tool.py +0 -0
  345. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/enter_plan_mode_tool.py +0 -0
  346. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/enter_worktree_tool.py +0 -0
  347. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/exit_plan_mode_tool.py +0 -0
  348. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/exit_worktree_tool.py +0 -0
  349. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/file_edit_tool.py +0 -0
  350. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/file_read_tool.py +0 -0
  351. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/file_write_tool.py +0 -0
  352. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/glob_tool.py +0 -0
  353. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/grep_tool.py +0 -0
  354. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/list_mcp_resources_tool.py +0 -0
  355. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/lsp_formatters.py +0 -0
  356. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/lsp_schemas.py +0 -0
  357. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/lsp_tool.py +0 -0
  358. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/mcp_auth_tool.py +0 -0
  359. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/mcp_tool.py +0 -0
  360. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/notebook_edit_tool.py +0 -0
  361. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/powershell_tool.py +0 -0
  362. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/read_mcp_resource_tool.py +0 -0
  363. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/repl_tool.py +0 -0
  364. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/send_message_tool.py +0 -0
  365. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/shell_common.py +0 -0
  366. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/skill_tool.py +0 -0
  367. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/sleep_tool.py +0 -0
  368. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/structured_output_tool.py +0 -0
  369. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/task_create_tool.py +0 -0
  370. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/task_get_tool.py +0 -0
  371. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/task_list_tool.py +0 -0
  372. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/task_output_tool.py +0 -0
  373. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/task_stop_tool.py +0 -0
  374. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/task_update_tool.py +0 -0
  375. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/team_create_tool.py +0 -0
  376. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/team_delete_tool.py +0 -0
  377. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/todo_write_tool.py +0 -0
  378. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/tool_search_tool.py +0 -0
  379. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/web_fetch_tool.py +0 -0
  380. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/tools/web_search_tool.py +0 -0
  381. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/__init__.py +0 -0
  382. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/app.py +0 -0
  383. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/backend_host.py +0 -0
  384. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/input.py +0 -0
  385. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/output.py +0 -0
  386. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/permission_dialog.py +0 -0
  387. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/permission_store.py +0 -0
  388. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/protocol.py +0 -0
  389. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/react_launcher.py +0 -0
  390. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/textual_app.py +0 -0
  391. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/web/__init__.py +0 -0
  392. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/web/server.py +0 -0
  393. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/web/ws_host.py +0 -0
  394. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/ui/web/ws_web_api.py +0 -0
  395. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/utils/__init__.py +0 -0
  396. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/utils/atomic_write.py +0 -0
  397. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/utils/file_state_cache.py +0 -0
  398. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/utils/ripgrep.py +0 -0
  399. {illusion_code-0.2.10 → illusion_code-0.2.11}/src/illusion/utils/shell.py +0 -0
  400. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/__init__.py +0 -0
  401. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/api/test_anthropic_client.py +0 -0
  402. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/api/test_client.py +0 -0
  403. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/api/test_codex_client.py +0 -0
  404. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/api/test_effort.py +0 -0
  405. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/api/test_fallback/346/217/220/347/244/272.py" +0 -0
  406. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/api/test_openai_client.py +0 -0
  407. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/__init__.py +0 -0
  408. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/feishu/__init__.py +0 -0
  409. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/feishu/test_adapter.py +0 -0
  410. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/feishu/test_commands.py +0 -0
  411. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/feishu/test_session_map.py +0 -0
  412. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/test_base.py +0 -0
  413. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/test_base_commands.py +0 -0
  414. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/test_config.py +0 -0
  415. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/test_pid.py +0 -0
  416. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/test_tool_registration.py +0 -0
  417. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/tools/__init__.py +0 -0
  418. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/tools/test_feishu_doc.py +0 -0
  419. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/tools/test_feishu_drive.py +0 -0
  420. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/weixin/__init__.py +0 -0
  421. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/weixin/test_adapter.py +0 -0
  422. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/weixin/test_config.py +0 -0
  423. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/weixin/test_ilink_api.py +0 -0
  424. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/channels/weixin/test_session_map.py +0 -0
  425. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/commands/init/__init__.py +0 -0
  426. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/commands/init/test_claudemd.py +0 -0
  427. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/commands/init/test_orchestrator.py +0 -0
  428. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/commands/init/test_scanner.py +0 -0
  429. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/commands/init/test_sections.py +0 -0
  430. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/commands/test_effort_command.py +0 -0
  431. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/config/test_i18n.py +0 -0
  432. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/config/test_settings.py +0 -0
  433. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/conftest.py +0 -0
  434. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/engine/test_query_engine.py +0 -0
  435. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/fixtures/fake_mcp_server.py +0 -0
  436. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/integration/test_effort_integration.py +0 -0
  437. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/services/lsp/test_lsp_client.py +0 -0
  438. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/services/lsp/test_lsp_config.py +0 -0
  439. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/services/lsp/test_lsp_manager.py +0 -0
  440. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/services/lsp/test_lsp_types.py +0 -0
  441. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_api/__init__.py +0 -0
  442. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_api/test_client.py +0 -0
  443. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_api/test_codex_client.py +0 -0
  444. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_api/test_compat.py +0 -0
  445. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_api/test_openai_client.py +0 -0
  446. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_auth/test_external.py +0 -0
  447. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_bridge/test_core.py +0 -0
  448. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_bridge/test_session_flow.py +0 -0
  449. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_commands/__init__.py +0 -0
  450. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_commands/test_cli.py +0 -0
  451. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_commands/test_command_flows.py +0 -0
  452. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_commands/test_registry.py +0 -0
  453. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_config/__init__.py +0 -0
  454. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_config/test_paths.py +0 -0
  455. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_config/test_settings.py +0 -0
  456. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_coordinator/test_agent_definitions.py +0 -0
  457. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_coordinator/test_coordinator_mode.py +0 -0
  458. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_engine/__init__.py +0 -0
  459. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_engine/test_media_block.py +0 -0
  460. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_engine/test_query_engine.py +0 -0
  461. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_engine/test_tool_result_media.py +0 -0
  462. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_hooks/__init__.py +0 -0
  463. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_hooks/test_executor.py +0 -0
  464. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_hooks/test_loader_permissions.py +0 -0
  465. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_hooks_skills_plugins_real.py +0 -0
  466. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_mcp/__init__.py +0 -0
  467. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_mcp/test_config_permissions.py +0 -0
  468. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_mcp/test_integration.py +0 -0
  469. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_mcp/test_stdio_flow.py +0 -0
  470. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_memory/__init__.py +0 -0
  471. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_memory/test_manager_permissions.py +0 -0
  472. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_memory/test_memdir.py +0 -0
  473. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_merged_prs_on_autoagent.py +0 -0
  474. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_permissions/__init__.py +0 -0
  475. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_permissions/test_checker.py +0 -0
  476. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_permissions/test_loader.py +0 -0
  477. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_permissions/test_project_permissions.py +0 -0
  478. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_platforms.py +0 -0
  479. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_plugins/__init__.py +0 -0
  480. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_plugins/test_lifecycle_flow.py +0 -0
  481. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_plugins/test_loader.py +0 -0
  482. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_plugins/test_loader_permissions.py +0 -0
  483. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_prompts/__init__.py +0 -0
  484. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_prompts/test_claudemd.py +0 -0
  485. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_prompts/test_claudemd_permissions.py +0 -0
  486. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_prompts/test_environment.py +0 -0
  487. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_prompts/test_system_prompt.py +0 -0
  488. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_qq_channel.py +0 -0
  489. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_real_large_tasks.py +0 -0
  490. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_sandbox/test_adapter.py +0 -0
  491. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_sandbox/test_config_schema.py +0 -0
  492. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_sandbox/test_platform_linux.py +0 -0
  493. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_sandbox/test_platform_macos.py +0 -0
  494. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_sandbox/test_platform_windows.py +0 -0
  495. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_sandbox/test_proxy_env_vars.py +0 -0
  496. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_sandbox/test_runtime.py +0 -0
  497. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_sandbox/test_symlink_protection.py +0 -0
  498. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_sandbox/test_utils.py +0 -0
  499. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_sandbox/test_violation_store.py +0 -0
  500. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_scripts/test_sync_version.py +0 -0
  501. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_services/test_compact.py +0 -0
  502. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_services/test_cron.py +0 -0
  503. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_services/test_cron_scheduler.py +0 -0
  504. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_services/test_session_storage.py +0 -0
  505. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_skills/test_loader.py +0 -0
  506. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_skills/test_loader_permissions.py +0 -0
  507. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_swarm/__init__.py +0 -0
  508. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_swarm/test_agent_executor.py +0 -0
  509. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_swarm/test_imports.py +0 -0
  510. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_swarm/test_in_process.py +0 -0
  511. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_swarm/test_types.py +0 -0
  512. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_swarm/test_worktree.py +0 -0
  513. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tasks/test_manager.py +0 -0
  514. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tools/__init__.py +0 -0
  515. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tools/test_agent_tool.py +0 -0
  516. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tools/test_core_tools.py +0 -0
  517. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tools/test_file_read_media.py +0 -0
  518. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tools/test_glob_tool.py +0 -0
  519. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tools/test_grep_tool.py +0 -0
  520. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tools/test_integration.py +0 -0
  521. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tools/test_integration_flows.py +0 -0
  522. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tools/test_mcp_auth_tool.py +0 -0
  523. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tools/test_ripgrep.py +0 -0
  524. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tools/test_shell_common.py +0 -0
  525. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tools/test_task_tools.py +0 -0
  526. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tools/test_team_tools.py +0 -0
  527. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_tools/test_web_fetch_tool.py +0 -0
  528. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_ui/__init__.py +0 -0
  529. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_ui/test_modes.py +0 -0
  530. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_ui/test_permission_store.py +0 -0
  531. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_ui/test_react_backend.py +0 -0
  532. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_ui/test_react_launcher.py +0 -0
  533. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_ui/test_textual_app.py +0 -0
  534. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_untested_features.py +0 -0
  535. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/test_utils/test_shell.py +0 -0
  536. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/ui/test_backend_host.py +0 -0
  537. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/ui/test_protocol_web.py +0 -0
  538. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/ui/test_web_api.py +0 -0
  539. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/unit/__init__.py +0 -0
  540. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/unit/test_channel_hints.py +0 -0
  541. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/unit/test_cross_channel.py +0 -0
  542. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/unit/test_delivery.py +0 -0
  543. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/unit/test_feishu_streaming.py +0 -0
  544. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/unit/test_media_tools.py +0 -0
  545. {illusion_code-0.2.10 → illusion_code-0.2.11}/tests/unit/test_session_list_active.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: illusion-code
3
- Version: 0.2.10
3
+ Version: 0.2.11
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.10",
3
+ "version": "0.2.11",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@illusion/terminal",
9
- "version": "0.2.10",
9
+ "version": "0.2.11",
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.10"
27
+ "version": "0.2.11"
28
28
  }
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  /** 当前版本号 */
9
- export const VERSION = '0.2.10';
9
+ export const VERSION = '0.2.11';
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@illusion/web",
3
- "version": "0.2.10",
3
+ "version": "0.2.11",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@illusion/web",
9
- "version": "0.2.10",
9
+ "version": "0.2.11",
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.10",
3
+ "version": "0.2.11",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  /** 当前版本号 */
9
- export const VERSION = '0.2.10';
9
+ export const VERSION = '0.2.11';
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "illusion-code"
7
- version = "0.2.10"
7
+ version = "0.2.11"
8
8
  description = "Open-source Python port of Claude Code - an AI-powered CLI coding assistant"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -23,4 +23,4 @@ IllusionCode 是一个 AI 驱动的编程助手,提供交互式会话和命令
23
23
 
24
24
  from __future__ import annotations
25
25
 
26
- __version__ = "0.2.10"
26
+ __version__ = "0.2.11"
@@ -35,6 +35,8 @@ logger = logging.getLogger(__name__)
35
35
  def _config_fingerprint(cfg: "ChannelsConfig") -> str:
36
36
  """计算渠道配置指纹(用于检测配置变更后重启守护进程)
37
37
 
38
+ 遍历 ChannelRegistry,对每个已启用渠道调用其 fingerprint_factory 生成标识。
39
+
38
40
  Args:
39
41
  cfg: 渠道配置
40
42
 
@@ -44,14 +46,14 @@ def _config_fingerprint(cfg: "ChannelsConfig") -> str:
44
46
  import hashlib
45
47
  import json as _json
46
48
 
47
- # 只取影响守护进程行为的字段
49
+ from illusion.channels.registry import ChannelRegistry
50
+
51
+ # 遍历 registry 调用各渠道的 fingerprint_factory
48
52
  enabled_channels = []
49
- if cfg.feishu.enabled:
50
- enabled_channels.append(f"feishu:{cfg.feishu.app_id}")
51
- if cfg.weixin.enabled:
52
- enabled_channels.append(f"weixin:{cfg.weixin.account_id}:{cfg.weixin.token}")
53
- if cfg.qq.enabled:
54
- enabled_channels.append(f"qq:{cfg.qq.app_id}:{cfg.qq.client_secret}")
53
+ for desc in ChannelRegistry.all_descriptors():
54
+ channel_cfg = getattr(cfg, desc.config_attr, None)
55
+ if channel_cfg is not None and channel_cfg.enabled:
56
+ enabled_channels.append(desc.fingerprint_factory(channel_cfg))
55
57
  raw = _json.dumps(sorted(enabled_channels), ensure_ascii=False)
56
58
  return hashlib.md5(raw.encode()).hexdigest()
57
59
 
@@ -318,23 +320,6 @@ class ChannelRunner:
318
320
  Args:
319
321
  msg: 入站消息
320
322
  """
321
- # 检查 /delete 信号:先执行 /new(清所有会话+发确认),再处理消息
322
- # 信号触发后直接 return,避免继续走 try_handle 处理 /new 命令
323
- # 导致"已开启新的对话"反馈消息发送两次
324
- if self.session_store.check_signal():
325
- for path in self.session_store.data_dir.glob("*.json"):
326
- try:
327
- path.unlink()
328
- except OSError:
329
- pass
330
- from illusion.config.i18n import t as _t
331
- # 统一使用 cmd_new,避免渠道专属文案不一致
332
- await self.channel.send_text(
333
- msg.chat_id, _t("cmd_new"), reply_to=msg.message_id,
334
- )
335
- self.session_store.clear_signal()
336
- return
337
-
338
323
  # 1. 待回复的权限/询问——不加锁,让回复立即送达
339
324
  # (agent turn 持锁等待回复时,下一条消息作为回复立即 set_result,
340
325
  # 不会因锁阻塞导致 300s 超时)
@@ -398,27 +383,16 @@ class ChannelRunner:
398
383
  def _get_command_handler(self) -> Any:
399
384
  """按渠道类型返回对应的斜杠命令处理器
400
385
 
386
+ 遍历 ChannelRegistry,匹配 adapter_class 后调用 command_handler_factory。
387
+
401
388
  Returns:
402
389
  BaseCommandHandler 实例或 None(未知渠道)
403
390
  """
404
- from illusion.channels.feishu.adapter import FeishuChannel
405
- from illusion.channels.feishu.commands import FeishuCommandHandler
406
- if isinstance(self.channel, FeishuChannel):
407
- return FeishuCommandHandler(self.channel, self.session_store)
408
- try:
409
- from illusion.channels.weixin.adapter import WeixinChannel
410
- from illusion.channels.weixin.commands import WeixinCommandHandler
411
- if isinstance(self.channel, WeixinChannel):
412
- return WeixinCommandHandler(self.channel, self.session_store)
413
- except ImportError:
414
- pass # 微信模块不可用时跳过
415
- try:
416
- from illusion.channels.qq.adapter import QQChannel
417
- from illusion.channels.qq.commands import QQCommandHandler
418
- if isinstance(self.channel, QQChannel):
419
- return QQCommandHandler(self.channel, self.session_store)
420
- except ImportError:
421
- pass # QQ 模块不可用时跳过
391
+ from illusion.channels.registry import ChannelRegistry
392
+
393
+ for desc in ChannelRegistry.all_descriptors():
394
+ if isinstance(self.channel, desc.adapter_class):
395
+ return desc.command_handler_factory(self.channel, self.session_store)
422
396
  return None
423
397
 
424
398
  async def _handle_stop(self, msg: "InboundMessage") -> None:
@@ -547,6 +521,14 @@ class ChannelRunner:
547
521
  key = self.session_store.build_session_key(msg)
548
522
  session = self.session_store.get_or_create(key, msg.user_id, msg.chat_type)
549
523
 
524
+ # 提前落盘会话索引(仅当文件尚不存在时):确保 session_id 落盘,
525
+ # 这样进程崩溃后下次启动 get_or_create 能命中该会话记录接续,
526
+ # 而非新建会话。注意:绝不覆盖已有 messages(否则会清空历史)。
527
+ try:
528
+ self.session_store.ensure_indexed(session)
529
+ except Exception as exc: # noqa: BLE001
530
+ logger.warning("会话索引提前落盘失败: %s", exc)
531
+
550
532
  # 检测渠道是否支持消息编辑(仅飞书支持卡片 patch)
551
533
  from illusion.channels.feishu.adapter import FeishuChannel
552
534
  from illusion.channels.qq.adapter import QQChannel
@@ -600,18 +582,12 @@ class ChannelRunner:
600
582
  await streaming_controller.start()
601
583
  elif qq_c2c_streaming and qq_channel is not None:
602
584
  # QQ C2C:用 stream_messages API 流式(首次有文本时才启动)
603
- # 确保 token 已获取
604
- if not qq_channel._token:
605
- from illusion.channels.qq.api import ensure_token
606
- qq_channel._token = await ensure_token(
607
- qq_channel._session,
608
- qq_channel.config.app_id,
609
- qq_channel.config.client_secret,
610
- )
585
+ # 确保 token 已获取(通过 _get_token,重连后自动刷新)
586
+ token = await qq_channel._get_token()
611
587
  from illusion.channels.qq.streaming import QQStreamingController
612
588
  qq_streaming_controller = QQStreamingController(
613
589
  session=qq_channel._session,
614
- token=qq_channel._token,
590
+ token=token,
615
591
  openid=msg.chat_id,
616
592
  msg_id=msg.message_id,
617
593
  )
@@ -889,10 +865,8 @@ def _create_session_store(
889
865
  ) -> Any:
890
866
  """根据渠道类型创建对应的 SessionStore
891
867
 
892
- 飞书 FeishuSessionStore
893
- QQ → QQSessionStore
894
- 微信 → WeixinSessionStore
895
- 未知 → FeishuSessionStore(向后兼容)
868
+ 遍历 ChannelRegistry,匹配 adapter_class 后调用 session_store_factory。
869
+ 未知渠道回退到 FeishuSessionStore(向后兼容)。
896
870
 
897
871
  Args:
898
872
  channel: 渠道实例
@@ -902,30 +876,13 @@ def _create_session_store(
902
876
  Returns:
903
877
  对应渠道的 SessionStore 实例
904
878
  """
905
- from illusion.channels.feishu.adapter import FeishuChannel
906
- if isinstance(channel, FeishuChannel):
907
- from illusion.channels.feishu.session_map import FeishuSessionStore
908
- return FeishuSessionStore(
909
- data_dir=data_dir,
910
- group_sessions_per_user=group_sessions_per_user,
911
- )
912
- try:
913
- from illusion.channels.qq.adapter import QQChannel
914
- if isinstance(channel, QQChannel):
915
- from illusion.channels.qq.session_map import QQSessionStore
916
- return QQSessionStore(
917
- data_dir=data_dir,
918
- group_sessions_per_user=group_sessions_per_user,
879
+ from illusion.channels.registry import ChannelRegistry
880
+
881
+ for desc in ChannelRegistry.all_descriptors():
882
+ if isinstance(channel, desc.adapter_class):
883
+ return desc.session_store_factory(
884
+ channel, data_dir, group_sessions_per_user
919
885
  )
920
- except ImportError:
921
- pass
922
- try:
923
- from illusion.channels.weixin.adapter import WeixinChannel
924
- if isinstance(channel, WeixinChannel):
925
- from illusion.channels.weixin.session_map import WeixinSessionStore
926
- return WeixinSessionStore(data_dir=data_dir)
927
- except ImportError:
928
- pass
929
886
  # 未知渠道回退到飞书(向后兼容)
930
887
  from illusion.channels.feishu.session_map import FeishuSessionStore
931
888
  return FeishuSessionStore(
@@ -161,24 +161,34 @@ class ChannelsConfig(BaseModel):
161
161
  def has_enabled_channels(self) -> bool:
162
162
  """是否有任何已启用的渠道
163
163
 
164
+ 遍历 ChannelRegistry 检查每个渠道的 enabled 字段。
165
+
164
166
  Returns:
165
167
  bool: 任一渠道 enabled 为 True 时返回 True
166
168
  """
167
- return self.feishu.enabled or self.weixin.enabled or self.qq.enabled
169
+ from illusion.channels.registry import ChannelRegistry
170
+
171
+ for desc in ChannelRegistry.all_descriptors():
172
+ channel_cfg = getattr(self, desc.config_attr, None)
173
+ if channel_cfg is not None and channel_cfg.enabled:
174
+ return True
175
+ return False
168
176
 
169
177
  def enabled_channel_names(self) -> list[str]:
170
178
  """返回所有已启用渠道的名称列表
171
179
 
180
+ 遍历 ChannelRegistry 收集已启用渠道名。
181
+
172
182
  Returns:
173
183
  list[str]: 已启用渠道名列表
174
184
  """
185
+ from illusion.channels.registry import ChannelRegistry
186
+
175
187
  names: list[str] = []
176
- if self.feishu.enabled:
177
- names.append("feishu")
178
- if self.weixin.enabled:
179
- names.append("weixin")
180
- if self.qq.enabled:
181
- names.append("qq")
188
+ for desc in ChannelRegistry.all_descriptors():
189
+ channel_cfg = getattr(self, desc.config_attr, None)
190
+ if channel_cfg is not None and channel_cfg.enabled:
191
+ names.append(desc.name)
182
192
  return names
183
193
 
184
194
 
@@ -0,0 +1,83 @@
1
+ """共享退出处理器
2
+ ==================
3
+
4
+ 统一 Ctrl+C / 正常退出时的守护进程退出行为,消除 cli.py 中
5
+ main() 和 web_start() 重复的内联退出确认逻辑。
6
+
7
+ 行为规则:
8
+ 1. 守护进程未运行 → 直接返回(程序正常退出)
9
+ 2. channels.json 无配置或无启用渠道 → 直接返回
10
+ 3. 否则弹出确认提示:
11
+ - 输入 y/Y/yes/回车(空输入)→ 停止守护进程
12
+ - 输入期间再次 Ctrl+C(KeyboardInterrupt)→ 停止守护进程
13
+ - 其他任何输入 → 不停止(守护进程保留运行)
14
+ - EOF(非 TTY 环境,如管道)→ 不停止
15
+
16
+ 函数说明:
17
+ - handle_daemon_exit_on_interrupt: 退出时调用,按上述规则处理
18
+ - _confirm_exit: 私有确认函数
19
+
20
+ 使用示例:
21
+ >>> from illusion.channels.exit_handler import handle_daemon_exit_on_interrupt
22
+ >>> # 在 cli.py 的 finally 块中调用
23
+ >>> handle_daemon_exit_on_interrupt()
24
+ """
25
+ from __future__ import annotations
26
+
27
+ from illusion.channels import (
28
+ is_channel_daemon_running,
29
+ stop_channel_daemon_by_pid,
30
+ )
31
+ from illusion.channels.config import load_channels_config
32
+
33
+
34
+ def handle_daemon_exit_on_interrupt() -> None:
35
+ """Ctrl+C 或正常退出时的守护进程退出处理
36
+
37
+ 行为:
38
+ 1. 守护进程未运行 → 直接返回(程序正常退出)
39
+ 2. channels.json 无配置或无启用渠道 → 直接返回
40
+ 3. 否则弹出确认提示:
41
+ - 输入 y/Y/yes/回车(空输入)→ 停止守护进程
42
+ - 输入期间再次 Ctrl+C(KeyboardInterrupt)→ 停止守护进程
43
+ - 其他任何输入 → 不停止(守护进程保留运行)
44
+
45
+ 退出路径必须比正常路径更健壮:任何异常(如 channels.json 权限不足、
46
+ PID 文件读取失败)都不应破坏退出体验,静默吞掉并记日志。
47
+ """
48
+ try:
49
+ if not is_channel_daemon_running():
50
+ return
51
+ cfg = load_channels_config()
52
+ if not cfg.has_enabled_channels():
53
+ return
54
+ if _confirm_exit():
55
+ stop_channel_daemon_by_pid()
56
+ except Exception: # noqa: BLE001
57
+ # 退出路径防御性兜底:避免配置文件异常/PID 读取失败等导致丑陋 traceback
58
+ import logging
59
+ logging.getLogger(__name__).debug("exit handler suppressed exception", exc_info=True)
60
+
61
+
62
+ def _confirm_exit() -> bool:
63
+ """确认是否退出守护进程
64
+
65
+ y/Y/yes/空回车/二次 Ctrl+C 均视为确认;
66
+ 其他输入或 EOF 视为拒绝。
67
+
68
+ Returns:
69
+ bool: True 表示确认停止守护进程
70
+ """
71
+ from illusion.config.i18n import t
72
+
73
+ try:
74
+ answer = input(t("channel_daemon_exit_prompt") + " ").strip()
75
+ return answer.lower() in ("", "y", "yes")
76
+ except KeyboardInterrupt:
77
+ # 再次 Ctrl+C = 确认退出。Windows 终端会回显 "^C" 到屏幕,
78
+ # 打印明确的确认信息让用户知道 Ctrl+C 已被正确处理
79
+ print()
80
+ print(t("channel_daemon_exit_confirmed"))
81
+ return True
82
+ except EOFError:
83
+ return False # 非 TTY 环境(如管道)默认不杀
@@ -98,21 +98,6 @@ class FeishuSessionStore:
98
98
  safe = key.replace(":", "_").replace("/", "_") # 安全文件名
99
99
  return self.data_dir / f"{safe}.json"
100
100
 
101
- def check_signal(self) -> bool:
102
- """检查 /delete 信号文件是否存在
103
-
104
- Returns:
105
- bool: 信号存在返回 True
106
- """
107
- return (self.data_dir / ".delete_signal").exists()
108
-
109
- def clear_signal(self) -> None:
110
- """删除信号文件"""
111
- try:
112
- (self.data_dir / ".delete_signal").unlink()
113
- except OSError:
114
- pass
115
-
116
101
  def get_or_create(self, key: str, user_id: str, chat_type: str) -> FeishuSession:
117
102
  """获取或创建会话
118
103
 
@@ -125,6 +110,10 @@ class FeishuSessionStore:
125
110
 
126
111
  Returns:
127
112
  FeishuSession: 会话状态
113
+
114
+ Note:
115
+ 会话索引在 _run_agent 进入 agent turn 前即提前落盘,
116
+ 保证进程崩溃后下次启动能接续同一 session_id。
128
117
  """
129
118
  path = self._key_to_path(key)
130
119
  if path.exists():
@@ -178,6 +167,27 @@ class FeishuSessionStore:
178
167
  except FileNotFoundError:
179
168
  pass # 已删除
180
169
 
170
+ def ensure_indexed(self, session: FeishuSession) -> None:
171
+ """确保会话索引已落盘(仅当文件不存在时创建)
172
+
173
+ 与 save 不同:本方法绝不覆盖已有 messages,只在文件尚不存在时
174
+ 写入 session_id 等索引字段,供进程崩溃后接续使用。
175
+
176
+ Args:
177
+ session: 会话状态
178
+ """
179
+ path = self._key_to_path(session.key)
180
+ if path.exists():
181
+ return # 已有记录,绝不覆盖(避免清空历史)
182
+ data = {
183
+ "session_id": session.session_id,
184
+ "messages": [],
185
+ "user_id": session.user_id,
186
+ "chat_type": session.chat_type,
187
+ "model": session.model,
188
+ }
189
+ atomic_write_text(path, json.dumps(data, ensure_ascii=False, indent=2))
190
+
181
191
  def clear_by_session_id(self, session_id: str) -> bool:
182
192
  """按 session_id 删除会话文件(用于 /delete 命令跨渠道清理)
183
193
 
@@ -83,7 +83,10 @@ class QQChannel(Channel):
83
83
  self._stop_event = asyncio.Event()
84
84
  self._ws_client: Any = None # QQWSClient 实例
85
85
  self._session: Any = None # aiohttp.ClientSession(发送用)
86
- self._token: str = ""
86
+ # 注意:不再缓存 self._token。每次 API 调用都通过 _get_token()
87
+ # 获取最新 token(内部有 _token_cache + 过期检查,不会重复请求)。
88
+ # 原因:WS 重连时 ws_client 会刷新 _token_cache,但旧的 self._token
89
+ # 不会更新,导致重连后发送消息用旧 token 报 "token not exist or expire"。
87
90
 
88
91
  # bot 自身 openid(用于自回显检测)
89
92
  self._bot_openid: str = ""
@@ -101,6 +104,22 @@ class QQChannel(Channel):
101
104
  # markdown 支持(从配置读取,默认启用)
102
105
  self._markdown_support: bool = getattr(config, "markdown_support", True)
103
106
 
107
+ async def _get_token(self) -> str:
108
+ """获取有效的 QQ Bot access token
109
+
110
+ 每次调用都经过 ensure_token(),内部有缓存+过期检查,
111
+ 不会重复请求。WS 重连后 _token_cache 已刷新,此方法自动
112
+ 返回新 token,无需手动同步。
113
+
114
+ Returns:
115
+ str: 有效的 access token
116
+ """
117
+ if not self._session:
118
+ raise RuntimeError("QQ adapter 未连接,无法获取 token")
119
+ return await ensure_token(
120
+ self._session, self.config.app_id, self.config.client_secret,
121
+ )
122
+
104
123
  async def connect(self) -> None:
105
124
  """建立 WS 连接和 HTTP session"""
106
125
  import aiohttp
@@ -130,12 +149,9 @@ class QQChannel(Channel):
130
149
  if not self._session:
131
150
  return
132
151
  try:
133
- if not self._token:
134
- self._token = await ensure_token(
135
- self._session, self.config.app_id, self.config.client_secret,
136
- )
152
+ token = await self._get_token()
137
153
  from illusion.channels.qq.api import API_BASE
138
- headers = {"Authorization": f"QQBot {self._token}"}
154
+ headers = {"Authorization": f"QQBot {token}"}
139
155
  async with self._session.get(f"{API_BASE}/users/@me", headers=headers) as resp:
140
156
  if resp.status == 200:
141
157
  data = await resp.json()
@@ -447,11 +463,8 @@ class QQChannel(Channel):
447
463
  if not self._session:
448
464
  return ""
449
465
 
450
- # 确保 token 有效
451
- if not self._token:
452
- self._token = await ensure_token(
453
- self._session, self.config.app_id, self.config.client_secret,
454
- )
466
+ # 确保 token 有效(每次调用,重连后自动获取新 token)
467
+ token = await self._get_token()
455
468
 
456
469
  # 格式化(markdown 原样传递 or 剥离为纯文本)
457
470
  formatted = self._format_message(text)
@@ -476,13 +489,13 @@ class QQChannel(Channel):
476
489
  try:
477
490
  if is_group:
478
491
  await send_group_message(
479
- self._session, self._token, chat_id, chunk,
492
+ self._session, token, chat_id, chunk,
480
493
  msg_id=reply_to,
481
494
  markdown=use_markdown,
482
495
  )
483
496
  else:
484
497
  await send_c2c_message(
485
- self._session, self._token, chat_id, chunk,
498
+ self._session, token, chat_id, chunk,
486
499
  msg_id=reply_to or "",
487
500
  markdown=use_markdown,
488
501
  )
@@ -516,8 +529,9 @@ class QQChannel(Channel):
516
529
  try:
517
530
  from illusion.channels.qq.api import upload_file
518
531
  is_group = self._chat_type_cache.get(chat_id) == "group"
532
+ token = await self._get_token()
519
533
  await upload_file(
520
- self._session, self._token, chat_id, file_path,
534
+ self._session, token, chat_id, file_path,
521
535
  is_group=is_group,
522
536
  )
523
537
  except Exception as exc: # noqa: BLE001
@@ -555,10 +569,7 @@ class QQChannel(Channel):
555
569
  upload_file,
556
570
  )
557
571
 
558
- if not self._token:
559
- self._token = await ensure_token(
560
- self._session, self.config.app_id, self.config.client_secret,
561
- )
572
+ token = await self._get_token()
562
573
 
563
574
  is_group = self._chat_type_cache.get(chat_id) == "group"
564
575
 
@@ -569,7 +580,7 @@ class QQChannel(Channel):
569
580
  )
570
581
 
571
582
  upload_resp = await upload_file(
572
- self._session, self._token, chat_id, image_path,
583
+ self._session, token, chat_id, image_path,
573
584
  is_group=is_group,
574
585
  file_type=MEDIA_TYPE_IMAGE,
575
586
  )
@@ -578,7 +589,7 @@ class QQChannel(Channel):
578
589
  raise RuntimeError(f"QQ 图片上传未返回 file_info: {upload_resp}")
579
590
 
580
591
  msg_id = await send_media_message(
581
- self._session, self._token, chat_id, file_info,
592
+ self._session, token, chat_id, file_info,
582
593
  is_group=is_group, msg_id=reply_to,
583
594
  )
584
595
 
@@ -619,10 +630,7 @@ class QQChannel(Channel):
619
630
  upload_file,
620
631
  )
621
632
 
622
- if not self._token:
623
- self._token = await ensure_token(
624
- self._session, self.config.app_id, self.config.client_secret,
625
- )
633
+ token = await self._get_token()
626
634
 
627
635
  is_group = self._chat_type_cache.get(chat_id) == "group"
628
636
 
@@ -633,7 +641,7 @@ class QQChannel(Channel):
633
641
  )
634
642
 
635
643
  upload_resp = await upload_file(
636
- self._session, self._token, chat_id, file_path,
644
+ self._session, token, chat_id, file_path,
637
645
  is_group=is_group,
638
646
  file_type=MEDIA_TYPE_FILE,
639
647
  )
@@ -642,7 +650,7 @@ class QQChannel(Channel):
642
650
  raise RuntimeError(f"QQ 文件上传未返回 file_info: {upload_resp}")
643
651
 
644
652
  msg_id = await send_media_message(
645
- self._session, self._token, chat_id, file_info,
653
+ self._session, token, chat_id, file_info,
646
654
  is_group=is_group, msg_id=reply_to,
647
655
  )
648
656
 
@@ -678,10 +686,7 @@ class QQChannel(Channel):
678
686
  if not self._session:
679
687
  raise NotImplementedError("QQ session 未初始化,无法下载附件")
680
688
 
681
- if not self._token:
682
- self._token = await ensure_token(
683
- self._session, self.config.app_id, self.config.client_secret,
684
- )
689
+ token = await self._get_token()
685
690
 
686
691
  # 优先使用 download_url(QQ 入站附件的临时 URL)
687
692
  url_error: Exception | None = None
@@ -694,7 +699,7 @@ class QQChannel(Channel):
694
699
  # 仅对 QQ 可信 CDN 域名附带 Authorization,避免 bot token 泄露到第三方 host
695
700
  headers: dict[str, str] = {}
696
701
  if _is_qq_cdn_url(url):
697
- headers["Authorization"] = f"QQBot {self._token}"
702
+ headers["Authorization"] = f"QQBot {token}"
698
703
  else:
699
704
  logger.warning(
700
705
  "QQ 附件 URL 非 QQ CDN 域名,不带 Authorization: %s",
@@ -724,7 +729,7 @@ class QQChannel(Channel):
724
729
  )
725
730
  try:
726
731
  data = await download_file(
727
- self._session, self._token, target_id,
732
+ self._session, token, target_id,
728
733
  attachment.file_key,
729
734
  is_group=False,
730
735
  )
@@ -758,8 +763,8 @@ class QQChannel(Channel):
758
763
 
759
764
  try:
760
765
  from illusion.channels.qq.api import send_typing
761
- if self._token:
762
- await send_typing(self._session, self._token, chat_id)
766
+ token = await self._get_token()
767
+ await send_typing(self._session, token, chat_id)
763
768
  except Exception as exc: # noqa: BLE001
764
769
  logger.debug("QQ 打字状态发送失败: %s", exc)
765
770