illusion-code 0.2.9__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 (546) hide show
  1. {illusion_code-0.2.9 → illusion_code-0.2.11}/PKG-INFO +1 -1
  2. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/package-lock.json +2 -2
  3. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/package.json +1 -1
  4. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/version.ts +1 -1
  5. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/package-lock.json +2 -2
  6. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/package.json +1 -1
  7. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/version.ts +1 -1
  8. {illusion_code-0.2.9 → illusion_code-0.2.11}/pyproject.toml +1 -1
  9. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/__init__.py +1 -1
  10. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/__init__.py +164 -75
  11. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/base_commands.py +4 -0
  12. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/config.py +17 -7
  13. illusion_code-0.2.11/src/illusion/channels/exit_handler.py +83 -0
  14. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/feishu/session_map.py +25 -15
  15. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/qq/adapter.py +39 -34
  16. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/qq/session_map.py +22 -12
  17. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/qq/ws_client.py +73 -18
  18. illusion_code-0.2.11/src/illusion/channels/registry.py +253 -0
  19. illusion_code-0.2.11/src/illusion/channels/serve.py +309 -0
  20. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/tools/feishu_doc.py +6 -6
  21. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/tools/feishu_drive.py +9 -9
  22. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/tools/media.py +5 -1
  23. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/weixin/ilink_api.py +93 -14
  24. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/weixin/session_map.py +22 -12
  25. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/cli.py +46 -17
  26. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/session.py +2 -18
  27. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/config/i18n.py +29 -2
  28. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/hooks/__init__.py +1 -1
  29. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/mcp/__init__.py +1 -0
  30. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/plugins/__init__.py +7 -0
  31. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/skills/__init__.py +6 -0
  32. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tasks/todo_sync.py +2 -2
  33. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/runtime.py +1 -1
  34. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/web/ws_host.py +5 -0
  35. illusion_code-0.2.11/tests/channels/test_exit_handler.py +192 -0
  36. illusion_code-0.2.11/tests/channels/test_registry.py +248 -0
  37. illusion_code-0.2.11/tests/channels/test_session_persist.py +72 -0
  38. illusion_code-0.2.11/tests/channels/test_supervise.py +71 -0
  39. illusion_code-0.2.11/tests/channels/weixin/test_ilink_retry.py +65 -0
  40. illusion_code-0.2.11/tests/test_cli_exit_handler.py +66 -0
  41. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/unit/test_qq_streaming.py +2 -2
  42. illusion_code-0.2.9/src/illusion/channels/serve.py +0 -251
  43. {illusion_code-0.2.9 → illusion_code-0.2.11}/.github/workflows/publish.yml +0 -0
  44. {illusion_code-0.2.9 → illusion_code-0.2.11}/.gitignore +0 -0
  45. {illusion_code-0.2.9 → illusion_code-0.2.11}/.python-version +0 -0
  46. {illusion_code-0.2.9 → illusion_code-0.2.11}/LICENSE +0 -0
  47. {illusion_code-0.2.9 → illusion_code-0.2.11}/README.md +0 -0
  48. {illusion_code-0.2.9 → illusion_code-0.2.11}/README.zh-CN.md +0 -0
  49. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/en/architecture.md +0 -0
  50. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/en/channels.md +0 -0
  51. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/en/commands.md +0 -0
  52. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/en/extensions.md +0 -0
  53. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/en/getting-started.md +0 -0
  54. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/en/introduction.md +0 -0
  55. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/en/project-files.md +0 -0
  56. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/en/settings.md +0 -0
  57. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/images/IllusionCode.png +0 -0
  58. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/images/image1.png +0 -0
  59. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/images/image2.png +0 -0
  60. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/zh-CN/architecture.md +0 -0
  61. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/zh-CN/channels.md +0 -0
  62. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/zh-CN/commands.md +0 -0
  63. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/zh-CN/extensions.md +0 -0
  64. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/zh-CN/getting-started.md +0 -0
  65. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/zh-CN/introduction.md +0 -0
  66. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/zh-CN/project-files.md +0 -0
  67. {illusion_code-0.2.9 → illusion_code-0.2.11}/docs/zh-CN/settings.md +0 -0
  68. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/build.mjs +0 -0
  69. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/App.tsx +0 -0
  70. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/CommandPicker.tsx +0 -0
  71. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/Composer.tsx +0 -0
  72. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/ComposerController.tsx +0 -0
  73. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/ConversationView.tsx +0 -0
  74. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/Footer.tsx +0 -0
  75. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/MarkdownContent.tsx +0 -0
  76. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/MarkdownTable.tsx +0 -0
  77. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/ModalHost.tsx +0 -0
  78. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/MultilineTextInput.tsx +0 -0
  79. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/PromptInput.tsx +0 -0
  80. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/QuestionNavigationBar.tsx +0 -0
  81. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/QuestionPreviewBox.tsx +0 -0
  82. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/SelectModal.tsx +0 -0
  83. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/SidePanel.tsx +0 -0
  84. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/Spinner.tsx +0 -0
  85. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/StatusBar.tsx +0 -0
  86. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/SwarmPanel.tsx +0 -0
  87. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/TodoPanel.tsx +0 -0
  88. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/ToolCallDisplay.tsx +0 -0
  89. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/TranscriptPane.tsx +0 -0
  90. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/components/WelcomeBanner.tsx +0 -0
  91. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/hooks/useAnimationFrame.ts +0 -0
  92. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/hooks/useBackendSession.ts +0 -0
  93. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/hooks/useBlink.ts +0 -0
  94. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/hooks/useQuestionState.ts +0 -0
  95. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/hooks/useTerminalSize.ts +0 -0
  96. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/i18n.ts +0 -0
  97. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/index.tsx +0 -0
  98. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/theme/ThemeContext.tsx +0 -0
  99. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/theme/builtinThemes.ts +0 -0
  100. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/ToolInterface.ts +0 -0
  101. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/AgentTool.ts +0 -0
  102. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/BashTool.ts +0 -0
  103. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/CronTool.ts +0 -0
  104. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/EditTool.ts +0 -0
  105. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/GenericTool.ts +0 -0
  106. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/LspTool.ts +0 -0
  107. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/McpTool.ts +0 -0
  108. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/NotebookTool.ts +0 -0
  109. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/PlanTool.ts +0 -0
  110. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/ReadTool.ts +0 -0
  111. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/SearchTool.ts +0 -0
  112. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/SkillTool.ts +0 -0
  113. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/TaskTool.ts +0 -0
  114. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/WebTool.ts +0 -0
  115. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/WorktreeTool.ts +0 -0
  116. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/implementations/WriteTool.ts +0 -0
  117. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/tools/registry.ts +0 -0
  118. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/types.ts +0 -0
  119. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/utils/markdown.ts +0 -0
  120. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/src/utils/thinking.ts +0 -0
  121. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/terminal/tsconfig.json +0 -0
  122. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/index.html +0 -0
  123. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/postcss.config.js +0 -0
  124. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/App.tsx +0 -0
  125. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/components/ChatArea.tsx +0 -0
  126. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/components/ErrorBoundary.tsx +0 -0
  127. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/components/MessageBubble.tsx +0 -0
  128. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/components/ModalCard.tsx +0 -0
  129. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/components/PromptInput.tsx +0 -0
  130. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/components/RightPanel.tsx +0 -0
  131. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/components/Sidebar.tsx +0 -0
  132. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/components/TodoPanel.tsx +0 -0
  133. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/components/Toolbar.tsx +0 -0
  134. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/components/WelcomeScreen.tsx +0 -0
  135. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/hooks/useTheme.ts +0 -0
  136. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/hooks/useWebSocketSession.ts +0 -0
  137. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/i18n.ts +0 -0
  138. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/index.css +0 -0
  139. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/main.tsx +0 -0
  140. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/remarkSuperscript.ts +0 -0
  141. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/types/protocol.ts +0 -0
  142. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/utils/toolDisplayName.ts +0 -0
  143. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/src/vite-env.d.ts +0 -0
  144. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/tailwind.config.js +0 -0
  145. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/tsconfig.json +0 -0
  146. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/tsconfig.node.json +0 -0
  147. {illusion_code-0.2.9 → illusion_code-0.2.11}/frontend/web/vite.config.ts +0 -0
  148. {illusion_code-0.2.9 → illusion_code-0.2.11}/scripts/build_frontend.py +0 -0
  149. {illusion_code-0.2.9 → illusion_code-0.2.11}/scripts/hatch_build.py +0 -0
  150. {illusion_code-0.2.9 → illusion_code-0.2.11}/scripts/publish.py +0 -0
  151. {illusion_code-0.2.9 → illusion_code-0.2.11}/scripts/sync_version.py +0 -0
  152. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/__main__.py +0 -0
  153. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/api/__init__.py +0 -0
  154. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/api/client.py +0 -0
  155. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/api/codex_client.py +0 -0
  156. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/api/compat.py +0 -0
  157. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/api/effort.py +0 -0
  158. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/api/errors.py +0 -0
  159. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/api/openai_client.py +0 -0
  160. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/api/provider.py +0 -0
  161. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/api/registry.py +0 -0
  162. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/api/usage.py +0 -0
  163. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/auth/__init__.py +0 -0
  164. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/auth/codex_oauth.py +0 -0
  165. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/auth/copilot.py +0 -0
  166. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/auth/external.py +0 -0
  167. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/auth/flows.py +0 -0
  168. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/auth/manager.py +0 -0
  169. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/auth/storage.py +0 -0
  170. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/bridge/__init__.py +0 -0
  171. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/bridge/manager.py +0 -0
  172. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/bridge/session_runner.py +0 -0
  173. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/bridge/types.py +0 -0
  174. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/bridge/work_secret.py +0 -0
  175. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/base.py +0 -0
  176. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/delivery.py +0 -0
  177. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/feishu/__init__.py +0 -0
  178. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/feishu/adapter.py +0 -0
  179. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/feishu/commands.py +0 -0
  180. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/feishu/messaging.py +0 -0
  181. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/feishu/streaming.py +0 -0
  182. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/feishu/ws_client.py +0 -0
  183. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/pid.py +0 -0
  184. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/qq/__init__.py +0 -0
  185. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/qq/api.py +0 -0
  186. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/qq/commands.py +0 -0
  187. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/qq/streaming.py +0 -0
  188. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/tools/__init__.py +0 -0
  189. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/tools/cross_channel.py +0 -0
  190. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/weixin/__init__.py +0 -0
  191. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/weixin/adapter.py +0 -0
  192. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/channels/weixin/commands.py +0 -0
  193. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/__init__.py +0 -0
  194. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/auth.py +0 -0
  195. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/bridge.py +0 -0
  196. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/context.py +0 -0
  197. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/git.py +0 -0
  198. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/helpers.py +0 -0
  199. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/__init__.py +0 -0
  200. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/analysis/__init__.py +0 -0
  201. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/analysis/architecture.py +0 -0
  202. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/analysis/conventions.py +0 -0
  203. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/analysis/dependencies.py +0 -0
  204. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/analysis/key_modules.py +0 -0
  205. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/extraction/__init__.py +0 -0
  206. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/extraction/lsp_symbols.py +0 -0
  207. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/extraction/readme.py +0 -0
  208. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/extraction/scanner.py +0 -0
  209. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/generation/__init__.py +0 -0
  210. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/generation/claudemd.py +0 -0
  211. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/generation/illusionmd.py +0 -0
  212. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/generation/memory_template.py +0 -0
  213. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/generation/rules.py +0 -0
  214. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/generation/sections.py +0 -0
  215. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/orchestrator.py +0 -0
  216. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/init/types.py +0 -0
  217. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/mcp.py +0 -0
  218. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/memory.py +0 -0
  219. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/misc.py +0 -0
  220. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/model.py +0 -0
  221. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/plugin.py +0 -0
  222. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/registry.py +0 -0
  223. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/rules.py +0 -0
  224. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/sandbox.py +0 -0
  225. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/settings.py +0 -0
  226. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/commands/types.py +0 -0
  227. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/config/__init__.py +0 -0
  228. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/config/paths.py +0 -0
  229. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/config/plan_file.py +0 -0
  230. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/config/settings.py +0 -0
  231. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/coordinator/__init__.py +0 -0
  232. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/coordinator/agent_definitions.py +0 -0
  233. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/coordinator/coordinator_mode.py +0 -0
  234. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/engine/__init__.py +0 -0
  235. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/engine/cost_tracker.py +0 -0
  236. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/engine/messages.py +0 -0
  237. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/engine/query.py +0 -0
  238. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/engine/query_engine.py +0 -0
  239. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/engine/stream_events.py +0 -0
  240. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/hooks/events.py +0 -0
  241. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/hooks/executor.py +0 -0
  242. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/hooks/hot_reload.py +0 -0
  243. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/hooks/loader.py +0 -0
  244. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/hooks/register_hooks.py +0 -0
  245. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/hooks/schemas.py +0 -0
  246. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/hooks/session_hooks.py +0 -0
  247. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/hooks/types.py +0 -0
  248. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/hooks/utils.py +0 -0
  249. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/mcp/client.py +0 -0
  250. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/mcp/config.py +0 -0
  251. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/mcp/types.py +0 -0
  252. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/memory/__init__.py +0 -0
  253. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/memory/manager.py +0 -0
  254. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/memory/memdir.py +0 -0
  255. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/memory/paths.py +0 -0
  256. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/memory/scan.py +0 -0
  257. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/memory/search.py +0 -0
  258. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/memory/types.py +0 -0
  259. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/output_styles/__init__.py +0 -0
  260. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/output_styles/loader.py +0 -0
  261. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/permissions/__init__.py +0 -0
  262. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/permissions/checker.py +0 -0
  263. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/permissions/loader.py +0 -0
  264. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/permissions/modes.py +0 -0
  265. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/permissions/schemas.py +0 -0
  266. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/platforms.py +0 -0
  267. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/plugins/installer.py +0 -0
  268. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/plugins/loader.py +0 -0
  269. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/plugins/options.py +0 -0
  270. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/plugins/schemas.py +0 -0
  271. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/plugins/types.py +0 -0
  272. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/prompts/__init__.py +0 -0
  273. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/prompts/channel_hints.py +0 -0
  274. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/prompts/claudemd.py +0 -0
  275. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/prompts/context.py +0 -0
  276. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/prompts/environment.py +0 -0
  277. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/prompts/system_prompt.py +0 -0
  278. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/sandbox/__init__.py +0 -0
  279. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/sandbox/adapter.py +0 -0
  280. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/sandbox/platforms/__init__.py +0 -0
  281. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/sandbox/platforms/base.py +0 -0
  282. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/sandbox/platforms/linux.py +0 -0
  283. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/sandbox/platforms/macos.py +0 -0
  284. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/sandbox/platforms/windows.py +0 -0
  285. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/sandbox/proxy/__init__.py +0 -0
  286. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/sandbox/proxy/env_vars.py +0 -0
  287. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/sandbox/runtime.py +0 -0
  288. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/sandbox/symlink_protection.py +0 -0
  289. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/sandbox/utils.py +0 -0
  290. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/sandbox/violation_store.py +0 -0
  291. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/__init__.py +0 -0
  292. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/compact/__init__.py +0 -0
  293. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/compact/auto_compact.py +0 -0
  294. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/compact/compact_core.py +0 -0
  295. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/compact/compact_prompt.py +0 -0
  296. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/compact/constants.py +0 -0
  297. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/compact/message_ops.py +0 -0
  298. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/compact/microcompact.py +0 -0
  299. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/compact/models.py +0 -0
  300. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/compact/token_utils.py +0 -0
  301. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/cron.py +0 -0
  302. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/cron_scheduler.py +0 -0
  303. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/file_history.py +0 -0
  304. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/lsp/__init__.py +0 -0
  305. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/lsp/client.py +0 -0
  306. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/lsp/config.py +0 -0
  307. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/lsp/manager.py +0 -0
  308. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/lsp/types.py +0 -0
  309. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/session_storage.py +0 -0
  310. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/services/token_estimation.py +0 -0
  311. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/skills/bundled/__init__.py +0 -0
  312. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/batch.md +0 -0
  313. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/debug.md +0 -0
  314. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/loop.md +0 -0
  315. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/remember.md +0 -0
  316. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/simplify.md +0 -0
  317. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/skillify.md +0 -0
  318. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/stuck.md +0 -0
  319. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/update-config.md +0 -0
  320. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/skills/bundled/content/verify.md +0 -0
  321. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/skills/loader.py +0 -0
  322. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/skills/registry.py +0 -0
  323. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/skills/types.py +0 -0
  324. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/state/__init__.py +0 -0
  325. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/state/app_state.py +0 -0
  326. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/state/store.py +0 -0
  327. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/swarm/__init__.py +0 -0
  328. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/swarm/agent_executor.py +0 -0
  329. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/swarm/in_process.py +0 -0
  330. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/swarm/subprocess_backend.py +0 -0
  331. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/swarm/team_helpers.py +0 -0
  332. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/swarm/types.py +0 -0
  333. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/swarm/worktree.py +0 -0
  334. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tasks/__init__.py +0 -0
  335. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tasks/local_agent_task.py +0 -0
  336. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tasks/local_shell_task.py +0 -0
  337. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tasks/manager.py +0 -0
  338. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tasks/stop_task.py +0 -0
  339. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tasks/types.py +0 -0
  340. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/__init__.py +0 -0
  341. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/agent_tool.py +0 -0
  342. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/ask_user_question_tool.py +0 -0
  343. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/base.py +0 -0
  344. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/bash_tool.py +0 -0
  345. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/config_tool.py +0 -0
  346. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/cron_tool.py +0 -0
  347. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/enter_plan_mode_tool.py +0 -0
  348. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/enter_worktree_tool.py +0 -0
  349. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/exit_plan_mode_tool.py +0 -0
  350. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/exit_worktree_tool.py +0 -0
  351. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/file_edit_tool.py +0 -0
  352. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/file_read_tool.py +0 -0
  353. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/file_write_tool.py +0 -0
  354. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/glob_tool.py +0 -0
  355. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/grep_tool.py +0 -0
  356. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/list_mcp_resources_tool.py +0 -0
  357. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/lsp_formatters.py +0 -0
  358. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/lsp_schemas.py +0 -0
  359. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/lsp_tool.py +0 -0
  360. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/mcp_auth_tool.py +0 -0
  361. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/mcp_tool.py +0 -0
  362. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/notebook_edit_tool.py +0 -0
  363. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/powershell_tool.py +0 -0
  364. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/read_mcp_resource_tool.py +0 -0
  365. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/repl_tool.py +0 -0
  366. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/send_message_tool.py +0 -0
  367. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/shell_common.py +0 -0
  368. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/skill_tool.py +0 -0
  369. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/sleep_tool.py +0 -0
  370. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/structured_output_tool.py +0 -0
  371. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/task_create_tool.py +0 -0
  372. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/task_get_tool.py +0 -0
  373. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/task_list_tool.py +0 -0
  374. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/task_output_tool.py +0 -0
  375. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/task_stop_tool.py +0 -0
  376. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/task_update_tool.py +0 -0
  377. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/team_create_tool.py +0 -0
  378. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/team_delete_tool.py +0 -0
  379. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/todo_write_tool.py +0 -0
  380. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/tool_search_tool.py +0 -0
  381. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/web_fetch_tool.py +0 -0
  382. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/tools/web_search_tool.py +0 -0
  383. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/__init__.py +0 -0
  384. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/app.py +0 -0
  385. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/backend_host.py +0 -0
  386. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/input.py +0 -0
  387. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/output.py +0 -0
  388. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/permission_dialog.py +0 -0
  389. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/permission_store.py +0 -0
  390. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/protocol.py +0 -0
  391. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/react_launcher.py +0 -0
  392. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/textual_app.py +0 -0
  393. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/web/__init__.py +0 -0
  394. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/web/server.py +0 -0
  395. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/ui/web/ws_web_api.py +0 -0
  396. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/utils/__init__.py +0 -0
  397. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/utils/atomic_write.py +0 -0
  398. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/utils/file_state_cache.py +0 -0
  399. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/utils/ripgrep.py +0 -0
  400. {illusion_code-0.2.9 → illusion_code-0.2.11}/src/illusion/utils/shell.py +0 -0
  401. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/__init__.py +0 -0
  402. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/api/test_anthropic_client.py +0 -0
  403. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/api/test_client.py +0 -0
  404. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/api/test_codex_client.py +0 -0
  405. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/api/test_effort.py +0 -0
  406. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/api/test_fallback/346/217/220/347/244/272.py" +0 -0
  407. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/api/test_openai_client.py +0 -0
  408. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/__init__.py +0 -0
  409. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/feishu/__init__.py +0 -0
  410. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/feishu/test_adapter.py +0 -0
  411. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/feishu/test_commands.py +0 -0
  412. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/feishu/test_session_map.py +0 -0
  413. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/test_base.py +0 -0
  414. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/test_base_commands.py +0 -0
  415. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/test_config.py +0 -0
  416. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/test_pid.py +0 -0
  417. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/test_tool_registration.py +0 -0
  418. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/tools/__init__.py +0 -0
  419. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/tools/test_feishu_doc.py +0 -0
  420. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/tools/test_feishu_drive.py +0 -0
  421. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/weixin/__init__.py +0 -0
  422. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/weixin/test_adapter.py +0 -0
  423. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/weixin/test_config.py +0 -0
  424. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/weixin/test_ilink_api.py +0 -0
  425. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/channels/weixin/test_session_map.py +0 -0
  426. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/commands/init/__init__.py +0 -0
  427. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/commands/init/test_claudemd.py +0 -0
  428. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/commands/init/test_orchestrator.py +0 -0
  429. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/commands/init/test_scanner.py +0 -0
  430. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/commands/init/test_sections.py +0 -0
  431. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/commands/test_effort_command.py +0 -0
  432. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/config/test_i18n.py +0 -0
  433. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/config/test_settings.py +0 -0
  434. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/conftest.py +0 -0
  435. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/engine/test_query_engine.py +0 -0
  436. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/fixtures/fake_mcp_server.py +0 -0
  437. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/integration/test_effort_integration.py +0 -0
  438. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/services/lsp/test_lsp_client.py +0 -0
  439. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/services/lsp/test_lsp_config.py +0 -0
  440. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/services/lsp/test_lsp_manager.py +0 -0
  441. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/services/lsp/test_lsp_types.py +0 -0
  442. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_api/__init__.py +0 -0
  443. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_api/test_client.py +0 -0
  444. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_api/test_codex_client.py +0 -0
  445. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_api/test_compat.py +0 -0
  446. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_api/test_openai_client.py +0 -0
  447. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_auth/test_external.py +0 -0
  448. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_bridge/test_core.py +0 -0
  449. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_bridge/test_session_flow.py +0 -0
  450. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_commands/__init__.py +0 -0
  451. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_commands/test_cli.py +0 -0
  452. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_commands/test_command_flows.py +0 -0
  453. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_commands/test_registry.py +0 -0
  454. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_config/__init__.py +0 -0
  455. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_config/test_paths.py +0 -0
  456. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_config/test_settings.py +0 -0
  457. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_coordinator/test_agent_definitions.py +0 -0
  458. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_coordinator/test_coordinator_mode.py +0 -0
  459. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_engine/__init__.py +0 -0
  460. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_engine/test_media_block.py +0 -0
  461. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_engine/test_query_engine.py +0 -0
  462. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_engine/test_tool_result_media.py +0 -0
  463. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_hooks/__init__.py +0 -0
  464. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_hooks/test_executor.py +0 -0
  465. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_hooks/test_loader_permissions.py +0 -0
  466. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_hooks_skills_plugins_real.py +0 -0
  467. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_mcp/__init__.py +0 -0
  468. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_mcp/test_config_permissions.py +0 -0
  469. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_mcp/test_integration.py +0 -0
  470. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_mcp/test_stdio_flow.py +0 -0
  471. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_memory/__init__.py +0 -0
  472. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_memory/test_manager_permissions.py +0 -0
  473. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_memory/test_memdir.py +0 -0
  474. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_merged_prs_on_autoagent.py +0 -0
  475. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_permissions/__init__.py +0 -0
  476. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_permissions/test_checker.py +0 -0
  477. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_permissions/test_loader.py +0 -0
  478. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_permissions/test_project_permissions.py +0 -0
  479. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_platforms.py +0 -0
  480. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_plugins/__init__.py +0 -0
  481. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_plugins/test_lifecycle_flow.py +0 -0
  482. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_plugins/test_loader.py +0 -0
  483. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_plugins/test_loader_permissions.py +0 -0
  484. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_prompts/__init__.py +0 -0
  485. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_prompts/test_claudemd.py +0 -0
  486. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_prompts/test_claudemd_permissions.py +0 -0
  487. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_prompts/test_environment.py +0 -0
  488. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_prompts/test_system_prompt.py +0 -0
  489. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_qq_channel.py +0 -0
  490. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_real_large_tasks.py +0 -0
  491. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_sandbox/test_adapter.py +0 -0
  492. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_sandbox/test_config_schema.py +0 -0
  493. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_sandbox/test_platform_linux.py +0 -0
  494. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_sandbox/test_platform_macos.py +0 -0
  495. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_sandbox/test_platform_windows.py +0 -0
  496. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_sandbox/test_proxy_env_vars.py +0 -0
  497. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_sandbox/test_runtime.py +0 -0
  498. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_sandbox/test_symlink_protection.py +0 -0
  499. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_sandbox/test_utils.py +0 -0
  500. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_sandbox/test_violation_store.py +0 -0
  501. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_scripts/test_sync_version.py +0 -0
  502. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_services/test_compact.py +0 -0
  503. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_services/test_cron.py +0 -0
  504. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_services/test_cron_scheduler.py +0 -0
  505. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_services/test_session_storage.py +0 -0
  506. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_skills/test_loader.py +0 -0
  507. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_skills/test_loader_permissions.py +0 -0
  508. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_swarm/__init__.py +0 -0
  509. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_swarm/test_agent_executor.py +0 -0
  510. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_swarm/test_imports.py +0 -0
  511. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_swarm/test_in_process.py +0 -0
  512. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_swarm/test_types.py +0 -0
  513. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_swarm/test_worktree.py +0 -0
  514. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tasks/test_manager.py +0 -0
  515. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tools/__init__.py +0 -0
  516. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tools/test_agent_tool.py +0 -0
  517. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tools/test_core_tools.py +0 -0
  518. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tools/test_file_read_media.py +0 -0
  519. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tools/test_glob_tool.py +0 -0
  520. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tools/test_grep_tool.py +0 -0
  521. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tools/test_integration.py +0 -0
  522. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tools/test_integration_flows.py +0 -0
  523. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tools/test_mcp_auth_tool.py +0 -0
  524. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tools/test_ripgrep.py +0 -0
  525. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tools/test_shell_common.py +0 -0
  526. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tools/test_task_tools.py +0 -0
  527. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tools/test_team_tools.py +0 -0
  528. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_tools/test_web_fetch_tool.py +0 -0
  529. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_ui/__init__.py +0 -0
  530. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_ui/test_modes.py +0 -0
  531. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_ui/test_permission_store.py +0 -0
  532. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_ui/test_react_backend.py +0 -0
  533. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_ui/test_react_launcher.py +0 -0
  534. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_ui/test_textual_app.py +0 -0
  535. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_untested_features.py +0 -0
  536. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/test_utils/test_shell.py +0 -0
  537. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/ui/test_backend_host.py +0 -0
  538. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/ui/test_protocol_web.py +0 -0
  539. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/ui/test_web_api.py +0 -0
  540. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/unit/__init__.py +0 -0
  541. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/unit/test_channel_hints.py +0 -0
  542. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/unit/test_cross_channel.py +0 -0
  543. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/unit/test_delivery.py +0 -0
  544. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/unit/test_feishu_streaming.py +0 -0
  545. {illusion_code-0.2.9 → illusion_code-0.2.11}/tests/unit/test_media_tools.py +0 -0
  546. {illusion_code-0.2.9 → 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.9
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.9",
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.9",
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.9"
27
+ "version": "0.2.11"
28
28
  }
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  /** 当前版本号 */
9
- export const VERSION = '0.2.9';
9
+ export const VERSION = '0.2.11';
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@illusion/web",
3
- "version": "0.2.9",
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.9",
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.9",
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.9';
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.9"
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.9"
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
 
