claude-mpm 4.14.6__py3-none-any.whl → 4.21.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_ENGINEER.md +286 -0
- claude_mpm/agents/BASE_PM.md +272 -23
- claude_mpm/agents/OUTPUT_STYLE.md +48 -3
- claude_mpm/agents/PM_INSTRUCTIONS.md +49 -0
- claude_mpm/agents/agent_loader.py +17 -5
- claude_mpm/agents/frontmatter_validator.py +284 -253
- claude_mpm/agents/templates/agentic-coder-optimizer.json +9 -2
- claude_mpm/agents/templates/api_qa.json +7 -1
- claude_mpm/agents/templates/clerk-ops.json +8 -1
- claude_mpm/agents/templates/code_analyzer.json +4 -1
- claude_mpm/agents/templates/dart_engineer.json +11 -1
- claude_mpm/agents/templates/data_engineer.json +11 -1
- claude_mpm/agents/templates/documentation.json +6 -1
- claude_mpm/agents/templates/engineer.json +18 -1
- claude_mpm/agents/templates/gcp_ops_agent.json +8 -1
- claude_mpm/agents/templates/golang_engineer.json +11 -1
- claude_mpm/agents/templates/java_engineer.json +12 -2
- claude_mpm/agents/templates/local_ops_agent.json +216 -37
- claude_mpm/agents/templates/nextjs_engineer.json +11 -1
- claude_mpm/agents/templates/ops.json +8 -1
- claude_mpm/agents/templates/php-engineer.json +20 -4
- claude_mpm/agents/templates/project_organizer.json +10 -3
- claude_mpm/agents/templates/prompt-engineer.json +5 -1
- claude_mpm/agents/templates/python_engineer.json +19 -4
- claude_mpm/agents/templates/qa.json +7 -1
- claude_mpm/agents/templates/react_engineer.json +11 -1
- claude_mpm/agents/templates/refactoring_engineer.json +8 -1
- claude_mpm/agents/templates/research.json +4 -1
- claude_mpm/agents/templates/ruby-engineer.json +11 -1
- claude_mpm/agents/templates/rust_engineer.json +23 -8
- claude_mpm/agents/templates/security.json +6 -1
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/agents/templates/ticketing.json +6 -1
- claude_mpm/agents/templates/typescript_engineer.json +11 -1
- claude_mpm/agents/templates/vercel_ops_agent.json +8 -1
- claude_mpm/agents/templates/version_control.json +8 -1
- claude_mpm/agents/templates/web_qa.json +7 -1
- claude_mpm/agents/templates/web_ui.json +11 -1
- claude_mpm/cli/__init__.py +34 -740
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/agent_manager.py +25 -12
- claude_mpm/cli/commands/agent_state_manager.py +186 -0
- claude_mpm/cli/commands/agents.py +204 -148
- claude_mpm/cli/commands/aggregate.py +7 -3
- claude_mpm/cli/commands/analyze.py +9 -4
- claude_mpm/cli/commands/analyze_code.py +7 -2
- claude_mpm/cli/commands/auto_configure.py +7 -9
- claude_mpm/cli/commands/config.py +47 -13
- claude_mpm/cli/commands/configure.py +294 -1788
- claude_mpm/cli/commands/configure_agent_display.py +261 -0
- claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
- claude_mpm/cli/commands/configure_hook_manager.py +225 -0
- claude_mpm/cli/commands/configure_models.py +18 -0
- claude_mpm/cli/commands/configure_navigation.py +167 -0
- claude_mpm/cli/commands/configure_paths.py +104 -0
- claude_mpm/cli/commands/configure_persistence.py +254 -0
- claude_mpm/cli/commands/configure_startup_manager.py +646 -0
- claude_mpm/cli/commands/configure_template_editor.py +497 -0
- claude_mpm/cli/commands/configure_validators.py +73 -0
- claude_mpm/cli/commands/local_deploy.py +3 -2
- claude_mpm/cli/commands/memory.py +54 -20
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +525 -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 +75 -4
- claude_mpm/cli/commands/skills.py +488 -0
- claude_mpm/cli/executor.py +204 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +3 -0
- claude_mpm/cli/interactive/skills_wizard.py +491 -0
- claude_mpm/cli/parsers/base_parser.py +7 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
- claude_mpm/cli/parsers/skills_parser.py +137 -0
- claude_mpm/cli/shared/output_formatters.py +28 -19
- claude_mpm/cli/startup.py +538 -0
- claude_mpm/commands/mpm-auto-configure.md +52 -0
- claude_mpm/commands/mpm-help.md +3 -0
- claude_mpm/commands/mpm-init.md +112 -6
- claude_mpm/commands/mpm-version.md +113 -0
- claude_mpm/commands/mpm.md +1 -0
- claude_mpm/config/agent_config.py +2 -2
- claude_mpm/constants.py +12 -0
- claude_mpm/core/base_service.py +13 -12
- claude_mpm/core/config.py +42 -0
- claude_mpm/core/enums.py +452 -0
- claude_mpm/core/factories.py +1 -1
- claude_mpm/core/instruction_reinforcement_hook.py +2 -1
- claude_mpm/core/interactive_session.py +6 -3
- claude_mpm/core/interfaces.py +56 -1
- claude_mpm/core/logging_config.py +6 -2
- claude_mpm/core/oneshot_session.py +8 -4
- claude_mpm/core/optimized_agent_loader.py +3 -3
- claude_mpm/core/output_style_manager.py +12 -192
- claude_mpm/core/service_registry.py +5 -1
- claude_mpm/core/types.py +2 -9
- claude_mpm/core/typing_utils.py +7 -6
- claude_mpm/dashboard/static/js/dashboard.js +0 -14
- claude_mpm/dashboard/templates/index.html +3 -41
- claude_mpm/hooks/__init__.py +8 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
- claude_mpm/hooks/instruction_reinforcement.py +7 -2
- claude_mpm/hooks/session_resume_hook.py +121 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/services/agents/auto_config_manager.py +10 -11
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
- claude_mpm/services/agents/deployment/agent_validator.py +17 -1
- claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
- claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
- claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +7 -6
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +5 -3
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
- claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
- claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
- claude_mpm/services/agents/local_template_manager.py +1 -1
- claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
- claude_mpm/services/agents/recommender.py +47 -0
- claude_mpm/services/agents/registry/modification_tracker.py +5 -2
- claude_mpm/services/cli/resume_service.py +617 -0
- claude_mpm/services/cli/session_manager.py +87 -0
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +372 -0
- claude_mpm/services/command_handler_service.py +11 -5
- claude_mpm/services/core/interfaces/process.py +6 -6
- claude_mpm/services/core/interfaces.py +56 -1
- claude_mpm/services/core/models/__init__.py +0 -2
- claude_mpm/services/core/models/agent_config.py +15 -28
- claude_mpm/services/core/models/health.py +1 -28
- claude_mpm/services/core/models/process.py +22 -41
- claude_mpm/services/core/path_resolver.py +1 -1
- claude_mpm/services/diagnostics/__init__.py +2 -2
- claude_mpm/services/diagnostics/checks/agent_check.py +25 -24
- claude_mpm/services/diagnostics/checks/claude_code_check.py +24 -23
- claude_mpm/services/diagnostics/checks/common_issues_check.py +25 -24
- claude_mpm/services/diagnostics/checks/configuration_check.py +24 -23
- claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
- claude_mpm/services/diagnostics/checks/installation_check.py +30 -29
- claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
- claude_mpm/services/diagnostics/checks/mcp_check.py +50 -36
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +36 -31
- claude_mpm/services/diagnostics/checks/monitor_check.py +23 -22
- claude_mpm/services/diagnostics/checks/startup_log_check.py +9 -8
- claude_mpm/services/diagnostics/diagnostic_runner.py +6 -5
- claude_mpm/services/diagnostics/doctor_reporter.py +28 -25
- claude_mpm/services/diagnostics/models.py +37 -21
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
- claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
- claude_mpm/services/infrastructure/monitoring/base.py +5 -13
- claude_mpm/services/infrastructure/monitoring/network.py +7 -6
- claude_mpm/services/infrastructure/monitoring/process.py +13 -12
- claude_mpm/services/infrastructure/monitoring/resources.py +7 -6
- claude_mpm/services/infrastructure/monitoring/service.py +16 -15
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/local_ops/__init__.py +5 -3
- claude_mpm/services/local_ops/crash_detector.py +1 -1
- claude_mpm/services/local_ops/health_checks/http_check.py +2 -1
- claude_mpm/services/local_ops/health_checks/process_check.py +2 -1
- claude_mpm/services/local_ops/health_checks/resource_check.py +2 -1
- claude_mpm/services/local_ops/health_manager.py +1 -1
- claude_mpm/services/local_ops/process_manager.py +12 -12
- claude_mpm/services/local_ops/restart_manager.py +1 -1
- claude_mpm/services/local_ops/state_manager.py +6 -5
- claude_mpm/services/local_ops/unified_manager.py +2 -2
- claude_mpm/services/mcp_config_manager.py +7 -126
- claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
- claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
- claude_mpm/services/mcp_gateway/core/base.py +18 -31
- claude_mpm/services/mcp_gateway/core/process_pool.py +19 -10
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +97 -45
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +30 -28
- claude_mpm/services/memory_hook_service.py +4 -1
- claude_mpm/services/monitor/daemon_manager.py +3 -2
- claude_mpm/services/monitor/handlers/dashboard.py +2 -1
- claude_mpm/services/monitor/handlers/hooks.py +2 -1
- claude_mpm/services/monitor/management/lifecycle.py +3 -2
- claude_mpm/services/monitor/server.py +2 -1
- claude_mpm/services/session_management_service.py +3 -2
- claude_mpm/services/session_manager.py +205 -1
- claude_mpm/services/shared/async_service_base.py +16 -27
- claude_mpm/services/shared/lifecycle_service_base.py +1 -14
- claude_mpm/services/socketio/handlers/__init__.py +5 -2
- claude_mpm/services/socketio/handlers/hook.py +13 -2
- claude_mpm/services/socketio/handlers/registry.py +4 -2
- claude_mpm/services/socketio/server/main.py +10 -8
- claude_mpm/services/subprocess_launcher_service.py +14 -5
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +8 -7
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +6 -5
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +8 -7
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +7 -6
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +5 -4
- claude_mpm/services/unified/config_strategies/validation_strategy.py +13 -9
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +10 -3
- claude_mpm/services/unified/deployment_strategies/local.py +6 -5
- claude_mpm/services/unified/deployment_strategies/utils.py +6 -5
- claude_mpm/services/unified/deployment_strategies/vercel.py +7 -6
- claude_mpm/services/unified/interfaces.py +3 -1
- claude_mpm/services/unified/unified_analyzer.py +14 -10
- claude_mpm/services/unified/unified_config.py +2 -1
- claude_mpm/services/unified/unified_deployment.py +9 -4
- claude_mpm/services/version_service.py +104 -1
- claude_mpm/skills/__init__.py +42 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
- claude_mpm/skills/bundled/__init__.py +6 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- 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/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- 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/database-migration.md +199 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -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/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -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 +499 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- 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 +303 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +567 -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/refactoring-patterns.md +180 -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/security-scanning.md +327 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- 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/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
- 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 +129 -0
- 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/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +286 -0
- claude_mpm/skills/skill_manager.py +310 -0
- claude_mpm/skills/skills_registry.py +348 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/tools/code_tree_analyzer.py +177 -141
- claude_mpm/tools/code_tree_events.py +4 -2
- claude_mpm/utils/agent_dependency_loader.py +2 -2
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.21.0.dist-info}/METADATA +211 -33
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.21.0.dist-info}/RECORD +339 -199
- claude_mpm/agents/INSTRUCTIONS_OLD_DEPRECATED.md +0 -602
- claude_mpm/cli/commands/mpm_init.py +0 -1994
- claude_mpm/dashboard/static/css/code-tree.css +0 -1639
- claude_mpm/dashboard/static/js/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/js/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/js/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/js/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/js/components/code-tree.js +0 -5869
- claude_mpm/dashboard/static/js/components/code-viewer.js +0 -1386
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
- claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1041
- claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
- claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
- claude_mpm/services/project/analyzer_refactored.py +0 -450
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.21.0.dist-info}/WHEEL +0 -0
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.21.0.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.21.0.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.21.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,770 @@
|
|
|
1
|
+
# Tauri Framework
|
|
2
|
+
|
|
3
|
+
Complete guide to building desktop applications with Tauri 2.x - the modern alternative to Electron with web UI + Rust backend.
|
|
4
|
+
|
|
5
|
+
## Architecture Overview
|
|
6
|
+
|
|
7
|
+
### What is Tauri?
|
|
8
|
+
|
|
9
|
+
Tauri is a framework for building desktop applications using web technologies for the frontend (HTML, CSS, JavaScript) and Rust for the backend. Unlike Electron which bundles Chromium and Node.js (~100MB+), Tauri uses the OS's native webview (WebKit on macOS, WebView2 on Windows, WebKitGTK on Linux) resulting in 3-5MB bundles.
|
|
10
|
+
|
|
11
|
+
**Core Architecture:**
|
|
12
|
+
```
|
|
13
|
+
┌─────────────────────────────────────────┐
|
|
14
|
+
│ Frontend (Web) │
|
|
15
|
+
│ React/Vue/Svelte/Vanilla │
|
|
16
|
+
│ ├─ UI Rendering │
|
|
17
|
+
│ ├─ User Interactions │
|
|
18
|
+
│ └─ invoke() calls to backend │
|
|
19
|
+
└──────────────┬──────────────────────────┘
|
|
20
|
+
│ IPC (JSON)
|
|
21
|
+
┌──────────────▼──────────────────────────┐
|
|
22
|
+
│ Tauri Core (Rust) │
|
|
23
|
+
│ ├─ Command Handlers │
|
|
24
|
+
│ ├─ Event System │
|
|
25
|
+
│ ├─ State Management │
|
|
26
|
+
│ └─ Plugin System │
|
|
27
|
+
└──────────────┬──────────────────────────┘
|
|
28
|
+
│
|
|
29
|
+
┌──────────────▼──────────────────────────┐
|
|
30
|
+
│ Native OS APIs │
|
|
31
|
+
│ ├─ File System │
|
|
32
|
+
│ ├─ Shell/Process │
|
|
33
|
+
│ ├─ HTTP Client │
|
|
34
|
+
│ ├─ System Tray │
|
|
35
|
+
│ └─ Notifications │
|
|
36
|
+
└─────────────────────────────────────────┘
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Project Structure
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
my-tauri-app/
|
|
43
|
+
├─ src-tauri/ # Rust backend
|
|
44
|
+
│ ├─ src/
|
|
45
|
+
│ │ ├─ main.rs # Entry point, command registration
|
|
46
|
+
│ │ ├─ commands/ # Command modules
|
|
47
|
+
│ │ ├─ state/ # Application state
|
|
48
|
+
│ │ └─ lib.rs # Optional library code
|
|
49
|
+
│ ├─ Cargo.toml # Rust dependencies
|
|
50
|
+
│ ├─ tauri.conf.json # Tauri configuration
|
|
51
|
+
│ ├─ icons/ # App icons
|
|
52
|
+
│ └─ capabilities/ # Security capabilities (v2)
|
|
53
|
+
├─ src/ # Frontend source
|
|
54
|
+
│ ├─ App.tsx # Main React/Vue component
|
|
55
|
+
│ ├─ components/
|
|
56
|
+
│ ├─ styles/
|
|
57
|
+
│ └─ main.tsx # Frontend entry
|
|
58
|
+
├─ package.json # Node dependencies
|
|
59
|
+
└─ vite.config.ts # Vite configuration
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Setup and Installation
|
|
63
|
+
|
|
64
|
+
### Prerequisites
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Rust toolchain (rustup.rs)
|
|
68
|
+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
69
|
+
|
|
70
|
+
# Node.js (for frontend tooling)
|
|
71
|
+
# Install via nvm, fnm, or nodejs.org
|
|
72
|
+
|
|
73
|
+
# Platform-specific requirements:
|
|
74
|
+
# Windows: WebView2, Visual Studio Build Tools
|
|
75
|
+
# macOS: Xcode Command Line Tools
|
|
76
|
+
# Linux: webkit2gtk, build-essential
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Create New Tauri Project
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Install Tauri CLI
|
|
83
|
+
cargo install tauri-cli --version "^2.0.0"
|
|
84
|
+
|
|
85
|
+
# Create project with wizard
|
|
86
|
+
cargo create-tauri-app
|
|
87
|
+
|
|
88
|
+
# Or with specific frontend:
|
|
89
|
+
npm create tauri-app@latest
|
|
90
|
+
# Select: Package manager (npm/yarn/pnpm)
|
|
91
|
+
# Frontend framework (React/Vue/Svelte/Vanilla)
|
|
92
|
+
# TypeScript (recommended: Yes)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Development Workflow
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Start development server (hot reload)
|
|
99
|
+
cargo tauri dev
|
|
100
|
+
# Opens app window + watches for changes
|
|
101
|
+
# Frontend: Vite HMR
|
|
102
|
+
# Backend: Cargo watch (rebuild on .rs changes)
|
|
103
|
+
|
|
104
|
+
# Build for production
|
|
105
|
+
cargo tauri build
|
|
106
|
+
# Creates optimized bundle in src-tauri/target/release/bundle/
|
|
107
|
+
|
|
108
|
+
# Run frontend only (testing UI)
|
|
109
|
+
npm run dev
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## IPC Communication
|
|
113
|
+
|
|
114
|
+
### Commands (Frontend → Backend)
|
|
115
|
+
|
|
116
|
+
Commands are Rust functions exposed to the frontend via `#[tauri::command]`.
|
|
117
|
+
|
|
118
|
+
**Basic Command:**
|
|
119
|
+
```rust
|
|
120
|
+
// src-tauri/src/main.rs
|
|
121
|
+
#[tauri::command]
|
|
122
|
+
fn greet(name: &str) -> String {
|
|
123
|
+
format!("Hello, {}!", name)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
fn main() {
|
|
127
|
+
tauri::Builder::default()
|
|
128
|
+
.invoke_handler(tauri::generate_handler![greet])
|
|
129
|
+
.run(tauri::generate_context!())
|
|
130
|
+
.expect("error while running tauri application");
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Frontend Usage:**
|
|
135
|
+
```typescript
|
|
136
|
+
// src/App.tsx
|
|
137
|
+
import { invoke } from '@tauri-apps/api/core';
|
|
138
|
+
|
|
139
|
+
async function handleGreet() {
|
|
140
|
+
const message = await invoke<string>('greet', { name: 'World' });
|
|
141
|
+
console.log(message); // "Hello, World!"
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Advanced Commands with State
|
|
146
|
+
|
|
147
|
+
```rust
|
|
148
|
+
use tauri::State;
|
|
149
|
+
use std::sync::Mutex;
|
|
150
|
+
|
|
151
|
+
struct AppState {
|
|
152
|
+
counter: Mutex<i32>,
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
#[tauri::command]
|
|
156
|
+
fn increment_counter(state: State<AppState>) -> i32 {
|
|
157
|
+
let mut counter = state.counter.lock().unwrap();
|
|
158
|
+
*counter += 1;
|
|
159
|
+
*counter
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
#[tauri::command]
|
|
163
|
+
fn get_counter(state: State<AppState>) -> i32 {
|
|
164
|
+
*state.counter.lock().unwrap()
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
fn main() {
|
|
168
|
+
tauri::Builder::default()
|
|
169
|
+
.manage(AppState {
|
|
170
|
+
counter: Mutex::new(0),
|
|
171
|
+
})
|
|
172
|
+
.invoke_handler(tauri::generate_handler![
|
|
173
|
+
increment_counter,
|
|
174
|
+
get_counter
|
|
175
|
+
])
|
|
176
|
+
.run(tauri::generate_context!())
|
|
177
|
+
.expect("error while running tauri application");
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Frontend:**
|
|
182
|
+
```typescript
|
|
183
|
+
import { invoke } from '@tauri-apps/api/core';
|
|
184
|
+
|
|
185
|
+
const count = await invoke<number>('increment_counter');
|
|
186
|
+
const current = await invoke<number>('get_counter');
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Async Commands with Tokio
|
|
190
|
+
|
|
191
|
+
```rust
|
|
192
|
+
use tokio::time::{sleep, Duration};
|
|
193
|
+
|
|
194
|
+
#[tauri::command]
|
|
195
|
+
async fn fetch_data(url: String) -> Result<String, String> {
|
|
196
|
+
let client = reqwest::Client::new();
|
|
197
|
+
let response = client
|
|
198
|
+
.get(&url)
|
|
199
|
+
.send()
|
|
200
|
+
.await
|
|
201
|
+
.map_err(|e| e.to_string())?;
|
|
202
|
+
|
|
203
|
+
response.text().await.map_err(|e| e.to_string())
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
#[tauri::command]
|
|
207
|
+
async fn long_running_task() -> Result<String, String> {
|
|
208
|
+
sleep(Duration::from_secs(5)).await;
|
|
209
|
+
Ok("Task completed".to_string())
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Error Handling
|
|
214
|
+
|
|
215
|
+
```rust
|
|
216
|
+
use serde::{Serialize, Deserialize};
|
|
217
|
+
|
|
218
|
+
#[derive(Debug, Serialize, Deserialize)]
|
|
219
|
+
struct ApiError {
|
|
220
|
+
message: String,
|
|
221
|
+
code: u32,
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
impl std::fmt::Display for ApiError {
|
|
225
|
+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
226
|
+
write!(f, "{}", self.message)
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
#[tauri::command]
|
|
231
|
+
fn risky_operation(value: i32) -> Result<String, ApiError> {
|
|
232
|
+
if value < 0 {
|
|
233
|
+
return Err(ApiError {
|
|
234
|
+
message: "Value must be positive".to_string(),
|
|
235
|
+
code: 400,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
Ok(format!("Success: {}", value))
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Frontend Error Handling:**
|
|
243
|
+
```typescript
|
|
244
|
+
try {
|
|
245
|
+
const result = await invoke<string>('risky_operation', { value: -1 });
|
|
246
|
+
} catch (error) {
|
|
247
|
+
console.error('Command failed:', error);
|
|
248
|
+
// error is serialized ApiError
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Events (Backend → Frontend)
|
|
253
|
+
|
|
254
|
+
Events enable pushing data from backend to frontend.
|
|
255
|
+
|
|
256
|
+
**Backend Emit:**
|
|
257
|
+
```rust
|
|
258
|
+
use tauri::{Emitter, Manager};
|
|
259
|
+
|
|
260
|
+
#[tauri::command]
|
|
261
|
+
async fn start_monitoring(app: tauri::AppHandle) {
|
|
262
|
+
tokio::spawn(async move {
|
|
263
|
+
loop {
|
|
264
|
+
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
265
|
+
app.emit("status-update", "Running").unwrap();
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Frontend Listen:**
|
|
272
|
+
```typescript
|
|
273
|
+
import { listen } from '@tauri-apps/api/event';
|
|
274
|
+
|
|
275
|
+
const unlisten = await listen<string>('status-update', (event) => {
|
|
276
|
+
console.log('Status:', event.payload);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// Later: cleanup
|
|
280
|
+
unlisten();
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Native API Access
|
|
284
|
+
|
|
285
|
+
### File System
|
|
286
|
+
|
|
287
|
+
```rust
|
|
288
|
+
use tauri::api::dialog::blocking::FileDialogBuilder;
|
|
289
|
+
use std::fs;
|
|
290
|
+
|
|
291
|
+
#[tauri::command]
|
|
292
|
+
fn open_file_dialog() -> Option<String> {
|
|
293
|
+
FileDialogBuilder::new().pick_file()
|
|
294
|
+
.map(|path| path.to_string_lossy().to_string())
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
#[tauri::command]
|
|
298
|
+
fn read_file_content(path: String) -> Result<String, String> {
|
|
299
|
+
fs::read_to_string(path).map_err(|e| e.to_string())
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
#[tauri::command]
|
|
303
|
+
fn write_file_content(path: String, content: String) -> Result<(), String> {
|
|
304
|
+
fs::write(path, content).map_err(|e| e.to_string())
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
**Frontend:**
|
|
309
|
+
```typescript
|
|
310
|
+
import { invoke } from '@tauri-apps/api/core';
|
|
311
|
+
|
|
312
|
+
async function openFile() {
|
|
313
|
+
const path = await invoke<string | null>('open_file_dialog');
|
|
314
|
+
if (path) {
|
|
315
|
+
const content = await invoke<string>('read_file_content', { path });
|
|
316
|
+
console.log(content);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### System Tray
|
|
322
|
+
|
|
323
|
+
```rust
|
|
324
|
+
use tauri::{
|
|
325
|
+
menu::{Menu, MenuItem},
|
|
326
|
+
tray::TrayIconBuilder,
|
|
327
|
+
Manager,
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
fn main() {
|
|
331
|
+
tauri::Builder::default()
|
|
332
|
+
.setup(|app| {
|
|
333
|
+
let quit = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?;
|
|
334
|
+
let menu = Menu::with_items(app, &[&quit])?;
|
|
335
|
+
|
|
336
|
+
let _tray = TrayIconBuilder::new()
|
|
337
|
+
.menu(&menu)
|
|
338
|
+
.on_menu_event(|app, event| match event.id.as_ref() {
|
|
339
|
+
"quit" => {
|
|
340
|
+
app.exit(0);
|
|
341
|
+
}
|
|
342
|
+
_ => {}
|
|
343
|
+
})
|
|
344
|
+
.build(app)?;
|
|
345
|
+
|
|
346
|
+
Ok(())
|
|
347
|
+
})
|
|
348
|
+
.run(tauri::generate_context!())
|
|
349
|
+
.expect("error while running tauri application");
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Notifications
|
|
354
|
+
|
|
355
|
+
```rust
|
|
356
|
+
use tauri::Notification;
|
|
357
|
+
|
|
358
|
+
#[tauri::command]
|
|
359
|
+
fn send_notification(app: tauri::AppHandle, message: String) -> Result<(), String> {
|
|
360
|
+
Notification::new(&app.config().identifier)
|
|
361
|
+
.title("My App")
|
|
362
|
+
.body(message)
|
|
363
|
+
.show()
|
|
364
|
+
.map_err(|e| e.to_string())
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Shell/Process Execution
|
|
369
|
+
|
|
370
|
+
```rust
|
|
371
|
+
use tauri::api::process::{Command, CommandEvent};
|
|
372
|
+
|
|
373
|
+
#[tauri::command]
|
|
374
|
+
async fn run_command(program: String, args: Vec<String>) -> Result<String, String> {
|
|
375
|
+
let (mut rx, _child) = Command::new(program)
|
|
376
|
+
.args(args)
|
|
377
|
+
.spawn()
|
|
378
|
+
.map_err(|e| e.to_string())?;
|
|
379
|
+
|
|
380
|
+
let mut output = String::new();
|
|
381
|
+
while let Some(event) = rx.recv().await {
|
|
382
|
+
match event {
|
|
383
|
+
CommandEvent::Stdout(line) => output.push_str(&line),
|
|
384
|
+
CommandEvent::Stderr(line) => output.push_str(&line),
|
|
385
|
+
CommandEvent::Terminated(_) => break,
|
|
386
|
+
_ => {}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
Ok(output)
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
## Configuration
|
|
394
|
+
|
|
395
|
+
### tauri.conf.json
|
|
396
|
+
|
|
397
|
+
```json
|
|
398
|
+
{
|
|
399
|
+
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
|
400
|
+
"productName": "My App",
|
|
401
|
+
"version": "1.0.0",
|
|
402
|
+
"identifier": "com.mycompany.myapp",
|
|
403
|
+
"build": {
|
|
404
|
+
"beforeDevCommand": "npm run dev",
|
|
405
|
+
"beforeBuildCommand": "npm run build",
|
|
406
|
+
"devUrl": "http://localhost:5173",
|
|
407
|
+
"frontendDist": "../dist"
|
|
408
|
+
},
|
|
409
|
+
"app": {
|
|
410
|
+
"windows": [
|
|
411
|
+
{
|
|
412
|
+
"title": "My App",
|
|
413
|
+
"width": 1200,
|
|
414
|
+
"height": 800,
|
|
415
|
+
"resizable": true,
|
|
416
|
+
"fullscreen": false,
|
|
417
|
+
"minWidth": 800,
|
|
418
|
+
"minHeight": 600
|
|
419
|
+
}
|
|
420
|
+
],
|
|
421
|
+
"security": {
|
|
422
|
+
"csp": "default-src 'self'; img-src 'self' https: data:;"
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
"bundle": {
|
|
426
|
+
"active": true,
|
|
427
|
+
"targets": "all",
|
|
428
|
+
"icon": [
|
|
429
|
+
"icons/32x32.png",
|
|
430
|
+
"icons/128x128.png",
|
|
431
|
+
"icons/icon.icns",
|
|
432
|
+
"icons/icon.ico"
|
|
433
|
+
],
|
|
434
|
+
"macOS": {
|
|
435
|
+
"minimumSystemVersion": "10.13"
|
|
436
|
+
},
|
|
437
|
+
"windows": {
|
|
438
|
+
"webviewInstallMode": {
|
|
439
|
+
"type": "downloadBootstrapper"
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### Security Configuration
|
|
447
|
+
|
|
448
|
+
**Content Security Policy (CSP):**
|
|
449
|
+
```json
|
|
450
|
+
{
|
|
451
|
+
"app": {
|
|
452
|
+
"security": {
|
|
453
|
+
"csp": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; connect-src 'self' https://api.myapp.com"
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
**Capabilities (Tauri v2):**
|
|
460
|
+
```json
|
|
461
|
+
// src-tauri/capabilities/default.json
|
|
462
|
+
{
|
|
463
|
+
"identifier": "default",
|
|
464
|
+
"description": "Default capabilities",
|
|
465
|
+
"windows": ["main"],
|
|
466
|
+
"permissions": [
|
|
467
|
+
"core:default",
|
|
468
|
+
"fs:allow-read-text-file",
|
|
469
|
+
"fs:allow-write-text-file",
|
|
470
|
+
"dialog:allow-open",
|
|
471
|
+
"dialog:allow-save",
|
|
472
|
+
"shell:allow-execute"
|
|
473
|
+
]
|
|
474
|
+
}
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
## Advanced Patterns
|
|
478
|
+
|
|
479
|
+
### Window Management
|
|
480
|
+
|
|
481
|
+
```rust
|
|
482
|
+
use tauri::{Manager, WebviewUrl, WebviewWindowBuilder};
|
|
483
|
+
|
|
484
|
+
#[tauri::command]
|
|
485
|
+
async fn open_new_window(app: tauri::AppHandle) -> Result<(), String> {
|
|
486
|
+
WebviewWindowBuilder::new(
|
|
487
|
+
&app,
|
|
488
|
+
"new-window",
|
|
489
|
+
WebviewUrl::App("index.html".into())
|
|
490
|
+
)
|
|
491
|
+
.title("New Window")
|
|
492
|
+
.inner_size(800.0, 600.0)
|
|
493
|
+
.build()
|
|
494
|
+
.map_err(|e| e.to_string())?;
|
|
495
|
+
|
|
496
|
+
Ok(())
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
#[tauri::command]
|
|
500
|
+
fn close_window(window: tauri::Window) -> Result<(), String> {
|
|
501
|
+
window.close().map_err(|e| e.to_string())
|
|
502
|
+
}
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
### Custom Protocol
|
|
506
|
+
|
|
507
|
+
```rust
|
|
508
|
+
use tauri::{http::ResponseBuilder, Manager};
|
|
509
|
+
|
|
510
|
+
fn main() {
|
|
511
|
+
tauri::Builder::default()
|
|
512
|
+
.setup(|app| {
|
|
513
|
+
app.handle().plugin(
|
|
514
|
+
tauri_plugin_localhost::Builder::new()
|
|
515
|
+
.build(),
|
|
516
|
+
)?;
|
|
517
|
+
Ok(())
|
|
518
|
+
})
|
|
519
|
+
.register_uri_scheme_protocol("myapp", |_app, request| {
|
|
520
|
+
// Handle custom myapp:// protocol
|
|
521
|
+
ResponseBuilder::new()
|
|
522
|
+
.status(200)
|
|
523
|
+
.body(b"Custom protocol response".to_vec())
|
|
524
|
+
.map_err(Into::into)
|
|
525
|
+
})
|
|
526
|
+
.run(tauri::generate_context!())
|
|
527
|
+
.expect("error while running tauri application");
|
|
528
|
+
}
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### Plugin Development
|
|
532
|
+
|
|
533
|
+
```rust
|
|
534
|
+
use tauri::{plugin::Plugin, Runtime};
|
|
535
|
+
|
|
536
|
+
pub struct MyPlugin<R: Runtime> {
|
|
537
|
+
_marker: std::marker::PhantomData<R>,
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
impl<R: Runtime> Plugin<R> for MyPlugin<R> {
|
|
541
|
+
fn name(&self) -> &'static str {
|
|
542
|
+
"my-plugin"
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
fn initialize(&mut self, app: &tauri::AppHandle<R>, _config: serde_json::Value) -> tauri::plugin::Result<()> {
|
|
546
|
+
// Initialize plugin
|
|
547
|
+
Ok(())
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// Usage in main.rs
|
|
552
|
+
fn main() {
|
|
553
|
+
tauri::Builder::default()
|
|
554
|
+
.plugin(MyPlugin { _marker: std::marker::PhantomData })
|
|
555
|
+
.run(tauri::generate_context!())
|
|
556
|
+
.expect("error while running tauri application");
|
|
557
|
+
}
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
## Performance Optimization
|
|
561
|
+
|
|
562
|
+
### Bundle Size Reduction
|
|
563
|
+
|
|
564
|
+
**Cargo.toml optimizations:**
|
|
565
|
+
```toml
|
|
566
|
+
[profile.release]
|
|
567
|
+
opt-level = "z" # Optimize for size
|
|
568
|
+
lto = true # Link-time optimization
|
|
569
|
+
codegen-units = 1 # Better optimization
|
|
570
|
+
panic = "abort" # Remove panic unwinding code
|
|
571
|
+
strip = true # Strip symbols
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
### Lazy Loading
|
|
575
|
+
|
|
576
|
+
```typescript
|
|
577
|
+
// Frontend: Code splitting
|
|
578
|
+
const HeavyComponent = lazy(() => import('./HeavyComponent'));
|
|
579
|
+
|
|
580
|
+
// Backend: Lazy state initialization
|
|
581
|
+
use once_cell::sync::Lazy;
|
|
582
|
+
static EXPENSIVE_RESOURCE: Lazy<ExpensiveType> = Lazy::new(|| {
|
|
583
|
+
// Initialize only when first accessed
|
|
584
|
+
ExpensiveType::new()
|
|
585
|
+
});
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
### Debouncing IPC Calls
|
|
589
|
+
|
|
590
|
+
```typescript
|
|
591
|
+
import { debounce } from 'lodash';
|
|
592
|
+
|
|
593
|
+
const debouncedSearch = debounce(async (query: string) => {
|
|
594
|
+
const results = await invoke('search', { query });
|
|
595
|
+
setResults(results);
|
|
596
|
+
}, 300);
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
## Build and Distribution
|
|
600
|
+
|
|
601
|
+
### Build Commands
|
|
602
|
+
|
|
603
|
+
```bash
|
|
604
|
+
# Development build
|
|
605
|
+
cargo tauri dev
|
|
606
|
+
|
|
607
|
+
# Production build (current platform)
|
|
608
|
+
cargo tauri build
|
|
609
|
+
|
|
610
|
+
# Build with debug info
|
|
611
|
+
cargo tauri build --debug
|
|
612
|
+
|
|
613
|
+
# Specific bundle type
|
|
614
|
+
cargo tauri build --bundles deb,appimage # Linux
|
|
615
|
+
cargo tauri build --bundles dmg,app # macOS
|
|
616
|
+
cargo tauri build --bundles msi,nsis # Windows
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
### Code Signing
|
|
620
|
+
|
|
621
|
+
**macOS:**
|
|
622
|
+
```bash
|
|
623
|
+
# Sign app
|
|
624
|
+
codesign --deep --force --verify --verbose \
|
|
625
|
+
--sign "Developer ID Application: Your Name" \
|
|
626
|
+
target/release/bundle/macos/MyApp.app
|
|
627
|
+
|
|
628
|
+
# Notarize
|
|
629
|
+
xcrun notarytool submit target/release/bundle/dmg/MyApp.dmg \
|
|
630
|
+
--apple-id "your@email.com" \
|
|
631
|
+
--password "app-specific-password" \
|
|
632
|
+
--team-id "TEAMID"
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
**Windows:**
|
|
636
|
+
```powershell
|
|
637
|
+
# Sign with signtool.exe
|
|
638
|
+
signtool sign /tr http://timestamp.digicert.com /td sha256 `
|
|
639
|
+
/fd sha256 /a "target\release\MyApp.exe"
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### Auto-Updates
|
|
643
|
+
|
|
644
|
+
```rust
|
|
645
|
+
// Install tauri-plugin-updater
|
|
646
|
+
use tauri_plugin_updater::UpdaterExt;
|
|
647
|
+
|
|
648
|
+
fn main() {
|
|
649
|
+
tauri::Builder::default()
|
|
650
|
+
.plugin(tauri_plugin_updater::init())
|
|
651
|
+
.setup(|app| {
|
|
652
|
+
let handle = app.handle().clone();
|
|
653
|
+
tauri::async_runtime::spawn(async move {
|
|
654
|
+
let update = handle.updater().check().await;
|
|
655
|
+
// Handle update
|
|
656
|
+
});
|
|
657
|
+
Ok(())
|
|
658
|
+
})
|
|
659
|
+
.run(tauri::generate_context!())
|
|
660
|
+
.expect("error while running tauri application");
|
|
661
|
+
}
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
## Production Examples
|
|
665
|
+
|
|
666
|
+
### File Manager Command
|
|
667
|
+
```rust
|
|
668
|
+
use serde::{Deserialize, Serialize};
|
|
669
|
+
use std::fs;
|
|
670
|
+
use std::path::PathBuf;
|
|
671
|
+
|
|
672
|
+
#[derive(Serialize, Deserialize)]
|
|
673
|
+
struct FileEntry {
|
|
674
|
+
name: String,
|
|
675
|
+
path: String,
|
|
676
|
+
is_dir: bool,
|
|
677
|
+
size: u64,
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
#[tauri::command]
|
|
681
|
+
fn list_directory(path: String) -> Result<Vec<FileEntry>, String> {
|
|
682
|
+
let dir_path = PathBuf::from(path);
|
|
683
|
+
|
|
684
|
+
if !dir_path.exists() {
|
|
685
|
+
return Err("Directory does not exist".to_string());
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
let mut entries = Vec::new();
|
|
689
|
+
|
|
690
|
+
for entry in fs::read_dir(dir_path).map_err(|e| e.to_string())? {
|
|
691
|
+
let entry = entry.map_err(|e| e.to_string())?;
|
|
692
|
+
let metadata = entry.metadata().map_err(|e| e.to_string())?;
|
|
693
|
+
|
|
694
|
+
entries.push(FileEntry {
|
|
695
|
+
name: entry.file_name().to_string_lossy().to_string(),
|
|
696
|
+
path: entry.path().to_string_lossy().to_string(),
|
|
697
|
+
is_dir: metadata.is_dir(),
|
|
698
|
+
size: metadata.len(),
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
Ok(entries)
|
|
703
|
+
}
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
### Database Integration
|
|
707
|
+
```rust
|
|
708
|
+
use sqlx::{SqlitePool, FromRow};
|
|
709
|
+
use tauri::State;
|
|
710
|
+
|
|
711
|
+
#[derive(FromRow, Serialize)]
|
|
712
|
+
struct User {
|
|
713
|
+
id: i64,
|
|
714
|
+
name: String,
|
|
715
|
+
email: String,
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
struct DbState {
|
|
719
|
+
pool: SqlitePool,
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
#[tauri::command]
|
|
723
|
+
async fn get_users(state: State<'_, DbState>) -> Result<Vec<User>, String> {
|
|
724
|
+
sqlx::query_as::<_, User>("SELECT id, name, email FROM users")
|
|
725
|
+
.fetch_all(&state.pool)
|
|
726
|
+
.await
|
|
727
|
+
.map_err(|e| e.to_string())
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
#[tokio::main]
|
|
731
|
+
async fn main() {
|
|
732
|
+
let pool = SqlitePool::connect("sqlite://app.db")
|
|
733
|
+
.await
|
|
734
|
+
.expect("Failed to connect to database");
|
|
735
|
+
|
|
736
|
+
tauri::Builder::default()
|
|
737
|
+
.manage(DbState { pool })
|
|
738
|
+
.invoke_handler(tauri::generate_handler![get_users])
|
|
739
|
+
.run(tauri::generate_context!())
|
|
740
|
+
.expect("error while running tauri application");
|
|
741
|
+
}
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
## Debugging
|
|
745
|
+
|
|
746
|
+
```bash
|
|
747
|
+
# Enable Rust backtraces
|
|
748
|
+
RUST_BACKTRACE=1 cargo tauri dev
|
|
749
|
+
|
|
750
|
+
# Open DevTools
|
|
751
|
+
# macOS/Linux: Cmd/Ctrl + Shift + I
|
|
752
|
+
# Or programmatically:
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
```rust
|
|
756
|
+
#[cfg(debug_assertions)]
|
|
757
|
+
window.open_devtools();
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
**Console logging from Rust:**
|
|
761
|
+
```rust
|
|
762
|
+
println!("Debug: {:?}", value); // Appears in terminal
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
**Frontend console:**
|
|
766
|
+
```typescript
|
|
767
|
+
console.log('Frontend log'); // Appears in DevTools
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
This comprehensive guide covers Tauri fundamentals through advanced patterns. Combine with architecture-patterns.md for structure, state-management.md for complex state, and platform-integration.md for OS-specific features.
|