illusion-code 0.1.5__tar.gz → 0.1.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (440) hide show
  1. {illusion_code-0.1.5 → illusion_code-0.1.6}/PKG-INFO +3 -3
  2. {illusion_code-0.1.5 → illusion_code-0.1.6}/README.md +2 -2
  3. {illusion_code-0.1.5 → illusion_code-0.1.6}/README.zh-CN.md +2 -2
  4. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/package-lock.json +2 -2
  5. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/package.json +1 -1
  6. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/App.tsx +7 -147
  7. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/ModalHost.tsx +175 -61
  8. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/version.ts +1 -1
  9. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/package-lock.json +2 -2
  10. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/package.json +1 -1
  11. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/components/ModalCard.tsx +135 -27
  12. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/version.ts +1 -1
  13. {illusion_code-0.1.5 → illusion_code-0.1.6}/pyproject.toml +1 -1
  14. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/__init__.py +1 -1
  15. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/auth/codex_oauth.py +4 -4
  16. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/helpers.py +12 -1
  17. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/config/i18n.py +7 -0
  18. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/permissions/checker.py +3 -1
  19. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/swarm/agent_executor.py +3 -12
  20. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/ui/backend_host.py +38 -36
  21. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/ui/protocol.py +0 -1
  22. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/ui/runtime.py +38 -8
  23. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/ui/web/ws_host.py +37 -33
  24. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/utils/ripgrep.py +10 -2
  25. {illusion_code-0.1.5 → illusion_code-0.1.6}/.github/workflows/publish.yml +0 -0
  26. {illusion_code-0.1.5 → illusion_code-0.1.6}/.gitignore +0 -0
  27. {illusion_code-0.1.5 → illusion_code-0.1.6}/.python-version +0 -0
  28. {illusion_code-0.1.5 → illusion_code-0.1.6}/LICENSE +0 -0
  29. {illusion_code-0.1.5 → illusion_code-0.1.6}/docs/images/image1.png +0 -0
  30. {illusion_code-0.1.5 → illusion_code-0.1.6}/docs/images/image2.png +0 -0
  31. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/build.mjs +0 -0
  32. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/CommandPicker.tsx +0 -0
  33. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/Composer.tsx +0 -0
  34. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/ComposerController.tsx +0 -0
  35. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/ConversationView.tsx +0 -0
  36. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/Footer.tsx +0 -0
  37. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/MarkdownContent.tsx +0 -0
  38. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/MarkdownTable.tsx +0 -0
  39. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/MultilineTextInput.tsx +0 -0
  40. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/PromptInput.tsx +0 -0
  41. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/SelectModal.tsx +0 -0
  42. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/SidePanel.tsx +0 -0
  43. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/Spinner.tsx +0 -0
  44. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/StatusBar.tsx +0 -0
  45. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/SwarmPanel.tsx +0 -0
  46. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/TodoPanel.tsx +0 -0
  47. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/ToolCallDisplay.tsx +0 -0
  48. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/TranscriptPane.tsx +0 -0
  49. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/components/WelcomeBanner.tsx +0 -0
  50. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/hooks/useAnimationFrame.ts +0 -0
  51. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/hooks/useBackendSession.ts +0 -0
  52. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/hooks/useBlink.ts +0 -0
  53. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/hooks/useTerminalSize.ts +0 -0
  54. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/i18n.ts +0 -0
  55. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/index.tsx +0 -0
  56. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/theme/ThemeContext.tsx +0 -0
  57. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/theme/builtinThemes.ts +0 -0
  58. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/ToolInterface.ts +0 -0
  59. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/AgentTool.ts +0 -0
  60. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/BashTool.ts +0 -0
  61. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/CronTool.ts +0 -0
  62. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/EditTool.ts +0 -0
  63. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/GenericTool.ts +0 -0
  64. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/LspTool.ts +0 -0
  65. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/McpTool.ts +0 -0
  66. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/NotebookTool.ts +0 -0
  67. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/PlanTool.ts +0 -0
  68. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/ReadTool.ts +0 -0
  69. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/SearchTool.ts +0 -0
  70. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/SkillTool.ts +0 -0
  71. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/TaskTool.ts +0 -0
  72. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/WebTool.ts +0 -0
  73. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/WorktreeTool.ts +0 -0
  74. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/implementations/WriteTool.ts +0 -0
  75. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/tools/registry.ts +0 -0
  76. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/types.ts +0 -0
  77. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/utils/markdown.ts +0 -0
  78. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/src/utils/thinking.ts +0 -0
  79. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/terminal/tsconfig.json +0 -0
  80. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/index.html +0 -0
  81. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/postcss.config.js +0 -0
  82. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/App.tsx +0 -0
  83. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/components/ChatArea.tsx +0 -0
  84. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/components/MessageBubble.tsx +0 -0
  85. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/components/PromptInput.tsx +0 -0
  86. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/components/RightPanel.tsx +0 -0
  87. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/components/Sidebar.tsx +0 -0
  88. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/components/TodoPanel.tsx +0 -0
  89. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/components/Toolbar.tsx +0 -0
  90. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/components/WelcomeScreen.tsx +0 -0
  91. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/hooks/useWebSocketSession.ts +0 -0
  92. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/i18n.ts +0 -0
  93. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/index.css +0 -0
  94. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/main.tsx +0 -0
  95. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/remarkSuperscript.ts +0 -0
  96. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/types/protocol.ts +0 -0
  97. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/src/vite-env.d.ts +0 -0
  98. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/tailwind.config.js +0 -0
  99. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/tsconfig.json +0 -0
  100. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/tsconfig.node.json +0 -0
  101. {illusion_code-0.1.5 → illusion_code-0.1.6}/frontend/web/vite.config.ts +0 -0
  102. {illusion_code-0.1.5 → illusion_code-0.1.6}/scripts/build_frontend.py +0 -0
  103. {illusion_code-0.1.5 → illusion_code-0.1.6}/scripts/hatch_build.py +0 -0
  104. {illusion_code-0.1.5 → illusion_code-0.1.6}/scripts/publish.py +0 -0
  105. {illusion_code-0.1.5 → illusion_code-0.1.6}/scripts/sync_version.py +0 -0
  106. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/__main__.py +0 -0
  107. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/api/__init__.py +0 -0
  108. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/api/client.py +0 -0
  109. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/api/codex_client.py +0 -0
  110. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/api/compat.py +0 -0
  111. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/api/effort.py +0 -0
  112. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/api/errors.py +0 -0
  113. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/api/openai_client.py +0 -0
  114. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/api/provider.py +0 -0
  115. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/api/registry.py +0 -0
  116. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/api/usage.py +0 -0
  117. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/auth/__init__.py +0 -0
  118. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/auth/copilot.py +0 -0
  119. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/auth/external.py +0 -0
  120. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/auth/flows.py +0 -0
  121. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/auth/manager.py +0 -0
  122. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/auth/storage.py +0 -0
  123. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/bridge/__init__.py +0 -0
  124. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/bridge/manager.py +0 -0
  125. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/bridge/session_runner.py +0 -0
  126. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/bridge/types.py +0 -0
  127. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/bridge/work_secret.py +0 -0
  128. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/cli.py +0 -0
  129. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/__init__.py +0 -0
  130. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/auth.py +0 -0
  131. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/bridge.py +0 -0
  132. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/context.py +0 -0
  133. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/git.py +0 -0
  134. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/__init__.py +0 -0
  135. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/analysis/__init__.py +0 -0
  136. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/analysis/architecture.py +0 -0
  137. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/analysis/conventions.py +0 -0
  138. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/analysis/dependencies.py +0 -0
  139. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/analysis/key_modules.py +0 -0
  140. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/extraction/__init__.py +0 -0
  141. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/extraction/lsp_symbols.py +0 -0
  142. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/extraction/readme.py +0 -0
  143. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/extraction/scanner.py +0 -0
  144. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/generation/__init__.py +0 -0
  145. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/generation/claudemd.py +0 -0
  146. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/generation/illusionmd.py +0 -0
  147. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/generation/memory_template.py +0 -0
  148. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/generation/rules.py +0 -0
  149. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/generation/sections.py +0 -0
  150. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/orchestrator.py +0 -0
  151. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/init/types.py +0 -0
  152. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/mcp.py +0 -0
  153. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/memory.py +0 -0
  154. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/misc.py +0 -0
  155. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/model.py +0 -0
  156. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/plugin.py +0 -0
  157. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/registry.py +0 -0
  158. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/rules.py +0 -0
  159. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/sandbox.py +0 -0
  160. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/session.py +0 -0
  161. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/settings.py +0 -0
  162. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/commands/types.py +0 -0
  163. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/config/__init__.py +0 -0
  164. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/config/paths.py +0 -0
  165. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/config/plan_file.py +0 -0
  166. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/config/settings.py +0 -0
  167. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/coordinator/__init__.py +0 -0
  168. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/coordinator/agent_definitions.py +0 -0
  169. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/coordinator/coordinator_mode.py +0 -0
  170. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/engine/__init__.py +0 -0
  171. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/engine/cost_tracker.py +0 -0
  172. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/engine/messages.py +0 -0
  173. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/engine/query.py +0 -0
  174. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/engine/query_engine.py +0 -0
  175. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/engine/stream_events.py +0 -0
  176. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/hooks/__init__.py +0 -0
  177. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/hooks/events.py +0 -0
  178. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/hooks/executor.py +0 -0
  179. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/hooks/hot_reload.py +0 -0
  180. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/hooks/loader.py +0 -0
  181. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/hooks/register_hooks.py +0 -0
  182. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/hooks/schemas.py +0 -0
  183. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/hooks/session_hooks.py +0 -0
  184. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/hooks/types.py +0 -0
  185. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/hooks/utils.py +0 -0
  186. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/mcp/__init__.py +0 -0
  187. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/mcp/client.py +0 -0
  188. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/mcp/config.py +0 -0
  189. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/mcp/types.py +0 -0
  190. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/memory/__init__.py +0 -0
  191. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/memory/manager.py +0 -0
  192. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/memory/memdir.py +0 -0
  193. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/memory/paths.py +0 -0
  194. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/memory/scan.py +0 -0
  195. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/memory/search.py +0 -0
  196. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/memory/types.py +0 -0
  197. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/output_styles/__init__.py +0 -0
  198. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/output_styles/loader.py +0 -0
  199. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/permissions/__init__.py +0 -0
  200. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/permissions/modes.py +0 -0
  201. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/platforms.py +0 -0
  202. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/plugins/__init__.py +0 -0
  203. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/plugins/installer.py +0 -0
  204. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/plugins/loader.py +0 -0
  205. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/plugins/options.py +0 -0
  206. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/plugins/schemas.py +0 -0
  207. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/plugins/types.py +0 -0
  208. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/prompts/__init__.py +0 -0
  209. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/prompts/claudemd.py +0 -0
  210. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/prompts/context.py +0 -0
  211. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/prompts/environment.py +0 -0
  212. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/prompts/system_prompt.py +0 -0
  213. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/sandbox/__init__.py +0 -0
  214. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/sandbox/adapter.py +0 -0
  215. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/sandbox/platforms/__init__.py +0 -0
  216. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/sandbox/platforms/base.py +0 -0
  217. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/sandbox/platforms/linux.py +0 -0
  218. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/sandbox/platforms/macos.py +0 -0
  219. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/sandbox/platforms/windows.py +0 -0
  220. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/sandbox/proxy/__init__.py +0 -0
  221. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/sandbox/proxy/env_vars.py +0 -0
  222. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/sandbox/runtime.py +0 -0
  223. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/sandbox/symlink_protection.py +0 -0
  224. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/sandbox/utils.py +0 -0
  225. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/sandbox/violation_store.py +0 -0
  226. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/__init__.py +0 -0
  227. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/compact/__init__.py +0 -0
  228. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/compact/auto_compact.py +0 -0
  229. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/compact/compact_core.py +0 -0
  230. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/compact/compact_prompt.py +0 -0
  231. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/compact/constants.py +0 -0
  232. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/compact/message_ops.py +0 -0
  233. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/compact/microcompact.py +0 -0
  234. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/compact/models.py +0 -0
  235. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/compact/token_utils.py +0 -0
  236. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/cron.py +0 -0
  237. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/cron_scheduler.py +0 -0
  238. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/file_history.py +0 -0
  239. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/lsp/__init__.py +0 -0
  240. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/lsp/client.py +0 -0
  241. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/lsp/config.py +0 -0
  242. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/lsp/manager.py +0 -0
  243. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/lsp/types.py +0 -0
  244. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/session_storage.py +0 -0
  245. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/services/token_estimation.py +0 -0
  246. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/__init__.py +0 -0
  247. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/bundled/__init__.py +0 -0
  248. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/bundled/content/batch.md +0 -0
  249. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/bundled/content/coding-guidelines.md +0 -0
  250. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/bundled/content/debug.md +0 -0
  251. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/bundled/content/loop.md +0 -0
  252. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/bundled/content/remember.md +0 -0
  253. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/bundled/content/simplify.md +0 -0
  254. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/bundled/content/skillify.md +0 -0
  255. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/bundled/content/stuck.md +0 -0
  256. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/bundled/content/update-config.md +0 -0
  257. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/bundled/content/verify.md +0 -0
  258. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/loader.py +0 -0
  259. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/registry.py +0 -0
  260. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/skills/types.py +0 -0
  261. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/state/__init__.py +0 -0
  262. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/state/app_state.py +0 -0
  263. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/state/store.py +0 -0
  264. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/swarm/__init__.py +0 -0
  265. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/swarm/in_process.py +0 -0
  266. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/swarm/subprocess_backend.py +0 -0
  267. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/swarm/team_helpers.py +0 -0
  268. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/swarm/types.py +0 -0
  269. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/swarm/worktree.py +0 -0
  270. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tasks/__init__.py +0 -0
  271. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tasks/local_agent_task.py +0 -0
  272. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tasks/local_shell_task.py +0 -0
  273. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tasks/manager.py +0 -0
  274. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tasks/stop_task.py +0 -0
  275. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tasks/types.py +0 -0
  276. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/__init__.py +0 -0
  277. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/agent_tool.py +0 -0
  278. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/ask_user_question_tool.py +0 -0
  279. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/base.py +0 -0
  280. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/bash_tool.py +0 -0
  281. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/config_tool.py +0 -0
  282. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/cron_tool.py +0 -0
  283. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/enter_plan_mode_tool.py +0 -0
  284. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/enter_worktree_tool.py +0 -0
  285. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/exit_plan_mode_tool.py +0 -0
  286. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/exit_worktree_tool.py +0 -0
  287. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/file_edit_tool.py +0 -0
  288. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/file_read_tool.py +0 -0
  289. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/file_write_tool.py +0 -0
  290. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/glob_tool.py +0 -0
  291. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/grep_tool.py +0 -0
  292. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/list_mcp_resources_tool.py +0 -0
  293. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/lsp_formatters.py +0 -0
  294. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/lsp_schemas.py +0 -0
  295. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/lsp_tool.py +0 -0
  296. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/mcp_auth_tool.py +0 -0
  297. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/mcp_tool.py +0 -0
  298. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/notebook_edit_tool.py +0 -0
  299. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/powershell_tool.py +0 -0
  300. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/read_mcp_resource_tool.py +0 -0
  301. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/repl_tool.py +0 -0
  302. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/send_message_tool.py +0 -0
  303. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/shell_common.py +0 -0
  304. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/skill_tool.py +0 -0
  305. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/sleep_tool.py +0 -0
  306. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/structured_output_tool.py +0 -0
  307. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/task_create_tool.py +0 -0
  308. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/task_get_tool.py +0 -0
  309. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/task_list_tool.py +0 -0
  310. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/task_output_tool.py +0 -0
  311. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/task_stop_tool.py +0 -0
  312. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/task_update_tool.py +0 -0
  313. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/team_create_tool.py +0 -0
  314. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/team_delete_tool.py +0 -0
  315. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/todo_write_tool.py +0 -0
  316. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/tool_search_tool.py +0 -0
  317. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/web_fetch_tool.py +0 -0
  318. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/tools/web_search_tool.py +0 -0
  319. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/ui/__init__.py +0 -0
  320. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/ui/app.py +0 -0
  321. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/ui/input.py +0 -0
  322. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/ui/output.py +0 -0
  323. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/ui/permission_dialog.py +0 -0
  324. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/ui/permission_store.py +0 -0
  325. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/ui/react_launcher.py +0 -0
  326. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/ui/textual_app.py +0 -0
  327. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/ui/web/__init__.py +0 -0
  328. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/ui/web/server.py +0 -0
  329. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/utils/__init__.py +0 -0
  330. {illusion_code-0.1.5 → illusion_code-0.1.6}/src/illusion/utils/shell.py +0 -0
  331. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/__init__.py +0 -0
  332. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/api/test_anthropic_client.py +0 -0
  333. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/api/test_client.py +0 -0
  334. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/api/test_codex_client.py +0 -0
  335. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/api/test_effort.py +0 -0
  336. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/api/test_fallback/346/217/220/347/244/272.py" +0 -0
  337. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/api/test_openai_client.py +0 -0
  338. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/commands/init/__init__.py +0 -0
  339. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/commands/init/test_claudemd.py +0 -0
  340. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/commands/init/test_orchestrator.py +0 -0
  341. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/commands/init/test_scanner.py +0 -0
  342. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/commands/init/test_sections.py +0 -0
  343. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/commands/test_effort_command.py +0 -0
  344. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/config/test_i18n.py +0 -0
  345. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/config/test_settings.py +0 -0
  346. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/conftest.py +0 -0
  347. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/engine/test_query_engine.py +0 -0
  348. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/fixtures/fake_mcp_server.py +0 -0
  349. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/integration/test_effort_integration.py +0 -0
  350. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/services/lsp/test_lsp_client.py +0 -0
  351. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/services/lsp/test_lsp_config.py +0 -0
  352. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/services/lsp/test_lsp_manager.py +0 -0
  353. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/services/lsp/test_lsp_types.py +0 -0
  354. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_api/__init__.py +0 -0
  355. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_api/test_client.py +0 -0
  356. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_api/test_codex_client.py +0 -0
  357. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_api/test_compat.py +0 -0
  358. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_api/test_openai_client.py +0 -0
  359. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_auth/test_external.py +0 -0
  360. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_bridge/test_core.py +0 -0
  361. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_bridge/test_session_flow.py +0 -0
  362. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_commands/__init__.py +0 -0
  363. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_commands/test_cli.py +0 -0
  364. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_commands/test_command_flows.py +0 -0
  365. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_commands/test_registry.py +0 -0
  366. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_config/__init__.py +0 -0
  367. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_config/test_paths.py +0 -0
  368. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_config/test_settings.py +0 -0
  369. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_coordinator/test_agent_definitions.py +0 -0
  370. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_coordinator/test_coordinator_mode.py +0 -0
  371. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_engine/__init__.py +0 -0
  372. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_engine/test_media_block.py +0 -0
  373. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_engine/test_query_engine.py +0 -0
  374. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_engine/test_tool_result_media.py +0 -0
  375. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_hooks/__init__.py +0 -0
  376. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_hooks/test_executor.py +0 -0
  377. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_hooks_skills_plugins_real.py +0 -0
  378. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_mcp/__init__.py +0 -0
  379. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_mcp/test_integration.py +0 -0
  380. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_mcp/test_stdio_flow.py +0 -0
  381. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_memory/__init__.py +0 -0
  382. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_memory/test_memdir.py +0 -0
  383. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_merged_prs_on_autoagent.py +0 -0
  384. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_permissions/__init__.py +0 -0
  385. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_permissions/test_checker.py +0 -0
  386. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_platforms.py +0 -0
  387. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_plugins/__init__.py +0 -0
  388. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_plugins/test_lifecycle_flow.py +0 -0
  389. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_plugins/test_loader.py +0 -0
  390. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_prompts/__init__.py +0 -0
  391. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_prompts/test_claudemd.py +0 -0
  392. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_prompts/test_environment.py +0 -0
  393. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_prompts/test_system_prompt.py +0 -0
  394. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_real_large_tasks.py +0 -0
  395. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_sandbox/test_adapter.py +0 -0
  396. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_sandbox/test_config_schema.py +0 -0
  397. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_sandbox/test_platform_linux.py +0 -0
  398. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_sandbox/test_platform_macos.py +0 -0
  399. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_sandbox/test_platform_windows.py +0 -0
  400. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_sandbox/test_proxy_env_vars.py +0 -0
  401. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_sandbox/test_runtime.py +0 -0
  402. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_sandbox/test_symlink_protection.py +0 -0
  403. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_sandbox/test_utils.py +0 -0
  404. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_sandbox/test_violation_store.py +0 -0
  405. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_scripts/test_sync_version.py +0 -0
  406. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_services/test_compact.py +0 -0
  407. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_services/test_cron.py +0 -0
  408. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_services/test_cron_scheduler.py +0 -0
  409. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_services/test_session_storage.py +0 -0
  410. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_skills/test_loader.py +0 -0
  411. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_swarm/__init__.py +0 -0
  412. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_swarm/test_agent_executor.py +0 -0
  413. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_swarm/test_imports.py +0 -0
  414. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_swarm/test_in_process.py +0 -0
  415. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_swarm/test_types.py +0 -0
  416. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_swarm/test_worktree.py +0 -0
  417. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tasks/test_manager.py +0 -0
  418. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tools/__init__.py +0 -0
  419. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tools/test_agent_tool.py +0 -0
  420. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tools/test_core_tools.py +0 -0
  421. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tools/test_file_read_media.py +0 -0
  422. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tools/test_glob_tool.py +0 -0
  423. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tools/test_grep_tool.py +0 -0
  424. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tools/test_integration.py +0 -0
  425. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tools/test_integration_flows.py +0 -0
  426. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tools/test_mcp_auth_tool.py +0 -0
  427. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tools/test_ripgrep.py +0 -0
  428. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tools/test_shell_common.py +0 -0
  429. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tools/test_task_tools.py +0 -0
  430. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tools/test_team_tools.py +0 -0
  431. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_tools/test_web_fetch_tool.py +0 -0
  432. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_ui/__init__.py +0 -0
  433. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_ui/test_modes.py +0 -0
  434. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_ui/test_permission_store.py +0 -0
  435. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_ui/test_react_backend.py +0 -0
  436. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_ui/test_react_launcher.py +0 -0
  437. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_ui/test_textual_app.py +0 -0
  438. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_untested_features.py +0 -0
  439. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/test_utils/test_shell.py +0 -0
  440. {illusion_code-0.1.5 → illusion_code-0.1.6}/tests/ui/test_backend_host.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: illusion-code
