illusion-code 0.2.9__tar.gz → 0.2.10__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 (537) hide show
  1. {illusion_code-0.2.9 → illusion_code-0.2.10}/PKG-INFO +1 -1
  2. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/package-lock.json +2 -2
  3. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/package.json +1 -1
  4. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/version.ts +1 -1
  5. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/package-lock.json +2 -2
  6. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/package.json +1 -1
  7. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/version.ts +1 -1
  8. {illusion_code-0.2.9 → illusion_code-0.2.10}/pyproject.toml +1 -1
  9. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/__init__.py +1 -1
  10. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/__init__.py +132 -0
  11. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/base_commands.py +4 -0
  12. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/serve.py +31 -0
  13. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/cli.py +82 -12
  14. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/config/i18n.py +8 -1
  15. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/web/ws_host.py +5 -0
  16. {illusion_code-0.2.9 → illusion_code-0.2.10}/.github/workflows/publish.yml +0 -0
  17. {illusion_code-0.2.9 → illusion_code-0.2.10}/.gitignore +0 -0
  18. {illusion_code-0.2.9 → illusion_code-0.2.10}/.python-version +0 -0
  19. {illusion_code-0.2.9 → illusion_code-0.2.10}/LICENSE +0 -0
  20. {illusion_code-0.2.9 → illusion_code-0.2.10}/README.md +0 -0
  21. {illusion_code-0.2.9 → illusion_code-0.2.10}/README.zh-CN.md +0 -0
  22. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/architecture.md +0 -0
  23. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/channels.md +0 -0
  24. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/commands.md +0 -0
  25. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/extensions.md +0 -0
  26. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/getting-started.md +0 -0
  27. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/introduction.md +0 -0
  28. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/project-files.md +0 -0
  29. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/settings.md +0 -0
  30. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/images/IllusionCode.png +0 -0
  31. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/images/image1.png +0 -0
  32. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/images/image2.png +0 -0
  33. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/architecture.md +0 -0
  34. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/channels.md +0 -0
  35. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/commands.md +0 -0
  36. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/extensions.md +0 -0
  37. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/getting-started.md +0 -0
  38. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/introduction.md +0 -0
  39. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/project-files.md +0 -0
  40. {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/settings.md +0 -0
  41. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/build.mjs +0 -0
  42. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/App.tsx +0 -0
  43. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/CommandPicker.tsx +0 -0
  44. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/Composer.tsx +0 -0
  45. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/ComposerController.tsx +0 -0
  46. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/ConversationView.tsx +0 -0
  47. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/Footer.tsx +0 -0
  48. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/MarkdownContent.tsx +0 -0
  49. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/MarkdownTable.tsx +0 -0
  50. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/ModalHost.tsx +0 -0
  51. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/MultilineTextInput.tsx +0 -0
  52. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/PromptInput.tsx +0 -0
  53. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/QuestionNavigationBar.tsx +0 -0
  54. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/QuestionPreviewBox.tsx +0 -0
  55. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/SelectModal.tsx +0 -0
  56. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/SidePanel.tsx +0 -0
  57. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/Spinner.tsx +0 -0
  58. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/StatusBar.tsx +0 -0
  59. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/SwarmPanel.tsx +0 -0
  60. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/TodoPanel.tsx +0 -0
  61. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/ToolCallDisplay.tsx +0 -0
  62. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/TranscriptPane.tsx +0 -0
  63. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/WelcomeBanner.tsx +0 -0
  64. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/hooks/useAnimationFrame.ts +0 -0
  65. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/hooks/useBackendSession.ts +0 -0
  66. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/hooks/useBlink.ts +0 -0
  67. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/hooks/useQuestionState.ts +0 -0
  68. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/hooks/useTerminalSize.ts +0 -0
  69. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/i18n.ts +0 -0
  70. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/index.tsx +0 -0
  71. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/theme/ThemeContext.tsx +0 -0
  72. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/theme/builtinThemes.ts +0 -0
  73. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/ToolInterface.ts +0 -0
  74. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/AgentTool.ts +0 -0
  75. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/BashTool.ts +0 -0
  76. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/CronTool.ts +0 -0
  77. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/EditTool.ts +0 -0
  78. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/GenericTool.ts +0 -0
  79. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/LspTool.ts +0 -0
  80. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/McpTool.ts +0 -0
  81. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/NotebookTool.ts +0 -0
  82. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/PlanTool.ts +0 -0
  83. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/ReadTool.ts +0 -0
  84. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/SearchTool.ts +0 -0
  85. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/SkillTool.ts +0 -0
  86. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/TaskTool.ts +0 -0
  87. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/WebTool.ts +0 -0
  88. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/WorktreeTool.ts +0 -0
  89. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/WriteTool.ts +0 -0
  90. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/registry.ts +0 -0
  91. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/types.ts +0 -0
  92. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/utils/markdown.ts +0 -0
  93. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/utils/thinking.ts +0 -0
  94. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/tsconfig.json +0 -0
  95. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/index.html +0 -0
  96. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/postcss.config.js +0 -0
  97. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/App.tsx +0 -0
  98. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/ChatArea.tsx +0 -0
  99. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/ErrorBoundary.tsx +0 -0
  100. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/MessageBubble.tsx +0 -0
  101. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/ModalCard.tsx +0 -0
  102. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/PromptInput.tsx +0 -0
  103. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/RightPanel.tsx +0 -0
  104. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/Sidebar.tsx +0 -0
  105. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/TodoPanel.tsx +0 -0
  106. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/Toolbar.tsx +0 -0
  107. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/WelcomeScreen.tsx +0 -0
  108. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/hooks/useTheme.ts +0 -0
  109. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/hooks/useWebSocketSession.ts +0 -0
  110. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/i18n.ts +0 -0
  111. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/index.css +0 -0
  112. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/main.tsx +0 -0
  113. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/remarkSuperscript.ts +0 -0
  114. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/types/protocol.ts +0 -0
  115. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/utils/toolDisplayName.ts +0 -0
  116. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/vite-env.d.ts +0 -0
  117. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/tailwind.config.js +0 -0
  118. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/tsconfig.json +0 -0
  119. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/tsconfig.node.json +0 -0
  120. {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/vite.config.ts +0 -0
  121. {illusion_code-0.2.9 → illusion_code-0.2.10}/scripts/build_frontend.py +0 -0
  122. {illusion_code-0.2.9 → illusion_code-0.2.10}/scripts/hatch_build.py +0 -0
  123. {illusion_code-0.2.9 → illusion_code-0.2.10}/scripts/publish.py +0 -0
  124. {illusion_code-0.2.9 → illusion_code-0.2.10}/scripts/sync_version.py +0 -0
  125. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/__main__.py +0 -0
  126. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/__init__.py +0 -0
  127. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/client.py +0 -0
  128. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/codex_client.py +0 -0
  129. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/compat.py +0 -0
  130. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/effort.py +0 -0
  131. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/errors.py +0 -0
  132. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/openai_client.py +0 -0
  133. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/provider.py +0 -0
  134. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/registry.py +0 -0
  135. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/usage.py +0 -0
  136. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/auth/__init__.py +0 -0
  137. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/auth/codex_oauth.py +0 -0
  138. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/auth/copilot.py +0 -0
  139. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/auth/external.py +0 -0
  140. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/auth/flows.py +0 -0
  141. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/auth/manager.py +0 -0
  142. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/auth/storage.py +0 -0
  143. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/bridge/__init__.py +0 -0
  144. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/bridge/manager.py +0 -0
  145. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/bridge/session_runner.py +0 -0
  146. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/bridge/types.py +0 -0
  147. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/bridge/work_secret.py +0 -0
  148. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/base.py +0 -0
  149. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/config.py +0 -0
  150. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/delivery.py +0 -0
  151. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/feishu/__init__.py +0 -0
  152. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/feishu/adapter.py +0 -0
  153. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/feishu/commands.py +0 -0
  154. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/feishu/messaging.py +0 -0
  155. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/feishu/session_map.py +0 -0
  156. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/feishu/streaming.py +0 -0
  157. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/feishu/ws_client.py +0 -0
  158. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/pid.py +0 -0
  159. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/qq/__init__.py +0 -0
  160. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/qq/adapter.py +0 -0
  161. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/qq/api.py +0 -0
  162. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/qq/commands.py +0 -0
  163. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/qq/session_map.py +0 -0
  164. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/qq/streaming.py +0 -0
  165. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/qq/ws_client.py +0 -0
  166. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/tools/__init__.py +0 -0
  167. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/tools/cross_channel.py +0 -0
  168. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/tools/feishu_doc.py +0 -0
  169. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/tools/feishu_drive.py +0 -0
  170. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/tools/media.py +0 -0
  171. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/weixin/__init__.py +0 -0
  172. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/weixin/adapter.py +0 -0
  173. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/weixin/commands.py +0 -0
  174. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/weixin/ilink_api.py +0 -0
  175. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/weixin/session_map.py +0 -0
  176. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/__init__.py +0 -0
  177. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/auth.py +0 -0
  178. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/bridge.py +0 -0
  179. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/context.py +0 -0
  180. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/git.py +0 -0
  181. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/helpers.py +0 -0
  182. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/__init__.py +0 -0
  183. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/analysis/__init__.py +0 -0
  184. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/analysis/architecture.py +0 -0
  185. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/analysis/conventions.py +0 -0
  186. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/analysis/dependencies.py +0 -0
  187. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/analysis/key_modules.py +0 -0
  188. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/extraction/__init__.py +0 -0
  189. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/extraction/lsp_symbols.py +0 -0
  190. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/extraction/readme.py +0 -0
  191. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/extraction/scanner.py +0 -0
  192. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/generation/__init__.py +0 -0
  193. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/generation/claudemd.py +0 -0
  194. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/generation/illusionmd.py +0 -0
  195. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/generation/memory_template.py +0 -0
  196. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/generation/rules.py +0 -0
  197. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/generation/sections.py +0 -0
  198. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/orchestrator.py +0 -0
  199. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/types.py +0 -0
  200. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/mcp.py +0 -0
  201. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/memory.py +0 -0
  202. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/misc.py +0 -0
  203. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/model.py +0 -0
  204. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/plugin.py +0 -0
  205. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/registry.py +0 -0
  206. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/rules.py +0 -0
  207. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/sandbox.py +0 -0
  208. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/session.py +0 -0
  209. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/settings.py +0 -0
  210. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/types.py +0 -0
  211. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/config/__init__.py +0 -0
  212. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/config/paths.py +0 -0
  213. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/config/plan_file.py +0 -0
  214. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/config/settings.py +0 -0
  215. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/coordinator/__init__.py +0 -0
  216. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/coordinator/agent_definitions.py +0 -0
  217. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/coordinator/coordinator_mode.py +0 -0
  218. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/engine/__init__.py +0 -0
  219. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/engine/cost_tracker.py +0 -0
  220. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/engine/messages.py +0 -0
  221. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/engine/query.py +0 -0
  222. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/engine/query_engine.py +0 -0
  223. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/engine/stream_events.py +0 -0
  224. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/__init__.py +0 -0
  225. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/events.py +0 -0
  226. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/executor.py +0 -0
  227. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/hot_reload.py +0 -0
  228. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/loader.py +0 -0
  229. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/register_hooks.py +0 -0
  230. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/schemas.py +0 -0
  231. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/session_hooks.py +0 -0
  232. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/types.py +0 -0
  233. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/utils.py +0 -0
  234. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/mcp/__init__.py +0 -0
  235. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/mcp/client.py +0 -0
  236. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/mcp/config.py +0 -0
  237. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/mcp/types.py +0 -0
  238. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/memory/__init__.py +0 -0
  239. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/memory/manager.py +0 -0
  240. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/memory/memdir.py +0 -0
  241. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/memory/paths.py +0 -0
  242. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/memory/scan.py +0 -0
  243. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/memory/search.py +0 -0
  244. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/memory/types.py +0 -0
  245. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/output_styles/__init__.py +0 -0
  246. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/output_styles/loader.py +0 -0
  247. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/permissions/__init__.py +0 -0
  248. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/permissions/checker.py +0 -0
  249. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/permissions/loader.py +0 -0
  250. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/permissions/modes.py +0 -0
  251. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/permissions/schemas.py +0 -0
  252. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/platforms.py +0 -0
  253. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/plugins/__init__.py +0 -0
  254. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/plugins/installer.py +0 -0
  255. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/plugins/loader.py +0 -0
  256. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/plugins/options.py +0 -0
  257. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/plugins/schemas.py +0 -0
  258. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/plugins/types.py +0 -0
  259. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/prompts/__init__.py +0 -0
  260. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/prompts/channel_hints.py +0 -0
  261. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/prompts/claudemd.py +0 -0
  262. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/prompts/context.py +0 -0
  263. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/prompts/environment.py +0 -0
  264. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/prompts/system_prompt.py +0 -0
  265. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/__init__.py +0 -0
  266. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/adapter.py +0 -0
  267. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/platforms/__init__.py +0 -0
  268. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/platforms/base.py +0 -0
  269. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/platforms/linux.py +0 -0
  270. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/platforms/macos.py +0 -0
  271. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/platforms/windows.py +0 -0
  272. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/proxy/__init__.py +0 -0
  273. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/proxy/env_vars.py +0 -0
  274. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/runtime.py +0 -0
  275. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/symlink_protection.py +0 -0
  276. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/utils.py +0 -0
  277. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/violation_store.py +0 -0
  278. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/__init__.py +0 -0
  279. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/__init__.py +0 -0
  280. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/auto_compact.py +0 -0
  281. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/compact_core.py +0 -0
  282. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/compact_prompt.py +0 -0
  283. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/constants.py +0 -0
  284. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/message_ops.py +0 -0
  285. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/microcompact.py +0 -0
  286. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/models.py +0 -0
  287. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/token_utils.py +0 -0
  288. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/cron.py +0 -0
  289. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/cron_scheduler.py +0 -0
  290. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/file_history.py +0 -0
  291. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/lsp/__init__.py +0 -0
  292. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/lsp/client.py +0 -0
  293. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/lsp/config.py +0 -0
  294. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/lsp/manager.py +0 -0
  295. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/lsp/types.py +0 -0
  296. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/session_storage.py +0 -0
  297. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/token_estimation.py +0 -0
  298. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/__init__.py +0 -0
  299. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/__init__.py +0 -0
  300. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/batch.md +0 -0
  301. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/debug.md +0 -0
  302. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/loop.md +0 -0
  303. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/remember.md +0 -0
  304. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/simplify.md +0 -0
  305. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/skillify.md +0 -0
  306. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/stuck.md +0 -0
  307. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/update-config.md +0 -0
  308. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/verify.md +0 -0
  309. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/loader.py +0 -0
  310. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/registry.py +0 -0
  311. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/types.py +0 -0
  312. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/state/__init__.py +0 -0
  313. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/state/app_state.py +0 -0
  314. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/state/store.py +0 -0
  315. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/swarm/__init__.py +0 -0
  316. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/swarm/agent_executor.py +0 -0
  317. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/swarm/in_process.py +0 -0
  318. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/swarm/subprocess_backend.py +0 -0
  319. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/swarm/team_helpers.py +0 -0
  320. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/swarm/types.py +0 -0
  321. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/swarm/worktree.py +0 -0
  322. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tasks/__init__.py +0 -0
  323. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tasks/local_agent_task.py +0 -0
  324. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tasks/local_shell_task.py +0 -0
  325. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tasks/manager.py +0 -0
  326. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tasks/stop_task.py +0 -0
  327. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tasks/todo_sync.py +0 -0
  328. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tasks/types.py +0 -0
  329. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/__init__.py +0 -0
  330. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/agent_tool.py +0 -0
  331. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/ask_user_question_tool.py +0 -0
  332. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/base.py +0 -0
  333. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/bash_tool.py +0 -0
  334. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/config_tool.py +0 -0
  335. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/cron_tool.py +0 -0
  336. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/enter_plan_mode_tool.py +0 -0
  337. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/enter_worktree_tool.py +0 -0
  338. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/exit_plan_mode_tool.py +0 -0
  339. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/exit_worktree_tool.py +0 -0
  340. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/file_edit_tool.py +0 -0
  341. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/file_read_tool.py +0 -0
  342. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/file_write_tool.py +0 -0
  343. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/glob_tool.py +0 -0
  344. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/grep_tool.py +0 -0
  345. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/list_mcp_resources_tool.py +0 -0
  346. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/lsp_formatters.py +0 -0
  347. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/lsp_schemas.py +0 -0
  348. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/lsp_tool.py +0 -0
  349. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/mcp_auth_tool.py +0 -0
  350. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/mcp_tool.py +0 -0
  351. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/notebook_edit_tool.py +0 -0
  352. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/powershell_tool.py +0 -0
  353. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/read_mcp_resource_tool.py +0 -0
  354. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/repl_tool.py +0 -0
  355. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/send_message_tool.py +0 -0
  356. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/shell_common.py +0 -0
  357. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/skill_tool.py +0 -0
  358. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/sleep_tool.py +0 -0
  359. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/structured_output_tool.py +0 -0
  360. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/task_create_tool.py +0 -0
  361. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/task_get_tool.py +0 -0
  362. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/task_list_tool.py +0 -0
  363. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/task_output_tool.py +0 -0
  364. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/task_stop_tool.py +0 -0
  365. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/task_update_tool.py +0 -0
  366. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/team_create_tool.py +0 -0
  367. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/team_delete_tool.py +0 -0
  368. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/todo_write_tool.py +0 -0
  369. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/tool_search_tool.py +0 -0
  370. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/web_fetch_tool.py +0 -0
  371. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/web_search_tool.py +0 -0
  372. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/__init__.py +0 -0
  373. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/app.py +0 -0
  374. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/backend_host.py +0 -0
  375. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/input.py +0 -0
  376. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/output.py +0 -0
  377. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/permission_dialog.py +0 -0
  378. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/permission_store.py +0 -0
  379. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/protocol.py +0 -0
  380. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/react_launcher.py +0 -0
  381. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/runtime.py +0 -0
  382. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/textual_app.py +0 -0
  383. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/web/__init__.py +0 -0
  384. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/web/server.py +0 -0
  385. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/web/ws_web_api.py +0 -0
  386. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/utils/__init__.py +0 -0
  387. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/utils/atomic_write.py +0 -0
  388. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/utils/file_state_cache.py +0 -0
  389. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/utils/ripgrep.py +0 -0
  390. {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/utils/shell.py +0 -0
  391. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/__init__.py +0 -0
  392. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/api/test_anthropic_client.py +0 -0
  393. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/api/test_client.py +0 -0
  394. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/api/test_codex_client.py +0 -0
  395. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/api/test_effort.py +0 -0
  396. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/api/test_fallback/346/217/220/347/244/272.py" +0 -0
  397. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/api/test_openai_client.py +0 -0
  398. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/__init__.py +0 -0
  399. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/feishu/__init__.py +0 -0
  400. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/feishu/test_adapter.py +0 -0
  401. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/feishu/test_commands.py +0 -0
  402. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/feishu/test_session_map.py +0 -0
  403. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/test_base.py +0 -0
  404. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/test_base_commands.py +0 -0
  405. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/test_config.py +0 -0
  406. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/test_pid.py +0 -0
  407. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/test_tool_registration.py +0 -0
  408. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/tools/__init__.py +0 -0
  409. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/tools/test_feishu_doc.py +0 -0
  410. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/tools/test_feishu_drive.py +0 -0
  411. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/weixin/__init__.py +0 -0
  412. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/weixin/test_adapter.py +0 -0
  413. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/weixin/test_config.py +0 -0
  414. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/weixin/test_ilink_api.py +0 -0
  415. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/weixin/test_session_map.py +0 -0
  416. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/commands/init/__init__.py +0 -0
  417. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/commands/init/test_claudemd.py +0 -0
  418. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/commands/init/test_orchestrator.py +0 -0
  419. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/commands/init/test_scanner.py +0 -0
  420. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/commands/init/test_sections.py +0 -0
  421. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/commands/test_effort_command.py +0 -0
  422. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/config/test_i18n.py +0 -0
  423. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/config/test_settings.py +0 -0
  424. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/conftest.py +0 -0
  425. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/engine/test_query_engine.py +0 -0
  426. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/fixtures/fake_mcp_server.py +0 -0
  427. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/integration/test_effort_integration.py +0 -0
  428. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/services/lsp/test_lsp_client.py +0 -0
  429. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/services/lsp/test_lsp_config.py +0 -0
  430. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/services/lsp/test_lsp_manager.py +0 -0
  431. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/services/lsp/test_lsp_types.py +0 -0
  432. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_api/__init__.py +0 -0
  433. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_api/test_client.py +0 -0
  434. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_api/test_codex_client.py +0 -0
  435. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_api/test_compat.py +0 -0
  436. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_api/test_openai_client.py +0 -0
  437. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_auth/test_external.py +0 -0
  438. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_bridge/test_core.py +0 -0
  439. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_bridge/test_session_flow.py +0 -0
  440. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_commands/__init__.py +0 -0
  441. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_commands/test_cli.py +0 -0
  442. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_commands/test_command_flows.py +0 -0
  443. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_commands/test_registry.py +0 -0
  444. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_config/__init__.py +0 -0
  445. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_config/test_paths.py +0 -0
  446. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_config/test_settings.py +0 -0
  447. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_coordinator/test_agent_definitions.py +0 -0
  448. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_coordinator/test_coordinator_mode.py +0 -0
  449. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_engine/__init__.py +0 -0
  450. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_engine/test_media_block.py +0 -0
  451. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_engine/test_query_engine.py +0 -0
  452. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_engine/test_tool_result_media.py +0 -0
  453. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_hooks/__init__.py +0 -0
  454. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_hooks/test_executor.py +0 -0
  455. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_hooks/test_loader_permissions.py +0 -0
  456. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_hooks_skills_plugins_real.py +0 -0
  457. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_mcp/__init__.py +0 -0
  458. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_mcp/test_config_permissions.py +0 -0
  459. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_mcp/test_integration.py +0 -0
  460. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_mcp/test_stdio_flow.py +0 -0
  461. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_memory/__init__.py +0 -0
  462. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_memory/test_manager_permissions.py +0 -0
  463. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_memory/test_memdir.py +0 -0
  464. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_merged_prs_on_autoagent.py +0 -0
  465. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_permissions/__init__.py +0 -0
  466. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_permissions/test_checker.py +0 -0
  467. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_permissions/test_loader.py +0 -0
  468. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_permissions/test_project_permissions.py +0 -0
  469. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_platforms.py +0 -0
  470. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_plugins/__init__.py +0 -0
  471. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_plugins/test_lifecycle_flow.py +0 -0
  472. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_plugins/test_loader.py +0 -0
  473. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_plugins/test_loader_permissions.py +0 -0
  474. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_prompts/__init__.py +0 -0
  475. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_prompts/test_claudemd.py +0 -0
  476. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_prompts/test_claudemd_permissions.py +0 -0
  477. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_prompts/test_environment.py +0 -0
  478. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_prompts/test_system_prompt.py +0 -0
  479. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_qq_channel.py +0 -0
  480. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_real_large_tasks.py +0 -0
  481. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_adapter.py +0 -0
  482. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_config_schema.py +0 -0
  483. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_platform_linux.py +0 -0
  484. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_platform_macos.py +0 -0
  485. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_platform_windows.py +0 -0
  486. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_proxy_env_vars.py +0 -0
  487. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_runtime.py +0 -0
  488. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_symlink_protection.py +0 -0
  489. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_utils.py +0 -0
  490. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_violation_store.py +0 -0
  491. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_scripts/test_sync_version.py +0 -0
  492. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_services/test_compact.py +0 -0
  493. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_services/test_cron.py +0 -0
  494. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_services/test_cron_scheduler.py +0 -0
  495. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_services/test_session_storage.py +0 -0
  496. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_skills/test_loader.py +0 -0
  497. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_skills/test_loader_permissions.py +0 -0
  498. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_swarm/__init__.py +0 -0
  499. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_swarm/test_agent_executor.py +0 -0
  500. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_swarm/test_imports.py +0 -0
  501. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_swarm/test_in_process.py +0 -0
  502. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_swarm/test_types.py +0 -0
  503. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_swarm/test_worktree.py +0 -0
  504. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tasks/test_manager.py +0 -0
  505. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/__init__.py +0 -0
  506. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_agent_tool.py +0 -0
  507. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_core_tools.py +0 -0
  508. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_file_read_media.py +0 -0
  509. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_glob_tool.py +0 -0
  510. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_grep_tool.py +0 -0
  511. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_integration.py +0 -0
  512. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_integration_flows.py +0 -0
  513. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_mcp_auth_tool.py +0 -0
  514. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_ripgrep.py +0 -0
  515. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_shell_common.py +0 -0
  516. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_task_tools.py +0 -0
  517. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_team_tools.py +0 -0
  518. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_web_fetch_tool.py +0 -0
  519. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_ui/__init__.py +0 -0
  520. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_ui/test_modes.py +0 -0
  521. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_ui/test_permission_store.py +0 -0
  522. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_ui/test_react_backend.py +0 -0
  523. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_ui/test_react_launcher.py +0 -0
  524. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_ui/test_textual_app.py +0 -0
  525. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_untested_features.py +0 -0
  526. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_utils/test_shell.py +0 -0
  527. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/ui/test_backend_host.py +0 -0
  528. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/ui/test_protocol_web.py +0 -0
  529. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/ui/test_web_api.py +0 -0
  530. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/__init__.py +0 -0
  531. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/test_channel_hints.py +0 -0
  532. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/test_cross_channel.py +0 -0
  533. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/test_delivery.py +0 -0
  534. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/test_feishu_streaming.py +0 -0
  535. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/test_media_tools.py +0 -0
  536. {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/test_qq_streaming.py +0 -0
  537. {illusion_code-0.2.9 → illusion_code-0.2.10}/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.10
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.10",
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.10",
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.10"
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.10';
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@illusion/web",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
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.10",
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.10",
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.10';
@@ -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.10"
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.10"
@@ -173,6 +173,68 @@ def kill_channel_daemon(proc: "subprocess.Popen[bytes] | None") -> None:
173
173
  pass
174
174
 
175
175
 
176
+ def is_channel_daemon_running() -> bool:
177
+ """检查渠道守护进程是否正在运行(通过 PID 文件,不依赖 proc 引用)
178
+
179
+ 用于退出时判断是否需要询问用户是否一同退出渠道。
180
+
181
+ Returns:
182
+ bool: 守护进程在运行返回 True
183
+ """
184
+ from illusion.config.paths import get_channels_data_dir
185
+ from illusion.channels.pid import PidFile
186
+ pid_file = PidFile(get_channels_data_dir() / "daemon.pid")
187
+ return pid_file.is_running()
188
+
189
+
190
+ def stop_channel_daemon_by_pid() -> bool:
191
+ """通过 PID 文件停止渠道守护进程(不依赖 proc 引用)
192
+
193
+ 供退出时交互式确认使用:无论当前进程是否是 spawn 者,
194
+ 都可以通过 PID 文件停止守护进程。
195
+
196
+ Windows 上用 taskkill /T /F 终止整个进程树(守护进程可能 spawn 了
197
+ aiohttp/WS 子线程,单独 TerminateProcess 可能留下孤儿线程)。
198
+ Unix 上用 SIGTERM 终止进程组。
199
+
200
+ Returns:
201
+ bool: 成功停止返回 True,守护进程不存在或已停止返回 False
202
+ """
203
+ from illusion.config.paths import get_channels_data_dir
204
+ from illusion.channels.pid import PidFile, read_pid
205
+
206
+ pid_file = PidFile(get_channels_data_dir() / "daemon.pid")
207
+ if not pid_file.is_running():
208
+ pid_file.release()
209
+ return False
210
+
211
+ old_pid = read_pid(pid_file.path)
212
+ if old_pid is not None:
213
+ try:
214
+ if os.name == "nt":
215
+ # Windows: 用 taskkill /T /F 终止整个进程树
216
+ # /T = 终止子进程,/F = 强制终止
217
+ import subprocess as _sp
218
+ _sp.run(
219
+ ["taskkill", "/PID", str(old_pid), "/T", "/F"],
220
+ capture_output=True, timeout=5,
221
+ )
222
+ else:
223
+ # Unix: 用 SIGTERM 终止进程组
224
+ import signal
225
+ os.kill(old_pid, signal.SIGTERM)
226
+ except (OSError, ProcessLookupError, Exception): # noqa: BLE001
227
+ pass
228
+ # 等待进程退出,最多 3 秒
229
+ for _ in range(30):
230
+ if not pid_file.is_running():
231
+ break
232
+ import time as _time
233
+ _time.sleep(0.1)
234
+ pid_file.release()
235
+ return True
236
+
237
+
176
238
  class ChannelRunner:
177
239
  """渠道消息接入 agent 的运行器
178
240
 
@@ -210,6 +272,8 @@ class ChannelRunner:
210
272
  # 按 chat_id 串行化 agent turn,避免并行消息导致会话历史覆盖
211
273
  # (同一会话连发多条消息时,M2/M3 排队等 M1 完成后再跑)
212
274
  self._chat_locks: dict[str, asyncio.Lock] = {}
275
+ # 当前正在运行的 agent task(按 chat_id 索引),供 /stop 中断
276
+ self._active_agent_tasks: dict[str, asyncio.Task[None]] = {}
213
277
  self._stop = False
214
278
 
215
279
  def _get_chat_lock(self, chat_id: str) -> asyncio.Lock:
@@ -255,6 +319,8 @@ class ChannelRunner:
255
319
  msg: 入站消息
256
320
  """
257
321
  # 检查 /delete 信号:先执行 /new(清所有会话+发确认),再处理消息
322
+ # 信号触发后直接 return,避免继续走 try_handle 处理 /new 命令
323
+ # 导致"已开启新的对话"反馈消息发送两次
258
324
  if self.session_store.check_signal():
259
325
  for path in self.session_store.data_dir.glob("*.json"):
260
326
  try:
@@ -267,6 +333,7 @@ class ChannelRunner:
267
333
  msg.chat_id, _t("cmd_new"), reply_to=msg.message_id,
268
334
  )
269
335
  self.session_store.clear_signal()
336
+ return
270
337
 
271
338
  # 1. 待回复的权限/询问——不加锁,让回复立即送达
272
339
  # (agent turn 持锁等待回复时,下一条消息作为回复立即 set_result,
@@ -277,6 +344,13 @@ class ChannelRunner:
277
344
  fut.set_result(msg.text)
278
345
  return
279
346
 
347
+ # /stop 命令:立即中断当前 chat_id 正在运行的 agent task,不排队等锁
348
+ # 必须在 _chat_locks 之前处理,否则会卡在串行队列里等到 agent 完成才生效
349
+ text = msg.text.strip()
350
+ if text.lower() == "/stop":
351
+ await self._handle_stop(msg)
352
+ return
353
+
280
354
  # 2/3. 斜杠命令 + agent turn:按 chat_id 串行化
281
355
  async with self._get_chat_lock(msg.chat_id):
282
356
  # 进入锁后再次检查 pending_replies:前一个 agent turn 可能
@@ -293,14 +367,33 @@ class ChannelRunner:
293
367
  return
294
368
 
295
369
  # 3. 跑 agent
370
+ # 将当前 task 注册到 _active_agent_tasks,供 /stop 中断
371
+ current_task = asyncio.current_task()
372
+ if current_task is not None:
373
+ self._active_agent_tasks[msg.chat_id] = current_task
296
374
  try:
297
375
  await self._run_agent(msg)
376
+ except asyncio.CancelledError:
377
+ # /stop 取消:agent 已中断,发提示消息
378
+ from illusion.config.i18n import t as _t
379
+ logger.info("agent 任务被 /stop 中断: chat_id=%s", msg.chat_id)
380
+ try:
381
+ await self.channel.send_text(
382
+ msg.chat_id, _t("cmd_stop_done"),
383
+ reply_to=msg.message_id,
384
+ )
385
+ except Exception: # noqa: BLE001
386
+ pass
387
+ raise
298
388
  except Exception as exc: # noqa: BLE001
299
389
  logger.exception("处理渠道消息异常: %s", exc)
300
390
  try:
301
391
  await self.channel.send_text(msg.chat_id, f"❌ 处理失败: {str(exc)[:100]}")
302
392
  except Exception: # noqa: BLE001
303
393
  pass
394
+ finally:
395
+ # 清理 task 注册(无论正常完成、异常还是取消)
396
+ self._active_agent_tasks.pop(msg.chat_id, None)
304
397
 
305
398
  def _get_command_handler(self) -> Any:
306
399
  """按渠道类型返回对应的斜杠命令处理器
@@ -328,6 +421,31 @@ class ChannelRunner:
328
421
  pass # QQ 模块不可用时跳过
329
422
  return None
330
423
 
424
+ async def _handle_stop(self, msg: "InboundMessage") -> None:
425
+ """处理 /stop 命令:中断当前 chat_id 正在运行的 agent 任务
426
+
427
+ 不加 _chat_locks 锁,立即取消正在运行的 agent task。
428
+ 如果没有正在运行的任务,回复提示"无正在执行的任务"。
429
+
430
+ Args:
431
+ msg: /stop 命令消息
432
+ """
433
+ from illusion.config.i18n import t as _t
434
+
435
+ task = self._active_agent_tasks.get(msg.chat_id)
436
+ if task is None or task.done():
437
+ # 无正在运行的任务
438
+ await self.channel.send_text(
439
+ msg.chat_id, _t("cmd_stop_no_task"),
440
+ reply_to=msg.message_id,
441
+ )
442
+ return
443
+
444
+ # 取消任务:触发 CancelledError,_run_agent 的 except 块清理流式控制器
445
+ # _handle_message 的 except CancelledError 块发送"已中断"提示
446
+ task.cancel()
447
+ logger.info("/stop 已取消 agent 任务: chat_id=%s", msg.chat_id)
448
+
331
449
  def _build_channel_tools(self, msg: "InboundMessage") -> list[Any]:
332
450
  """构造渠道内置工具列表
333
451
 
@@ -613,6 +731,20 @@ class ChannelRunner:
613
731
  logger.warning("渠道会话持久化失败: %s", exc)
614
732
  else:
615
733
  logger.warning("无法从 bundle.engine 获取会话历史,跳过持久化")
734
+ except asyncio.CancelledError:
735
+ # /stop 中断:清理流式控制器后重新抛出,让上层 _handle_message 发提示
736
+ logger.info("agent 任务被取消: chat_id=%s", msg.chat_id)
737
+ if supports_edit and streaming_controller:
738
+ try:
739
+ await streaming_controller.error("已中断")
740
+ except Exception: # noqa: BLE001
741
+ pass
742
+ elif qq_streaming_controller:
743
+ try:
744
+ await qq_streaming_controller.abort("已中断")
745
+ except Exception: # noqa: BLE001
746
+ pass
747
+ raise
616
748
  except Exception as exc:
617
749
  logger.exception("agent 处理异常")
618
750
  if supports_edit and streaming_controller:
@@ -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":
@@ -32,6 +32,24 @@ def run_channel_serve() -> None:
32
32
  Windows 下 Ctrl+C 通过 KeyboardInterrupt 捕获,关闭后用 os._exit 确保退出
33
33
  (WS executor 线程可能无法干净终止)。
34
34
  """
35
+ # 启动前检查:若已有守护进程在运行(PID 文件指向存活进程),则拒绝启动
36
+ # 防止 maybe_spawn_channel_daemon 竞态条件导致两个守护进程同时运行
37
+ # (两个进程同时 spawn 时,PID 文件写入有竞态,可能都写入成功导致孤儿)
38
+ from illusion.config.paths import get_channels_data_dir
39
+ from illusion.channels.pid import PidFile, read_pid
40
+
41
+ data_dir = get_channels_data_dir()
42
+ pid_file = PidFile(data_dir / "daemon.pid")
43
+ if pid_file.is_running():
44
+ existing_pid = read_pid(pid_file.path) or 0
45
+ # 当前进程的 PID 与 PID 文件记录的不同 → 已有另一个守护进程在运行
46
+ if existing_pid and existing_pid != os.getpid():
47
+ print(
48
+ f"[channel] 守护进程已在运行 (PID={existing_pid}),拒绝重复启动。"
49
+ f" 若确信无进程在运行,请删除 {pid_file.path} 后重试。"
50
+ )
51
+ return
52
+
35
53
  cfg = load_channels_config()
36
54
  settings = _load_settings_safely()
37
55
 
@@ -101,6 +119,13 @@ def run_channel_serve() -> None:
101
119
  root_logger.addHandler(stream_handler)
102
120
  logger.info("渠道守护进程启动,日志文件: %s", log_path)
103
121
 
122
+ # 写入当前进程 PID 到 PID 文件(覆盖 maybe_spawn_channel_daemon 写入的 PID)
123
+ # 确保后续 maybe_spawn_channel_daemon 检查时能正确识别当前守护进程
124
+ try:
125
+ pid_file.acquire(os.getpid())
126
+ except Exception as exc: # noqa: BLE001
127
+ logger.warning("写入 daemon.pid 失败: %s", exc)
128
+
104
129
  try:
105
130
  asyncio.run(_serve_async(cfg, settings))
106
131
  except KeyboardInterrupt:
@@ -109,6 +134,12 @@ def run_channel_serve() -> None:
109
134
  print("\n收到中断信号,正在关闭...")
110
135
  # 关闭资源后强制退出(WS executor 线程可能阻塞 os.kill 无法终止)
111
136
  _force_shutdown()
137
+ finally:
138
+ # 退出时释放 PID 文件,避免 maybe_spawn_channel_daemon 误判为仍在运行
139
+ try:
140
+ pid_file.release()
141
+ except Exception: # noqa: BLE001
142
+ pass
112
143
 
113
144
 
114
145
  def _load_settings_safely() -> Any:
@@ -938,7 +938,6 @@ def web_start(
938
938
  typer.echo(_t("cwd_invalid", path=settings.working_directory), err=True)
939
939
 
940
940
  # 渠道自动激活:有 enabled 渠道时 spawn 守护进程(与 illusion 主命令一致)
941
- from illusion.channels import kill_channel_daemon
942
941
  _daemon_proc = None
943
942
  try:
944
943
  from illusion.channels import maybe_spawn_channel_daemon
@@ -947,8 +946,42 @@ def web_start(
947
946
  import logging
948
947
  logging.getLogger(__name__).warning("渠道自动激活失败: %s", exc)
949
948
 
949
+ # PC 端渠道感知:与 illusion 主命令一致,注入 channel_hint + channel_tools
950
+ # 让 web 端 LLM 也能看到已启用渠道并用跨渠道工具发文件
951
+ pc_channel_hint: str | None = None
952
+ pc_channel_tools: list[Any] | None = None
953
+ try:
954
+ from illusion.channels.config import load_channels_config
955
+ from illusion.prompts.channel_hints import (
956
+ get_channel_hint,
957
+ list_active_sessions,
958
+ )
959
+ _cfg = load_channels_config()
960
+ if _cfg.has_enabled_channels():
961
+ other_names = _cfg.enabled_channel_names()
962
+ _active = {
963
+ name: list_active_sessions(name, _cfg, limit=5)
964
+ for name in other_names
965
+ }
966
+ pc_channel_hint = get_channel_hint(
967
+ current_channel=None,
968
+ channels_config=_cfg,
969
+ active_sessions=_active,
970
+ )
971
+ # 注入跨渠道工具
972
+ from illusion.channels.tools.cross_channel import (
973
+ ListChannelSessionsTool,
974
+ SendToChannelTool,
975
+ )
976
+ pc_channel_tools = [ListChannelSessionsTool(_cfg), SendToChannelTool(_cfg)]
977
+ except Exception as exc: # noqa: BLE001
978
+ import logging
979
+ logging.getLogger(__name__).warning("PC 渠道感知加载失败: %s", exc)
980
+
950
981
  config = WebHostConfig(
951
982
  model=model,
983
+ channel_hint=pc_channel_hint,
984
+ channel_tools=pc_channel_tools,
952
985
  )
953
986
 
954
987
  app = create_app(dev=dev, host_config=config)
@@ -959,15 +992,29 @@ def web_start(
959
992
  import webbrowser
960
993
  threading.Thread(target=webbrowser.open, args=(url,), daemon=True).start()
961
994
 
962
- # ctrl+c / 正常退出时终止渠道守护进程,避免孤儿进程
995
+ # ctrl+c / 正常退出时询问是否终止渠道守护进程(与 illusion 主命令一致)
996
+ # ctrl+c 触发时 force=True 直接停止守护进程
997
+ # 正常退出时询问用户(y/回车默认杀灭)
998
+ _interrupted = False
963
999
  try:
964
1000
  uvicorn.run(app, host=host, port=port, log_level="warning")
1001
+ except KeyboardInterrupt:
1002
+ _interrupted = True
965
1003
  finally:
966
- if _daemon_proc is not None:
967
- try:
968
- kill_channel_daemon(_daemon_proc)
969
- except Exception: # noqa: BLE001
970
- pass
1004
+ try:
1005
+ from illusion.channels import is_channel_daemon_running, stop_channel_daemon_by_pid
1006
+ if is_channel_daemon_running():
1007
+ if _interrupted:
1008
+ # ctrl+c 触发:直接停止守护进程
1009
+ stop_channel_daemon_by_pid()
1010
+ else:
1011
+ # 正常退出:询问用户,y/回车默认杀灭
1012
+ from illusion.config.i18n import t
1013
+ answer = input(t("channel_daemon_exit_prompt") + " ").strip().lower()
1014
+ if answer in ("", "y", "yes"):
1015
+ stop_channel_daemon_by_pid()
1016
+ except Exception: # noqa: BLE001
1017
+ pass
971
1018
 
972
1019
 
973
1020
  # ---- update 子命令 ----
@@ -1306,7 +1353,6 @@ def main(
1306
1353
  )
1307
1354
 
1308
1355
  # 渠道自动激活:有 enabled 渠道时 spawn 守护进程
1309
- from illusion.channels import kill_channel_daemon
1310
1356
  _daemon_proc = None
1311
1357
  try:
1312
1358
  from illusion.channels import maybe_spawn_channel_daemon
@@ -1315,10 +1361,29 @@ def main(
1315
1361
  import logging
1316
1362
  logging.getLogger(__name__).warning("渠道自动激活失败: %s", exc)
1317
1363
 
1318
- def _kill_channel_daemon() -> None:
1319
- """退出时终止渠道守护进程(复用模块级函数,与 web 命令一致)"""
1364
+ def _kill_channel_daemon(*, force: bool = False) -> None:
1365
+ """退出时询问是否终止渠道守护进程
1366
+
1367
+ illusion 和 illusion web 可能同时运行并共享同一个守护进程。
1368
+ 退出时如果守护进程仍在运行,询问用户是否一同退出,避免
1369
+ 一个进程退出导致另一个进程失去渠道服务。
1370
+
1371
+ Args:
1372
+ force: True 时直接停止守护进程(用于 ctrl+c 场景),False 时询问用户
1373
+ """
1320
1374
  try:
1321
- kill_channel_daemon(_daemon_proc)
1375
+ from illusion.channels import is_channel_daemon_running, stop_channel_daemon_by_pid
1376
+ if not is_channel_daemon_running():
1377
+ return
1378
+ if force:
1379
+ # ctrl+c 触发的退出:直接停止守护进程(用户已通过 ctrl+c 表达退出意图)
1380
+ stop_channel_daemon_by_pid()
1381
+ return
1382
+ # 正常退出时询问用户;y 或直接回车(空输入)默认杀灭
1383
+ from illusion.config.i18n import t
1384
+ answer = input(t("channel_daemon_exit_prompt") + " ").strip().lower()
1385
+ if answer in ("", "y", "yes"):
1386
+ stop_channel_daemon_by_pid()
1322
1387
  except Exception: # noqa: BLE001
1323
1388
  pass
1324
1389
 
@@ -1448,6 +1513,9 @@ def main(
1448
1513
  return
1449
1514
 
1450
1515
  # 启动交互式 REPL 会话
1516
+ # ctrl+c 触发 KeyboardInterrupt 时,force=True 直接停止守护进程
1517
+ # 正常退出时,询问用户是否一同退出渠道(y/回车默认杀灭)
1518
+ _interrupted = False
1451
1519
  try:
1452
1520
  asyncio.run(
1453
1521
  run_repl(
@@ -1465,8 +1533,10 @@ def main(
1465
1533
  channel_tools=pc_channel_tools,
1466
1534
  )
1467
1535
  )
1536
+ except KeyboardInterrupt:
1537
+ _interrupted = True
1468
1538
  finally:
1469
- _kill_channel_daemon()
1539
+ _kill_channel_daemon(force=_interrupted)
1470
1540
 
1471
1541
 
1472
1542
  # ---- channel 子命令 ----
@@ -209,10 +209,12 @@ MESSAGES: dict[str, dict[str, str]] = {
209
209
  "channel_disconnected": {"zh-CN": "未连接", "en-US": "disconnected"},
210
210
  # --- 飞书侧(用户在飞书中看到)---
211
211
  "feishu_thinking": {"zh-CN": "illusion code 正在思考中...", "en-US": "illusion code is thinking..."},
212
- "feishu_cmd_help": {"zh-CN": "可用命令: /help /clear /new /delete /sessions /resume /detach /model", "en-US": "Commands: /help /clear /new /delete /sessions /resume /detach /model"},
212
+ "feishu_cmd_help": {"zh-CN": "可用命令: /help /clear /new /delete /stop /sessions /resume /detach /model", "en-US": "Commands: /help /clear /new /delete /stop /sessions /resume /detach /model"},
213
213
  "feishu_cmd_cleared": {"zh-CN": "飞书会话已清空,开始新对话。", "en-US": "Feishu session cleared, starting fresh."},
214
214
  # --- 通用渠道命令文案(不限渠道)---
215
215
  "cmd_new": {"zh-CN": "已开启新的会话。", "en-US": "New session started."},
216
+ "cmd_stop_no_task": {"zh-CN": "当前没有正在执行的任务。", "en-US": "No running task to stop."},
217
+ "cmd_stop_done": {"zh-CN": "已中断当前任务。", "en-US": "Task interrupted."},
216
218
  "feishu_cmd_sessions_title": {"zh-CN": "本地未完成会话:", "en-US": "Local unfinished sessions:"},
217
219
  "feishu_cmd_no_sessions": {"zh-CN": "没有本地会话可恢复。", "en-US": "No local sessions to resume."},
218
220
  "feishu_cmd_resumed": {"zh-CN": "已恢复本地会话({n} 条历史),继续吧。", "en-US": "Resumed local session ({n} messages), continue."},
@@ -242,6 +244,11 @@ MESSAGES: dict[str, dict[str, str]] = {
242
244
  "zh-CN": "请先访问 https://q.qq.com 注册机器人应用,获取 App ID 和 Client Secret",
243
245
  "en-US": "Please visit https://q.qq.com to register a bot app and obtain App ID and Client Secret",
244
246
  },
247
+ # 渠道守护进程退出确认
248
+ "channel_daemon_exit_prompt": {
249
+ "zh-CN": "渠道守护进程仍在运行,是否一同退出?(y/N)",
250
+ "en-US": "Channel daemon is still running. Stop it too? (y/N)",
251
+ },
245
252
  }
246
253
 
247
254
  # --- 命令描述翻译 ---
@@ -106,6 +106,9 @@ class WebHostConfig:
106
106
  restore_session_id: str | None = None
107
107
  enforce_max_turns: bool = True
108
108
  effort: str | None = None
109
+ # 渠道感知:与 illusion 主命令一致,注入渠道提示词和跨渠道工具
110
+ channel_hint: str | None = None
111
+ channel_tools: list[Any] | None = None
109
112
 
110
113
 
111
114
  class WebBackendHost:
@@ -168,6 +171,8 @@ class WebBackendHost:
168
171
  ask_user_prompt=self._ask_question, # type: ignore[arg-type]
169
172
  plan_approval_prompt=self._ask_plan_approval,
170
173
  effort=self._config.effort,
174
+ channel_hint=self._config.channel_hint,
175
+ channel_tools=self._config.channel_tools,
171
176
  )
172
177
  except Exception as exc:
173
178
  log.exception("Failed to build runtime")
File without changes
File without changes
File without changes