@@ -173,6 +175,68 @@ def kill_channel_daemon(proc: "subprocess.Popen[bytes] | None") -> None:
173
175
  pass
174
176
 
175
177
 
178
+ def is_channel_daemon_running() -> bool:
179
+ """检查渠道守护进程是否正在运行(通过 PID 文件,不依赖 proc 引用)
180
+
181
+ 用于退出时判断是否需要询问用户是否一同退出渠道。
182
+
183
+ Returns:
184
+ bool: 守护进程在运行返回 True
185
+ """
186
+ from illusion.config.paths import get_channels_data_dir
187
+ from illusion.channels.pid import PidFile
188
+ pid_file = PidFile(get_channels_data_dir() / "daemon.pid")
189
+ return pid_file.is_running()
190
+
191
+
192
+ def stop_channel_daemon_by_pid() -> bool:
193
+ """通过 PID 文件停止渠道守护进程(不依赖 proc 引用)
194
+
195
+ 供退出时交互式确认使用:无论当前进程是否是 spawn 者,
196
+ 都可以通过 PID 文件停止守护进程。
197
+
198
+ Windows 上用 taskkill /T /F 终止整个进程树(守护进程可能 spawn 了
199
+ aiohttp/WS 子线程,单独 TerminateProcess 可能留下孤儿线程)。
200
+ Unix 上用 SIGTERM 终止进程组。
201
+
202
+ Returns:
203
+ bool: 成功停止返回 True,守护进程不存在或已停止返回 False
204
+ """
205
+ from illusion.config.paths import get_channels_data_dir
206
+ from illusion.channels.pid import PidFile, read_pid
207
+
208
+ pid_file = PidFile(get_channels_data_dir() / "daemon.pid")
209
+ if not pid_file.is_running():
210
+ pid_file.release()
211
+ return False
212
+
213
+ old_pid = read_pid(pid_file.path)
214
+ if old_pid is not None:
215
+ try:
216
+ if os.name == "nt":
217
+ # Windows: 用 taskkill /T /F 终止整个进程树
218
+ # /T = 终止子进程,/F = 强制终止
219
+ import subprocess as _sp
220
+ _sp.run(
221
+ ["taskkill", "/PID", str(old_pid), "/T", "/F"],
222
+ capture_output=True, timeout=5,
223
+ )
224
+ else:
225
+ # Unix: 用 SIGTERM 终止进程组
226
+ import signal
227
+ os.kill(old_pid, signal.SIGTERM)
228
+ except (OSError, ProcessLookupError, Exception): # noqa: BLE001
229
+ pass
230
+ # 等待进程退出,最多 3 秒
231
+ for _ in range(30):
232
+ if not pid_file.is_running():
233
+ break
234
+ import time as _time
235
+ _time.sleep(0.1)
236
+ pid_file.release()
237
+ return True
238
+
239
+
176
240
  class ChannelRunner:
