illusion-code 0.1.0__py3-none-any.whl

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 (214) hide show
  1. illusion/__init__.py +24 -0
  2. illusion/__main__.py +15 -0
  3. illusion/_frontend/dist/index.mjs +39208 -0
  4. illusion/_frontend/package.json +27 -0
  5. illusion/_frontend/src/App.tsx +624 -0
  6. illusion/_frontend/src/components/CommandPicker.tsx +98 -0
  7. illusion/_frontend/src/components/Composer.tsx +55 -0
  8. illusion/_frontend/src/components/ComposerController.tsx +128 -0
  9. illusion/_frontend/src/components/ConversationView.tsx +750 -0
  10. illusion/_frontend/src/components/Footer.tsx +25 -0
  11. illusion/_frontend/src/components/MarkdownContent.tsx +537 -0
  12. illusion/_frontend/src/components/MarkdownTable.tsx +245 -0
  13. illusion/_frontend/src/components/ModalHost.tsx +425 -0
  14. illusion/_frontend/src/components/MultilineTextInput.tsx +250 -0
  15. illusion/_frontend/src/components/PromptInput.tsx +64 -0
  16. illusion/_frontend/src/components/SelectModal.tsx +78 -0
  17. illusion/_frontend/src/components/SidePanel.tsx +175 -0
  18. illusion/_frontend/src/components/Spinner.tsx +77 -0
  19. illusion/_frontend/src/components/StatusBar.tsx +142 -0
  20. illusion/_frontend/src/components/SwarmPanel.tsx +141 -0
  21. illusion/_frontend/src/components/TodoPanel.tsx +126 -0
  22. illusion/_frontend/src/components/ToolCallDisplay.tsx +202 -0
  23. illusion/_frontend/src/components/TranscriptPane.tsx +79 -0
  24. illusion/_frontend/src/components/WelcomeBanner.tsx +37 -0
  25. illusion/_frontend/src/hooks/useBackendSession.ts +468 -0
  26. illusion/_frontend/src/hooks/useTerminalSize.ts +9 -0
  27. illusion/_frontend/src/i18n.ts +78 -0
  28. illusion/_frontend/src/index.tsx +42 -0
  29. illusion/_frontend/src/theme/ThemeContext.tsx +19 -0
  30. illusion/_frontend/src/theme/builtinThemes.ts +89 -0
  31. illusion/_frontend/src/types.ts +110 -0
  32. illusion/_frontend/src/utils/markdown.ts +33 -0
  33. illusion/_frontend/src/utils/thinking.ts +191 -0
  34. illusion/_frontend/tsconfig.json +13 -0
  35. illusion/_web_dist/assets/index-BseIw-ik.css +10 -0
  36. illusion/_web_dist/assets/index-C_0ZWMuW.js +82 -0
  37. illusion/_web_dist/index.html +16 -0
  38. illusion/api/__init__.py +36 -0
  39. illusion/api/client.py +568 -0
  40. illusion/api/codex_client.py +563 -0
  41. illusion/api/compat.py +138 -0
  42. illusion/api/effort.py +128 -0
  43. illusion/api/errors.py +57 -0
  44. illusion/api/openai_client.py +819 -0
  45. illusion/api/provider.py +148 -0
  46. illusion/api/registry.py +479 -0
  47. illusion/api/usage.py +45 -0
  48. illusion/auth/__init__.py +50 -0
  49. illusion/auth/copilot.py +419 -0
  50. illusion/auth/external.py +612 -0
  51. illusion/auth/flows.py +58 -0
  52. illusion/auth/manager.py +214 -0
  53. illusion/auth/storage.py +372 -0
  54. illusion/bridge/__init__.py +38 -0
  55. illusion/bridge/manager.py +190 -0
  56. illusion/bridge/session_runner.py +84 -0
  57. illusion/bridge/types.py +113 -0
  58. illusion/bridge/work_secret.py +131 -0
  59. illusion/cli.py +1228 -0
  60. illusion/commands/__init__.py +32 -0
  61. illusion/commands/registry.py +1934 -0
  62. illusion/config/__init__.py +39 -0
  63. illusion/config/i18n.py +522 -0
  64. illusion/config/paths.py +259 -0
  65. illusion/config/settings.py +564 -0
  66. illusion/coordinator/__init__.py +41 -0
  67. illusion/coordinator/agent_definitions.py +1093 -0
  68. illusion/coordinator/coordinator_mode.py +127 -0
  69. illusion/engine/__init__.py +95 -0
  70. illusion/engine/cost_tracker.py +55 -0
  71. illusion/engine/messages.py +369 -0
  72. illusion/engine/query.py +632 -0
  73. illusion/engine/query_engine.py +343 -0
  74. illusion/engine/stream_events.py +169 -0
  75. illusion/hooks/__init__.py +67 -0
  76. illusion/hooks/events.py +43 -0
  77. illusion/hooks/executor.py +397 -0
  78. illusion/hooks/hot_reload.py +74 -0
  79. illusion/hooks/loader.py +133 -0
  80. illusion/hooks/schemas.py +121 -0
  81. illusion/hooks/types.py +86 -0
  82. illusion/mcp/__init__.py +104 -0
  83. illusion/mcp/client.py +377 -0
  84. illusion/mcp/config.py +140 -0
  85. illusion/mcp/types.py +175 -0
  86. illusion/memory/__init__.py +36 -0
  87. illusion/memory/manager.py +94 -0
  88. illusion/memory/memdir.py +58 -0
  89. illusion/memory/paths.py +57 -0
  90. illusion/memory/scan.py +120 -0
  91. illusion/memory/search.py +83 -0
  92. illusion/memory/types.py +43 -0
  93. illusion/output_styles/__init__.py +15 -0
  94. illusion/output_styles/loader.py +64 -0
  95. illusion/permissions/__init__.py +39 -0
  96. illusion/permissions/checker.py +174 -0
  97. illusion/permissions/modes.py +38 -0
  98. illusion/platforms.py +148 -0
  99. illusion/plugins/__init__.py +71 -0
  100. illusion/plugins/bundled/__init__.py +0 -0
  101. illusion/plugins/installer.py +59 -0
  102. illusion/plugins/loader.py +301 -0
  103. illusion/plugins/schemas.py +51 -0
  104. illusion/plugins/types.py +56 -0
  105. illusion/prompts/__init__.py +29 -0
  106. illusion/prompts/claudemd.py +74 -0
  107. illusion/prompts/context.py +187 -0
  108. illusion/prompts/environment.py +189 -0
  109. illusion/prompts/system_prompt.py +155 -0
  110. illusion/py.typed +0 -0
  111. illusion/sandbox/__init__.py +29 -0
  112. illusion/sandbox/adapter.py +174 -0
  113. illusion/services/__init__.py +59 -0
  114. illusion/services/compact/__init__.py +1015 -0
  115. illusion/services/cron.py +338 -0
  116. illusion/services/cron_scheduler.py +715 -0
  117. illusion/services/file_history.py +258 -0
  118. illusion/services/lsp/__init__.py +455 -0
  119. illusion/services/session_storage.py +237 -0
  120. illusion/services/token_estimation.py +72 -0
  121. illusion/skills/__init__.py +60 -0
  122. illusion/skills/bundled/__init__.py +110 -0
  123. illusion/skills/bundled/content/batch.md +86 -0
  124. illusion/skills/bundled/content/coding-guidelines.md +70 -0
  125. illusion/skills/bundled/content/debug.md +38 -0
  126. illusion/skills/bundled/content/loop.md +82 -0
  127. illusion/skills/bundled/content/remember.md +105 -0
  128. illusion/skills/bundled/content/simplify.md +53 -0
  129. illusion/skills/bundled/content/skillify.md +113 -0
  130. illusion/skills/bundled/content/stuck.md +54 -0
  131. illusion/skills/bundled/content/update-config.md +329 -0
  132. illusion/skills/bundled/content/verify.md +74 -0
  133. illusion/skills/loader.py +219 -0
  134. illusion/skills/registry.py +40 -0
  135. illusion/skills/types.py +24 -0
  136. illusion/state/__init__.py +18 -0
  137. illusion/state/app_state.py +67 -0
  138. illusion/state/store.py +93 -0
  139. illusion/swarm/__init__.py +71 -0
  140. illusion/swarm/agent_executor.py +857 -0
  141. illusion/swarm/in_process.py +259 -0
  142. illusion/swarm/subprocess_backend.py +136 -0
  143. illusion/swarm/team_helpers.py +123 -0
  144. illusion/swarm/types.py +159 -0
  145. illusion/swarm/worktree.py +347 -0
  146. illusion/tasks/__init__.py +33 -0
  147. illusion/tasks/local_agent_task.py +42 -0
  148. illusion/tasks/local_shell_task.py +27 -0
  149. illusion/tasks/manager.py +377 -0
  150. illusion/tasks/stop_task.py +21 -0
  151. illusion/tasks/types.py +88 -0
  152. illusion/tools/__init__.py +126 -0
  153. illusion/tools/agent_tool.py +388 -0
  154. illusion/tools/ask_user_question_tool.py +186 -0
  155. illusion/tools/base.py +149 -0
  156. illusion/tools/bash_tool.py +413 -0
  157. illusion/tools/config_tool.py +90 -0
  158. illusion/tools/cron_tool.py +473 -0
  159. illusion/tools/enter_plan_mode_tool.py +147 -0
  160. illusion/tools/enter_worktree_tool.py +188 -0
  161. illusion/tools/exit_plan_mode_tool.py +69 -0
  162. illusion/tools/exit_worktree_tool.py +225 -0
  163. illusion/tools/file_edit_tool.py +283 -0
  164. illusion/tools/file_read_tool.py +294 -0
  165. illusion/tools/file_write_tool.py +184 -0
  166. illusion/tools/glob_tool.py +165 -0
  167. illusion/tools/grep_tool.py +190 -0
  168. illusion/tools/list_mcp_resources_tool.py +80 -0
  169. illusion/tools/lsp_tool.py +333 -0
  170. illusion/tools/mcp_auth_tool.py +100 -0
  171. illusion/tools/mcp_tool.py +75 -0
  172. illusion/tools/notebook_edit_tool.py +242 -0
  173. illusion/tools/powershell_tool.py +334 -0
  174. illusion/tools/read_mcp_resource_tool.py +63 -0
  175. illusion/tools/repl_tool.py +100 -0
  176. illusion/tools/send_message_tool.py +112 -0
  177. illusion/tools/shell_common.py +187 -0
  178. illusion/tools/skill_tool.py +86 -0
  179. illusion/tools/sleep_tool.py +62 -0
  180. illusion/tools/structured_output_tool.py +58 -0
  181. illusion/tools/task_create_tool.py +98 -0
  182. illusion/tools/task_get_tool.py +94 -0
  183. illusion/tools/task_list_tool.py +94 -0
  184. illusion/tools/task_output_tool.py +55 -0
  185. illusion/tools/task_stop_tool.py +52 -0
  186. illusion/tools/task_update_tool.py +224 -0
  187. illusion/tools/team_create_tool.py +236 -0
  188. illusion/tools/team_delete_tool.py +104 -0
  189. illusion/tools/todo_write_tool.py +198 -0
  190. illusion/tools/tool_search_tool.py +156 -0
  191. illusion/tools/web_fetch_tool.py +264 -0
  192. illusion/tools/web_search_tool.py +186 -0
  193. illusion/ui/__init__.py +23 -0
  194. illusion/ui/app.py +258 -0
  195. illusion/ui/backend_host.py +1180 -0
  196. illusion/ui/input.py +86 -0
  197. illusion/ui/output.py +363 -0
  198. illusion/ui/permission_dialog.py +47 -0
  199. illusion/ui/permission_store.py +99 -0
  200. illusion/ui/protocol.py +384 -0
  201. illusion/ui/react_launcher.py +280 -0
  202. illusion/ui/runtime.py +787 -0
  203. illusion/ui/textual_app.py +603 -0
  204. illusion/ui/web/__init__.py +10 -0
  205. illusion/ui/web/server.py +87 -0
  206. illusion/ui/web/ws_host.py +1197 -0
  207. illusion/utils/__init__.py +0 -0
  208. illusion/utils/ripgrep.py +299 -0
  209. illusion/utils/shell.py +248 -0
  210. illusion_code-0.1.0.dist-info/METADATA +1159 -0
  211. illusion_code-0.1.0.dist-info/RECORD +214 -0
  212. illusion_code-0.1.0.dist-info/WHEEL +4 -0
  213. illusion_code-0.1.0.dist-info/entry_points.txt +2 -0
  214. illusion_code-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,59 @@