3
- Version: 0.1.5
3
+ Version: 0.1.6
4
4
  Summary: Open-source Python port of Claude Code - an AI-powered CLI coding assistant
5
5
  Project-URL: Homepage, https://github.com/YunTaiHua/illusion-code
6
6
  Project-URL: Repository, https://github.com/YunTaiHua/illusion-code
@@ -127,7 +127,7 @@ IllusionCode is an open-source AI-powered command-line programming assistant tha
127
127
  ### Requirements
128
128
 
129
129
  - Python >= 3.10
130
- - Node.js (for frontend TUI)
130
+ - Node.js 18+
131
131
  - Supports Windows, macOS, Linux
132
132
  - Windows users: Auto-detect Git, no manual PATH configuration needed
133
133
 
@@ -141,7 +141,7 @@ The simplest way to install IllusionCode. Automatically installs both frontends
141
141
  pip install illusion-code
142
142
  ```
143
143
 
144
- No git clone or Node.js required — everything is included in the package.
144
+ No git clone required — everything is included in the package.
145
145
 
146
146
  #### Alternative: pip install from source
147
147
 
@@ -79,7 +79,7 @@ IllusionCode is an open-source AI-powered command-line programming assistant tha
79
79
  ### Requirements
80
80
 
81
81
  - Python >= 3.10
82
- - Node.js (for frontend TUI)
82
+ - Node.js 18+
83
83
  - Supports Windows, macOS, Linux
84
84
  - Windows users: Auto-detect Git, no manual PATH configuration needed
85
85
 
@@ -93,7 +93,7 @@ The simplest way to install IllusionCode. Automatically installs both frontends
93
93
  pip install illusion-code
94
94
  ```