177
241
  """渠道消息接入 agent 的运行器
178
242
 
@@ -210,6 +274,8 @@ class ChannelRunner:
210
274
  # 按 chat_id 串行化 agent turn,避免并行消息导致会话历史覆盖
211
275
  # (同一会话连发多条消息时,M2/M3 排队等 M1 完成后再跑)
212
276
  self._chat_locks: dict[str, asyncio.Lock] = {}
277
+ # 当前正在运行的 agent task(按 chat_id 索引),供 /stop 中断
278
+ self._active_agent_tasks: dict[str, asyncio.Task[None]] = {}
213
279
  self._stop = False
214
280
 
215
281
  def _get_chat_lock(self, chat_id: str) -> asyncio.Lock:
@@ -254,20 +320,6 @@ class ChannelRunner:
254
320
  Args:
255
321
  msg: 入站消息
256
322
  """
257
- # 检查 /delete 信号:先执行 /new(清所有会话+发确认),再处理消息
258
- if self.session_store.check_signal():
259
- for path in self.session_store.data_dir.glob("*.json"):
260
- try:
261
- path.unlink()
262
- except OSError:
263
- pass
264
- from illusion.config.i18n import t as _t
265
- # 统一使用 cmd_new,避免渠道专属文案不一致
266
- await self.channel.send_text(
267
- msg.chat_id, _t("cmd_new"), reply_to=msg.message_id,
268
- )
269
- self.session_store.clear_signal()
270
-
271
323
  # 1. 待回复的权限/询问——不加锁,让回复立即送达