1
+ """
2
+ 插件安装辅助模块
3
+ ================
4
+
5
+ 本模块提供插件安装和卸载功能。
6
+
7
+ 主要功能:
8
+ - 从路径安装插件到用户插件目录
9
+ - 卸载用户插件
10
+
11
+ 使用示例:
12
+ >>> from illusion.plugins.installer import install_plugin_from_path, uninstall_plugin
13
+ >>> install_plugin_from_path("/path/to/plugin")
14
+ >>> uninstall_plugin("my_plugin")
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import shutil
20
+ from pathlib import Path
21
+
22
+ from illusion.plugins.loader import get_user_plugins_dir
23
+
24
+
25
+ def install_plugin_from_path(source: str | Path) -> Path:
26
+ """安装插件目录到用户插件目录
27
+
28
+ 将源插件目录复制到用户插件目录。
29
+
30
+ Args:
31
+ source: 插件源目录路径
32
+
33
+ Returns:
34
+ Path: 安装后的插件目录路径
35
+ """
36
+ src = Path(source).resolve()
37
+ dest = get_user_plugins_dir() / src.name
38
+ if dest.exists():
39
+ shutil.rmtree(dest)
40
+ shutil.copytree(src, dest)
41
+ return dest
42
+
43
+
44
+ def uninstall_plugin(name: str) -> bool:
45
+ """卸载用户插件
46
+
47
+ 根据目录名称删除用户插件。
48
+
49
+ Args:
50
+ name: 插件名称(目录名)
51
+
52
+ Returns:
53
+ bool: 是否成功卸载
54
+ """
55
+ path = get_user_plugins_dir() / name
56
+ if not path.exists():
57
+ return False
58
+ shutil.rmtree(path)
59
+ return True
@@ -0,0 +1,301 @@
1
+ """
2
+ 插件发现和加载模块
3
+ ==================
4
+
5
+ 本模块实现插件的发现和加载功能。
6
+
7
+ 主要功能:
8
+ - 发现用户和项目插件目录
9
+ - 加载插件清单和配置
10
+ - 解析插件技能、命令、钩子和 MCP 服务器
11
+
12
+ 使用示例:
13
+ >>> from illusion.plugins.loader import load_plugins, get_user_plugins_dir
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import json
19
+ import logging
20
+ from pathlib import Path
21
+
22
+ from illusion.config.paths import get_config_dir
23
+ from illusion.plugins.schemas import PluginManifest
24
+ from illusion.plugins.types import LoadedPlugin
25
+ from illusion.skills.loader import _parse_skill_markdown
26
+ from illusion.skills.types import SkillDefinition
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+
31
+ def get_user_plugins_dir() -> Path:
32
+ """获取用户插件目录
33
+
34
+ 返回用户级别的插件目录,如果不存在则创建。
35
+
36
+ Returns:
37
+ Path: 用户插件目录路径
38
+ """
39
+ path = get_config_dir() / "plugins"
40
+ path.mkdir(parents=True, exist_ok=True)
41
+ return path
42
+
43
+
44
+ def get_project_plugins_dir(cwd: str | Path) -> Path:
45
+ """获取项目插件目录
46
+
47
+ 返回项目级别的插件目录。
48
+
49
+ Args:
50
+ cwd: 工作目录
51
+
52
+ Returns:
53
+ Path: 项目插件目录路径
54
+ """
55
+ path = Path(cwd).resolve() / ".illusion" / "plugins"
56
+ path.mkdir(parents=True, exist_ok=True)
57
+ return path
58
+
59
+
60
+ def _find_manifest(plugin_dir: Path) -> Path | None:
61
+ """查找插件清单文件
62
+
63
+ 在标准位置或 .claude-plugin/ 目录下查找 plugin.json。
64
+
65
+ Args:
66
+ plugin_dir: 插件目录
67
+
68
+ Returns:
69
+ Path | None: 找到的清单文件路径,不存在则返回 None
70
+ """
71
+ for candidate in [
72
+ plugin_dir / "plugin.json",
73
+ plugin_dir / ".claude-plugin" / "plugin.json",
74
+ ]:
75
+ if candidate.exists():
76
+ return candidate
77
+ return None
78
+
79
+
80
+ def discover_plugin_paths(cwd: str | Path) -> list[Path]:
81
+ """发现插件目录
82
+
83
+ 从用户和项目位置查找所有插件目录。
84
+
85
+ Args:
86
+ cwd: 工作目录
87
+
88
+ Returns:
89
+ list[Path]: 插件目录路径列表
90
+ """
91
+ roots = [get_user_plugins_dir(), get_project_plugins_dir(cwd)]
92
+ paths: list[Path] = []
93
+ for root in roots:
94
+ if not root.exists():
95
+ continue
96
+ for path in sorted(root.iterdir()):
97
+ if path.is_dir() and _find_manifest(path) is not None:
98
+ paths.append(path)
99
+ return paths
100
+
101
+
102
+ def load_plugins(settings, cwd: str | Path) -> list[LoadedPlugin]:
103
+ """从磁盘加载所有插件
104
+
105
+ Args:
106
+ settings: 设置对象
107
+ cwd: 工作目录
108
+
109
+ Returns:
110
+ list[LoadedPlugin]: 已加载的插件列表
111
+ """
112
+ plugins: list[LoadedPlugin] = []
113
+ for path in discover_plugin_paths(cwd):
114
+ plugin = load_plugin(path, settings.enabled_plugins)
115
+ if plugin is not None:
116
+ plugins.append(plugin)
117
+ return plugins
118
+
119
+
120
+ def load_plugin(path: Path, enabled_plugins: dict[str, bool]) -> LoadedPlugin | None:
121
+ """加载单个插件目录
122
+
123
+ Args:
124
+ path: 插件目录路径
125
+ enabled_plugins: 启用的插件配置
126
+
127
+ Returns:
128
+ LoadedPlugin | None: 已加载的插件,未找到清单则返回 None
129
+ """
130
+ manifest_path = _find_manifest(path)
131
+ if manifest_path is None:
132
+ return None
133
+ try:
134
+ manifest = PluginManifest.model_validate_json(manifest_path.read_text(encoding="utf-8"))
135
+ except Exception as exc:
136
+ logger.debug("Failed to load plugin manifest from %s: %s", manifest_path, exc)
137
+ return None
138
+ enabled = enabled_plugins.get(manifest.name, manifest.enabled_by_default)
139
+
140
+ # 从多个位置发现技能
141
+ skills = _load_plugin_skills(path / manifest.skills_dir)
142
+
143
+ # 从 plugin commands/ 目录发现命令
144
+ commands_dir = path / "commands"
145
+ if commands_dir.exists():
146
+ skills.extend(_load_plugin_skills(commands_dir))
147
+
148
+ # 从 plugin agents/ 目录发现智能体
149
+ agents_dir = path / "agents"
150
+ if agents_dir.exists():
151
+ skills.extend(_load_plugin_skills(agents_dir))
152
+
153
+ # 从 hooks/ 目录或根 hooks.json 发现钩子
154
+ hooks = _load_plugin_hooks(path / manifest.hooks_file)
155
+ hooks_dir_file = path / "hooks" / "hooks.json"
156
+ if not hooks and hooks_dir_file.exists():
157
+ hooks = _load_plugin_hooks_structured(hooks_dir_file, path)
158
+
159
+ mcp = _load_plugin_mcp(path / manifest.mcp_file)
160
+ mcp_json = path / ".mcp.json"
161
+ if not mcp and mcp_json.exists():
162
+ mcp = _load_plugin_mcp(mcp_json)
163
+
164
+ return LoadedPlugin(
165
+ manifest=manifest,
166
+ path=path,
167
+ enabled=enabled,
168
+ skills=skills,
169
+ hooks=hooks,
170
+ mcp_servers=mcp,
171
+ commands=[s for s in skills if s.source == "plugin"],
172
+ )
173
+
174
+
175
+ def _load_plugin_skills(path: Path) -> list[SkillDefinition]:
176
+ """从目录中的 markdown 和 yaml 文件加载技能定义
177
+
178
+ Args:
179
+ path: 包含 .md/.yaml/.yml 技能文件的目录
180
+
181
+ Returns:
182
+ list[SkillDefinition]: 解析后的技能定义列表,如果路径不存在则返回空列表
183
+ """
184
+ if not path.exists():
185
+ return []
186
+ from illusion.skills.loader import _load_yaml_skill
187
+
188
+ skills: list[SkillDefinition] = []
189
+ for skill_path in sorted(path.iterdir()):
190
+ if not skill_path.is_file():
191
+ continue
192
+ if skill_path.suffix in (".yaml", ".yml"):
193
+ skill = _load_yaml_skill(skill_path, source="plugin")
194
+ if skill:
195
+ skills.append(skill)
196
+ elif skill_path.suffix == ".md":
197
+ content = skill_path.read_text(encoding="utf-8")
198
+ name, description = _parse_skill_markdown(skill_path.stem, content)
199
+ skills.append(
200
+ SkillDefinition(
201
+ name=name,
202
+ description=description,
203
+ content=content,
204
+ source="plugin",
205
+ path=str(skill_path),
206
+ )
207
+ )
208
+ return skills
209
+
210
+
211
+ def _load_plugin_hooks(path: Path) -> dict[str, list]:
212
+ """从平面 hooks.json 文件加载钩子
213
+
214
+ Args:
215
+ path: hooks JSON 文件路径
216
+
217
+ Returns:
218
+ dict[str, list]: 事件名称到钩子定义对象列表的字典
219
+ """
220
+ if not path.exists():
221
+ return {}
222
+ from illusion.hooks.schemas import (
223
+ AgentHookDefinition,
224
+ CommandHookDefinition,
225
+ HttpHookDefinition,
226
+ PromptHookDefinition,
227
+ )
228
+
229
+ raw = json.loads(path.read_text(encoding="utf-8"))
230
+ parsed: dict[str, list] = {}
231
+ for event, hooks in raw.items():
232
+ parsed[event] = []
233
+ for hook in hooks:
234
+ hook_type = hook.get("type")
235
+ if hook_type == "command":
236
+ parsed[event].append(CommandHookDefinition.model_validate(hook))
237
+ elif hook_type == "prompt":
238
+ parsed[event].append(PromptHookDefinition.model_validate(hook))
239
+ elif hook_type == "http":
240
+ parsed[event].append(HttpHookDefinition.model_validate(hook))
241
+ elif hook_type == "agent":
242
+ parsed[event].append(AgentHookDefinition.model_validate(hook))
243
+ return parsed
244
+
245
+
246
+ def _load_plugin_hooks_structured(path: Path, plugin_root: Path) -> dict[str, list]:
247
+ """从结构化 hooks.json 格式加载钩子
248
+
249
+ Args:
250
+ path: hooks.json 文件路径
251
+ plugin_root: 插件根目录
252
+
253
+ Returns:
254
+ dict[str, list]: 解析后的钩子字典
255
+ """
256
+ if not path.exists():
257
+ return {}
258
+ try:
259
+ raw = json.loads(path.read_text(encoding="utf-8"))
260
+ except (json.JSONDecodeError, OSError):
261
+ return {}
262
+ hooks_data = raw.get("hooks", raw)
263
+ if not isinstance(hooks_data, dict):
264
+ return {}
265
+ parsed: dict[str, list] = {}
266
+ for event, entries in hooks_data.items():
267
+ if not isinstance(entries, list):
268
+ continue
269
+ parsed[event] = []
270
+ for entry in entries:
271
+ hook_list = entry.get("hooks", [])
272
+ matcher = entry.get("matcher", "")
273
+ for hook in hook_list:
274
+ # 将 ${CLAUDE_PLUGIN_ROOT} 替换为实际路径
275
+ cmd = hook.get("command", "")
276
+ cmd = cmd.replace("${CLAUDE_PLUGIN_ROOT}", str(plugin_root))
277
+ parsed[event].append({
278
+ "type": hook.get("type", "command"),
279
+ "command": cmd,
280
+ "matcher": matcher,
281
+ "timeout": hook.get("timeout"),
282
+ })
283
+ return parsed
284
+
285
+
286
+ def _load_plugin_mcp(path: Path) -> dict[str, object]:
287
+ """从 JSON 文件加载 MCP 服务器配置
288
+
289
+ Args:
290
+ path: MCP 配置文件路径(例如 .mcp.json)
291
+
292
+ Returns:
293
+ dict[str, object]: 服务器名称到配置对象的字典
294
+ """
295
+ if not path.exists():
296
+ return {}
297
+ from illusion.mcp.types import McpJsonConfig
298
+
299
+ raw = json.loads(path.read_text(encoding="utf-8"))
300
+ parsed = McpJsonConfig.model_validate(raw)
301
+ return parsed.mcpServers
@@ -0,0 +1,51 @@
1
+ """
2
+ 插件清单模式模块
3
+ ================
4
+
5
+ 本模块定义插件清单的数据模型。
6
+
7
+ 主要组件:
8
+ - PluginManifest: 插件清单
9
+
10
+ 使用示例:
11
+ >>> from illusion.plugins.schemas import PluginManifest
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from pydantic import BaseModel
17
+
18
+
19
+ class PluginManifest(BaseModel):
20
+ """插件清单
21
+
22
+ 定义插件的元数据,存储在 plugin.json 或 .claude-plugin/plugin.json 文件中。
23
+
24
+ Attributes:
25
+ name: 插件名称
26
+ version: 插件版本
27
+ description: 插件描述
28
+ enabled_by_default: 默认是否启用
29
+ skills_dir: 技能目录名称
30
+ hooks_file: 钩子文件名
31
+ mcp_file: MCP 配置文件名
32
+ author: 作者信息
33
+ commands: 命令配置
34
+ agents: 智能体配置
35
+ skills: 技能配置
36
+ hooks: 钩子配置
37
+ """
38
+
39
+ name: str # 插件名称
40
+ version: str = "0.0.0" # 插件版本
41
+ description: str = "" # 插件描述
42
+ enabled_by_default: bool = True # 默认是否启用
43
+ skills_dir: str = "skills" # 技能目录名称
44
+ hooks_file: str = "hooks.json" # 钩子文件名
45
+ mcp_file: str = "mcp.json" # MCP 配置文件名
46
+ # 扩展字段:可选的 author, commands, agents 等
47
+ author: dict | None = None # 作者信息
48
+ commands: str | list | dict | None = None # 命令配置
49
+ agents: str | list | None = None # 智能体配置
50
+ skills: str | list | None = None # 技能配置
51
+ hooks: str | dict | list | None = None # 钩子配置
@@ -0,0 +1,56 @@
1
+ """
2
+ 插件运行时类型模块
3
+ ==================
4
+
5
+ 本模块定义插件运行时使用的类型。
6
+
7
+ 主要组件:
8
+ - LoadedPlugin: 已加载的插件
9
+
10
+ 使用示例:
11
+ >>> from illusion.plugins.types import LoadedPlugin
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from dataclasses import dataclass, field
17
+ from pathlib import Path
18
+
19
+ from illusion.mcp.types import McpServerConfig
20
+ from illusion.plugins.schemas import PluginManifest
21
+ from illusion.skills.types import SkillDefinition
22
+
23
+
24
+ @dataclass(frozen=True)
25
+ class LoadedPlugin:
26
+ """已加载的插件及其贡献的内容
27
+
28
+ 表示一个已加载的插件,包含清单、路径、启用状态、技能、钩子等。
29
+
30
+ Attributes:
31
+ manifest: 插件清单
32
+ path: 插件目录路径
33
+ enabled: 是否启用
34
+ skills: 技能定义列表
35
+ hooks: 钩子字典
36
+ mcp_servers: MCP 服务器配置字典
37
+ commands: 命令技能列表
38
+ """
39
+
40
+ manifest: PluginManifest # 插件清单
41
+ path: Path # 插件目录路径
42
+ enabled: bool # 是否启用
43
+ skills: list[SkillDefinition] = field(default_factory=list) # 技能列表
44
+ hooks: dict[str, list] = field(default_factory=dict) # 钩子字典
45
+ mcp_servers: dict[str, McpServerConfig] = field(default_factory=dict) # MCP 服务器配置
46
+ commands: list[SkillDefinition] = field(default_factory=list) # 命令列表
47
+
48
+ @property
49
+ def name(self) -> str:
50
+ """获取插件名称"""
51
+ return self.manifest.name
52
+
53
+ @property
54
+ def description(self) -> str:
55
+ """获取插件描述"""
56
+ return self.manifest.description
@@ -0,0 +1,29 @@
1
+ """
2
+ 提示词模块
3
+ ==========
4
+
5
+ 本模块提供 IllusionCode 系统提示词构建功能。
6
+
7
+ 主要组件:
8
+ - build_system_prompt: 构建系统提示词
9
+ - build_runtime_system_prompt: 构建运行时系统提示词
10
+ - discover_claude_md_files: 发现 Claude.md 文件
11
+ - load_claude_md_prompt: 加载 Claude.md 提示词
12
+ - get_environment_info: 获取环境信息
13
+
14
+ 使用示例:
15
+ >>> from illusion.prompts import build_system_prompt, get_environment_info
16
+ """
17
+
18
+ from illusion.prompts.claudemd import discover_claude_md_files, load_claude_md_prompt
19
+ from illusion.prompts.context import build_runtime_system_prompt
20
+ from illusion.prompts.system_prompt import build_system_prompt
21
+ from illusion.prompts.environment import get_environment_info
22
+
23
+ __all__ = [
24
+ "build_runtime_system_prompt",
25
+ "build_system_prompt",
26
+ "discover_claude_md_files",
27
+ "get_environment_info",
28
+ "load_claude_md_prompt",
29
+ ]
@@ -0,0 +1,74 @@
1
+ """
2
+ CLAUDE.md 发现和加载模块
3
+ ========================
4
+
5
+ 本模块实现 CLAUDE.md 指令文件的发现和加载功能。
6
+
7
+ 主要功能:
8
+ - 在当前目录中查找 CLAUDE.md 文件
9
+ - 发现 .claude/rules 目录下的规则文件
10
+ - 将多个指令文件加载为一个提示词章节
11
+
12
+ 使用示例:
13
+ >>> from illusion.prompts.claudemd import discover_claude_md_files, load_claude_md_prompt
14
+ >>> files = discover_claude_md_files("/path/to/project")
15
+ >>> prompt = load_claude_md_prompt("/path/to/project")
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ from pathlib import Path
21
+
22
+
23
+ def discover_claude_md_files(cwd: str | Path) -> list[Path]:
24
+ """发现相关的 CLAUDE.md 指令文件(只在 cwd 中查找)
25
+
26
+ Args:
27
+ cwd: 工作目录
28
+
29
+ Returns:
30
+ list[Path]: 找到的指令文件路径列表
31
+ """
32
+ current = Path(cwd).resolve()
33
+ results: list[Path] = []
34
+ seen: set[Path] = set()
35
+
36
+ for candidate in (
37
+ current / "CLAUDE.md",
38
+ current / ".claude" / "CLAUDE.md",
39
+ ):
40
+ if candidate.exists() and candidate not in seen:
41
+ results.append(candidate)
42
+ seen.add(candidate)
43
+
44
+ rules_dir = current / ".claude" / "rules"
45
+ if rules_dir.is_dir():
46
+ for rule in sorted(rules_dir.glob("*.md")):
47
+ if rule not in seen:
48
+ results.append(rule)
49
+ seen.add(rule)
50
+
51
+ return results
52
+
53
+
54
+ def load_claude_md_prompt(cwd: str | Path, *, max_chars_per_file: int = 12000) -> str | None:
55
+ """将发现的指令文件加载为一个提示词章节
56
+
57
+ Args:
58
+ cwd: 工作目录
59
+ max_chars_per_file: 每个文件的最大字符数
60
+
61
+ Returns:
62
+ str | None: 格式化的提示词章节,如果没有文件则返回 None
63
+ """
64
+ files = discover_claude_md_files(cwd)
65
+ if not files:
66
+ return None
67
+
68
+ lines = ["# Project Instructions"]
69
+ for path in files:
70
+ content = path.read_text(encoding="utf-8", errors="replace")
71
+ if len(content) > max_chars_per_file:
72
+ content = content[:max_chars_per_file] + "\n...[truncated]..."
73
+ lines.extend(["", f"## {path}", "```md", content.strip(), "```"])
74
+ return "\n".join(lines)