claude-mpm 5.4.48__py3-none-any.whl → 5.6.34__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.

Potentially problematic release.


This version of claude-mpm might be problematic. Click here for more details.

Files changed (467) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +66 -241
  3. claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
  4. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
  5. claude_mpm/agents/PM_INSTRUCTIONS.md +119 -689
  6. claude_mpm/agents/WORKFLOW.md +2 -0
  7. claude_mpm/agents/templates/circuit-breakers.md +26 -17
  8. claude_mpm/cli/__init__.py +5 -1
  9. claude_mpm/cli/commands/agents.py +2 -4
  10. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  11. claude_mpm/cli/commands/autotodos.py +566 -0
  12. claude_mpm/cli/commands/commander.py +216 -0
  13. claude_mpm/cli/commands/configure.py +620 -21
  14. claude_mpm/cli/commands/configure_agent_display.py +3 -1
  15. claude_mpm/cli/commands/hook_errors.py +60 -60
  16. claude_mpm/cli/commands/monitor.py +2 -2
  17. claude_mpm/cli/commands/mpm_init/core.py +15 -8
  18. claude_mpm/cli/commands/profile.py +9 -10
  19. claude_mpm/cli/commands/run.py +35 -3
  20. claude_mpm/cli/commands/skill_source.py +51 -2
  21. claude_mpm/cli/commands/skills.py +171 -17
  22. claude_mpm/cli/executor.py +120 -16
  23. claude_mpm/cli/interactive/__init__.py +10 -0
  24. claude_mpm/cli/interactive/agent_wizard.py +30 -50
  25. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  26. claude_mpm/cli/interactive/skill_selector.py +481 -0
  27. claude_mpm/cli/parsers/base_parser.py +76 -1
  28. claude_mpm/cli/parsers/commander_parser.py +116 -0
  29. claude_mpm/cli/parsers/profile_parser.py +0 -1
  30. claude_mpm/cli/parsers/run_parser.py +10 -0
  31. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  32. claude_mpm/cli/parsers/skills_parser.py +5 -0
  33. claude_mpm/cli/startup.py +544 -511
  34. claude_mpm/cli/startup_display.py +74 -6
  35. claude_mpm/cli/startup_logging.py +2 -2
  36. claude_mpm/cli/utils.py +7 -3
  37. claude_mpm/commander/__init__.py +78 -0
  38. claude_mpm/commander/adapters/__init__.py +60 -0
  39. claude_mpm/commander/adapters/auggie.py +260 -0
  40. claude_mpm/commander/adapters/base.py +288 -0
  41. claude_mpm/commander/adapters/claude_code.py +392 -0
  42. claude_mpm/commander/adapters/codex.py +237 -0
  43. claude_mpm/commander/adapters/communication.py +366 -0
  44. claude_mpm/commander/adapters/example_usage.py +310 -0
  45. claude_mpm/commander/adapters/mpm.py +389 -0
  46. claude_mpm/commander/adapters/registry.py +204 -0
  47. claude_mpm/commander/api/__init__.py +16 -0
  48. claude_mpm/commander/api/app.py +121 -0
  49. claude_mpm/commander/api/errors.py +133 -0
  50. claude_mpm/commander/api/routes/__init__.py +8 -0
  51. claude_mpm/commander/api/routes/events.py +184 -0
  52. claude_mpm/commander/api/routes/inbox.py +171 -0
  53. claude_mpm/commander/api/routes/messages.py +148 -0
  54. claude_mpm/commander/api/routes/projects.py +271 -0
  55. claude_mpm/commander/api/routes/sessions.py +226 -0
  56. claude_mpm/commander/api/routes/work.py +296 -0
  57. claude_mpm/commander/api/schemas.py +186 -0
  58. claude_mpm/commander/chat/__init__.py +7 -0
  59. claude_mpm/commander/chat/cli.py +146 -0
  60. claude_mpm/commander/chat/commands.py +96 -0
  61. claude_mpm/commander/chat/repl.py +310 -0
  62. claude_mpm/commander/config.py +51 -0
  63. claude_mpm/commander/config_loader.py +115 -0
  64. claude_mpm/commander/core/__init__.py +10 -0
  65. claude_mpm/commander/core/block_manager.py +325 -0
  66. claude_mpm/commander/core/response_manager.py +323 -0
  67. claude_mpm/commander/daemon.py +603 -0
  68. claude_mpm/commander/env_loader.py +59 -0
  69. claude_mpm/commander/events/__init__.py +26 -0
  70. claude_mpm/commander/events/manager.py +332 -0
  71. claude_mpm/commander/frameworks/__init__.py +12 -0
  72. claude_mpm/commander/frameworks/base.py +146 -0
  73. claude_mpm/commander/frameworks/claude_code.py +58 -0
  74. claude_mpm/commander/frameworks/mpm.py +62 -0
  75. claude_mpm/commander/inbox/__init__.py +16 -0
  76. claude_mpm/commander/inbox/dedup.py +128 -0
  77. claude_mpm/commander/inbox/inbox.py +224 -0
  78. claude_mpm/commander/inbox/models.py +70 -0
  79. claude_mpm/commander/instance_manager.py +450 -0
  80. claude_mpm/commander/llm/__init__.py +6 -0
  81. claude_mpm/commander/llm/openrouter_client.py +167 -0
  82. claude_mpm/commander/llm/summarizer.py +70 -0
  83. claude_mpm/commander/memory/__init__.py +45 -0
  84. claude_mpm/commander/memory/compression.py +347 -0
  85. claude_mpm/commander/memory/embeddings.py +230 -0
  86. claude_mpm/commander/memory/entities.py +310 -0
  87. claude_mpm/commander/memory/example_usage.py +290 -0
  88. claude_mpm/commander/memory/integration.py +325 -0
  89. claude_mpm/commander/memory/search.py +381 -0
  90. claude_mpm/commander/memory/store.py +657 -0
  91. claude_mpm/commander/models/__init__.py +18 -0
  92. claude_mpm/commander/models/events.py +121 -0
  93. claude_mpm/commander/models/project.py +162 -0
  94. claude_mpm/commander/models/work.py +214 -0
  95. claude_mpm/commander/parsing/__init__.py +20 -0
  96. claude_mpm/commander/parsing/extractor.py +132 -0
  97. claude_mpm/commander/parsing/output_parser.py +270 -0
  98. claude_mpm/commander/parsing/patterns.py +100 -0
  99. claude_mpm/commander/persistence/__init__.py +11 -0
  100. claude_mpm/commander/persistence/event_store.py +274 -0
  101. claude_mpm/commander/persistence/state_store.py +309 -0
  102. claude_mpm/commander/persistence/work_store.py +164 -0
  103. claude_mpm/commander/polling/__init__.py +13 -0
  104. claude_mpm/commander/polling/event_detector.py +104 -0
  105. claude_mpm/commander/polling/output_buffer.py +49 -0
  106. claude_mpm/commander/polling/output_poller.py +153 -0
  107. claude_mpm/commander/project_session.py +268 -0
  108. claude_mpm/commander/proxy/__init__.py +12 -0
  109. claude_mpm/commander/proxy/formatter.py +89 -0
  110. claude_mpm/commander/proxy/output_handler.py +191 -0
  111. claude_mpm/commander/proxy/relay.py +155 -0
  112. claude_mpm/commander/registry.py +410 -0
  113. claude_mpm/commander/runtime/__init__.py +10 -0
  114. claude_mpm/commander/runtime/executor.py +191 -0
  115. claude_mpm/commander/runtime/monitor.py +346 -0
  116. claude_mpm/commander/session/__init__.py +6 -0
  117. claude_mpm/commander/session/context.py +81 -0
  118. claude_mpm/commander/session/manager.py +59 -0
  119. claude_mpm/commander/tmux_orchestrator.py +361 -0
  120. claude_mpm/commander/web/__init__.py +1 -0
  121. claude_mpm/commander/work/__init__.py +30 -0
  122. claude_mpm/commander/work/executor.py +207 -0
  123. claude_mpm/commander/work/queue.py +405 -0
  124. claude_mpm/commander/workflow/__init__.py +27 -0
  125. claude_mpm/commander/workflow/event_handler.py +241 -0
  126. claude_mpm/commander/workflow/notifier.py +146 -0
  127. claude_mpm/commands/mpm-config.md +8 -0
  128. claude_mpm/commands/mpm-doctor.md +8 -0
  129. claude_mpm/commands/mpm-help.md +8 -0
  130. claude_mpm/commands/mpm-init.md +8 -0
  131. claude_mpm/commands/mpm-monitor.md +8 -0
  132. claude_mpm/commands/mpm-organize.md +8 -0
  133. claude_mpm/commands/mpm-postmortem.md +8 -0
  134. claude_mpm/commands/mpm-session-resume.md +9 -1
  135. claude_mpm/commands/mpm-status.md +8 -0
  136. claude_mpm/commands/mpm-ticket-view.md +8 -0
  137. claude_mpm/commands/mpm-version.md +8 -0
  138. claude_mpm/commands/mpm.md +8 -0
  139. claude_mpm/config/agent_presets.py +8 -7
  140. claude_mpm/config/skill_sources.py +16 -0
  141. claude_mpm/constants.py +1 -0
  142. claude_mpm/core/claude_runner.py +154 -2
  143. claude_mpm/core/config.py +35 -22
  144. claude_mpm/core/config_constants.py +74 -9
  145. claude_mpm/core/constants.py +56 -12
  146. claude_mpm/core/hook_manager.py +51 -3
  147. claude_mpm/core/interactive_session.py +12 -11
  148. claude_mpm/core/logger.py +26 -9
  149. claude_mpm/core/logging_utils.py +39 -13
  150. claude_mpm/core/network_config.py +148 -0
  151. claude_mpm/core/oneshot_session.py +7 -6
  152. claude_mpm/core/optimized_startup.py +3 -1
  153. claude_mpm/core/output_style_manager.py +66 -18
  154. claude_mpm/core/shared/config_loader.py +3 -1
  155. claude_mpm/core/socketio_pool.py +47 -15
  156. claude_mpm/core/unified_config.py +54 -8
  157. claude_mpm/core/unified_paths.py +95 -90
  158. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
  159. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
  160. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
  161. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
  162. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
  163. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
  164. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
  165. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
  166. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
  167. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js +1 -0
  168. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  169. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js +4 -0
  170. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uj46x2Wr.js → BSNlmTZj.js} +1 -1
  171. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
  172. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
  173. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
  174. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
  175. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
  176. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
  177. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
  178. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
  179. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
  180. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
  181. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
  182. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
  183. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
  184. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
  185. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
  186. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
  187. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
  188. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
  189. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  190. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
  191. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  192. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
  193. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
  194. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
  195. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
  196. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
  197. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{N4qtv3Hx.js → DR8nis88.js} +2 -2
  198. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
  199. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  200. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
  201. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
  202. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
  203. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
  204. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
  205. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
  206. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  207. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
  208. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
  209. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
  210. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DjhvlsAc.js → NqQ1dWOy.js} +1 -1
  211. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
  212. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
  213. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
  214. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
  215. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
  216. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
  217. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
  218. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
  219. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.CAGBuiOw.js → 0.RgBboRvH.js} +1 -1
  220. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
  221. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
  222. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
  223. claude_mpm/dashboard/static/svelte-build/index.html +11 -11
  224. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  225. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  226. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  227. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  228. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  229. claude_mpm/experimental/cli_enhancements.py +2 -1
  230. claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
  231. claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
  232. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  233. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  234. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  235. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  236. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  237. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
  238. claude_mpm/hooks/claude_hooks/event_handlers.py +527 -136
  239. claude_mpm/hooks/claude_hooks/hook_handler.py +170 -104
  240. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  241. claude_mpm/hooks/claude_hooks/installer.py +206 -36
  242. claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
  243. claude_mpm/hooks/claude_hooks/response_tracking.py +43 -60
  244. claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
  245. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  246. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  247. claude_mpm/hooks/claude_hooks/services/__pycache__/container.cpython-311.pyc +0 -0
  248. claude_mpm/hooks/claude_hooks/services/__pycache__/protocols.cpython-311.pyc +0 -0
  249. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  250. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  251. claude_mpm/hooks/claude_hooks/services/connection_manager.py +41 -26
  252. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
  253. claude_mpm/hooks/claude_hooks/services/container.py +310 -0
  254. claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
  255. claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
  256. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +75 -77
  257. claude_mpm/hooks/session_resume_hook.py +89 -1
  258. claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
  259. claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
  260. claude_mpm/init.py +215 -2
  261. claude_mpm/scripts/claude-hook-handler.sh +46 -19
  262. claude_mpm/scripts/start_activity_logging.py +0 -0
  263. claude_mpm/services/agents/agent_recommendation_service.py +8 -8
  264. claude_mpm/services/agents/agent_selection_service.py +2 -2
  265. claude_mpm/services/agents/cache_git_manager.py +1 -1
  266. claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -1
  267. claude_mpm/services/agents/deployment/agent_format_converter.py +8 -6
  268. claude_mpm/services/agents/deployment/agent_template_builder.py +14 -4
  269. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  270. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +4 -4
  271. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +4 -1
  272. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  273. claude_mpm/services/agents/git_source_manager.py +6 -2
  274. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  275. claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
  276. claude_mpm/services/agents/sources/git_source_sync_service.py +10 -5
  277. claude_mpm/services/agents/startup_sync.py +5 -2
  278. claude_mpm/services/cli/__init__.py +3 -0
  279. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  280. claude_mpm/services/cli/session_resume_helper.py +10 -2
  281. claude_mpm/services/command_deployment_service.py +44 -26
  282. claude_mpm/services/delegation_detector.py +175 -0
  283. claude_mpm/services/diagnostics/checks/agent_sources_check.py +30 -0
  284. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
  285. claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
  286. claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
  287. claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
  288. claude_mpm/services/diagnostics/models.py +14 -1
  289. claude_mpm/services/event_log.py +325 -0
  290. claude_mpm/services/hook_installer_service.py +77 -8
  291. claude_mpm/services/infrastructure/__init__.py +4 -0
  292. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  293. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  294. claude_mpm/services/monitor/daemon_manager.py +15 -4
  295. claude_mpm/services/monitor/management/lifecycle.py +8 -3
  296. claude_mpm/services/monitor/server.py +106 -16
  297. claude_mpm/services/pm_skills_deployer.py +267 -94
  298. claude_mpm/services/profile_manager.py +10 -4
  299. claude_mpm/services/skills/git_skill_source_manager.py +192 -29
  300. claude_mpm/services/skills/selective_skill_deployer.py +211 -46
  301. claude_mpm/services/skills/skill_discovery_service.py +74 -4
  302. claude_mpm/services/skills_deployer.py +188 -67
  303. claude_mpm/services/socketio/handlers/hook.py +14 -7
  304. claude_mpm/services/socketio/server/main.py +12 -4
  305. claude_mpm/skills/__init__.py +2 -1
  306. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  307. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  308. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  309. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  310. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  311. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  312. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  313. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  314. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  315. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  316. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  317. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  318. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  319. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  320. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  321. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  322. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  323. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  324. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  325. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  326. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  327. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  328. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  329. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  330. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  331. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  332. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  333. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  334. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  335. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  336. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  337. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  338. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  339. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  340. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  341. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  342. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  343. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  344. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  345. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  346. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  347. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  348. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  349. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  350. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  351. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  352. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  353. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  354. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  355. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  356. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  357. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  358. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  359. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  360. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  361. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  362. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  363. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  364. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  365. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  366. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  367. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  368. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  369. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  370. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  371. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  372. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  373. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  374. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  375. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  376. claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
  377. claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
  378. claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
  379. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  380. claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
  381. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  382. claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
  383. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  384. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  385. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  386. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  387. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  388. claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
  389. claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
  390. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  391. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  392. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  393. claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
  394. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  395. claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
  396. claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
  397. claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
  398. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  399. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  400. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  401. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  402. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  403. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  404. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  405. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  406. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  407. claude_mpm/skills/bundled/security-scanning.md +112 -0
  408. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  409. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  410. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  411. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  412. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  413. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  414. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  415. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  416. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  417. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  418. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  419. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  420. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  421. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  422. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  423. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  424. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  425. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  426. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  427. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  428. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  429. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  430. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  431. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  432. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  433. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  434. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  435. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  436. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  437. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  438. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  439. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  440. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  441. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  442. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  443. claude_mpm/skills/registry.py +295 -90
  444. claude_mpm/skills/skill_manager.py +29 -23
  445. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  446. claude_mpm/utils/agent_dependency_loader.py +103 -4
  447. claude_mpm/utils/robust_installer.py +45 -24
  448. claude_mpm-5.6.34.dist-info/METADATA +393 -0
  449. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/RECORD +453 -151
  450. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +0 -1
  451. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +0 -1
  452. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +0 -1
  453. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +0 -1
  454. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +0 -1
  455. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +0 -2
  456. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +0 -2
  457. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +0 -1
  458. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +0 -1
  459. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +0 -10
  460. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  461. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  462. claude_mpm-5.4.48.dist-info/METADATA +0 -999
  463. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/WHEEL +0 -0
  464. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/entry_points.txt +0 -0
  465. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE +0 -0
  466. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  467. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,384 @@
1
+ ---
2
+ name: tauri-testing
3
+ description: Comprehensive testing strategies for Tauri apps including unit tests, integration tests, IPC mocking, and end-to-end testing
4
+ version: 1.0.0
5
+ category: development
6
+ author: Claude MPM Team
7
+ license: MIT
8
+ progressive_disclosure:
9
+ entry_point:
10
+ summary: "Complete testing: unit tests for commands, integration tests for IPC, mocking patterns, E2E with WebDriver"
11
+ when_to_use: "Ensuring Tauri app quality with comprehensive test coverage for both Rust backend and frontend"
12
+ quick_start: "1. Unit test commands 2. Mock IPC in frontend 3. Integration test with MockRuntime 4. E2E with tauri-driver"
13
+ context_limit: 500
14
+ tags:
15
+ - tauri
16
+ - testing
17
+ - unit-tests
18
+ - integration-tests
19
+ - mocking
20
+ - e2e
21
+ requires_tools: []
22
+ ---
23
+
24
+ # Tauri Testing Strategies
25
+
26
+ ## Unit Testing Commands
27
+
28
+ ```rust
29
+ // src-tauri/src/commands/files.rs
30
+ #[tauri::command]
31
+ pub async fn read_file_content(path: String) -> Result<String, String> {
32
+ tokio::fs::read_to_string(path)
33
+ .await
34
+ .map_err(|e| e.to_string())
35
+ }
36
+
37
+ #[cfg(test)]
38
+ mod tests {
39
+ use super::*;
40
+
41
+ #[tokio::test]
42
+ async fn test_read_file_content() {
43
+ // Create temp file
44
+ let temp_dir = std::env::temp_dir();
45
+ let test_file = temp_dir.join("test.txt");
46
+ tokio::fs::write(&test_file, "test content").await.unwrap();
47
+
48
+ // Test command
49
+ let result = read_file_content(
50
+ test_file.to_string_lossy().to_string()
51
+ ).await;
52
+
53
+ assert!(result.is_ok());
54
+ assert_eq!(result.unwrap(), "test content");
55
+
56
+ // Cleanup
57
+ tokio::fs::remove_file(test_file).await.unwrap();
58
+ }
59
+
60
+ #[tokio::test]
61
+ async fn test_read_nonexistent_file() {
62
+ let result = read_file_content("/nonexistent/file.txt".to_string()).await;
63
+ assert!(result.is_err());
64
+ }
65
+ }
66
+ ```
67
+
68
+ ## Testing with State
69
+
70
+ ```rust
71
+ use std::sync::Arc;
72
+ use tokio::sync::Mutex;
73
+
74
+ #[cfg(test)]
75
+ mod tests {
76
+ use super::*;
77
+
78
+ async fn create_test_state() -> AppState {
79
+ AppState {
80
+ database: Arc::new(Mutex::new(Database::new_in_memory())),
81
+ config: Arc::new(Mutex::new(Config::default())),
82
+ }
83
+ }
84
+
85
+ #[tokio::test]
86
+ async fn test_command_with_state() {
87
+ let state = create_test_state().await;
88
+
89
+ // Mock State wrapper
90
+ struct MockState(AppState);
91
+
92
+ impl<'r> tauri::State<'r, AppState> {
93
+ fn new_mock(state: AppState) -> Self {
94
+ // Use internal test API
95
+ unimplemented!("Use integration test instead")
96
+ }
97
+ }
98
+
99
+ // For unit tests, call inner functions directly
100
+ let result = get_data_internal(&state).await;
101
+ assert!(result.is_ok());
102
+ }
103
+ }
104
+ ```
105
+
106
+ ## Frontend IPC Mocking
107
+
108
+ ```typescript
109
+ // __mocks__/@tauri-apps/api/core.ts
110
+ export const invoke = jest.fn();
111
+
112
+ // Mock setup
113
+ import { invoke } from '@tauri-apps/api/core';
114
+
115
+ beforeEach(() => {
116
+ (invoke as jest.Mock).mockClear();
117
+ });
118
+
119
+ test('calls read_file command', async () => {
120
+ (invoke as jest.Mock).mockResolvedValue('file content');
121
+
122
+ const content = await readFile('test.txt');
123
+
124
+ expect(invoke).toHaveBeenCalledWith('read_file', {
125
+ filename: 'test.txt'
126
+ });
127
+ expect(content).toBe('file content');
128
+ });
129
+
130
+ test('handles command errors', async () => {
131
+ (invoke as jest.Mock).mockRejectedValue('File not found');
132
+
133
+ await expect(readFile('missing.txt')).rejects.toThrow('File not found');
134
+ });
135
+ ```
136
+
137
+ ## Integration Testing
138
+
139
+ ```rust
140
+ // tests/integration_test.rs
141
+ #[cfg(test)]
142
+ mod tests {
143
+ use tauri::test::{mock_builder, MockRuntime, mock_context};
144
+
145
+ #[test]
146
+ fn test_app_creation() {
147
+ let app = mock_builder()
148
+ .invoke_handler(tauri::generate_handler![
149
+ my_command,
150
+ another_command,
151
+ ])
152
+ .build(MockRuntime::default())
153
+ .expect("failed to build app");
154
+
155
+ assert!(app.get_window("main").is_some());
156
+ }
157
+
158
+ #[test]
159
+ fn test_command_invocation() {
160
+ let app = mock_builder()
161
+ .invoke_handler(tauri::generate_handler![test_command])
162
+ .build(MockRuntime::default())
163
+ .expect("failed to build app");
164
+
165
+ // Commands can be tested via window
166
+ let window = app.get_window("main").unwrap();
167
+ // Test window interactions
168
+ }
169
+ }
170
+ ```
171
+
172
+ ## End-to-End Testing with WebDriver
173
+
174
+ ### Setup
175
+
176
+ **Add to Cargo.toml**:
177
+ ```toml
178
+ [dev-dependencies]
179
+ tauri-driver = "0.1"
180
+ ```
181
+
182
+ **Add test runner**:
183
+ ```rust
184
+ // tests/webdriver.rs
185
+ use tauri_driver::test::*;
186
+
187
+ #[test]
188
+ fn run_webdriver_tests() {
189
+ let mut driver = DriverBuilder::native()
190
+ .build()
191
+ .expect("Failed to create driver");
192
+
193
+ // Navigate to app
194
+ driver.goto("tauri://localhost");
195
+
196
+ // Find element and click
197
+ let button = driver.find_element(By::Id("my-button"))
198
+ .expect("Button not found");
199
+ button.click().expect("Failed to click");
200
+
201
+ // Verify result
202
+ let result = driver.find_element(By::Id("result"))
203
+ .expect("Result not found");
204
+ assert_eq!(result.text().unwrap(), "Success");
205
+ }
206
+ ```
207
+
208
+ ## Mock Event System
209
+
210
+ ```typescript
211
+ // __mocks__/@tauri-apps/api/event.ts
212
+ type EventCallback = (event: any) => void;
213
+ const listeners = new Map<string, EventCallback[]>();
214
+
215
+ export const listen = jest.fn(async (event: string, callback: EventCallback) => {
216
+ if (!listeners.has(event)) {
217
+ listeners.set(event, []);
218
+ }
219
+ listeners.get(event)!.push(callback);
220
+
221
+ return jest.fn(() => {
222
+ const callbacks = listeners.get(event);
223
+ if (callbacks) {
224
+ const index = callbacks.indexOf(callback);
225
+ if (index > -1) {
226
+ callbacks.splice(index, 1);
227
+ }
228
+ }
229
+ });
230
+ });
231
+
232
+ export const emit = jest.fn((event: string, payload: any) => {
233
+ const callbacks = listeners.get(event) || [];
234
+ callbacks.forEach(cb => cb({ payload }));
235
+ });
236
+
237
+ // Test usage
238
+ test('handles progress events', async () => {
239
+ const progressHandler = jest.fn();
240
+ const unlisten = await listen('progress', progressHandler);
241
+
242
+ emit('progress', { current: 50, total: 100 });
243
+
244
+ expect(progressHandler).toHaveBeenCalledWith({
245
+ payload: { current: 50, total: 100 }
246
+ });
247
+
248
+ unlisten();
249
+ });
250
+ ```
251
+
252
+ ## Testing Async Commands
253
+
254
+ ```rust
255
+ #[cfg(test)]
256
+ mod tests {
257
+ use super::*;
258
+ use tokio::time::{timeout, Duration};
259
+
260
+ #[tokio::test]
261
+ async fn test_long_operation_completes() {
262
+ let result = timeout(
263
+ Duration::from_secs(5),
264
+ long_running_command()
265
+ ).await;
266
+
267
+ assert!(result.is_ok());
268
+ assert!(result.unwrap().is_ok());
269
+ }
270
+
271
+ #[tokio::test]
272
+ async fn test_operation_with_progress() {
273
+ let (tx, mut rx) = tokio::sync::mpsc::channel(100);
274
+
275
+ tokio::spawn(async move {
276
+ // Simulate command emitting progress
277
+ for i in 0..10 {
278
+ tx.send(i).await.ok();
279
+ }
280
+ });
281
+
282
+ let mut count = 0;
283
+ while let Some(progress) = rx.recv().await {
284
+ assert_eq!(progress, count);
285
+ count += 1;
286
+ }
287
+
288
+ assert_eq!(count, 10);
289
+ }
290
+ }
291
+ ```
292
+
293
+ ## Frontend Component Testing
294
+
295
+ ```typescript
296
+ import { render, screen, waitFor } from '@testing-library/react';
297
+ import '@testing-library/jest-dom';
298
+ import { invoke } from '@tauri-apps/api/core';
299
+ import { DocumentView } from './DocumentView';
300
+
301
+ jest.mock('@tauri-apps/api/core');
302
+
303
+ test('renders document content', async () => {
304
+ (invoke as jest.Mock).mockResolvedValue('Test content');
305
+
306
+ render(<DocumentView filename="test.txt" />);
307
+
308
+ expect(screen.getByText('Loading...')).toBeInTheDocument();
309
+
310
+ await waitFor(() => {
311
+ expect(screen.getByText('Test content')).toBeInTheDocument();
312
+ });
313
+ });
314
+
315
+ test('displays error on failure', async () => {
316
+ (invoke as jest.Mock).mockRejectedValue('File not found');
317
+
318
+ render(<DocumentView filename="missing.txt" />);
319
+
320
+ await waitFor(() => {
321
+ expect(screen.getByText(/error/i)).toBeInTheDocument();
322
+ });
323
+ });
324
+ ```
325
+
326
+ ## Best Practices
327
+
328
+ 1. **Unit test all commands** - Test logic without Tauri runtime
329
+ 2. **Mock IPC in frontend** - Use jest.mock for @tauri-apps/api
330
+ 3. **Test error paths** - Verify error handling works
331
+ 4. **Use integration tests** - For command registration
332
+ 5. **E2E for critical flows** - User workflows with WebDriver
333
+ 6. **Test async operations** - With timeouts and proper await
334
+ 7. **Mock external dependencies** - Databases, APIs, file system
335
+ 8. **Test state management** - Concurrent access, race conditions
336
+ 9. **Coverage targets** - Aim for >80% coverage
337
+ 10. **CI integration** - Run tests on every commit
338
+
339
+ ## Common Pitfalls
340
+
341
+ ❌ **Forgetting async in tests**:
342
+ ```rust
343
+ // WRONG
344
+ #[test]
345
+ fn test_async_command() {
346
+ let result = async_command().await; // Won't compile
347
+ }
348
+
349
+ // CORRECT
350
+ #[tokio::test]
351
+ async fn test_async_command() {
352
+ let result = async_command().await;
353
+ }
354
+ ```
355
+
356
+ ❌ **Not cleaning up temp files**:
357
+ ```rust
358
+ // WRONG - leaves files behind
359
+ #[tokio::test]
360
+ async fn test() {
361
+ tokio::fs::write("test.txt", "content").await.unwrap();
362
+ // Test... but never removes file
363
+ }
364
+
365
+ // CORRECT
366
+ #[tokio::test]
367
+ async fn test() {
368
+ let file = "test.txt";
369
+ tokio::fs::write(file, "content").await.unwrap();
370
+ // Test...
371
+ tokio::fs::remove_file(file).await.unwrap();
372
+ }
373
+ ```
374
+
375
+ ## Summary
376
+
377
+ - **Unit tests** for command logic
378
+ - **Integration tests** with MockRuntime
379
+ - **Mock IPC** in frontend tests
380
+ - **E2E tests** with tauri-driver
381
+ - **Test async** with #[tokio::test]
382
+ - **Mock events** for event testing
383
+ - **Test error paths** always
384
+ - **CI integration** for automation