claude-mpm 4.20.3__py3-none-any.whl → 4.25.10__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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_PM.md +23 -6
- claude_mpm/agents/OUTPUT_STYLE.md +3 -48
- claude_mpm/agents/PM_INSTRUCTIONS.md +1783 -34
- claude_mpm/agents/WORKFLOW.md +75 -2
- claude_mpm/agents/base_agent.json +6 -3
- claude_mpm/agents/frontmatter_validator.py +1 -1
- claude_mpm/agents/templates/api_qa.json +5 -2
- claude_mpm/agents/templates/circuit_breakers.md +108 -2
- claude_mpm/agents/templates/documentation.json +33 -6
- claude_mpm/agents/templates/javascript_engineer_agent.json +380 -0
- claude_mpm/agents/templates/php-engineer.json +10 -4
- claude_mpm/agents/templates/pm_red_flags.md +89 -19
- claude_mpm/agents/templates/project_organizer.json +7 -3
- claude_mpm/agents/templates/qa.json +2 -1
- claude_mpm/agents/templates/react_engineer.json +1 -0
- claude_mpm/agents/templates/research.json +82 -12
- claude_mpm/agents/templates/security.json +4 -4
- claude_mpm/agents/templates/tauri_engineer.json +274 -0
- claude_mpm/agents/templates/ticketing.json +10 -6
- claude_mpm/agents/templates/version_control.json +4 -2
- claude_mpm/agents/templates/web_qa.json +2 -1
- claude_mpm/cli/README.md +253 -0
- claude_mpm/cli/__init__.py +11 -1
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/analyze.py +3 -3
- claude_mpm/cli/commands/cleanup.py +1 -1
- claude_mpm/cli/commands/configure_agent_display.py +4 -4
- claude_mpm/cli/commands/debug.py +12 -12
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/mcp_install_commands.py +1 -1
- claude_mpm/cli/commands/mcp_install_commands.py.backup +284 -0
- claude_mpm/cli/commands/mpm_init/README.md +365 -0
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +573 -0
- claude_mpm/cli/commands/mpm_init/display.py +341 -0
- claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
- claude_mpm/cli/commands/mpm_init/modes.py +397 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
- claude_mpm/cli/commands/mpm_init_cli.py +396 -0
- claude_mpm/cli/commands/mpm_init_handler.py +67 -1
- claude_mpm/cli/commands/run.py +124 -128
- claude_mpm/cli/commands/skills.py +522 -34
- claude_mpm/cli/executor.py +56 -0
- claude_mpm/cli/interactive/agent_wizard.py +5 -5
- claude_mpm/cli/parsers/base_parser.py +28 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
- claude_mpm/cli/parsers/skills_parser.py +138 -0
- claude_mpm/cli/startup.py +111 -8
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/cli_module/commands.py +1 -1
- claude_mpm/cli_module/refactoring_guide.md +253 -0
- claude_mpm/commands/mpm-help.md +3 -0
- claude_mpm/commands/mpm-init.md +19 -3
- claude_mpm/commands/mpm-resume.md +372 -0
- claude_mpm/commands/mpm-tickets.md +56 -7
- claude_mpm/commands/mpm.md +1 -0
- claude_mpm/config/agent_capabilities.yaml +658 -0
- claude_mpm/config/async_logging_config.yaml +145 -0
- claude_mpm/constants.py +12 -0
- claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +34 -0
- claude_mpm/core/api_validator.py +1 -1
- claude_mpm/core/claude_runner.py +14 -1
- claude_mpm/core/config.py +8 -0
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/framework/processors/metadata_processor.py +1 -1
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +48 -3
- claude_mpm/core/interfaces.py +56 -1
- claude_mpm/core/logger.py +3 -1
- claude_mpm/core/oneshot_session.py +39 -0
- claude_mpm/d2/.gitignore +22 -0
- claude_mpm/d2/ARCHITECTURE_COMPARISON.md +273 -0
- claude_mpm/d2/FLASK_INTEGRATION.md +156 -0
- claude_mpm/d2/IMPLEMENTATION_SUMMARY.md +452 -0
- claude_mpm/d2/QUICKSTART.md +186 -0
- claude_mpm/d2/README.md +232 -0
- claude_mpm/d2/STORE_FIX_SUMMARY.md +167 -0
- claude_mpm/d2/SVELTE5_STORES_GUIDE.md +180 -0
- claude_mpm/d2/TESTING.md +288 -0
- claude_mpm/d2/index.html +118 -0
- claude_mpm/d2/package.json +19 -0
- claude_mpm/d2/src/App.svelte +110 -0
- claude_mpm/d2/src/components/Header.svelte +153 -0
- claude_mpm/d2/src/components/MainContent.svelte +74 -0
- claude_mpm/d2/src/components/Sidebar.svelte +85 -0
- claude_mpm/d2/src/components/tabs/EventsTab.svelte +326 -0
- claude_mpm/d2/src/lib/socketio.js +144 -0
- claude_mpm/d2/src/main.js +7 -0
- claude_mpm/d2/src/stores/events.js +114 -0
- claude_mpm/d2/src/stores/socket.js +108 -0
- claude_mpm/d2/src/stores/theme.js +65 -0
- claude_mpm/d2/svelte.config.js +12 -0
- claude_mpm/d2/vite.config.js +15 -0
- claude_mpm/dashboard/.claude-mpm/memories/README.md +36 -0
- claude_mpm/dashboard/BUILD_NUMBER +1 -0
- claude_mpm/dashboard/README.md +121 -0
- claude_mpm/dashboard/VERSION +1 -0
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.tsx +273 -0
- claude_mpm/dashboard/react/components/ErrorBoundary.tsx +75 -0
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.tsx +141 -0
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.tsx +36 -0
- claude_mpm/dashboard/react/components/shared/FilterBar.tsx +89 -0
- claude_mpm/dashboard/react/contexts/DashboardContext.tsx +215 -0
- claude_mpm/dashboard/react/entries/events.tsx +165 -0
- claude_mpm/dashboard/react/hooks/useEvents.ts +191 -0
- claude_mpm/dashboard/react/hooks/useSocket.ts +225 -0
- claude_mpm/dashboard/static/built/REFACTORING_SUMMARY.md +170 -0
- claude_mpm/dashboard/static/built/components/activity-tree.js.map +1 -0
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/built/components/agent-inference.js.map +1 -0
- claude_mpm/dashboard/static/built/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/built/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +29 -29
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +24 -24
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +27 -27
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +25 -25
- claude_mpm/dashboard/static/built/components/code-tree.js.map +1 -0
- claude_mpm/dashboard/static/built/components/code-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/built/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/built/components/event-processor.js.map +1 -0
- claude_mpm/dashboard/static/built/components/event-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/export-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js.map +1 -0
- claude_mpm/dashboard/static/built/components/file-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/hud-library-loader.js.map +1 -0
- claude_mpm/dashboard/static/built/components/hud-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/hud-visualizer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/module-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/session-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/socket-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/ui-state-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/working-directory.js.map +1 -0
- claude_mpm/dashboard/static/built/connection-manager.js +76 -76
- claude_mpm/dashboard/static/built/dashboard.js.map +1 -0
- claude_mpm/dashboard/static/built/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/built/react/events.js.map +1 -0
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +9 -9
- claude_mpm/dashboard/static/built/shared/event-bus.js +5 -5
- claude_mpm/dashboard/static/built/shared/logger.js +16 -16
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +6 -6
- claude_mpm/dashboard/static/built/socket-client.js.map +1 -0
- claude_mpm/dashboard/static/css/activity.css +69 -69
- claude_mpm/dashboard/static/css/connection-status.css +10 -10
- claude_mpm/dashboard/static/css/dashboard.css +15 -15
- claude_mpm/dashboard/static/index.html +22 -22
- claude_mpm/dashboard/static/js/REFACTORING_SUMMARY.md +170 -0
- claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
- claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
- claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
- claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
- claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
- claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
- claude_mpm/dashboard/static/js/connection-manager.js +76 -76
- claude_mpm/dashboard/static/js/dashboard.js +76 -58
- claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +9 -9
- claude_mpm/dashboard/static/js/shared/event-bus.js +5 -5
- claude_mpm/dashboard/static/js/shared/logger.js +16 -16
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +6 -6
- claude_mpm/dashboard/static/js/socket-client.js +138 -121
- claude_mpm/dashboard/static/navigation-test-results.md +118 -0
- claude_mpm/dashboard/static/production/main.html +21 -21
- claude_mpm/dashboard/static/test-archive/dashboard.html +22 -22
- claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +36 -0
- claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +39 -0
- claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +38 -0
- claude_mpm/dashboard/templates/code_simple.html +23 -23
- claude_mpm/dashboard/templates/index.html +18 -18
- claude_mpm/hooks/README.md +143 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
- claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
- claude_mpm/hooks/claude_hooks/installer.py +45 -0
- claude_mpm/hooks/templates/README.md +180 -0
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/hooks/templates/settings.json.example +147 -0
- claude_mpm/schemas/agent_schema.json +596 -0
- claude_mpm/schemas/frontmatter_schema.json +165 -0
- claude_mpm/scripts/claude-hook-handler.sh +3 -3
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
- claude_mpm/services/agents/loading/framework_agent_loader.py +8 -8
- claude_mpm/services/agents/local_template_manager.py +3 -1
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +36 -16
- claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
- claude_mpm/services/core/base.py +26 -11
- claude_mpm/services/core/interfaces.py +56 -1
- claude_mpm/services/core/models/agent_config.py +3 -0
- claude_mpm/services/core/models/process.py +4 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
- claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
- claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
- claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
- claude_mpm/services/diagnostics/doctor_reporter.py +6 -4
- claude_mpm/services/diagnostics/models.py +21 -0
- claude_mpm/services/event_bus/README.md +244 -0
- claude_mpm/services/event_bus/direct_relay.py +3 -3
- claude_mpm/services/event_bus/event_bus.py +36 -3
- claude_mpm/services/event_bus/relay.py +23 -7
- claude_mpm/services/events/README.md +303 -0
- claude_mpm/services/events/consumers/logging.py +1 -2
- claude_mpm/services/framework_claude_md_generator/README.md +119 -0
- claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
- claude_mpm/services/local_ops/__init__.py +2 -0
- claude_mpm/services/local_ops/process_manager.py +1 -1
- claude_mpm/services/local_ops/resource_monitor.py +2 -2
- claude_mpm/services/mcp_gateway/README.md +185 -0
- claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
- claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
- claude_mpm/services/mcp_gateway/core/process_pool.py +19 -10
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
- claude_mpm/services/memory/failure_tracker.py +19 -4
- claude_mpm/services/memory/optimizer.py +1 -1
- claude_mpm/services/model/model_router.py +8 -9
- claude_mpm/services/monitor/daemon.py +1 -1
- claude_mpm/services/monitor/server.py +2 -2
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/port_manager.py +1 -1
- claude_mpm/services/project/documentation_manager.py +2 -1
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +1 -0
- claude_mpm/services/self_upgrade_service.py +165 -7
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +955 -0
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/connection.py.backup +217 -0
- claude_mpm/services/socketio/handlers/git.py +2 -2
- claude_mpm/services/socketio/handlers/hook.py.backup +154 -0
- claude_mpm/services/static/.gitkeep +2 -0
- claude_mpm/services/system_instructions_service.py +1 -3
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
- claude_mpm/services/version_control/VERSION +1 -0
- claude_mpm/services/version_control/conflict_resolution.py +6 -4
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/__init__.py +3 -3
- claude_mpm/skills/agent_skills_injector.py +42 -49
- claude_mpm/skills/bundled/.gitkeep +2 -0
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +4 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +108 -114
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +46 -41
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +36 -73
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +100 -125
- claude_mpm/skills/bundled/debugging/root-cause-tracing/find-polluter.sh +63 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +28 -72
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +11 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +272 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/main/artifacts-builder/LICENSE.txt +202 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +13 -1
- claude_mpm/skills/bundled/main/artifacts-builder/scripts/bundle-artifact.sh +54 -0
- claude_mpm/skills/bundled/main/artifacts-builder/scripts/init-artifact.sh +322 -0
- claude_mpm/skills/bundled/main/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- claude_mpm/skills/bundled/main/internal-comms/LICENSE.txt +202 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +11 -0
- claude_mpm/skills/bundled/main/mcp-builder/LICENSE.txt +202 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +109 -277
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +17 -10
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +92 -39
- claude_mpm/skills/bundled/main/mcp-builder/scripts/example_evaluation.xml +22 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/requirements.txt +2 -0
- claude_mpm/skills/bundled/main/skill-creator/LICENSE.txt +202 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +135 -155
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +13 -12
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +5 -3
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +19 -12
- claude_mpm/skills/bundled/performance-profiling.md +6 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
- claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
- claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
- claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
- claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
- claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
- claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
- claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
- claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
- claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
- claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +21 -25
- claude_mpm/skills/bundled/testing/condition-based-waiting/example.ts +158 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +86 -250
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/LICENSE.txt +202 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +145 -57
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +6 -6
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +13 -9
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +8 -8
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +37 -15
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/skills/skills_registry.py +44 -48
- claude_mpm/skills/skills_service.py +117 -108
- claude_mpm/templates/questions/EXAMPLES.md +501 -0
- claude_mpm/templates/questions/__init__.py +43 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +314 -0
- claude_mpm/templates/questions/project_init.py +388 -0
- claude_mpm/templates/questions/ticket_mgmt.py +397 -0
- claude_mpm/tools/README_SOCKETIO_DEBUG.md +224 -0
- claude_mpm/tools/__main__.py +8 -8
- claude_mpm/tools/code_tree_analyzer/README.md +64 -0
- claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
- claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
- claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
- claude_mpm/tools/code_tree_analyzer/core.py +380 -0
- claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
- claude_mpm/tools/code_tree_analyzer/events.py +168 -0
- claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
- claude_mpm/tools/code_tree_analyzer/models.py +39 -0
- claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
- claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
- claude_mpm/utils/agent_dependency_loader.py +3 -3
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +241 -0
- claude_mpm/utils/log_cleanup.py +3 -3
- claude_mpm/utils/robust_installer.py +3 -5
- claude_mpm/utils/structured_questions.py +619 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/METADATA +218 -31
- {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/RECORD +409 -246
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
- claude_mpm/cli/commands/mpm_init.py +0 -2093
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
- claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
- claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
- claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
- claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
- claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
- claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/dist/dashboard.js +0 -2
- claude_mpm/dashboard/static/dist/react/events.js +0 -30
- claude_mpm/dashboard/static/dist/socket-client.js +0 -2
- claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/common-failures.md +0 -213
- claude_mpm/tools/code_tree_analyzer.py +0 -1825
- /claude_mpm/skills/bundled/collaboration/requesting-code-review/{code-reviewer.md → references/code-reviewer-template.md} +0 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/WHEEL +0 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tauri-state-management
|
|
3
|
+
description: Advanced state management in Tauri using Arc, Mutex, RwLock, DashMap for concurrent access patterns and complex state architectures
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: development
|
|
6
|
+
author: Claude MPM Team
|
|
7
|
+
license: MIT
|
|
8
|
+
progressive_disclosure:
|
|
9
|
+
entry_point:
|
|
10
|
+
summary: "Advanced Tauri state patterns: Arc/Mutex, RwLock for read-heavy, DashMap for lock-free maps, multi-state management"
|
|
11
|
+
when_to_use: "When managing complex shared state, high-concurrency scenarios, or multiple independent state containers"
|
|
12
|
+
quick_start: "1. Choose container (Mutex/RwLock/DashMap) 2. Define state struct 3. Register with .manage() 4. Access via State<'_, T>"
|
|
13
|
+
context_limit: 600
|
|
14
|
+
tags:
|
|
15
|
+
- tauri
|
|
16
|
+
- state
|
|
17
|
+
- concurrency
|
|
18
|
+
- arc
|
|
19
|
+
- mutex
|
|
20
|
+
- rwlock
|
|
21
|
+
- dashmap
|
|
22
|
+
requires_tools: []
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Tauri Advanced State Management
|
|
26
|
+
|
|
27
|
+
## State Container Patterns
|
|
28
|
+
|
|
29
|
+
### Arc<Mutex<T>> - Basic Exclusive Access
|
|
30
|
+
|
|
31
|
+
Best for: Infrequent writes, occasional reads, simple synchronization
|
|
32
|
+
|
|
33
|
+
```rust
|
|
34
|
+
use std::sync::Arc;
|
|
35
|
+
use tokio::sync::Mutex;
|
|
36
|
+
|
|
37
|
+
pub struct AppState {
|
|
38
|
+
pub database: Arc<Mutex<Database>>,
|
|
39
|
+
pub config: Arc<Mutex<Config>>,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
impl AppState {
|
|
43
|
+
pub fn new() -> Self {
|
|
44
|
+
Self {
|
|
45
|
+
database: Arc::new(Mutex::new(Database::new())),
|
|
46
|
+
config: Arc::new(Mutex::new(Config::default())),
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
#[tauri::command]
|
|
52
|
+
async fn update_config(
|
|
53
|
+
key: String,
|
|
54
|
+
value: String,
|
|
55
|
+
state: tauri::State<'_, AppState>,
|
|
56
|
+
) -> Result<(), String> {
|
|
57
|
+
let mut config = state.config.lock().await;
|
|
58
|
+
config.set(&key, value);
|
|
59
|
+
Ok(())
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
#[tauri::command]
|
|
63
|
+
async fn get_config_value(
|
|
64
|
+
key: String,
|
|
65
|
+
state: tauri::State<'_, AppState>,
|
|
66
|
+
) -> Result<Option<String>, String> {
|
|
67
|
+
let config = state.config.lock().await;
|
|
68
|
+
Ok(config.get(&key).cloned())
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Key Points**:
|
|
73
|
+
- `Arc` enables shared ownership across async tasks
|
|
74
|
+
- `Mutex` provides exclusive access (one writer OR one reader at a time)
|
|
75
|
+
- Use tokio's `Mutex` (not std) for async contexts
|
|
76
|
+
- Always `.await` on lock acquisition
|
|
77
|
+
|
|
78
|
+
### Arc<RwLock<T>> - Read-Heavy Workloads
|
|
79
|
+
|
|
80
|
+
Best for: Frequent reads, rare writes, read-dominant patterns
|
|
81
|
+
|
|
82
|
+
```rust
|
|
83
|
+
use std::sync::Arc;
|
|
84
|
+
use tokio::sync::RwLock;
|
|
85
|
+
|
|
86
|
+
pub struct CacheState {
|
|
87
|
+
pub cache: Arc<RwLock<HashMap<String, CachedData>>>,
|
|
88
|
+
pub stats: Arc<RwLock<CacheStats>>,
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
#[tauri::command]
|
|
92
|
+
async fn get_cached_data(
|
|
93
|
+
key: String,
|
|
94
|
+
state: tauri::State<'_, CacheState>,
|
|
95
|
+
) -> Result<Option<CachedData>, String> {
|
|
96
|
+
// Read lock - multiple concurrent readers allowed
|
|
97
|
+
let cache = state.cache.read().await;
|
|
98
|
+
Ok(cache.get(&key).cloned())
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
#[tauri::command]
|
|
102
|
+
async fn update_cache(
|
|
103
|
+
key: String,
|
|
104
|
+
data: CachedData,
|
|
105
|
+
state: tauri::State<'_, CacheState>,
|
|
106
|
+
) -> Result<(), String> {
|
|
107
|
+
// Write lock - exclusive access
|
|
108
|
+
let mut cache = state.cache.write().await;
|
|
109
|
+
cache.insert(key, data);
|
|
110
|
+
Ok(())
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
#[tauri::command]
|
|
114
|
+
async fn get_stats(
|
|
115
|
+
state: tauri::State<'_, CacheState>,
|
|
116
|
+
) -> Result<CacheStats, String> {
|
|
117
|
+
// Read lock doesn't block other readers
|
|
118
|
+
let stats = state.stats.read().await;
|
|
119
|
+
Ok(stats.clone())
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Key Points**:
|
|
124
|
+
- `read()` allows multiple concurrent readers
|
|
125
|
+
- `write()` requires exclusive access
|
|
126
|
+
- Perfect for caches, configuration, read-heavy data
|
|
127
|
+
- Readers don't block other readers
|
|
128
|
+
|
|
129
|
+
### Arc<DashMap<K, V>> - Lock-Free Concurrent Map
|
|
130
|
+
|
|
131
|
+
Best for: High-concurrency, frequent map operations, no lock contention
|
|
132
|
+
|
|
133
|
+
```rust
|
|
134
|
+
use std::sync::Arc;
|
|
135
|
+
use dashmap::DashMap;
|
|
136
|
+
|
|
137
|
+
pub struct SessionState {
|
|
138
|
+
pub sessions: Arc<DashMap<String, Session>>,
|
|
139
|
+
pub active_connections: Arc<DashMap<String, Connection>>,
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
impl SessionState {
|
|
143
|
+
pub fn new() -> Self {
|
|
144
|
+
Self {
|
|
145
|
+
sessions: Arc::new(DashMap::new()),
|
|
146
|
+
active_connections: Arc::new(DashMap::new()),
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
#[tauri::command]
|
|
152
|
+
async fn create_session(
|
|
153
|
+
session_id: String,
|
|
154
|
+
state: tauri::State<'_, SessionState>,
|
|
155
|
+
) -> Result<(), String> {
|
|
156
|
+
// No explicit locking needed
|
|
157
|
+
state.sessions.insert(
|
|
158
|
+
session_id.clone(),
|
|
159
|
+
Session::new(session_id)
|
|
160
|
+
);
|
|
161
|
+
Ok(())
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
#[tauri::command]
|
|
165
|
+
async fn get_session(
|
|
166
|
+
session_id: String,
|
|
167
|
+
state: tauri::State<'_, SessionState>,
|
|
168
|
+
) -> Result<Option<Session>, String> {
|
|
169
|
+
// Returns Option without holding lock
|
|
170
|
+
Ok(state.sessions.get(&session_id)
|
|
171
|
+
.map(|entry| entry.value().clone()))
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
#[tauri::command]
|
|
175
|
+
async fn remove_session(
|
|
176
|
+
session_id: String,
|
|
177
|
+
state: tauri::State<'_, SessionState>,
|
|
178
|
+
) -> Result<(), String> {
|
|
179
|
+
state.sessions.remove(&session_id);
|
|
180
|
+
Ok(())
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
#[tauri::command]
|
|
184
|
+
async fn list_active_sessions(
|
|
185
|
+
state: tauri::State<'_, SessionState>,
|
|
186
|
+
) -> Result<Vec<String>, String> {
|
|
187
|
+
// Iterate without holding global lock
|
|
188
|
+
Ok(state.sessions.iter()
|
|
189
|
+
.map(|entry| entry.key().clone())
|
|
190
|
+
.collect())
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Key Points**:
|
|
195
|
+
- No explicit `.lock()` needed
|
|
196
|
+
- Lock-free concurrent operations
|
|
197
|
+
- Better performance under high concurrency
|
|
198
|
+
- Use for session management, caches, registries
|
|
199
|
+
|
|
200
|
+
**Add to Cargo.toml**:
|
|
201
|
+
```toml
|
|
202
|
+
[dependencies]
|
|
203
|
+
dashmap = "6.0"
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Complex State Architectures
|
|
207
|
+
|
|
208
|
+
### Multi-State Pattern
|
|
209
|
+
|
|
210
|
+
```rust
|
|
211
|
+
// Separate concerns into different state containers
|
|
212
|
+
pub struct DatabaseState {
|
|
213
|
+
pub pool: Arc<Mutex<DbPool>>,
|
|
214
|
+
pub migrations: Arc<Mutex<MigrationTracker>>,
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
pub struct UIState {
|
|
218
|
+
pub theme: Arc<RwLock<Theme>>,
|
|
219
|
+
pub preferences: Arc<RwLock<Preferences>>,
|
|
220
|
+
pub window_states: Arc<DashMap<String, WindowState>>,
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
pub struct AuthState {
|
|
224
|
+
pub sessions: Arc<DashMap<String, Session>>,
|
|
225
|
+
pub tokens: Arc<RwLock<TokenManager>>,
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Register all states
|
|
229
|
+
fn main() {
|
|
230
|
+
tauri::Builder::default()
|
|
231
|
+
.manage(DatabaseState::new())
|
|
232
|
+
.manage(UIState::new())
|
|
233
|
+
.manage(AuthState::new())
|
|
234
|
+
.invoke_handler(tauri::generate_handler![
|
|
235
|
+
/* commands */
|
|
236
|
+
])
|
|
237
|
+
.run(tauri::generate_context!())
|
|
238
|
+
.expect("error while running tauri application");
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Access multiple states in one command
|
|
242
|
+
#[tauri::command]
|
|
243
|
+
async fn authenticated_query(
|
|
244
|
+
query: String,
|
|
245
|
+
session_id: String,
|
|
246
|
+
db_state: tauri::State<'_, DatabaseState>,
|
|
247
|
+
auth_state: tauri::State<'_, AuthState>,
|
|
248
|
+
) -> Result<Vec<Row>, String> {
|
|
249
|
+
// Validate session
|
|
250
|
+
let session = auth_state.sessions.get(&session_id)
|
|
251
|
+
.ok_or("Invalid session")?;
|
|
252
|
+
|
|
253
|
+
// Execute query
|
|
254
|
+
let pool = db_state.pool.lock().await;
|
|
255
|
+
pool.query(&query).await
|
|
256
|
+
.map_err(|e| e.to_string())
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Nested State with Interior Mutability
|
|
261
|
+
|
|
262
|
+
```rust
|
|
263
|
+
use std::sync::Arc;
|
|
264
|
+
use tokio::sync::RwLock;
|
|
265
|
+
|
|
266
|
+
pub struct User {
|
|
267
|
+
pub id: String,
|
|
268
|
+
pub name: String,
|
|
269
|
+
pub last_active: Arc<RwLock<SystemTime>>,
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
pub struct AppState {
|
|
273
|
+
pub users: Arc<DashMap<String, User>>,
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
#[tauri::command]
|
|
277
|
+
async fn update_user_activity(
|
|
278
|
+
user_id: String,
|
|
279
|
+
state: tauri::State<'_, AppState>,
|
|
280
|
+
) -> Result<(), String> {
|
|
281
|
+
// Get user from DashMap
|
|
282
|
+
if let Some(user_entry) = state.users.get(&user_id) {
|
|
283
|
+
// Update nested RwLock without locking entire map
|
|
284
|
+
let mut last_active = user_entry.last_active.write().await;
|
|
285
|
+
*last_active = SystemTime::now();
|
|
286
|
+
}
|
|
287
|
+
Ok(())
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## Advanced Patterns
|
|
292
|
+
|
|
293
|
+
### State with Cleanup
|
|
294
|
+
|
|
295
|
+
```rust
|
|
296
|
+
pub struct ResourceState {
|
|
297
|
+
pub connections: Arc<DashMap<String, Connection>>,
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
impl ResourceState {
|
|
301
|
+
pub async fn cleanup_expired(&self) {
|
|
302
|
+
let now = SystemTime::now();
|
|
303
|
+
self.connections.retain(|_k, v| {
|
|
304
|
+
!v.is_expired(now)
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Background cleanup task
|
|
310
|
+
#[tauri::command]
|
|
311
|
+
async fn start_cleanup_task(
|
|
312
|
+
state: tauri::State<'_, ResourceState>,
|
|
313
|
+
) -> Result<(), String> {
|
|
314
|
+
let state_clone = state.inner().clone();
|
|
315
|
+
|
|
316
|
+
tokio::spawn(async move {
|
|
317
|
+
loop {
|
|
318
|
+
tokio::time::sleep(Duration::from_secs(60)).await;
|
|
319
|
+
state_clone.cleanup_expired().await;
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
Ok(())
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### State Initialization with Dependencies
|
|
328
|
+
|
|
329
|
+
```rust
|
|
330
|
+
pub struct AppState {
|
|
331
|
+
pub db: Arc<Mutex<Database>>,
|
|
332
|
+
pub cache: Arc<RwLock<Cache>>,
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
impl AppState {
|
|
336
|
+
pub async fn new(config: &Config) -> Result<Self, String> {
|
|
337
|
+
// Initialize with dependencies
|
|
338
|
+
let db = Database::connect(&config.db_url)
|
|
339
|
+
.await
|
|
340
|
+
.map_err(|e| e.to_string())?;
|
|
341
|
+
|
|
342
|
+
let cache = Cache::with_capacity(config.cache_size);
|
|
343
|
+
|
|
344
|
+
Ok(Self {
|
|
345
|
+
db: Arc::new(Mutex::new(db)),
|
|
346
|
+
cache: Arc::new(RwLock::new(cache)),
|
|
347
|
+
})
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// In main.rs
|
|
352
|
+
fn main() {
|
|
353
|
+
let config = Config::load().expect("Failed to load config");
|
|
354
|
+
|
|
355
|
+
let runtime = tokio::runtime::Runtime::new()
|
|
356
|
+
.expect("Failed to create runtime");
|
|
357
|
+
|
|
358
|
+
let state = runtime.block_on(async {
|
|
359
|
+
AppState::new(&config).await
|
|
360
|
+
.expect("Failed to initialize state")
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
tauri::Builder::default()
|
|
364
|
+
.manage(state)
|
|
365
|
+
.invoke_handler(tauri::generate_handler![/* commands */])
|
|
366
|
+
.run(tauri::generate_context!())
|
|
367
|
+
.expect("error while running tauri application");
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Transactional State Updates
|
|
372
|
+
|
|
373
|
+
```rust
|
|
374
|
+
#[tauri::command]
|
|
375
|
+
async fn transfer_funds(
|
|
376
|
+
from_account: String,
|
|
377
|
+
to_account: String,
|
|
378
|
+
amount: f64,
|
|
379
|
+
state: tauri::State<'_, BankState>,
|
|
380
|
+
) -> Result<(), String> {
|
|
381
|
+
// Lock both accounts to prevent race conditions
|
|
382
|
+
let mut accounts = state.accounts.write().await;
|
|
383
|
+
|
|
384
|
+
let from_balance = accounts.get_mut(&from_account)
|
|
385
|
+
.ok_or("Source account not found")?;
|
|
386
|
+
|
|
387
|
+
if *from_balance < amount {
|
|
388
|
+
return Err("Insufficient funds".to_string());
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
*from_balance -= amount;
|
|
392
|
+
|
|
393
|
+
let to_balance = accounts.get_mut(&to_account)
|
|
394
|
+
.ok_or("Destination account not found")?;
|
|
395
|
+
|
|
396
|
+
*to_balance += amount;
|
|
397
|
+
|
|
398
|
+
// Both updates succeed or both fail (atomic)
|
|
399
|
+
Ok(())
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## Lock Management Best Practices
|
|
404
|
+
|
|
405
|
+
### ❌ Holding Locks Across Await Points
|
|
406
|
+
|
|
407
|
+
```rust
|
|
408
|
+
// WRONG - Lock held across await (potential deadlock)
|
|
409
|
+
#[tauri::command]
|
|
410
|
+
async fn bad_pattern(
|
|
411
|
+
state: tauri::State<'_, AppState>,
|
|
412
|
+
) -> Result<(), String> {
|
|
413
|
+
let mut data = state.data.lock().await;
|
|
414
|
+
// Lock is held here
|
|
415
|
+
expensive_async_operation().await?; // Deadlock risk!
|
|
416
|
+
data.update();
|
|
417
|
+
Ok(())
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// CORRECT - Release lock before await
|
|
421
|
+
#[tauri::command]
|
|
422
|
+
async fn good_pattern(
|
|
423
|
+
state: tauri::State<'_, AppState>,
|
|
424
|
+
) -> Result<(), String> {
|
|
425
|
+
let result = expensive_async_operation().await?;
|
|
426
|
+
|
|
427
|
+
{
|
|
428
|
+
let mut data = state.data.lock().await;
|
|
429
|
+
data.update_with(result);
|
|
430
|
+
} // Lock released here
|
|
431
|
+
|
|
432
|
+
Ok(())
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### ✅ Minimizing Lock Scope
|
|
437
|
+
|
|
438
|
+
```rust
|
|
439
|
+
#[tauri::command]
|
|
440
|
+
async fn optimized_read(
|
|
441
|
+
key: String,
|
|
442
|
+
state: tauri::State<'_, AppState>,
|
|
443
|
+
) -> Result<String, String> {
|
|
444
|
+
// Clone only what you need, release lock immediately
|
|
445
|
+
let value = {
|
|
446
|
+
let cache = state.cache.read().await;
|
|
447
|
+
cache.get(&key).cloned()
|
|
448
|
+
}; // Lock released here
|
|
449
|
+
|
|
450
|
+
match value {
|
|
451
|
+
Some(v) => Ok(v),
|
|
452
|
+
None => {
|
|
453
|
+
// Compute without holding lock
|
|
454
|
+
let computed = compute_value(&key).await?;
|
|
455
|
+
|
|
456
|
+
// Lock only for insertion
|
|
457
|
+
{
|
|
458
|
+
let mut cache = state.cache.write().await;
|
|
459
|
+
cache.insert(key, computed.clone());
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
Ok(computed)
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### ✅ Using Try-Lock for Non-Blocking
|
|
469
|
+
|
|
470
|
+
```rust
|
|
471
|
+
use tokio::sync::Mutex;
|
|
472
|
+
|
|
473
|
+
#[tauri::command]
|
|
474
|
+
async fn try_update(
|
|
475
|
+
state: tauri::State<'_, AppState>,
|
|
476
|
+
) -> Result<String, String> {
|
|
477
|
+
// Try to acquire lock without blocking
|
|
478
|
+
match state.data.try_lock() {
|
|
479
|
+
Ok(mut data) => {
|
|
480
|
+
data.update();
|
|
481
|
+
Ok("Updated".to_string())
|
|
482
|
+
}
|
|
483
|
+
Err(_) => {
|
|
484
|
+
// Lock is held, don't wait
|
|
485
|
+
Ok("Busy, try again later".to_string())
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
## Decision Matrix
|
|
492
|
+
|
|
493
|
+
| Use Case | Container | Reason |
|
|
494
|
+
|----------|-----------|--------|
|
|
495
|
+
| Simple shared data | `Arc<Mutex<T>>` | Easy, works for everything |
|
|
496
|
+
| Frequent reads, rare writes | `Arc<RwLock<T>>` | Concurrent readers |
|
|
497
|
+
| High-concurrency map | `Arc<DashMap<K,V>>` | Lock-free operations |
|
|
498
|
+
| Session management | `Arc<DashMap<K,V>>` | Concurrent access |
|
|
499
|
+
| Configuration cache | `Arc<RwLock<T>>` | Many readers, few writers |
|
|
500
|
+
| Database connection | `Arc<Mutex<T>>` | Exclusive access needed |
|
|
501
|
+
| Active connections | `Arc<DashMap<K,V>>` | High concurrency |
|
|
502
|
+
| User preferences | `Arc<RwLock<T>>` | Read-heavy |
|
|
503
|
+
|
|
504
|
+
## Performance Considerations
|
|
505
|
+
|
|
506
|
+
### Benchmarking State Access
|
|
507
|
+
|
|
508
|
+
```rust
|
|
509
|
+
use std::time::Instant;
|
|
510
|
+
|
|
511
|
+
#[tauri::command]
|
|
512
|
+
async fn benchmark_state_access(
|
|
513
|
+
iterations: usize,
|
|
514
|
+
state: tauri::State<'_, AppState>,
|
|
515
|
+
) -> Result<BenchmarkResults, String> {
|
|
516
|
+
let start = Instant::now();
|
|
517
|
+
|
|
518
|
+
for _ in 0..iterations {
|
|
519
|
+
let _data = state.data.read().await;
|
|
520
|
+
// Simulate work
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
let duration = start.elapsed();
|
|
524
|
+
|
|
525
|
+
Ok(BenchmarkResults {
|
|
526
|
+
iterations,
|
|
527
|
+
total_ms: duration.as_millis(),
|
|
528
|
+
avg_us: duration.as_micros() / iterations as u128,
|
|
529
|
+
})
|
|
530
|
+
}
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
## Common Pitfalls
|
|
534
|
+
|
|
535
|
+
❌ **Using std::sync::Mutex in async code**:
|
|
536
|
+
```rust
|
|
537
|
+
use std::sync::Mutex; // WRONG for async
|
|
538
|
+
|
|
539
|
+
// Use tokio's Mutex instead
|
|
540
|
+
use tokio::sync::Mutex; // CORRECT for async
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
❌ **Not using Arc for shared state**:
|
|
544
|
+
```rust
|
|
545
|
+
// WRONG - Mutex alone doesn't provide shared ownership
|
|
546
|
+
pub struct AppState {
|
|
547
|
+
data: Mutex<Data>, // Can't clone/share
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// CORRECT - Arc enables shared ownership
|
|
551
|
+
pub struct AppState {
|
|
552
|
+
data: Arc<Mutex<Data>>, // Can clone Arc, share across tasks
|
|
553
|
+
}
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
❌ **Forgetting to .await lock acquisition**:
|
|
557
|
+
```rust
|
|
558
|
+
// WRONG - forgot .await
|
|
559
|
+
let data = state.data.lock(); // Returns Future, not MutexGuard
|
|
560
|
+
|
|
561
|
+
// CORRECT
|
|
562
|
+
let data = state.data.lock().await;
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
## Summary
|
|
566
|
+
|
|
567
|
+
- **`Arc<Mutex<T>>`** - General purpose, exclusive access
|
|
568
|
+
- **`Arc<RwLock<T>>`** - Read-heavy workloads, concurrent readers
|
|
569
|
+
- **`Arc<DashMap<K,V>>`** - Lock-free maps, high concurrency
|
|
570
|
+
- **Minimize lock scope** - Hold locks for shortest time possible
|
|
571
|
+
- **Don't hold locks across await** - Deadlock risk
|
|
572
|
+
- **Use multiple states** - Separate concerns for better granularity
|
|
573
|
+
- **Always use tokio's Mutex/RwLock** - Not std's version in async
|