illusion-code 0.1.0__tar.gz → 0.1.1__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.
- {illusion_code-0.1.0 → illusion_code-0.1.1}/.github/workflows/publish.yml +1 -9
- {illusion_code-0.1.0 → illusion_code-0.1.1}/PKG-INFO +27 -13
- {illusion_code-0.1.0 → illusion_code-0.1.1}/README.md +26 -12
- {illusion_code-0.1.0 → illusion_code-0.1.1}/README.zh-CN.md +25 -13
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/App.tsx +144 -9
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/ConversationView.tsx +12 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/i18n.ts +12 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/types.ts +1 -1
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/package-lock.json +2 -2
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/package.json +1 -1
- {illusion_code-0.1.0 → illusion_code-0.1.1}/pyproject.toml +1 -1
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/cli.py +1 -1
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/commands/__init__.py +2 -2
- illusion_code-0.1.1/src/illusion/commands/auth.py +55 -0
- illusion_code-0.1.1/src/illusion/commands/bridge.py +75 -0
- illusion_code-0.1.1/src/illusion/commands/context.py +66 -0
- illusion_code-0.1.1/src/illusion/commands/git.py +54 -0
- illusion_code-0.1.1/src/illusion/commands/helpers.py +159 -0
- illusion_code-0.1.1/src/illusion/commands/init/__init__.py +20 -0
- illusion_code-0.1.1/src/illusion/commands/init/analysis/__init__.py +1 -0
- illusion_code-0.1.1/src/illusion/commands/init/analysis/architecture.py +184 -0
- illusion_code-0.1.1/src/illusion/commands/init/analysis/conventions.py +221 -0
- illusion_code-0.1.1/src/illusion/commands/init/analysis/dependencies.py +173 -0
- illusion_code-0.1.1/src/illusion/commands/init/analysis/key_modules.py +205 -0
- illusion_code-0.1.1/src/illusion/commands/init/extraction/__init__.py +1 -0
- illusion_code-0.1.1/src/illusion/commands/init/extraction/enhanced_scan.py +178 -0
- illusion_code-0.1.1/src/illusion/commands/init/extraction/python_ast.py +281 -0
- illusion_code-0.1.1/src/illusion/commands/init/extraction/readme.py +138 -0
- illusion_code-0.1.1/src/illusion/commands/init/extraction/scanner.py +528 -0
- illusion_code-0.1.1/src/illusion/commands/init/generation/__init__.py +1 -0
- illusion_code-0.1.1/src/illusion/commands/init/generation/claudemd.py +241 -0
- illusion_code-0.1.1/src/illusion/commands/init/generation/illusionmd.py +125 -0
- illusion_code-0.1.1/src/illusion/commands/init/generation/memory_template.py +81 -0
- illusion_code-0.1.1/src/illusion/commands/init/generation/rules.py +110 -0
- illusion_code-0.1.1/src/illusion/commands/init/generation/sections.py +73 -0
- illusion_code-0.1.1/src/illusion/commands/init/orchestrator.py +267 -0
- illusion_code-0.1.1/src/illusion/commands/init/types.py +109 -0
- illusion_code-0.1.1/src/illusion/commands/mcp.py +63 -0
- illusion_code-0.1.1/src/illusion/commands/memory.py +54 -0
- illusion_code-0.1.1/src/illusion/commands/misc.py +177 -0
- illusion_code-0.1.1/src/illusion/commands/model.py +52 -0
- illusion_code-0.1.1/src/illusion/commands/plugin.py +40 -0
- illusion_code-0.1.1/src/illusion/commands/registry.py +287 -0
- illusion_code-0.1.1/src/illusion/commands/rules.py +57 -0
- illusion_code-0.1.1/src/illusion/commands/session.py +285 -0
- illusion_code-0.1.1/src/illusion/commands/settings.py +298 -0
- illusion_code-0.1.1/src/illusion/commands/types.py +70 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/config/i18n.py +21 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/config/paths.py +4 -4
- illusion_code-0.1.1/src/illusion/config/plan_file.py +185 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/config/settings.py +13 -1
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/engine/query.py +5 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/engine/query_engine.py +5 -1
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/mcp/client.py +18 -2
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/memory/__init__.py +8 -2
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/memory/paths.py +36 -8
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/permissions/checker.py +45 -2
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/prompts/claudemd.py +34 -6
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/prompts/context.py +36 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/enter_plan_mode_tool.py +37 -19
- illusion_code-0.1.1/src/illusion/tools/exit_plan_mode_tool.py +120 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/glob_tool.py +7 -1
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/grep_tool.py +1 -1
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/ui/backend_host.py +67 -19
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/ui/protocol.py +6 -3
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/ui/runtime.py +3 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/ui/web/ws_host.py +65 -19
- illusion_code-0.1.1/tests/commands/init/test_claudemd.py +135 -0
- illusion_code-0.1.1/tests/commands/init/test_orchestrator.py +108 -0
- illusion_code-0.1.1/tests/commands/init/test_python_ast.py +192 -0
- illusion_code-0.1.1/tests/commands/init/test_scanner.py +58 -0
- illusion_code-0.1.1/tests/commands/init/test_sections.py +53 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_commands/test_registry.py +5 -3
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_mcp/test_stdio_flow.py +1 -4
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_plugins/test_lifecycle_flow.py +1 -4
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_skills/test_loader.py +1 -1
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_tools/test_core_tools.py +2 -2
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_tools/test_integration_flows.py +1 -1
- illusion_code-0.1.0/src/illusion/commands/registry.py +0 -1934
- illusion_code-0.1.0/src/illusion/tools/exit_plan_mode_tool.py +0 -69
- {illusion_code-0.1.0 → illusion_code-0.1.1}/.gitignore +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/.python-version +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/LICENSE +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/docs/images/image1.png +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/docs/images/image2.png +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/build.mjs +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/package-lock.json +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/package.json +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/CommandPicker.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/Composer.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/ComposerController.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/Footer.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/MarkdownContent.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/MarkdownTable.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/ModalHost.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/MultilineTextInput.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/PromptInput.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/SelectModal.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/SidePanel.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/Spinner.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/StatusBar.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/SwarmPanel.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/TodoPanel.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/ToolCallDisplay.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/TranscriptPane.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/WelcomeBanner.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/hooks/useBackendSession.ts +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/hooks/useTerminalSize.ts +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/index.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/theme/ThemeContext.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/theme/builtinThemes.ts +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/utils/markdown.ts +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/utils/thinking.ts +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/tsconfig.json +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/index.html +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/postcss.config.js +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/App.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/components/ChatArea.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/components/MessageBubble.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/components/ModalCard.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/components/PromptInput.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/components/RightPanel.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/components/Sidebar.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/components/TodoPanel.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/components/Toolbar.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/components/WelcomeScreen.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/hooks/useWebSocketSession.ts +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/i18n.ts +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/index.css +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/main.tsx +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/remarkSuperscript.ts +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/src/types/protocol.ts +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/tailwind.config.js +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/tsconfig.json +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/web/vite.config.ts +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/main.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/scripts/build_frontend.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/scripts/hatch_build.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/scripts/publish.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/__main__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/api/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/api/client.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/api/codex_client.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/api/compat.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/api/effort.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/api/errors.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/api/openai_client.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/api/provider.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/api/registry.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/api/usage.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/auth/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/auth/copilot.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/auth/external.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/auth/flows.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/auth/manager.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/auth/storage.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/bridge/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/bridge/manager.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/bridge/session_runner.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/bridge/types.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/bridge/work_secret.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/config/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/coordinator/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/coordinator/agent_definitions.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/coordinator/coordinator_mode.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/engine/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/engine/cost_tracker.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/engine/messages.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/engine/stream_events.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/hooks/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/hooks/events.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/hooks/executor.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/hooks/hot_reload.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/hooks/loader.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/hooks/schemas.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/hooks/types.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/mcp/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/mcp/config.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/mcp/types.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/memory/manager.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/memory/memdir.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/memory/scan.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/memory/search.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/memory/types.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/output_styles/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/output_styles/loader.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/permissions/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/permissions/modes.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/platforms.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/plugins/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/plugins/bundled/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/plugins/installer.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/plugins/loader.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/plugins/schemas.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/plugins/types.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/prompts/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/prompts/environment.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/prompts/system_prompt.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/sandbox/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/sandbox/adapter.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/services/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/services/compact/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/services/cron.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/services/cron_scheduler.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/services/file_history.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/services/lsp/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/services/session_storage.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/services/token_estimation.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/bundled/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/bundled/content/batch.md +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/bundled/content/coding-guidelines.md +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/bundled/content/debug.md +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/bundled/content/loop.md +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/bundled/content/remember.md +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/bundled/content/simplify.md +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/bundled/content/skillify.md +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/bundled/content/stuck.md +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/bundled/content/update-config.md +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/bundled/content/verify.md +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/loader.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/registry.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/skills/types.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/state/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/state/app_state.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/state/store.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/swarm/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/swarm/agent_executor.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/swarm/in_process.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/swarm/subprocess_backend.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/swarm/team_helpers.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/swarm/types.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/swarm/worktree.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tasks/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tasks/local_agent_task.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tasks/local_shell_task.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tasks/manager.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tasks/stop_task.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tasks/types.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/agent_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/ask_user_question_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/base.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/bash_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/config_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/cron_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/enter_worktree_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/exit_worktree_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/file_edit_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/file_read_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/file_write_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/list_mcp_resources_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/lsp_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/mcp_auth_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/mcp_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/notebook_edit_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/powershell_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/read_mcp_resource_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/repl_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/send_message_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/shell_common.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/skill_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/sleep_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/structured_output_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/task_create_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/task_get_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/task_list_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/task_output_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/task_stop_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/task_update_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/team_create_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/team_delete_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/todo_write_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/tool_search_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/web_fetch_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/tools/web_search_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/ui/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/ui/app.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/ui/input.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/ui/output.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/ui/permission_dialog.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/ui/permission_store.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/ui/react_launcher.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/ui/textual_app.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/ui/web/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/ui/web/server.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/utils/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/utils/ripgrep.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/src/illusion/utils/shell.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/api/test_anthropic_client.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/api/test_client.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/api/test_codex_client.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/api/test_effort.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/api/test_fallback/346/217/220/347/244/272.py" +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/api/test_openai_client.py +0 -0
- {illusion_code-0.1.0/tests/test_api → illusion_code-0.1.1/tests/commands/init}/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/commands/test_effort_command.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/config/test_i18n.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/config/test_settings.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/conftest.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/engine/test_query_engine.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/fixtures/fake_mcp_server.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/integration/test_effort_integration.py +0 -0
- {illusion_code-0.1.0/tests/test_commands → illusion_code-0.1.1/tests/test_api}/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_api/test_client.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_api/test_codex_client.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_api/test_compat.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_api/test_openai_client.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_auth/test_external.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_bridge/test_core.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_bridge/test_session_flow.py +0 -0
- {illusion_code-0.1.0/tests/test_config → illusion_code-0.1.1/tests/test_commands}/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_commands/test_cli.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_commands/test_command_flows.py +0 -0
- {illusion_code-0.1.0/tests/test_engine → illusion_code-0.1.1/tests/test_config}/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_config/test_paths.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_config/test_settings.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_coordinator/test_agent_definitions.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_coordinator/test_coordinator_mode.py +0 -0
- {illusion_code-0.1.0/tests/test_hooks → illusion_code-0.1.1/tests/test_engine}/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_engine/test_media_block.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_engine/test_query_engine.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_engine/test_tool_result_media.py +0 -0
- {illusion_code-0.1.0/tests/test_mcp → illusion_code-0.1.1/tests/test_hooks}/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_hooks/test_executor.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_hooks_skills_plugins_real.py +0 -0
- {illusion_code-0.1.0/tests/test_memory → illusion_code-0.1.1/tests/test_mcp}/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_mcp/test_integration.py +0 -0
- {illusion_code-0.1.0/tests/test_permissions → illusion_code-0.1.1/tests/test_memory}/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_memory/test_memdir.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_merged_prs_on_autoagent.py +0 -0
- {illusion_code-0.1.0/tests/test_plugins → illusion_code-0.1.1/tests/test_permissions}/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_permissions/test_checker.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_platforms.py +0 -0
- {illusion_code-0.1.0/tests/test_prompts → illusion_code-0.1.1/tests/test_plugins}/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_plugins/test_loader.py +0 -0
- {illusion_code-0.1.0/tests/test_swarm → illusion_code-0.1.1/tests/test_prompts}/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_prompts/test_claudemd.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_prompts/test_environment.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_prompts/test_system_prompt.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_real_large_tasks.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_sandbox/test_adapter.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_services/test_compact.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_services/test_cron.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_services/test_cron_scheduler.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_services/test_session_storage.py +0 -0
- {illusion_code-0.1.0/tests/test_tools → illusion_code-0.1.1/tests/test_swarm}/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_swarm/test_agent_executor.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_swarm/test_imports.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_swarm/test_in_process.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_swarm/test_types.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_swarm/test_worktree.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_tasks/test_manager.py +0 -0
- {illusion_code-0.1.0/tests/test_ui → illusion_code-0.1.1/tests/test_tools}/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_tools/test_agent_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_tools/test_file_read_media.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_tools/test_glob_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_tools/test_grep_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_tools/test_integration.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_tools/test_mcp_auth_tool.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_tools/test_ripgrep.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_tools/test_shell_common.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_tools/test_task_tools.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_tools/test_team_tools.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_tools/test_web_fetch_tool.py +0 -0
- /illusion_code-0.1.0/src/illusion/py.typed → /illusion_code-0.1.1/tests/test_ui/__init__.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_ui/test_modes.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_ui/test_permission_store.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_ui/test_react_backend.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_ui/test_react_launcher.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_ui/test_textual_app.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_untested_features.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/test_utils/test_shell.py +0 -0
- {illusion_code-0.1.0 → illusion_code-0.1.1}/tests/ui/test_backend_host.py +0 -0
|
@@ -34,15 +34,7 @@ jobs:
|
|
|
34
34
|
run: ruff check src/
|
|
35
35
|
|
|
36
36
|
- name: Test
|
|
37
|
-
run:
|
|
38
|
-
pytest tests/ -q \
|
|
39
|
-
--deselect tests/test_mcp/test_stdio_flow.py::test_stdio_mcp_manager_connects_and_executes_real_server \
|
|
40
|
-
--deselect tests/test_plugins/test_lifecycle_flow.py::test_plugin_install_load_and_uninstall_flow \
|
|
41
|
-
--deselect tests/test_skills/test_loader.py::test_load_skill_registry_includes_bundled \
|
|
42
|
-
--deselect tests/test_tools/test_core_tools.py::test_glob_and_grep \
|
|
43
|
-
--deselect tests/test_tools/test_integration_flows.py::test_search_edit_flow_across_registry \
|
|
44
|
-
--deselect tests/test_auth/test_external.py::test_external_binding_for_codex_without_switching \
|
|
45
|
-
--deselect tests/test_commands/test_registry.py::test_agents_session_files_and_reload_plugins_commands
|
|
37
|
+
run: pytest tests/ -q
|
|
46
38
|
|
|
47
39
|
- name: Build
|
|
48
40
|
run: python -m build
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: illusion-code
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
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
|
|
@@ -133,17 +133,27 @@ IllusionCode is an open-source AI-powered command-line programming assistant tha
|
|
|
133
133
|
|
|
134
134
|
### Installation
|
|
135
135
|
|
|
136
|
-
#### Recommended: pip install
|
|
136
|
+
#### Recommended: pip install from PyPI
|
|
137
137
|
|
|
138
|
-
|
|
138
|
+
The simplest way to install IllusionCode. Automatically installs both frontends and registers the `illusion` command globally.
|
|
139
139
|
|
|
140
140
|
```bash
|
|
141
|
-
|
|
141
|
+
pip install illusion-code
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
No git clone or Node.js required — everything is included in the package.
|
|
145
|
+
|
|
146
|
+
#### Alternative: pip install from source
|
|
147
|
+
|
|
148
|
+
Clone the repository and install locally. Triggers the hatch build hook to build frontends automatically.
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
git clone https://github.com/YunTaiHua/illusion-code.git
|
|
142
152
|
cd illusion-code
|
|
143
153
|
pip install .
|
|
144
154
|
```
|
|
145
155
|
|
|
146
|
-
|
|
156
|
+
Requires Node.js 18+ (for frontend build).
|
|
147
157
|
|
|
148
158
|
#### Alternative: uv sync (for development)
|
|
149
159
|
|
|
@@ -178,9 +188,11 @@ python scripts/build_frontend.py --web # Web UI only
|
|
|
178
188
|
> pip install .
|
|
179
189
|
> ```
|
|
180
190
|
|
|
181
|
-
#### Manual frontend build (for
|
|
191
|
+
#### Manual frontend build (for source installs only)
|
|
182
192
|
|
|
183
|
-
If you need to rebuild frontends
|
|
193
|
+
If you installed from source and need to rebuild frontends (e.g., after updating frontend code). PyPI users do not need this step.
|
|
194
|
+
|
|
195
|
+
**Build script (recommended)**
|
|
184
196
|
|
|
185
197
|
**Build script (recommended)**
|
|
186
198
|
|
|
@@ -208,12 +220,14 @@ cd ../..
|
|
|
208
220
|
|
|
209
221
|
#### Key differences
|
|
210
222
|
|
|
211
|
-
| | `pip install .` | `uv sync` |
|
|
212
|
-
|
|
213
|
-
|
|
|
214
|
-
|
|
|
215
|
-
|
|
|
216
|
-
|
|
|
223
|
+
| | `pip install illusion-code` | `pip install .` | `uv sync` |
|
|
224
|
+
|---|---|---|---|
|
|
225
|
+
| Source | PyPI | Local git clone | Local git clone |
|
|
226
|
+
| Frontend build | Pre-built (included) | Automatic (hatch hook) | Manual |
|
|
227
|
+
| Node.js required | No | Yes (18+) | Yes (18+) |
|
|
228
|
+
| `illusion` command | Global | Global | Project-only (via `uv run` or venv activation) |
|
|
229
|
+
| Install type | Standard | Standard | Editable |
|
|
230
|
+
| Best for | End users | Contributors | Developers |
|
|
217
231
|
|
|
218
232
|
### Basic Usage
|
|
219
233
|
|
|
@@ -85,17 +85,27 @@ IllusionCode is an open-source AI-powered command-line programming assistant tha
|
|
|
85
85
|
|
|
86
86
|
### Installation
|
|
87
87
|
|
|
88
|
-
#### Recommended: pip install
|
|
88
|
+
#### Recommended: pip install from PyPI
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
The simplest way to install IllusionCode. Automatically installs both frontends and registers the `illusion` command globally.
|
|
91
91
|
|
|
92
92
|
```bash
|
|
93
|
-
|
|
93
|
+
pip install illusion-code
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
No git clone or Node.js required — everything is included in the package.
|
|
97
|
+
|
|
98
|
+
#### Alternative: pip install from source
|
|
99
|
+
|
|
100
|
+
Clone the repository and install locally. Triggers the hatch build hook to build frontends automatically.
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
git clone https://github.com/YunTaiHua/illusion-code.git
|
|
94
104
|
cd illusion-code
|
|
95
105
|
pip install .
|
|
96
106
|
```
|
|
97
107
|
|
|
98
|
-
|
|
108
|
+
Requires Node.js 18+ (for frontend build).
|
|
99
109
|
|
|
100
110
|
#### Alternative: uv sync (for development)
|
|
101
111
|
|
|
@@ -130,9 +140,11 @@ python scripts/build_frontend.py --web # Web UI only
|
|
|
130
140
|
> pip install .
|
|
131
141
|
> ```
|
|
132
142
|
|
|
133
|
-
#### Manual frontend build (for
|
|
143
|
+
#### Manual frontend build (for source installs only)
|
|
134
144
|
|
|
135
|
-
If you need to rebuild frontends
|
|
145
|
+
If you installed from source and need to rebuild frontends (e.g., after updating frontend code). PyPI users do not need this step.
|
|
146
|
+
|
|
147
|
+
**Build script (recommended)**
|
|
136
148
|
|
|
137
149
|
**Build script (recommended)**
|
|
138
150
|
|
|
@@ -160,12 +172,14 @@ cd ../..
|
|
|
160
172
|
|
|
161
173
|
#### Key differences
|
|
162
174
|
|
|
163
|
-
| | `pip install .` | `uv sync` |
|
|
164
|
-
|
|
165
|
-
|
|
|
166
|
-
|
|
|
167
|
-
|
|
|
168
|
-
|
|
|
175
|
+
| | `pip install illusion-code` | `pip install .` | `uv sync` |
|
|
176
|
+
|---|---|---|---|
|
|
177
|
+
| Source | PyPI | Local git clone | Local git clone |
|
|
178
|
+
| Frontend build | Pre-built (included) | Automatic (hatch hook) | Manual |
|
|
179
|
+
| Node.js required | No | Yes (18+) | Yes (18+) |
|
|
180
|
+
| `illusion` command | Global | Global | Project-only (via `uv run` or venv activation) |
|
|
181
|
+
| Install type | Standard | Standard | Editable |
|
|
182
|
+
| Best for | End users | Contributors | Developers |
|
|
169
183
|
|
|
170
184
|
### Basic Usage
|
|
171
185
|
|
|
@@ -85,17 +85,27 @@ IllusionCode 是一个开源的 AI 驱动命令行编程助手,集成了众多
|
|
|
85
85
|
|
|
86
86
|
### 安装
|
|
87
87
|
|
|
88
|
-
####
|
|
88
|
+
#### 推荐方式:从 PyPI 安装
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
最简单的安装方式,自动安装前端并注册 `illusion` 命令到全局 PATH。
|
|
91
91
|
|
|
92
92
|
```bash
|
|
93
|
-
|
|
93
|
+
pip install illusion-code
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
无需克隆仓库或安装 Node.js,所有内容已包含在包中。
|
|
97
|
+
|
|
98
|
+
#### 备选方式:从源码安装
|
|
99
|
+
|
|
100
|
+
克隆仓库后本地安装,hatch build hook 会自动构建前端。
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
git clone https://github.com/YunTaiHua/illusion-code.git
|
|
94
104
|
cd illusion-code
|
|
95
105
|
pip install .
|
|
96
106
|
```
|
|
97
107
|
|
|
98
|
-
|
|
108
|
+
需要 Node.js 18+(用于前端构建)。
|
|
99
109
|
|
|
100
110
|
#### 开发方式:uv sync(适合开发者)
|
|
101
111
|
|
|
@@ -130,9 +140,9 @@ python scripts/build_frontend.py --web # 只构建 Web UI
|
|
|
130
140
|
> pip install .
|
|
131
141
|
> ```
|
|
132
142
|
|
|
133
|
-
####
|
|
143
|
+
#### 手动构建前端(仅源码安装需要)
|
|
134
144
|
|
|
135
|
-
|
|
145
|
+
如从源码安装后需要重新构建前端(例如更新了前端代码)。PyPI 用户无需此步骤。
|
|
136
146
|
|
|
137
147
|
**构建脚本(推荐)**
|
|
138
148
|
|
|
@@ -158,14 +168,16 @@ npm run build
|
|
|
158
168
|
cd ../..
|
|
159
169
|
```
|
|
160
170
|
|
|
161
|
-
####
|
|
171
|
+
#### 三种方式对比
|
|
162
172
|
|
|
163
|
-
| | `pip install .` | `uv sync` |
|
|
164
|
-
|
|
165
|
-
|
|
|
166
|
-
|
|
|
167
|
-
|
|
|
168
|
-
|
|
|
173
|
+
| | `pip install illusion-code` | `pip install .` | `uv sync` |
|
|
174
|
+
|---|---|---|---|
|
|
175
|
+
| 来源 | PyPI | 本地 git clone | 本地 git clone |
|
|
176
|
+
| 前端构建 | 预构建(已包含) | 自动(hatch hook) | 手动 |
|
|
177
|
+
| 需要 Node.js | 否 | 是(18+) | 是(18+) |
|
|
178
|
+
| `illusion` 命令 | 全局可用 | 全局可用 | 仅项目内(需 `uv run` 或激活虚拟环境) |
|
|
179
|
+
| 安装类型 | 标准安装 | 标准安装 | Editable 安装 |
|
|
180
|
+
| 适用场景 | 终端用户 | 贡献者 | 开发者 |
|
|
169
181
|
|
|
170
182
|
### 基本使用
|
|
171
183
|
|
|
@@ -47,6 +47,11 @@ const PERMISSION_PROMPT_OPTIONS: SelectOption[] = [
|
|
|
47
47
|
{value: 'deny', label: 'Deny', description: 'Reject this tool execution'},
|
|
48
48
|
];
|
|
49
49
|
|
|
50
|
+
const PLAN_APPROVAL_OPTIONS: SelectOption[] = [
|
|
51
|
+
{value: 'approve', label: 'Approve', description: 'Approve plan and start implementation'},
|
|
52
|
+
{value: 'reject', label: 'Reject', description: 'Reject plan and provide feedback'},
|
|
53
|
+
];
|
|
54
|
+
|
|
50
55
|
|
|
51
56
|
export function App({config}: {config: FrontendConfig}): React.JSX.Element {
|
|
52
57
|
return (
|
|
@@ -67,12 +72,24 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
|
|
|
67
72
|
const [selectIndex, setSelectIndex] = useState(0);
|
|
68
73
|
const [permissionIndex, setPermissionIndex] = useState(2);
|
|
69
74
|
const [pendingPermissionAck, setPendingPermissionAck] = useState(false);
|
|
75
|
+
const [planApprovalIndex, setPlanApprovalIndex] = useState(0);
|
|
76
|
+
const [planFeedbackMode, setPlanFeedbackMode] = useState(false);
|
|
77
|
+
const [planFeedback, setPlanFeedback] = useState('');
|
|
70
78
|
const [cursorReset, setCursorReset] = useState(0);
|
|
71
79
|
const session = useBackendSession(config, () => exit());
|
|
72
80
|
const isPermissionModal = session.modal?.kind === 'permission';
|
|
81
|
+
const isPlanApprovalModal = session.modal?.kind === 'plan_approval';
|
|
73
82
|
const language = normalizeLanguage(session.status.ui_language);
|
|
74
83
|
const permissionRequestId =
|
|
75
84
|
isPermissionModal && typeof session.modal?.request_id === 'string' ? String(session.modal.request_id) : '';
|
|
85
|
+
const planApprovalRequestId =
|
|
86
|
+
isPlanApprovalModal && typeof session.modal?.request_id === 'string' ? String(session.modal.request_id) : '';
|
|
87
|
+
const localizedPlanApprovalOptions = PLAN_APPROVAL_OPTIONS.map((opt) => {
|
|
88
|
+
if (opt.value === 'approve') {
|
|
89
|
+
return {...opt, label: t(language, 'approve')};
|
|
90
|
+
}
|
|
91
|
+
return {...opt, label: t(language, 'reject')};
|
|
92
|
+
});
|
|
76
93
|
const localizedPermissionOptions = PERMISSION_PROMPT_OPTIONS.map((opt) => {
|
|
77
94
|
if (opt.value === 'allow') {
|
|
78
95
|
return {...opt, label: t(language, 'allow')};
|
|
@@ -159,6 +176,18 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
|
|
|
159
176
|
setPendingPermissionAck(false);
|
|
160
177
|
}, [permissionRequestId, isPermissionModal]);
|
|
161
178
|
|
|
179
|
+
useEffect(() => {
|
|
180
|
+
if (!isPlanApprovalModal) {
|
|
181
|
+
setPlanApprovalIndex(0);
|
|
182
|
+
setPlanFeedbackMode(false);
|
|
183
|
+
setPlanFeedback('');
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
setPlanApprovalIndex(0);
|
|
187
|
+
setPlanFeedbackMode(false);
|
|
188
|
+
setPlanFeedback('');
|
|
189
|
+
}, [planApprovalRequestId, isPlanApprovalModal]);
|
|
190
|
+
|
|
162
191
|
// Intercept special commands that need interactive UI
|
|
163
192
|
const handleCommand = (cmd: string): boolean => {
|
|
164
193
|
const trimmed = cmd.trim();
|
|
@@ -262,7 +291,7 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
|
|
|
262
291
|
// /version → 显示版本信息(前端处理,不发送到后端)
|
|
263
292
|
if (trimmed === '/version') {
|
|
264
293
|
session.setCommandResult({
|
|
265
|
-
text: 'IllusionCode 0.1.
|
|
294
|
+
text: 'IllusionCode 0.1.1',
|
|
266
295
|
type: 'info',
|
|
267
296
|
});
|
|
268
297
|
return true;
|
|
@@ -386,6 +415,78 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
|
|
|
386
415
|
return;
|
|
387
416
|
}
|
|
388
417
|
|
|
418
|
+
// --- Plan approval modal (MUST be before busy check — modal appears while busy) ---
|
|
419
|
+
if (isPlanApprovalModal) {
|
|
420
|
+
// Feedback input mode
|
|
421
|
+
if (planFeedbackMode) {
|
|
422
|
+
if (key.return) {
|
|
423
|
+
// Submit rejection with feedback
|
|
424
|
+
if (planApprovalRequestId) {
|
|
425
|
+
session.sendRequest({
|
|
426
|
+
type: 'plan_approval_response',
|
|
427
|
+
request_id: planApprovalRequestId,
|
|
428
|
+
allowed: false,
|
|
429
|
+
feedback: planFeedback,
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
setPlanFeedbackMode(false);
|
|
433
|
+
setPlanFeedback('');
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
if (key.escape) {
|
|
437
|
+
// Cancel feedback, go back to options
|
|
438
|
+
setPlanFeedbackMode(false);
|
|
439
|
+
setPlanFeedback('');
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (key.backspace || key.delete) {
|
|
443
|
+
setPlanFeedback((f) => f.slice(0, -1));
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
// Append printable characters
|
|
447
|
+
if (chunk && !key.ctrl && !key.meta) {
|
|
448
|
+
setPlanFeedback((f) => f + chunk);
|
|
449
|
+
}
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
if (key.upArrow || key.downArrow) {
|
|
453
|
+
setPlanApprovalIndex((i) => {
|
|
454
|
+
if (key.upArrow) return i <= 0 ? localizedPlanApprovalOptions.length - 1 : i - 1;
|
|
455
|
+
return i >= localizedPlanApprovalOptions.length - 1 ? 0 : i + 1;
|
|
456
|
+
});
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
if (key.return) {
|
|
460
|
+
if (!planApprovalRequestId) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
const selected = localizedPlanApprovalOptions[planApprovalIndex]?.value;
|
|
464
|
+
if (selected === 'approve') {
|
|
465
|
+
session.sendRequest({
|
|
466
|
+
type: 'plan_approval_response',
|
|
467
|
+
request_id: planApprovalRequestId,
|
|
468
|
+
allowed: true,
|
|
469
|
+
});
|
|
470
|
+
} else {
|
|
471
|
+
// Enter feedback mode for rejection
|
|
472
|
+
setPlanFeedbackMode(true);
|
|
473
|
+
}
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
if (key.escape) {
|
|
477
|
+
// Escape = reject without feedback
|
|
478
|
+
if (planApprovalRequestId) {
|
|
479
|
+
session.sendRequest({
|
|
480
|
+
type: 'plan_approval_response',
|
|
481
|
+
request_id: planApprovalRequestId,
|
|
482
|
+
allowed: false,
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
|
|
389
490
|
// --- Question modal (also appears while busy) ---
|
|
390
491
|
if (session.modal?.kind === 'question') {
|
|
391
492
|
return;
|
|
@@ -497,7 +598,7 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
|
|
|
497
598
|
clearCount={session.clearCount}
|
|
498
599
|
assistantBuffer={session.assistantBuffer}
|
|
499
600
|
showWelcome={session.ready}
|
|
500
|
-
showThinking={session.showThinking}
|
|
601
|
+
showThinking={session.showThinking && !isPlanApprovalModal}
|
|
501
602
|
language={language}
|
|
502
603
|
pendingToolCalls={session.pendingToolCalls}
|
|
503
604
|
commandPickerOpen={showPicker}
|
|
@@ -505,6 +606,40 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
|
|
|
505
606
|
</Box>
|
|
506
607
|
|
|
507
608
|
<Box flexDirection="column" paddingX={1}>
|
|
609
|
+
{/* Plan approval modal — lightweight, plan content rendered in conversation */}
|
|
610
|
+
{isPlanApprovalModal ? (
|
|
611
|
+
<Box flexDirection="column" marginTop={1} paddingX={1}>
|
|
612
|
+
{planFeedbackMode ? (
|
|
613
|
+
<Box flexDirection="column">
|
|
614
|
+
<Text color={theme.colors.warning}>{t(language, 'planFeedbackPrompt')}</Text>
|
|
615
|
+
<Box marginTop={1}>
|
|
616
|
+
<Text color={theme.colors.muted}>{'>'} </Text>
|
|
617
|
+
<Text>{planFeedback}</Text>
|
|
618
|
+
<Text color={theme.colors.muted}>{'_'}</Text>
|
|
619
|
+
</Box>
|
|
620
|
+
</Box>
|
|
621
|
+
) : (
|
|
622
|
+
<Box flexDirection="column">
|
|
623
|
+
{localizedPlanApprovalOptions.map((opt, i) => (
|
|
624
|
+
<Box key={opt.value}>
|
|
625
|
+
<Text color={i === planApprovalIndex ? theme.colors.info : theme.colors.muted}>
|
|
626
|
+
{i === planApprovalIndex ? theme.icons.check : ' '} {opt.label}
|
|
627
|
+
</Text>
|
|
628
|
+
<Text dimColor> - {opt.description}</Text>
|
|
629
|
+
</Box>
|
|
630
|
+
))}
|
|
631
|
+
<Box marginTop={1}>
|
|
632
|
+
<Text dimColor>
|
|
633
|
+
<Text color={theme.colors.muted}>enter</Text> {t(language, 'approve')}
|
|
634
|
+
<Text> {theme.icons.middleDot} </Text>
|
|
635
|
+
<Text color={theme.colors.muted}>esc</Text> {t(language, 'reject')}
|
|
636
|
+
</Text>
|
|
637
|
+
</Box>
|
|
638
|
+
</Box>
|
|
639
|
+
)}
|
|
640
|
+
</Box>
|
|
641
|
+
) : null}
|
|
642
|
+
|
|
508
643
|
{/* Permission confirm modal */}
|
|
509
644
|
{isPermissionModal ? (
|
|
510
645
|
<SelectModal
|
|
@@ -515,7 +650,7 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
|
|
|
515
650
|
) : null}
|
|
516
651
|
|
|
517
652
|
{/* Backend modal (question, mcp auth) */}
|
|
518
|
-
{session.modal && !isPermissionModal ? (
|
|
653
|
+
{session.modal && !isPermissionModal && !isPlanApprovalModal ? (
|
|
519
654
|
<ModalHost
|
|
520
655
|
modal={session.modal}
|
|
521
656
|
modalInput={modalInput}
|
|
@@ -548,18 +683,18 @@ function AppInner({config}: {config: FrontendConfig}): React.JSX.Element {
|
|
|
548
683
|
/>
|
|
549
684
|
) : null}
|
|
550
685
|
|
|
551
|
-
{/* Todo panel */}
|
|
552
|
-
{session.ready && session.todoItems.length > 0 ? (
|
|
686
|
+
{/* Todo panel — hidden during plan approval */}
|
|
687
|
+
{!isPlanApprovalModal && session.ready && session.todoItems.length > 0 ? (
|
|
553
688
|
<TodoPanel items={session.todoItems} />
|
|
554
689
|
) : null}
|
|
555
690
|
|
|
556
|
-
{/* Swarm panel */}
|
|
557
|
-
{session.ready && (session.swarmTeammates.length > 0 || session.swarmNotifications.length > 0) ? (
|
|
691
|
+
{/* Swarm panel — hidden during plan approval */}
|
|
692
|
+
{!isPlanApprovalModal && session.ready && (session.swarmTeammates.length > 0 || session.swarmNotifications.length > 0) ? (
|
|
558
693
|
<SwarmPanel teammates={session.swarmTeammates} notifications={session.swarmNotifications} />
|
|
559
694
|
) : null}
|
|
560
695
|
|
|
561
|
-
{/* Status bar
|
|
562
|
-
{session.ready ? (
|
|
696
|
+
{/* Status bar — hidden during plan approval */}
|
|
697
|
+
{!isPlanApprovalModal && session.ready ? (
|
|
563
698
|
<StatusBar status={session.status} tasks={session.tasks} />
|
|
564
699
|
) : null}
|
|
565
700
|
|
{illusion_code-0.1.0 → illusion_code-0.1.1}/frontend/terminal/src/components/ConversationView.tsx
RENAMED
|
@@ -509,6 +509,18 @@ function MessageRow({
|
|
|
509
509
|
);
|
|
510
510
|
}
|
|
511
511
|
|
|
512
|
+
case 'plan':
|
|
513
|
+
return (
|
|
514
|
+
<Box marginTop={1} flexDirection="column" borderStyle="round" borderColor={theme.colors.info} paddingX={1}>
|
|
515
|
+
<Box marginBottom={0}>
|
|
516
|
+
<Text bold color={theme.colors.info}>{t(language, 'planReview')}</Text>
|
|
517
|
+
</Box>
|
|
518
|
+
<Box flexDirection="column">
|
|
519
|
+
<MarkdownContent text={item.text} availableWidth={Math.max(40, terminalWidth - 6)} />
|
|
520
|
+
</Box>
|
|
521
|
+
</Box>
|
|
522
|
+
);
|
|
523
|
+
|
|
512
524
|
case 'log':
|
|
513
525
|
return (
|
|
514
526
|
<Box>
|
|
@@ -31,6 +31,12 @@ const ZH: Dict = {
|
|
|
31
31
|
assistantReply: '助手回复',
|
|
32
32
|
bgAgentWaiting: '等待后台代理完成',
|
|
33
33
|
bgAgentResuming: '后台代理已完成,继续执行',
|
|
34
|
+
planReview: '计划审批',
|
|
35
|
+
approve: '批准',
|
|
36
|
+
reject: '拒绝',
|
|
37
|
+
planApproved: '计划已批准,开始实施。',
|
|
38
|
+
planRejected: '计划已拒绝。',
|
|
39
|
+
planFeedbackPrompt: '请输入修改意见(可选,Enter 提交,Esc 跳过):',
|
|
34
40
|
};
|
|
35
41
|
|
|
36
42
|
const EN: Dict = {
|
|
@@ -62,6 +68,12 @@ const EN: Dict = {
|
|
|
62
68
|
assistantReply: 'Response',
|
|
63
69
|
bgAgentWaiting: 'Waiting for background agent',
|
|
64
70
|
bgAgentResuming: 'Background agent completed, resuming',
|
|
71
|
+
planReview: 'Plan Review',
|
|
72
|
+
approve: 'Approve',
|
|
73
|
+
reject: 'Reject',
|
|
74
|
+
planApproved: 'Plan approved. Starting implementation.',
|
|
75
|
+
planRejected: 'Plan rejected.',
|
|
76
|
+
planFeedbackPrompt: 'Enter feedback (optional, Enter to submit, Esc to skip): ',
|
|
65
77
|
};
|
|
66
78
|
|
|
67
79
|
const ALL: Record<UiLanguage, Dict> = {
|
|
@@ -10,7 +10,7 @@ export type FrontendConfig = {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
export type TranscriptItem = {
|
|
13
|
-
role: 'system' | 'user' | 'assistant' | 'assistant_streaming' | 'tool' | 'tool_result' | 'log';
|
|
13
|
+
role: 'system' | 'user' | 'assistant' | 'assistant_streaming' | 'tool' | 'tool_result' | 'log' | 'plan';
|
|
14
14
|
text: string;
|
|
15
15
|
tool_name?: string;
|
|
16
16
|
tool_input?: Record<string, unknown>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@illusion/web",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@illusion/web",
|
|
9
|
-
"version": "0.1.
|
|
9
|
+
"version": "0.1.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"highlight.js": "^11.11.0",
|
|
12
12
|
"react": "^18.3.1",
|
|
@@ -15,16 +15,16 @@
|
|
|
15
15
|
>>> from illusion.commands import CommandRegistry, SlashCommand
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
+
from illusion.commands.types import CommandContext, CommandHandler, CommandResult
|
|
18
19
|
from illusion.commands.registry import (
|
|
19
|
-
CommandContext,
|
|
20
20
|
CommandRegistry,
|
|
21
|
-
CommandResult,
|
|
22
21
|
SlashCommand,
|
|
23
22
|
create_default_command_registry,
|
|
24
23
|
)
|
|
25
24
|
|
|
26
25
|
__all__ = [
|
|
27
26
|
"CommandContext",
|
|
27
|
+
"CommandHandler",
|
|
28
28
|
"CommandRegistry",
|
|
29
29
|
"CommandResult",
|
|
30
30
|
"SlashCommand",
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""
|
|
2
|
+
认证相关斜杠命令
|
|
3
|
+
================
|
|
4
|
+
|
|
5
|
+
/login, /logout
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from illusion.commands.types import CommandContext, CommandResult
|
|
11
|
+
from illusion.api.provider import auth_status, detect_provider
|
|
12
|
+
from illusion.config.settings import load_settings, save_settings
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
async def login_handler(args: str, context: CommandContext) -> CommandResult:
|
|
16
|
+
"""显示认证状态或存储 API Key"""
|
|
17
|
+
del context
|
|
18
|
+
settings = load_settings()
|
|
19
|
+
provider = detect_provider(settings)
|
|
20
|
+
api_key = args.strip()
|
|
21
|
+
if not api_key:
|
|
22
|
+
masked = (
|
|
23
|
+
f"{settings.api_key[:6]}...{settings.api_key[-4:]}"
|
|
24
|
+
if settings.api_key
|
|
25
|
+
else "(not configured)"
|
|
26
|
+
)
|
|
27
|
+
return CommandResult(
|
|
28
|
+
message=(
|
|
29
|
+
f"Auth status:\n"
|
|
30
|
+
f"- provider: {provider.name}\n"
|
|
31
|
+
f"- auth_status: {auth_status(settings)}\n"
|
|
32
|
+
f"- base_url: {settings.base_url or '(default)'}\n"
|
|
33
|
+
f"- model: {settings.model}\n"
|
|
34
|
+
f"- api_key: {masked}\n"
|
|
35
|
+
"Usage: /login API_KEY"
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
env_key = settings._active_env_key
|
|
39
|
+
env = settings._active_env
|
|
40
|
+
env.api_key = api_key
|
|
41
|
+
settings.model_extra[env_key] = env.model_dump()
|
|
42
|
+
save_settings(settings)
|
|
43
|
+
return CommandResult(message="Stored API key in ~/.illusion/settings.json")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
async def logout_handler(_: str, context: CommandContext) -> CommandResult:
|
|
47
|
+
"""清除已存储的 API Key"""
|
|
48
|
+
del context
|
|
49
|
+
settings = load_settings()
|
|
50
|
+
env_key = settings._active_env_key
|
|
51
|
+
env = settings._active_env
|
|
52
|
+
env.api_key = ""
|
|
53
|
+
settings.model_extra[env_key] = env.model_dump()
|
|
54
|
+
save_settings(settings)
|
|
55
|
+
return CommandResult(message="Cleared stored API key.")
|