272
324
  # (agent turn 持锁等待回复时,下一条消息作为回复立即 set_result,
273
325
  # 不会因锁阻塞导致 300s 超时)
@@ -277,6 +329,13 @@ class ChannelRunner:
277
329
  fut.set_result(msg.text)
278
330
  return
279
331
 
332
+ # /stop 命令:立即中断当前 chat_id 正在运行的 agent task,不排队等锁
333
+ # 必须在 _chat_locks 之前处理,否则会卡在串行队列里等到 agent 完成才生效
334
+ text = msg.text.strip()
335
+ if text.lower() == "/stop":
336
+ await self._handle_stop(msg)
337
+ return
338
+
280
339
  # 2/3. 斜杠命令 + agent turn:按 chat_id 串行化
281
340
  async with self._get_chat_lock(msg.chat_id):
282
341
  # 进入锁后再次检查 pending_replies:前一个 agent turn 可能
@@ -293,41 +352,74 @@ class ChannelRunner:
293
352
  return
294
353
 
295
354
  # 3. 跑 agent
355
+ # 将当前 task 注册到 _active_agent_tasks,供 /stop 中断
356
+ current_task = asyncio.current_task()
357
+ if current_task is not None:
358
+ self._active_agent_tasks[msg.chat_id] = current_task
296
359
  try:
297
360
  await self._run_agent(msg)
361
+ except asyncio.CancelledError:
362
+ # /stop 取消:agent 已中断,发提示消息
363
+ from illusion.config.i18n import t as _t
364
+ logger.info("agent 任务被 /stop 中断: chat_id=%s", msg.chat_id)
365
+ try:
366
+ await self.channel.send_text(
367
+ msg.chat_id, _t("cmd_stop_done"),
368
+ reply_to=msg.message_id,
369
+ )
370
+ except Exception: # noqa: BLE001
371
+ pass
372
+ raise
298
373
  except Exception as exc: # noqa: BLE001
299
374
  logger.exception("处理渠道消息异常: %s", exc)
300
375
  try:
301
376
  await self.channel.send_text(msg.chat_id, f"❌ 处理失败: {str(exc)[:100]}")
302
377
  except Exception: # noqa: BLE001
303
378
  pass
379
+ finally:
380
+ # 清理 task 注册(无论正常完成、异常还是取消)
381
+ self._active_agent_tasks.pop(msg.chat_id, None)
304
382
 
305
383
  def _get_command_handler(self) -> Any:
306
384
  """按渠道类型返回对应的斜杠命令处理器
307
385
 
386
+ 遍历 ChannelRegistry,匹配 adapter_class 后调用 command_handler_factory。
387
+
308
388
  Returns:
309
389
  BaseCommandHandler 实例或 None(未知渠道)
310
390
  """