95
95
 
96
- No git clone or Node.js required — everything is included in the package.
96
+ No git clone required — everything is included in the package.
97
97
 
98
98
  #### Alternative: pip install from source
99
99
 
@@ -79,7 +79,7 @@ IllusionCode 是一个开源的 AI 驱动命令行编程助手,集成了众多
79
79
  ### 环境要求
80
80
 
81
81
  - Python >= 3.10
82
- - Node.js (用于前端 TUI)
82
+ - Node.js 18+
83
83
  - 支持 Windows、macOS、Linux
84
84
  - Windows 用户:自动查找 Git,无需手动配置 PATH
85
85
 
@@ -93,7 +93,7 @@ IllusionCode 是一个开源的 AI 驱动命令行编程助手,集成了众多
93
93
  pip install illusion-code
94
94
  ```
95
95
 
96
- 无需克隆仓库或安装 Node.js,所有内容已包含在包中。
96
+ 无需克隆仓库,所有内容已包含在包中。
97
97
 
98
98
  #### 备选方式:从源码安装
99
99
 
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@illusion/terminal",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@illusion/terminal",
9
- "version": "0.1.5",
9
+ "version": "0.1.6",
10
10
  "dependencies": {
11
11
  "chalk": "^5.6.2",
12
12
  "ink": "^5.1.0",
@@ -24,5 +24,5 @@
24
24
  "tsx": "^4.19.2",
25
25
  "typescript": "^5.7.3"
26
26
  },
27
- "version": "0.1.5"
27
+ "version": "0.1.6"
28
28
  }
@@ -88,16 +88,6 @@ const PERMISSION_PROMPT_OPTIONS: SelectOption[] = [
88
88
  {value: 'deny', label: 'Deny', description: 'Reject this tool execution'},
89
89
  ];
90
90
 
91
- /**
92
- * 计划审批选项列表
93
- * 当 AI 生成执行计划后,用户可以选择批准或拒绝该计划
94
- */
95
- const PLAN_APPROVAL_OPTIONS: SelectOption[] = [
96
- {value: 'approve', label: 'Approve', description: 'Approve plan and start implementation'},
97
- {value: 'reject', label: 'Reject', description: 'Reject plan and provide feedback'},
98
- ];
99
-
100
-
101
91
  /**
102
92
  * 应用程序根组件
103
93
  *
@@ -141,24 +131,12 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
141
131
  const [selectIndex, setSelectIndex] = useState(0);
142
132
  const [permissionIndex, setPermissionIndex] = useState(2);
143
133
  const [pendingPermissionAck, setPendingPermissionAck] = useState(false);
144
- const [planApprovalIndex, setPlanApprovalIndex] = useState(0);
145
- const [planFeedbackMode, setPlanFeedbackMode] = useState(false);
146
- const [planFeedback, setPlanFeedback] = useState('');
147
134
  const [cursorReset, setCursorReset] = useState(0);
148
135
  const session = useBackendSession(config, () => exit());
149
136
  const isPermissionModal = session.modal?.kind === 'permission';
150
- const isPlanApprovalModal = session.modal?.kind === 'plan_approval';
151
137
  const language = normalizeLanguage(session.status.ui_language);
152
138
  const permissionRequestId =
153
139
  isPermissionModal && typeof session.modal?.request_id === 'string' ? String(session.modal.request_id) : '';
154
- const planApprovalRequestId =
155
- isPlanApprovalModal && typeof session.modal?.request_id === 'string' ? String(session.modal.request_id) : '';
156
- const localizedPlanApprovalOptions = PLAN_APPROVAL_OPTIONS.map((opt) => {
157
- if (opt.value === 'approve') {
158
- return {...opt, label: t(language, 'approve')};
159
- }
160
- return {...opt, label: t(language, 'reject')};
161
- });
162
140
  const localizedPermissionOptions = PERMISSION_PROMPT_OPTIONS.map((opt) => {
163
141
  if (opt.value === 'allow') {
164
142
  return {...opt, label: t(language, 'allow')};
@@ -267,18 +245,6 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
267
245
  setPendingPermissionAck(false);
268
246
  }, [permissionRequestId, isPermissionModal]);
269
247
 
270
- useEffect(() => {
271
- if (!isPlanApprovalModal) {
272
- setPlanApprovalIndex(0);
273
- setPlanFeedbackMode(false);
274
- setPlanFeedback('');
275
- return;
276
- }
277
- setPlanApprovalIndex(0);
278
- setPlanFeedbackMode(false);
279
- setPlanFeedback('');
280
- }, [planApprovalRequestId, isPlanApprovalModal]);
281
-
282
248
  /**
283
249
  * 拦截需要交互式界面的特殊命令
284
250
  *
@@ -530,78 +496,6 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
530
496
  return;
531
497
  }
532
498
 
533
- // --- 计划审批模态对话框(必须在忙碌状态检查之前 — 模态框在忙碌时也会出现) ---
534
- if (isPlanApprovalModal) {
535
- // 反馈输入模式
536
- if (planFeedbackMode) {
537
- if (key.return) {
538
- // 提交拒绝并附带反馈
539
- if (planApprovalRequestId) {
540
- session.sendRequest({
541
- type: 'plan_approval_response',
542
- request_id: planApprovalRequestId,
543
- allowed: false,
544
- feedback: planFeedback,
545
- });
546
- }
547
- setPlanFeedbackMode(false);
548
- setPlanFeedback('');
549
- return;
550
- }
551
- if (key.escape) {
552
- // 取消反馈,返回选项界面
553
- setPlanFeedbackMode(false);
554
- setPlanFeedback('');
555
- return;
556
- }
557
- if (key.backspace || key.delete) {
558
- setPlanFeedback((f) => f.slice(0, -1));
559
- return;
560
- }
561
- // 追加可打印字符
562
- if (chunk && !key.ctrl && !key.meta) {
563
- setPlanFeedback((f) => f + chunk);
564
- }
565
- return;
566
- }
567
- if (key.upArrow || key.downArrow) {
568
- setPlanApprovalIndex((i) => {
569
- if (key.upArrow) return i <= 0 ? localizedPlanApprovalOptions.length - 1 : i - 1;
570
- return i >= localizedPlanApprovalOptions.length - 1 ? 0 : i + 1;
571
- });
572
- return;
573
- }
574
- if (key.return) {
575
- if (!planApprovalRequestId) {
576
- return;
577
- }
578
- const selected = localizedPlanApprovalOptions[planApprovalIndex]?.value;
579
- if (selected === 'approve') {
580
- session.sendRequest({
581
- type: 'plan_approval_response',
582
- request_id: planApprovalRequestId,
583
- allowed: true,
584
- });
585
- } else {
586
- // 进入反馈模式以拒绝计划
587
- setPlanFeedbackMode(true);
588
- }
589
- return;
590
- }
591
- if (key.escape) {
592
- // ESC = 不带反馈直接拒绝
593
- if (planApprovalRequestId) {
594
- session.sendRequest({
595
- type: 'plan_approval_response',
596
- request_id: planApprovalRequestId,
597
- allowed: false,
598
- });
599
- }
600
- return;
601
- }
602
- return;
603
- }
604
-
605
499
  // --- 问题模态对话框(在忙碌时也会出现) ---
606
500
  if (session.modal?.kind === 'question') {
607
501
  return;
@@ -730,7 +624,7 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
730
624
  clearCount={session.clearCount}
731
625
  assistantBuffer={session.assistantBuffer}
732
626
  showWelcome={session.ready}
733
- showThinking={session.showThinking && !isPlanApprovalModal}
627
+ showThinking={session.showThinking}
734
628
  language={language}
735
629
  pendingToolCalls={session.pendingToolCalls}
736
630
  commandPickerOpen={showPicker}
@@ -738,40 +632,6 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
738
632
  </Box>
739
633
 
740
634
  <Box flexDirection="column" paddingX={1}>
741
- {/* 计划审批模态框 — 轻量级,计划内容在对话区域渲染 */}
742
- {isPlanApprovalModal ? (
743
- <Box flexDirection="column" marginTop={1} paddingX={1}>
744
- {planFeedbackMode ? (
745
- <Box flexDirection="column">
746
- <Text color={theme.colors.warning}>{t(language, 'planFeedbackPrompt')}</Text>
747
- <Box marginTop={1}>
748
- <Text color={theme.colors.muted}>{'>'} </Text>
749
- <Text>{planFeedback}</Text>
750
- <Text color={theme.colors.muted}>{'_'}</Text>
751
- </Box>
752
- </Box>
753
- ) : (
754
- <Box flexDirection="column">
755
- {localizedPlanApprovalOptions.map((opt, i) => (
756
- <Box key={opt.value}>
757
- <Text color={i === planApprovalIndex ? theme.colors.info : theme.colors.muted}>
758
- {i === planApprovalIndex ? theme.icons.check : ' '} {opt.label}
759
- </Text>
760
- <Text dimColor> - {opt.description}</Text>
761
- </Box>
762
- ))}
763
- <Box marginTop={1}>
764
- <Text dimColor>
765
- <Text color={theme.colors.muted}>enter</Text> {t(language, 'approve')}
766
- <Text> {theme.icons.middleDot} </Text>
767
- <Text color={theme.colors.muted}>esc</Text> {t(language, 'reject')}
768
- </Text>
769
- </Box>
770
- </Box>
771
- )}
772
- </Box>
773
- ) : null}
774
-
775
635
  {/* 权限确认模态框 */}
776
636
  {isPermissionModal ? (
777
637
  <SelectModal
@@ -782,7 +642,7 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
782
642
  ) : null}
783
643
 
784
644
  {/* 后端模态框(问答、MCP 认证) */}
785
- {session.modal && !isPermissionModal && !isPlanApprovalModal ? (
645
+ {session.modal && !isPermissionModal ? (
786
646
  <ModalHost
787
647
  modal={session.modal}
788
648
  modalInput={modalInput}
@@ -816,17 +676,17 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
816
676
  ) : null}
817
677
 
818
678
  {/* 待办面板 — 计划审批期间隐藏 */}
819
- {!isPlanApprovalModal && session.ready && session.todoItems.length > 0 ? (
679
+ {session.ready && session.todoItems.length > 0 ? (
820
680
  <TodoPanel items={session.todoItems} />
821
681
  ) : null}
822
682
 
823
- {/* 群体协作面板 — 计划审批期间隐藏 */}
824
- {!isPlanApprovalModal && session.ready && (session.swarmTeammates.length > 0 || session.swarmNotifications.length > 0) ? (
683
+ {/* 群体协作面板 */}
684
+ {session.ready && (session.swarmTeammates.length > 0 || session.swarmNotifications.length > 0) ? (
825
685
  <SwarmPanel teammates={session.swarmTeammates} notifications={session.swarmNotifications} />
826
686
  ) : null}
827
687
 
828
- {/* 状态栏 — 计划审批期间隐藏 */}
829
- {!isPlanApprovalModal && session.ready ? (
688
+ {/* 状态栏 */}
689
+ {session.ready ? (
830
690
  <StatusBar status={session.status} tasks={session.tasks} />
831
691
  ) : null}
832
692
 
@@ -74,7 +74,10 @@ function QuestionModal({
74
74
  const theme = useTheme();
75
75
  const [extraLines, setExtraLines] = useState<string[]>([]);
76
76
  const [optionIndex, setOptionIndex] = useState(0);
77
- const [isCustomInput, setIsCustomInput] = useState(false);
77
+ /** "其他"选项是否处于输入状态(聚焦在输入框上) */
78
+ const [isOtherFocused, setIsOtherFocused] = useState(false);
79
+ /** "其他"选项的输入内容 */
80
+ const [otherInput, setOtherInput] = useState('');
78
81
  const [selectedIndices, setSelectedIndices] = useState<Set<number>>(new Set());
79
82
 
80
83
  const questions: QuestionItem[] = useMemo(() => {
@@ -92,38 +95,65 @@ function QuestionModal({
92
95
 
93
96
  const allOptions = useMemo(() => {
94
97
  if (!hasOptions) return [] as OptionEntry[];
95
- const result: OptionEntry[] = options.map((opt) => ({type: 'option' as const, label: opt.label, description: opt.description}));
96
- // 多选模式或指定 noCustomInput 时不追加"其他"选项
97
- if (isMultiSelect) return result;
98
- const noCustom = firstQuestion?.noCustomInput === true;
99
- if (noCustom) return result;
100
- const hasOtherAlready = options.some((opt) => {
98
+ // 过滤掉LLM返回的"其他"选项,保留工具自动添加的
99
+ const filteredOpts = options.filter((opt) => {
101
100
  const lbl = opt.label.toLowerCase();
102
- return lbl === 'other' || lbl === '其他' || lbl.startsWith('other') || lbl.startsWith('其他');
101
+ return !(lbl === 'other' || lbl === '其他' || lbl.startsWith('other') || lbl.startsWith('其他'));
103
102
  });
104
- if (!hasOtherAlready) {
105
- result.push({type: 'other' as const, label: language === 'zh-CN' ? '其他(手动输入)' : 'Other (type your answer)', description: undefined});
106
- }
103
+ const result: OptionEntry[] = filteredOpts.map((opt) => ({type: 'option' as const, label: opt.label, description: opt.description}));
104
+ // 指定 noCustomInput 时不追加"其他"选项(如沙箱权限对话框)
105
+ const noCustom = firstQuestion?.noCustomInput === true;
106
+ if (noCustom) return result;
107
+ // 始终添加工具自动的"其他"选项(单选和多选均适用)
108
+ result.push({type: 'other' as const, label: language === 'zh-CN' ? '其他' : 'Other', description: undefined});
107
109
  return result;
108
- }, [options, hasOptions, isMultiSelect, language]);
110
+ }, [options, hasOptions, language, firstQuestion?.noCustomInput]);
111
+
112
+ const otherIdx = allOptions.findIndex((o) => o.type === 'other');
113
+ const isOtherOption = otherIdx >= 0 && optionIndex === otherIdx;
109
114
 
110
115
  useEffect(() => {
111
116
  setOptionIndex(0);
112
- setIsCustomInput(false);
117
+ setIsOtherFocused(false);
118
+ setOtherInput('');
113
119
  setSelectedIndices(new Set());
114
120
  }, [hasOptions, allOptions.length, isMultiSelect]);
115
121
 
116
122
  useInput((_chunk, key) => {
117
- // ---- 自定义输入模式 ----
118
- if (isCustomInput) {
119
- if (key.shift && key.return) {
120
- setExtraLines((lines) => [...lines, modalInput]);
121
- setModalInput('');
122
- }
123
+ // ---- "其他"选项输入模式 ----
124
+ // 只拦截特殊键(Escape、箭头、Enter),字符输入交给 TextInput 处理
125
+ if (isOtherFocused) {
123
126
  if (key.escape) {
124
- setIsCustomInput(false);
125
- setModalInput('');
127
+ setIsOtherFocused(false);
128
+ setOtherInput('');
129
+ // 多选模式下取消选中"其他"
130
+ if (isMultiSelect && otherIdx >= 0) {
131
+ setSelectedIndices((prev) => {
132
+ const next = new Set(prev);
133
+ next.delete(otherIdx);
134
+ return next;
135
+ });
136
+ }
137
+ return;
126
138
  }
139
+ // 上下箭头:退出输入模式并导航选项
140
+ if (key.upArrow) {
141
+ setIsOtherFocused(false);
142
+ setOptionIndex((i) => Math.max(0, i - 1));
143
+ return;
144
+ }
145
+ if (key.downArrow) {
146
+ setIsOtherFocused(false);
147
+ setOptionIndex((i) => Math.min(allOptions.length - 1, i + 1));
148
+ return;
149
+ }
150
+ // Shift+Enter 换行
151
+ if (key.shift && key.return) {
152
+ setExtraLines((lines) => [...lines, otherInput]);
153
+ setOtherInput('');
154
+ return;
155
+ }
156
+ // Enter 和字符输入都交给 TextInput.onSubmit 处理,不做拦截
127
157
  return;
128
158
  }
129
159
 
@@ -138,50 +168,94 @@ function QuestionModal({
138
168
  return;
139
169
  }
140
170
  if (key.return) {
141
- // 收集所有选中项
171
+ // 收集所有选中项(不含"其他")
142
172
  const selected = allOptions
143
- .filter((_, i) => selectedIndices.has(i))
173
+ .filter((opt, i) => opt.type !== 'other' && selectedIndices.has(i))
144
174
  .map((opt) => opt.label);
175
+ // 如果选中了"其他"且有输入内容,加入结果
176
+ const allOtherLines = [...extraLines, otherInput].filter(Boolean);
177
+ if (otherIdx >= 0 && selectedIndices.has(otherIdx) && allOtherLines.length > 0) {
178
+ selected.push(allOtherLines.join('\n'));
179
+ }
145
180
  // 如果什么都没选,默认选中当前高亮的选项
146
181
  if (selected.length === 0) {
147
- selected.push(allOptions[optionIndex]!.label);
182
+ const highlighted = allOptions[optionIndex];
183
+ if (highlighted?.type === 'other') {
184
+ // 聚焦到"其他"输入框
185
+ setIsOtherFocused(true);
186
+ return;
187
+ } else if (highlighted) {
188
+ selected.push(highlighted.label);
189
+ }
148
190
  }
191
+ if (selected.length === 0) return;
149
192
  const header = firstQuestion?.header ?? 'answer';
150
193
  onSubmit(JSON.stringify({[header]: selected}));
151
194
  return;
152
195
  }
153
196
  if (_chunk === ' ') {
154
197
  // Space 切换选中/取消
155
- setSelectedIndices((prev) => {
156
- const next = new Set(prev);
157
- if (next.has(optionIndex)) {
158
- next.delete(optionIndex);
159
- } else {
160
- next.add(optionIndex);
161
- }
162
- return next;
163
- });
198
+ if (isOtherOption) {
199
+ setSelectedIndices((prev) => {
200
+ const next = new Set(prev);
201
+ if (next.has(optionIndex)) {
202
+ next.delete(optionIndex);
203
+ setIsOtherFocused(false);
204
+ setOtherInput('');
205
+ } else {
206
+ next.add(optionIndex);
207
+ setIsOtherFocused(true);
208
+ }
209
+ return next;
210
+ });
211
+ } else {
212
+ setSelectedIndices((prev) => {
213
+ const next = new Set(prev);
214
+ if (next.has(optionIndex)) {
215
+ next.delete(optionIndex);
216
+ } else {
217
+ next.add(optionIndex);
218
+ }
219
+ return next;
220
+ });
221
+ }
164
222
  return;
165
223
  }
166
224
  // 数字键也切换选中(不立即提交)
167
225
  const num = parseInt(_chunk, 10);
168
226
  if (num >= 1 && num <= allOptions.length) {
169
- setSelectedIndices((prev) => {
170
- const next = new Set(prev);
171
- const idx = num - 1;
172
- if (next.has(idx)) {
173
- next.delete(idx);
174
- } else {
175
- next.add(idx);
176
- }
177
- return next;
178
- });
227
+ const targetIdx = num - 1;
228
+ if (targetIdx === otherIdx) {
229
+ setSelectedIndices((prev) => {
230
+ const next = new Set(prev);
231
+ if (next.has(targetIdx)) {
232
+ next.delete(targetIdx);
233
+ setIsOtherFocused(false);
234
+ setOtherInput('');
235
+ } else {
236
+ next.add(targetIdx);
237
+ setIsOtherFocused(true);
238
+ setOptionIndex(targetIdx);
239
+ }
240
+ return next;
241
+ });
242
+ } else {
243
+ setSelectedIndices((prev) => {
244
+ const next = new Set(prev);
245
+ if (next.has(targetIdx)) {
246
+ next.delete(targetIdx);
247
+ } else {
248
+ next.add(targetIdx);
249
+ }
250
+ return next;
251
+ });
252
+ }
179
253
  return;
180
254
  }
181
255
  return;
182
256
  }
183
257
 
184
- // ---- 单选模式(原逻辑) ----
258
+ // ---- 单选模式 ----
185
259
  if (hasOptions && allOptions.length > 0) {
186
260
  if (key.upArrow) {
187
261
  setOptionIndex((i) => Math.max(0, i - 1));
@@ -194,7 +268,7 @@ function QuestionModal({
194
268
  if (key.return) {
195
269
  const selected = allOptions[optionIndex];
196
270
  if (selected?.type === 'other') {
197
- setIsCustomInput(true);
271
+ setIsOtherFocused(true);
198
272
  } else if (selected) {
199
273
  const idx = optionIndex + 1;
200
274
  onSubmit(`${idx}. ${selected.label}`);
@@ -205,7 +279,8 @@ function QuestionModal({
205
279
  if (num >= 1 && num <= allOptions.length) {
206
280
  const target = allOptions[num - 1];
207
281
  if (target?.type === 'other') {
208
- setIsCustomInput(true);
282
+ setOptionIndex(num - 1);
283
+ setIsOtherFocused(true);
209
284
  } else if (target) {
210
285
  onSubmit(`${num}. ${target.label}`);
211
286
  }
@@ -220,13 +295,6 @@ function QuestionModal({
220
295
  });
221
296
 
222
297
  const handleSubmit = (value: string): void => {
223
- if (isCustomInput) {
224
- const allLines = [...extraLines, value];
225
- setExtraLines([]);
226
- setIsCustomInput(false);
227
- onSubmit(allLines.join('\n'));
228
- return;
229
- }
230
298
  if (hasOptions) {
231
299
  return;
232
300
  }
@@ -267,11 +335,63 @@ function QuestionModal({
267
335
  </Box>
268
336
  ) : null}
269
337
 
270
- {hasOptions && !isCustomInput ? (
338
+ {hasOptions ? (
271
339
  <Box flexDirection="column" marginTop={1}>
272
340
  {allOptions.map((opt, i) => {
273
341
  const isCurrent = i === optionIndex;
274
342
  const isSelected = isMultiSelect ? selectedIndices.has(i) : false;
343
+ if (opt.type === 'other') {
344
+ // "其他"选项:内联输入框,带序号与普通选项格式一致
345
+ const isActive = isOtherFocused;
346
+ return (
347
+ <Box key={i}>
348
+ <Text color={isCurrent ? theme.colors.suggestion : theme.colors.muted}>
349
+ {isCurrent ? `${theme.icons.pointer} ` : ' '}
350
+ </Text>
351
+ {isMultiSelect && (
352
+ <Text color={isSelected ? theme.colors.suggestion : theme.colors.muted}>
353
+ [{isSelected ? 'x' : ' '}]
354
+ </Text>
355
+ )}
356
+ <Text color={isActive ? theme.colors.suggestion : (isCurrent ? theme.colors.suggestion : undefined)} bold={isCurrent && !isMultiSelect} dimColor={!isCurrent && !isActive}>
357
+ {`${i + 1}. `}
358
+ {opt.label}
359
+ </Text>
360
+ {isActive ? (
361
+ // 聚焦状态:显示内联输入框
362
+ <Text>
363
+ <Text> </Text>
364
+ <TextInput
365
+ value={otherInput}
366
+ onChange={setOtherInput}
367
+ placeholder={language === 'zh-CN' ? '请输入...' : 'Type something...'}
368
+ focus={true}
369
+ showCursor={true}
370
+ onSubmit={(v) => {
371
+ if (isMultiSelect) {
372
+ // 多选:退出输入模式,保留选中状态,等 Enter 提交全部
373
+ setIsOtherFocused(false);
374
+ return;
375
+ }
376
+ // 单选:直接提交
377
+ const allLines = [...extraLines, v].filter(Boolean);
378
+ setExtraLines([]);
379
+ setIsOtherFocused(false);
380
+ if (allLines.length > 0) {
381
+ onSubmit(allLines.join('\n'));
382
+ }
383
+ }}
384
+ />
385
+ </Text>
386
+ ) : otherInput ? (
387
+ // 非聚焦但有内容:显示已输入的文本
388
+ <Text> {otherInput}</Text>
389
+ ) : null}
390
+ {isCurrent && !isMultiSelect ? <Text dimColor>{' [enter]'}</Text> : null}
391
+ </Box>
392
+ );
393
+ }
394
+ // 普通选项
275
395
  return (
276
396
  <Box key={i}>
277
397
  <Text color={isCurrent ? theme.colors.suggestion : theme.colors.muted}>
@@ -320,14 +440,8 @@ function QuestionModal({
320
440
  </Box>
321
441
  ) : null}
322
442
 
323
- {(isCustomInput || !hasOptions) ? (
443
+ {!hasOptions ? (
324
444
  <>
325
- {isCustomInput ? (
326
- <Box marginTop={1}>
327
- <Text dimColor>{` ${theme.icons.resultPrefix} `}</Text>
328
- <Text dimColor>{language === 'zh-CN' ? '请输入您的回答:' : 'Type your answer:'}</Text>
329
- </Box>
330
- ) : null}
331
445
  {extraLines.length > 0 && (
332
446
  <Box flexDirection="column" marginTop={1}>
333
447
  {extraLines.map((line, i) => (
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  /** 当前版本号 */
9
- export const VERSION = '0.1.5';
9
+ export const VERSION = '0.1.6';
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@illusion/web",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@illusion/web",
9
- "version": "0.1.5",
9
+ "version": "0.1.6",
10
10
  "dependencies": {
11
11
  "highlight.js": "^11.11.0",
12
12
  "react": "^18.3.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@illusion/web",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {