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
@@ -81,6 +81,36 @@ API_KEY = "sk-1234567890abcdef" # In code! # pragma: allowlist secret
81
81
 
82
82
  # ✅ Safe: Use environment variables
83
83
  API_KEY = os.getenv("API_KEY")
84
+
85
+ # ❌ CRITICAL: MCP config files with API keys
86
+ # NEVER commit these files:
87
+ # - .mcp-vector-search/config.json (OpenRouter API keys)
88
+ # - .mcp/config.json (MCP server credentials)
89
+ # - openrouter.json, anthropic-config.json
90
+ # - credentials.json, secrets.json, api-keys.json
91
+
92
+ # ✅ Safe: Verify .gitignore before committing
93
+ # Check file is ignored: git check-ignore <file_path>
94
+ # Check file not tracked: git ls-files <file_path>
95
+ ```
96
+
97
+ **MCP Secret File Patterns (High Risk):**
98
+ ```bash
99
+ # Files that commonly contain API keys:
100
+ .mcp-vector-search/config.json # OpenRouter, OpenAI keys
101
+ .mcp/config.json # MCP server credentials
102
+ **/mcp-config.json
103
+ openrouter.json
104
+ anthropic-config.json
105
+ openai-config.json
106
+ credentials.json
107
+ secrets.json
108
+ api-keys.json
109
+
110
+ # ALWAYS add to .gitignore:
111
+ echo ".mcp-vector-search/" >> .gitignore
112
+ echo "credentials.json" >> .gitignore
113
+ echo "secrets.json" >> .gitignore
84
114
  ```
85
115
 
86
116
  ### 4. XML External Entities (XXE)
@@ -178,6 +208,88 @@ if failed_login_count > 5:
178
208
  alert_security_team()
179
209
  ```
180
210
 
211
+ ## Secret Detection and Prevention
212
+
213
+ ### Pre-commit Hooks with detect-secrets
214
+ ```bash
215
+ # Install detect-secrets
216
+ pip install detect-secrets
217
+
218
+ # Create baseline of existing secrets
219
+ detect-secrets scan > .secrets.baseline
220
+
221
+ # Install pre-commit hooks
222
+ pip install pre-commit
223
+ pre-commit install
224
+
225
+ # Add to .pre-commit-config.yaml:
226
+ # - repo: https://github.com/Yelp/detect-secrets
227
+ # rev: v1.5.0
228
+ # hooks:
229
+ # - id: detect-secrets
230
+ # args: ['--baseline', '.secrets.baseline']
231
+
232
+ # Scan for new secrets
233
+ detect-secrets scan --baseline .secrets.baseline
234
+
235
+ # Audit baseline (mark false positives)
236
+ detect-secrets audit .secrets.baseline
237
+ ```
238
+
239
+ ### Manual Secret Scanning
240
+ ```bash
241
+ # Check if file is ignored by git
242
+ git check-ignore .mcp-vector-search/config.json
243
+ # Exit code 0 = ignored (safe)
244
+ # Exit code 1 = NOT ignored (DANGER!)
245
+
246
+ # Check if file is tracked by git
247
+ git ls-files .mcp-vector-search/config.json
248
+ # Output present = tracked (CRITICAL - remove immediately!)
249
+ # No output = not tracked (safe if also in .gitignore)
250
+
251
+ # Search git history for committed secrets
252
+ git log --all --full-history -- .mcp-vector-search/config.json
253
+
254
+ # Remove file from git history (if accidentally committed)
255
+ git filter-branch --force --index-filter \
256
+ 'git rm --cached --ignore-unmatch .mcp-vector-search/config.json' \
257
+ --prune-empty --tag-name-filter cat -- --all
258
+ ```
259
+
260
+ ### Incident Response: Exposed API Key
261
+ If you've committed an API key to git:
262
+
263
+ 1. **IMMEDIATELY rotate the exposed credential**
264
+ - OpenRouter: https://openrouter.ai/settings/keys
265
+ - Anthropic: https://console.anthropic.com/settings/keys
266
+ - OpenAI: https://platform.openai.com/api-keys
267
+
268
+ 2. **Remove from git history**
269
+ ```bash
270
+ # Using git-filter-repo (recommended)
271
+ git filter-repo --path .mcp-vector-search/config.json --invert-paths
272
+
273
+ # Force push to remote (WARNING: destructive)
274
+ git push origin --force --all
275
+ git push origin --force --tags
276
+ ```
277
+
278
+ 3. **Add to .gitignore** (if not already there)
279
+ ```bash
280
+ echo ".mcp-vector-search/" >> .gitignore
281
+ git add .gitignore
282
+ git commit -m "chore: add MCP config to gitignore"
283
+ ```
284
+
285
+ 4. **Verify cleanup**
286
+ ```bash
287
+ git log --all --full-history -- .mcp-vector-search/config.json
288
+ # Should show no results
289
+ ```
290
+
291
+ 5. **Notify stakeholders** if the key had production access
292
+
181
293
  ## Security Scanning Tools
182
294
 
183
295
  ### Python
@@ -0,0 +1,495 @@
1
+ ---
2
+ name: tauri-async-patterns
3
+ description: Advanced async patterns in Tauri including long-running tasks, background work, cancellation, and concurrent operations
4
+ version: 1.0.0
5
+ category: development
6
+ author: Claude MPM Team
7
+ license: MIT
8
+ progressive_disclosure:
9
+ entry_point:
10
+ summary: "Async mastery: long-running operations with progress, background tasks, cancellation patterns, concurrent processing"
11
+ when_to_use: "Implementing downloads, file processing, background sync, or any long-running async operations"
12
+ quick_start: "1. Use tokio::spawn for background work 2. Emit progress events 3. Implement cancellation with channels 4. Handle graceful shutdown"
13
+ context_limit: 500
14
+ tags:
15
+ - tauri
16
+ - async
17
+ - tokio
18
+ - concurrency
19
+ - background-tasks
20
+ requires_tools: []
21
+ ---
22
+
23
+ # Tauri Async Patterns
24
+
25
+ ## Long-Running Operations with Progress
26
+
27
+ ```rust
28
+ use tokio::time::{sleep, Duration};
29
+
30
+ #[tauri::command]
31
+ async fn long_download(
32
+ url: String,
33
+ window: tauri::Window,
34
+ ) -> Result<String, String> {
35
+ let total_chunks = 100;
36
+
37
+ for chunk in 0..total_chunks {
38
+ // Simulate download
39
+ sleep(Duration::from_millis(50)).await;
40
+
41
+ // Emit progress
42
+ window.emit("download-progress", serde_json::json!({
43
+ "current": chunk + 1,
44
+ "total": total_chunks,
45
+ "percentage": ((chunk + 1) as f64 / total_chunks as f64) * 100.0
46
+ })).map_err(|e| e.to_string())?;
47
+ }
48
+
49
+ window.emit("download-complete", url.clone())
50
+ .map_err(|e| e.to_string())?;
51
+
52
+ Ok(format!("Downloaded: {}", url))
53
+ }
54
+ ```
55
+
56
+ ## Background Tasks
57
+
58
+ ### Spawning Background Work
59
+
60
+ ```rust
61
+ #[tauri::command]
62
+ async fn start_background_sync(
63
+ app: tauri::AppHandle,
64
+ ) -> Result<(), String> {
65
+ // Spawn task that outlives command
66
+ tokio::spawn(async move {
67
+ loop {
68
+ // Perform sync
69
+ match perform_sync().await {
70
+ Ok(_) => {
71
+ if let Some(window) = app.get_window("main") {
72
+ let _ = window.emit("sync-complete", ());
73
+ }
74
+ }
75
+ Err(e) => {
76
+ log::error!("Sync failed: {}", e);
77
+ }
78
+ }
79
+
80
+ // Wait before next sync
81
+ tokio::time::sleep(Duration::from_secs(300)).await;
82
+ }
83
+ });
84
+
85
+ Ok(())
86
+ }
87
+ ```
88
+
89
+ ### Task Management State
90
+
91
+ ```rust
92
+ use std::sync::Arc;
93
+ use tokio::sync::Mutex;
94
+ use std::collections::HashMap;
95
+
96
+ pub struct TaskManager {
97
+ tasks: Arc<Mutex<HashMap<String, TaskHandle>>>,
98
+ }
99
+
100
+ struct TaskHandle {
101
+ cancel_tx: tokio::sync::mpsc::Sender<()>,
102
+ status: Arc<Mutex<TaskStatus>>,
103
+ }
104
+
105
+ #[derive(Clone)]
106
+ enum TaskStatus {
107
+ Running,
108
+ Completed,
109
+ Cancelled,
110
+ Failed(String),
111
+ }
112
+
113
+ impl TaskManager {
114
+ pub async fn spawn_task<F>(&self, id: String, task: F) -> String
115
+ where
116
+ F: Future<Output = Result<(), String>> + Send + 'static,
117
+ {
118
+ let (cancel_tx, mut cancel_rx) = tokio::sync::mpsc::channel::<()>(1);
119
+ let status = Arc::new(Mutex::new(TaskStatus::Running));
120
+ let status_clone = status.clone();
121
+
122
+ tokio::spawn(async move {
123
+ tokio::select! {
124
+ result = task => {
125
+ let mut s = status_clone.lock().await;
126
+ *s = match result {
127
+ Ok(_) => TaskStatus::Completed,
128
+ Err(e) => TaskStatus::Failed(e),
129
+ };
130
+ }
131
+ _ = cancel_rx.recv() => {
132
+ let mut s = status_clone.lock().await;
133
+ *s = TaskStatus::Cancelled;
134
+ }
135
+ }
136
+ });
137
+
138
+ self.tasks.lock().await.insert(id.clone(), TaskHandle {
139
+ cancel_tx,
140
+ status,
141
+ });
142
+
143
+ id
144
+ }
145
+
146
+ pub async fn cancel_task(&self, id: &str) -> Result<(), String> {
147
+ let mut tasks = self.tasks.lock().await;
148
+ if let Some(handle) = tasks.remove(id) {
149
+ handle.cancel_tx.send(()).await.ok();
150
+ Ok(())
151
+ } else {
152
+ Err(format!("Task '{}' not found", id))
153
+ }
154
+ }
155
+
156
+ pub async fn get_status(&self, id: &str) -> Option<TaskStatus> {
157
+ let tasks = self.tasks.lock().await;
158
+ if let Some(handle) = tasks.get(id) {
159
+ Some(handle.status.lock().await.clone())
160
+ } else {
161
+ None
162
+ }
163
+ }
164
+ }
165
+ ```
166
+
167
+ ## Cancellation Patterns
168
+
169
+ ### Using tokio::select! for Cancellation
170
+
171
+ ```rust
172
+ #[tauri::command]
173
+ async fn cancellable_operation(
174
+ state: tauri::State<'_, TaskManager>,
175
+ ) -> Result<String, String> {
176
+ let task_id = uuid::Uuid::new_v4().to_string();
177
+
178
+ state.spawn_task(task_id.clone(), async move {
179
+ for i in 0..1000 {
180
+ // Check if cancelled via select!
181
+ tokio::time::sleep(Duration::from_millis(10)).await;
182
+
183
+ // Do work
184
+ process_item(i).await?;
185
+ }
186
+
187
+ Ok(())
188
+ }).await;
189
+
190
+ Ok(task_id)
191
+ }
192
+
193
+ #[tauri::command]
194
+ async fn cancel_operation(
195
+ task_id: String,
196
+ state: tauri::State<'_, TaskManager>,
197
+ ) -> Result<(), String> {
198
+ state.cancel_task(&task_id).await
199
+ }
200
+ ```
201
+
202
+ ### Manual Cancellation Token
203
+
204
+ ```rust
205
+ use std::sync::atomic::{AtomicBool, Ordering};
206
+
207
+ #[tauri::command]
208
+ async fn start_with_token(
209
+ state: tauri::State<'_, AppState>,
210
+ window: tauri::Window,
211
+ ) -> Result<String, String> {
212
+ let task_id = uuid::Uuid::new_v4().to_string();
213
+ let cancel_flag = Arc::new(AtomicBool::new(false));
214
+
215
+ // Store cancel flag
216
+ state.cancel_flags.insert(task_id.clone(), cancel_flag.clone());
217
+
218
+ let task_id_clone = task_id.clone();
219
+ tokio::spawn(async move {
220
+ for i in 0..1000 {
221
+ // Check cancellation
222
+ if cancel_flag.load(Ordering::Relaxed) {
223
+ window.emit("task-cancelled", task_id_clone).ok();
224
+ break;
225
+ }
226
+
227
+ // Do work
228
+ process_item(i).await.ok();
229
+ }
230
+ });
231
+
232
+ Ok(task_id)
233
+ }
234
+
235
+ #[tauri::command]
236
+ fn cancel_with_token(
237
+ task_id: String,
238
+ state: tauri::State<'_, AppState>,
239
+ ) -> Result<(), String> {
240
+ if let Some(flag) = state.cancel_flags.get(&task_id) {
241
+ flag.store(true, Ordering::Relaxed);
242
+ Ok(())
243
+ } else {
244
+ Err("Task not found".to_string())
245
+ }
246
+ }
247
+ ```
248
+
249
+ ## Concurrent Operations
250
+
251
+ ### Parallel Processing
252
+
253
+ ```rust
254
+ use futures::stream::{self, StreamExt};
255
+
256
+ #[tauri::command]
257
+ async fn process_files_parallel(
258
+ files: Vec<String>,
259
+ window: tauri::Window,
260
+ ) -> Result<Vec<String>, String> {
261
+ let results = stream::iter(files)
262
+ .map(|file| {
263
+ let window = window.clone();
264
+ async move {
265
+ let result = process_file(&file).await;
266
+
267
+ window.emit("file-processed", file.clone()).ok();
268
+
269
+ result
270
+ }
271
+ })
272
+ .buffer_unordered(4) // Process 4 at a time
273
+ .collect::<Vec<_>>()
274
+ .await;
275
+
276
+ let successes: Vec<String> = results
277
+ .into_iter()
278
+ .filter_map(|r| r.ok())
279
+ .collect();
280
+
281
+ Ok(successes)
282
+ }
283
+ ```
284
+
285
+ ### Bounded Concurrency
286
+
287
+ ```rust
288
+ use tokio::sync::Semaphore;
289
+
290
+ #[tauri::command]
291
+ async fn batch_download(
292
+ urls: Vec<String>,
293
+ max_concurrent: usize,
294
+ ) -> Result<Vec<String>, String> {
295
+ let semaphore = Arc::new(Semaphore::new(max_concurrent));
296
+ let mut handles = Vec::new();
297
+
298
+ for url in urls {
299
+ let permit = semaphore.clone().acquire_owned().await.unwrap();
300
+
301
+ let handle = tokio::spawn(async move {
302
+ let result = download_file(&url).await;
303
+ drop(permit); // Release permit
304
+ result
305
+ });
306
+
307
+ handles.push(handle);
308
+ }
309
+
310
+ let results = futures::future::join_all(handles).await;
311
+
312
+ Ok(results.into_iter()
313
+ .filter_map(|r| r.ok().and_then(|r| r.ok()))
314
+ .collect())
315
+ }
316
+ ```
317
+
318
+ ## Stream Processing
319
+
320
+ ```rust
321
+ use tokio::io::{AsyncBufReadExt, BufReader};
322
+
323
+ #[tauri::command]
324
+ async fn stream_log_file(
325
+ filepath: String,
326
+ window: tauri::Window,
327
+ ) -> Result<(), String> {
328
+ let file = tokio::fs::File::open(filepath)
329
+ .await
330
+ .map_err(|e| e.to_string())?;
331
+
332
+ let reader = BufReader::new(file);
333
+ let mut lines = reader.lines();
334
+
335
+ while let Some(line) = lines.next_line()
336
+ .await
337
+ .map_err(|e| e.to_string())? {
338
+
339
+ window.emit("log-line", line)
340
+ .map_err(|e| e.to_string())?;
341
+
342
+ // Throttle to avoid overwhelming frontend
343
+ tokio::time::sleep(Duration::from_millis(10)).await;
344
+ }
345
+
346
+ window.emit("log-complete", ())
347
+ .map_err(|e| e.to_string())?;
348
+
349
+ Ok(())
350
+ }
351
+ ```
352
+
353
+ ## Timeout Patterns
354
+
355
+ ```rust
356
+ use tokio::time::timeout;
357
+
358
+ #[tauri::command]
359
+ async fn operation_with_timeout(
360
+ duration_secs: u64,
361
+ ) -> Result<String, String> {
362
+ let operation = async {
363
+ long_running_task().await
364
+ };
365
+
366
+ match timeout(Duration::from_secs(duration_secs), operation).await {
367
+ Ok(Ok(result)) => Ok(result),
368
+ Ok(Err(e)) => Err(format!("Operation failed: {}", e)),
369
+ Err(_) => Err("Operation timed out".to_string()),
370
+ }
371
+ }
372
+ ```
373
+
374
+ ## Graceful Shutdown
375
+
376
+ ```rust
377
+ use tokio::sync::broadcast;
378
+
379
+ pub struct ShutdownManager {
380
+ shutdown_tx: broadcast::Sender<()>,
381
+ }
382
+
383
+ impl ShutdownManager {
384
+ pub fn new() -> Self {
385
+ let (shutdown_tx, _) = broadcast::channel(1);
386
+ Self { shutdown_tx }
387
+ }
388
+
389
+ pub fn subscribe(&self) -> broadcast::Receiver<()> {
390
+ self.shutdown_tx.subscribe()
391
+ }
392
+
393
+ pub fn shutdown(&self) {
394
+ let _ = self.shutdown_tx.send(());
395
+ }
396
+ }
397
+
398
+ #[tauri::command]
399
+ async fn start_service(
400
+ state: tauri::State<'_, ShutdownManager>,
401
+ ) -> Result<(), String> {
402
+ let mut shutdown_rx = state.subscribe();
403
+
404
+ tokio::spawn(async move {
405
+ loop {
406
+ tokio::select! {
407
+ _ = tokio::time::sleep(Duration::from_secs(1)) => {
408
+ // Do work
409
+ perform_service_work().await;
410
+ }
411
+ _ = shutdown_rx.recv() => {
412
+ log::info!("Service shutting down");
413
+ cleanup().await;
414
+ break;
415
+ }
416
+ }
417
+ }
418
+ });
419
+
420
+ Ok(())
421
+ }
422
+ ```
423
+
424
+ ## Best Practices
425
+
426
+ 1. **Always emit progress** - For operations >1 second
427
+ 2. **Implement cancellation** - For long-running tasks
428
+ 3. **Use tokio::spawn** - For true background work
429
+ 4. **Limit concurrency** - Use Semaphore for bounded parallelism
430
+ 5. **Add timeouts** - Prevent hung operations
431
+ 6. **Handle graceful shutdown** - Clean up resources
432
+ 7. **Throttle events** - Don't overwhelm frontend with updates
433
+ 8. **Use select!** - For cancellation and timeouts
434
+ 9. **Store task handles** - Enable management and cancellation
435
+ 10. **Test async paths** - Verify cancellation and timeouts work
436
+
437
+ ## Common Pitfalls
438
+
439
+ ❌ **Blocking async runtime**:
440
+ ```rust
441
+ // WRONG
442
+ std::thread::sleep(Duration::from_secs(1));
443
+
444
+ // CORRECT
445
+ tokio::time::sleep(Duration::from_secs(1)).await;
446
+ ```
447
+
448
+ ❌ **Forgetting to spawn**:
449
+ ```rust
450
+ // WRONG - command waits for completion
451
+ async fn start_background() {
452
+ background_work().await; // Blocks command
453
+ }
454
+
455
+ // CORRECT - spawn to background
456
+ async fn start_background() {
457
+ tokio::spawn(async {
458
+ background_work().await;
459
+ });
460
+ }
461
+ ```
462
+
463
+ ❌ **No cancellation mechanism**:
464
+ ```rust
465
+ // WRONG - can't stop once started
466
+ tokio::spawn(async {
467
+ loop {
468
+ work().await;
469
+ sleep(Duration::from_secs(1)).await;
470
+ }
471
+ });
472
+
473
+ // CORRECT - cancellable
474
+ let (tx, mut rx) = tokio::sync::mpsc::channel(1);
475
+ tokio::spawn(async move {
476
+ loop {
477
+ tokio::select! {
478
+ _ = work() => {}
479
+ _ = rx.recv() => break,
480
+ }
481
+ }
482
+ });
483
+ ```
484
+
485
+ ## Summary
486
+
487
+ - **tokio::spawn** for background tasks
488
+ - **tokio::select!** for cancellation
489
+ - **Progress events** for long operations
490
+ - **Semaphore** for bounded concurrency
491
+ - **timeout()** to prevent hung operations
492
+ - **broadcast** for shutdown signals
493
+ - **Stream processing** for large data
494
+ - **Task management** with cancel tokens
495
+ - **Graceful cleanup** on shutdown