311
- from illusion.channels.feishu.adapter import FeishuChannel
312
- from illusion.channels.feishu.commands import FeishuCommandHandler
313
- if isinstance(self.channel, FeishuChannel):
314
- return FeishuCommandHandler(self.channel, self.session_store)
315
- try:
316
- from illusion.channels.weixin.adapter import WeixinChannel
317
- from illusion.channels.weixin.commands import WeixinCommandHandler
318
- if isinstance(self.channel, WeixinChannel):
319
- return WeixinCommandHandler(self.channel, self.session_store)
320
- except ImportError:
321
- pass # 微信模块不可用时跳过
322
- try:
323
- from illusion.channels.qq.adapter import QQChannel
324
- from illusion.channels.qq.commands import QQCommandHandler
325
- if isinstance(self.channel, QQChannel):
326
- return QQCommandHandler(self.channel, self.session_store)
327
- except ImportError:
328
- 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)
329
396
  return None
330
397
 
398
+ async def _handle_stop(self, msg: "InboundMessage") -> None:
399
+ """处理 /stop 命令:中断当前 chat_id 正在运行的 agent 任务
400
+
401
+ 不加 _chat_locks 锁,立即取消正在运行的 agent task。
402
+ 如果没有正在运行的任务,回复提示"无正在执行的任务"。
403
+
404
+ Args:
405
+ msg: /stop 命令消息
406
+ """
407
+ from illusion.config.i18n import t as _t
408
+
409
+ task = self._active_agent_tasks.get(msg.chat_id)
410
+ if task is None or task.done():
411
+ # 无正在运行的任务
412
+ await self.channel.send_text(
413
+ msg.chat_id, _t("cmd_stop_no_task"),
414
+ reply_to=msg.message_id,
415
+ )
416
+ return
417
+
418
+ # 取消任务:触发 CancelledError,_run_agent 的 except 块清理流式控制器
419
+ # _handle_message 的 except CancelledError 块发送"已中断"提示
420
+ task.cancel()
421
+ logger.info("/stop 已取消 agent 任务: chat_id=%s", msg.chat_id)
422
+
331
423
  def _build_channel_tools(self, msg: "InboundMessage") -> list[Any]:
332
424
  """构造渠道内置工具列表
333
425
 
@@ -429,6 +521,14 @@ class ChannelRunner:
429
521
  key = self.session_store.build_session_key(msg)
430
522
  session = self.session_store.get_or_create(key, msg.user_id, msg.chat_type)
431
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
+
432
532
  # 检测渠道是否支持消息编辑(仅飞书支持卡片 patch)
433
533
  from illusion.channels.feishu.adapter import FeishuChannel
434
534
  from illusion.channels.qq.adapter import QQChannel
@@ -482,18 +582,12 @@ class ChannelRunner:
482
582
  await streaming_controller.start()
483
583
  elif qq_c2c_streaming and qq_channel is not None:
484
584
  # QQ C2C:用 stream_messages API 流式(首次有文本时才启动)
485
- # 确保 token 已获取
486
- if not qq_channel._token:
487
- from illusion.channels.qq.api import ensure_token
488
- qq_channel._token = await ensure_token(
489
- qq_channel._session,
490
- qq_channel.config.app_id,
491
- qq_channel.config.client_secret,
492
- )
585
+ # 确保 token 已获取(通过 _get_token,重连后自动刷新)
586
+ token = await qq_channel._get_token()
493
587
  from illusion.channels.qq.streaming import QQStreamingController
494
588
  qq_streaming_controller = QQStreamingController(
495
589
  session=qq_channel._session,
496
- token=qq_channel._token,
590
+ token=token,
497
591
  openid=msg.chat_id,
498
592
  msg_id=msg.message_id,
499
593
  )
@@ -613,6 +707,20 @@ class ChannelRunner:
613
707
  logger.warning("渠道会话持久化失败: %s", exc)
614
708
  else:
615
709
  logger.warning("无法从 bundle.engine 获取会话历史,跳过持久化")
710
+ except asyncio.CancelledError:
711
+ # /stop 中断:清理流式控制器后重新抛出,让上层 _handle_message 发提示
712
+ logger.info("agent 任务被取消: chat_id=%s", msg.chat_id)
713
+ if supports_edit and streaming_controller:
714
+ try:
715
+ await streaming_controller.error("已中断")
716
+ except Exception: # noqa: BLE001
717
+ pass
718
+ elif qq_streaming_controller:
719
+ try:
720
+ await qq_streaming_controller.abort("已中断")
721
+ except Exception: # noqa: BLE001
722
+ pass
723
+ raise
616
724
  except Exception as exc:
617
725
  logger.exception("agent 处理异常")
618
726
  if supports_edit and streaming_controller:
@@ -757,10 +865,8 @@ def _create_session_store(
757
865
  ) -> Any:
758
866
  """根据渠道类型创建对应的 SessionStore
759
867
 
760
- 飞书 FeishuSessionStore
761
- QQ → QQSessionStore
762
- 微信 → WeixinSessionStore
763
- 未知 → FeishuSessionStore(向后兼容)
868
+ 遍历 ChannelRegistry,匹配 adapter_class 后调用 session_store_factory。
869
+ 未知渠道回退到 FeishuSessionStore(向后兼容)。
764
870
 
765
871
  Args:
766
872
  channel: 渠道实例
@@ -770,30 +876,13 @@ def _create_session_store(
770
876
  Returns:
771
877
  对应渠道的 SessionStore 实例
772
878
  """
773
- from illusion.channels.feishu.adapter import FeishuChannel
774
- if isinstance(channel, FeishuChannel):
775
- from illusion.channels.feishu.session_map import FeishuSessionStore
776
- return FeishuSessionStore(
777
- data_dir=data_dir,
778
- group_sessions_per_user=group_sessions_per_user,
779
- )
780
- try:
781
- from illusion.channels.qq.adapter import QQChannel
782
- if isinstance(channel, QQChannel):
783
- from illusion.channels.qq.session_map import QQSessionStore
784
- return QQSessionStore(
785
- data_dir=data_dir,
786
- 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
787
885
  )
788
- except ImportError:
789
- pass
790
- try:
791
- from illusion.channels.weixin.adapter import WeixinChannel
792
- if isinstance(channel, WeixinChannel):
793
- from illusion.channels.weixin.session_map import WeixinSessionStore
794
- return WeixinSessionStore(data_dir=data_dir)
795
- except ImportError:
796
- pass
797
886
  # 未知渠道回退到飞书(向后兼容)
798
887
  from illusion.channels.feishu.session_map import FeishuSessionStore
799
888
  return FeishuSessionStore(
@@ -80,6 +80,10 @@ class BaseCommandHandler:
80
80
  elif cmd == "new":
81
81
  self.session_store.clear(key)
82
82
  await self._reply(msg, t("cmd_new"))
83
+ elif cmd == "stop":
84
+ # /stop 在 ChannelRunner._handle_message 开头已被拦截处理,
85
+ # 不会走到这里。此分支仅作为防御性兜底(如 PC 终端直接调用)
86
+ await self._reply(msg, t("cmd_stop_no_task"))
83
87
  elif cmd == "model":
84
88
  await self._cmd_model(msg, key, args)
85
89
  elif cmd == "sessions":
@@ -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