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,628 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tauri-window-management
|
|
3
|
+
description: Advanced window management in Tauri including multi-window apps, window creation, communication, lifecycle, and window-specific state
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: development
|
|
6
|
+
author: Claude MPM Team
|
|
7
|
+
license: MIT
|
|
8
|
+
progressive_disclosure:
|
|
9
|
+
entry_point:
|
|
10
|
+
summary: "Multi-window management: creation, communication, lifecycle, window-specific state, modals, and inter-window messaging"
|
|
11
|
+
when_to_use: "Building apps with multiple windows, settings dialogs, modal windows, or complex window layouts"
|
|
12
|
+
quick_start: "1. Create windows with WindowBuilder 2. Use window labels 3. Emit events between windows 4. Manage window state"
|
|
13
|
+
context_limit: 600
|
|
14
|
+
tags:
|
|
15
|
+
- tauri
|
|
16
|
+
- windows
|
|
17
|
+
- multi-window
|
|
18
|
+
- window-management
|
|
19
|
+
- modals
|
|
20
|
+
requires_tools: []
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Tauri Window Management
|
|
24
|
+
|
|
25
|
+
## Window Creation
|
|
26
|
+
|
|
27
|
+
### Basic Window Creation
|
|
28
|
+
|
|
29
|
+
```rust
|
|
30
|
+
use tauri::{Manager, WindowBuilder, WindowUrl};
|
|
31
|
+
|
|
32
|
+
#[tauri::command]
|
|
33
|
+
async fn open_settings(app: tauri::AppHandle) -> Result<(), String> {
|
|
34
|
+
// Check if window already exists
|
|
35
|
+
if app.get_window("settings").is_some() {
|
|
36
|
+
return Err("Settings window already open".to_string());
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
WindowBuilder::new(
|
|
40
|
+
&app,
|
|
41
|
+
"settings", // Unique window label
|
|
42
|
+
WindowUrl::App("settings.html".into())
|
|
43
|
+
)
|
|
44
|
+
.title("Settings")
|
|
45
|
+
.inner_size(800.0, 600.0)
|
|
46
|
+
.resizable(true)
|
|
47
|
+
.center()
|
|
48
|
+
.build()
|
|
49
|
+
.map_err(|e| e.to_string())?;
|
|
50
|
+
|
|
51
|
+
Ok(())
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Advanced Window Configuration
|
|
56
|
+
|
|
57
|
+
```rust
|
|
58
|
+
#[tauri::command]
|
|
59
|
+
async fn create_editor_window(
|
|
60
|
+
filepath: String,
|
|
61
|
+
app: tauri::AppHandle,
|
|
62
|
+
) -> Result<String, String> {
|
|
63
|
+
use tauri::WindowBuilder;
|
|
64
|
+
|
|
65
|
+
let window_label = format!("editor-{}", uuid::Uuid::new_v4());
|
|
66
|
+
|
|
67
|
+
let window = WindowBuilder::new(
|
|
68
|
+
&app,
|
|
69
|
+
window_label.clone(),
|
|
70
|
+
WindowUrl::App("editor.html".into())
|
|
71
|
+
)
|
|
72
|
+
.title(format!("Editing: {}", filepath))
|
|
73
|
+
.inner_size(1200.0, 800.0)
|
|
74
|
+
.min_inner_size(400.0, 300.0)
|
|
75
|
+
.resizable(true)
|
|
76
|
+
.decorations(true)
|
|
77
|
+
.always_on_top(false)
|
|
78
|
+
.skip_taskbar(false)
|
|
79
|
+
.visible(false) // Start hidden, show after load
|
|
80
|
+
.center()
|
|
81
|
+
.build()
|
|
82
|
+
.map_err(|e| e.to_string())?;
|
|
83
|
+
|
|
84
|
+
// Store filepath in window config
|
|
85
|
+
window.set_title(&format!("Editing: {}", filepath))
|
|
86
|
+
.map_err(|e| e.to_string())?;
|
|
87
|
+
|
|
88
|
+
// Show window after creation
|
|
89
|
+
window.show().map_err(|e| e.to_string())?;
|
|
90
|
+
|
|
91
|
+
Ok(window_label)
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Modal/Dialog Windows
|
|
96
|
+
|
|
97
|
+
```rust
|
|
98
|
+
#[tauri::command]
|
|
99
|
+
async fn open_modal_dialog(
|
|
100
|
+
app: tauri::AppHandle,
|
|
101
|
+
parent_label: String,
|
|
102
|
+
) -> Result<(), String> {
|
|
103
|
+
let parent = app.get_window(&parent_label)
|
|
104
|
+
.ok_or("Parent window not found")?;
|
|
105
|
+
|
|
106
|
+
WindowBuilder::new(
|
|
107
|
+
&app,
|
|
108
|
+
"modal-dialog",
|
|
109
|
+
WindowUrl::App("dialog.html".into())
|
|
110
|
+
)
|
|
111
|
+
.title("Confirm Action")
|
|
112
|
+
.inner_size(400.0, 200.0)
|
|
113
|
+
.resizable(false)
|
|
114
|
+
.decorations(true)
|
|
115
|
+
.always_on_top(true) // Stay on top
|
|
116
|
+
.skip_taskbar(true) // Don't show in taskbar
|
|
117
|
+
.center()
|
|
118
|
+
.parent_window(parent.hwnd().map_err(|e| e.to_string())?)
|
|
119
|
+
.build()
|
|
120
|
+
.map_err(|e| e.to_string())?;
|
|
121
|
+
|
|
122
|
+
Ok(())
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Window Communication
|
|
127
|
+
|
|
128
|
+
### Targeted Window Messaging
|
|
129
|
+
|
|
130
|
+
```rust
|
|
131
|
+
#[tauri::command]
|
|
132
|
+
async fn send_to_window(
|
|
133
|
+
target_label: String,
|
|
134
|
+
message: String,
|
|
135
|
+
app: tauri::AppHandle,
|
|
136
|
+
) -> Result<(), String> {
|
|
137
|
+
if let Some(window) = app.get_window(&target_label) {
|
|
138
|
+
window.emit("message", message)
|
|
139
|
+
.map_err(|e| e.to_string())?;
|
|
140
|
+
Ok(())
|
|
141
|
+
} else {
|
|
142
|
+
Err(format!("Window '{}' not found", target_label))
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
#[tauri::command]
|
|
147
|
+
async fn broadcast_to_all(
|
|
148
|
+
message: String,
|
|
149
|
+
app: tauri::AppHandle,
|
|
150
|
+
) -> Result<(), String> {
|
|
151
|
+
app.emit_all("broadcast", message)
|
|
152
|
+
.map_err(|e| e.to_string())
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Window-to-Window Relay
|
|
157
|
+
|
|
158
|
+
```rust
|
|
159
|
+
#[derive(serde::Deserialize)]
|
|
160
|
+
struct WindowMessage {
|
|
161
|
+
target: String,
|
|
162
|
+
payload: serde_json::Value,
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
#[tauri::command]
|
|
166
|
+
async fn relay_message(
|
|
167
|
+
msg: WindowMessage,
|
|
168
|
+
app: tauri::AppHandle,
|
|
169
|
+
) -> Result<(), String> {
|
|
170
|
+
if let Some(target_window) = app.get_window(&msg.target) {
|
|
171
|
+
target_window.emit("relay", msg.payload)
|
|
172
|
+
.map_err(|e| e.to_string())?;
|
|
173
|
+
Ok(())
|
|
174
|
+
} else {
|
|
175
|
+
Err(format!("Target window '{}' not found", msg.target))
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Frontend sender**:
|
|
181
|
+
```typescript
|
|
182
|
+
import { invoke } from '@tauri-apps/api/core';
|
|
183
|
+
|
|
184
|
+
async function sendToWindow(target: string, data: any) {
|
|
185
|
+
await invoke('relay_message', {
|
|
186
|
+
msg: {
|
|
187
|
+
target,
|
|
188
|
+
payload: data
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Frontend receiver**:
|
|
195
|
+
```typescript
|
|
196
|
+
import { listen } from '@tauri-apps/api/event';
|
|
197
|
+
|
|
198
|
+
listen('relay', (event) => {
|
|
199
|
+
console.log('Received from another window:', event.payload);
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Window Lifecycle
|
|
204
|
+
|
|
205
|
+
### Window Close Handling
|
|
206
|
+
|
|
207
|
+
```rust
|
|
208
|
+
use tauri::Manager;
|
|
209
|
+
|
|
210
|
+
fn main() {
|
|
211
|
+
tauri::Builder::default()
|
|
212
|
+
.on_window_event(|event| {
|
|
213
|
+
match event.event() {
|
|
214
|
+
tauri::WindowEvent::CloseRequested { api, .. } => {
|
|
215
|
+
let window = event.window();
|
|
216
|
+
|
|
217
|
+
// Prevent close and show confirmation
|
|
218
|
+
api.prevent_close();
|
|
219
|
+
|
|
220
|
+
// Emit event to frontend for confirmation
|
|
221
|
+
window.emit("close-requested", ()).unwrap();
|
|
222
|
+
}
|
|
223
|
+
tauri::WindowEvent::Destroyed => {
|
|
224
|
+
println!("Window {} destroyed", event.window().label());
|
|
225
|
+
}
|
|
226
|
+
_ => {}
|
|
227
|
+
}
|
|
228
|
+
})
|
|
229
|
+
.run(tauri::generate_context!())
|
|
230
|
+
.expect("error while running tauri application");
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**Frontend close confirmation**:
|
|
235
|
+
```typescript
|
|
236
|
+
import { listen } from '@tauri-apps/api/event';
|
|
237
|
+
import { getCurrent } from '@tauri-apps/api/window';
|
|
238
|
+
|
|
239
|
+
listen('close-requested', async () => {
|
|
240
|
+
const confirmed = confirm('Are you sure you want to close?');
|
|
241
|
+
|
|
242
|
+
if (confirmed) {
|
|
243
|
+
const window = getCurrent();
|
|
244
|
+
await window.close();
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Window Focus Management
|
|
250
|
+
|
|
251
|
+
```rust
|
|
252
|
+
#[tauri::command]
|
|
253
|
+
async fn focus_window(
|
|
254
|
+
label: String,
|
|
255
|
+
app: tauri::AppHandle,
|
|
256
|
+
) -> Result<(), String> {
|
|
257
|
+
if let Some(window) = app.get_window(&label) {
|
|
258
|
+
window.set_focus().map_err(|e| e.to_string())?;
|
|
259
|
+
Ok(())
|
|
260
|
+
} else {
|
|
261
|
+
Err(format!("Window '{}' not found", label))
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
#[tauri::command]
|
|
266
|
+
async fn minimize_window(
|
|
267
|
+
label: String,
|
|
268
|
+
app: tauri::AppHandle,
|
|
269
|
+
) -> Result<(), String> {
|
|
270
|
+
if let Some(window) = app.get_window(&label) {
|
|
271
|
+
window.minimize().map_err(|e| e.to_string())?;
|
|
272
|
+
Ok(())
|
|
273
|
+
} else {
|
|
274
|
+
Err("Window not found".to_string())
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
#[tauri::command]
|
|
279
|
+
async fn maximize_window(
|
|
280
|
+
label: String,
|
|
281
|
+
app: tauri::AppHandle,
|
|
282
|
+
) -> Result<(), String> {
|
|
283
|
+
if let Some(window) = app.get_window(&label) {
|
|
284
|
+
window.maximize().map_err(|e| e.to_string())?;
|
|
285
|
+
Ok(())
|
|
286
|
+
} else {
|
|
287
|
+
Err("Window not found".to_string())
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Window-Specific State
|
|
293
|
+
|
|
294
|
+
### Per-Window Data Management
|
|
295
|
+
|
|
296
|
+
```rust
|
|
297
|
+
use std::sync::Arc;
|
|
298
|
+
use dashmap::DashMap;
|
|
299
|
+
|
|
300
|
+
pub struct WindowData {
|
|
301
|
+
pub filepath: Option<String>,
|
|
302
|
+
pub modified: bool,
|
|
303
|
+
pub cursor_position: (usize, usize),
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
pub struct AppState {
|
|
307
|
+
pub window_data: Arc<DashMap<String, WindowData>>,
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
#[tauri::command]
|
|
311
|
+
async fn set_window_data(
|
|
312
|
+
window: tauri::Window,
|
|
313
|
+
filepath: String,
|
|
314
|
+
state: tauri::State<'_, AppState>,
|
|
315
|
+
) -> Result<(), String> {
|
|
316
|
+
let label = window.label().to_string();
|
|
317
|
+
|
|
318
|
+
state.window_data.insert(label, WindowData {
|
|
319
|
+
filepath: Some(filepath),
|
|
320
|
+
modified: false,
|
|
321
|
+
cursor_position: (0, 0),
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
Ok(())
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
#[tauri::command]
|
|
328
|
+
async fn get_window_data(
|
|
329
|
+
window: tauri::Window,
|
|
330
|
+
state: tauri::State<'_, AppState>,
|
|
331
|
+
) -> Result<Option<WindowData>, String> {
|
|
332
|
+
let label = window.label();
|
|
333
|
+
|
|
334
|
+
Ok(state.window_data.get(label)
|
|
335
|
+
.map(|entry| entry.value().clone()))
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
#[tauri::command]
|
|
339
|
+
async fn mark_window_modified(
|
|
340
|
+
window: tauri::Window,
|
|
341
|
+
state: tauri::State<'_, AppState>,
|
|
342
|
+
) -> Result<(), String> {
|
|
343
|
+
let label = window.label();
|
|
344
|
+
|
|
345
|
+
if let Some(mut entry) = state.window_data.get_mut(label) {
|
|
346
|
+
entry.modified = true;
|
|
347
|
+
|
|
348
|
+
// Update window title to show modified
|
|
349
|
+
window.set_title(&format!("{}*", entry.filepath.as_deref().unwrap_or("Untitled")))
|
|
350
|
+
.map_err(|e| e.to_string())?;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
Ok(())
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## Window Management Patterns
|
|
358
|
+
|
|
359
|
+
### Window Registry
|
|
360
|
+
|
|
361
|
+
```rust
|
|
362
|
+
use std::collections::HashMap;
|
|
363
|
+
|
|
364
|
+
pub struct WindowRegistry {
|
|
365
|
+
windows: Arc<Mutex<HashMap<String, WindowMetadata>>>,
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
#[derive(Clone)]
|
|
369
|
+
struct WindowMetadata {
|
|
370
|
+
label: String,
|
|
371
|
+
window_type: WindowType,
|
|
372
|
+
created_at: SystemTime,
|
|
373
|
+
parent: Option<String>,
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
#[derive(Clone)]
|
|
377
|
+
enum WindowType {
|
|
378
|
+
Main,
|
|
379
|
+
Editor,
|
|
380
|
+
Settings,
|
|
381
|
+
Dialog,
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
impl WindowRegistry {
|
|
385
|
+
pub async fn register(&self, label: String, window_type: WindowType) {
|
|
386
|
+
let mut windows = self.windows.lock().await;
|
|
387
|
+
windows.insert(label.clone(), WindowMetadata {
|
|
388
|
+
label,
|
|
389
|
+
window_type,
|
|
390
|
+
created_at: SystemTime::now(),
|
|
391
|
+
parent: None,
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
pub async fn unregister(&self, label: &str) {
|
|
396
|
+
let mut windows = self.windows.lock().await;
|
|
397
|
+
windows.remove(label);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
pub async fn get_windows_by_type(&self, window_type: WindowType) -> Vec<String> {
|
|
401
|
+
let windows = self.windows.lock().await;
|
|
402
|
+
windows.values()
|
|
403
|
+
.filter(|m| matches!(m.window_type, window_type))
|
|
404
|
+
.map(|m| m.label.clone())
|
|
405
|
+
.collect()
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Single Instance Window Pattern
|
|
411
|
+
|
|
412
|
+
```rust
|
|
413
|
+
use std::sync::Arc;
|
|
414
|
+
use tokio::sync::Mutex;
|
|
415
|
+
|
|
416
|
+
pub struct SingletonWindows {
|
|
417
|
+
settings: Arc<Mutex<Option<String>>>,
|
|
418
|
+
about: Arc<Mutex<Option<String>>>,
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
#[tauri::command]
|
|
422
|
+
async fn open_settings_singleton(
|
|
423
|
+
app: tauri::AppHandle,
|
|
424
|
+
state: tauri::State<'_, SingletonWindows>,
|
|
425
|
+
) -> Result<(), String> {
|
|
426
|
+
let mut settings_lock = state.settings.lock().await;
|
|
427
|
+
|
|
428
|
+
// Check if window already exists
|
|
429
|
+
if let Some(label) = settings_lock.as_ref() {
|
|
430
|
+
if let Some(window) = app.get_window(label) {
|
|
431
|
+
// Focus existing window
|
|
432
|
+
window.set_focus().map_err(|e| e.to_string())?;
|
|
433
|
+
return Ok(());
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Create new window
|
|
438
|
+
let label = "settings".to_string();
|
|
439
|
+
WindowBuilder::new(
|
|
440
|
+
&app,
|
|
441
|
+
label.clone(),
|
|
442
|
+
WindowUrl::App("settings.html".into())
|
|
443
|
+
)
|
|
444
|
+
.title("Settings")
|
|
445
|
+
.build()
|
|
446
|
+
.map_err(|e| e.to_string())?;
|
|
447
|
+
|
|
448
|
+
*settings_lock = Some(label);
|
|
449
|
+
|
|
450
|
+
Ok(())
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
## Frontend Window API
|
|
455
|
+
|
|
456
|
+
### Getting Current Window
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
import { getCurrent, Window } from '@tauri-apps/api/window';
|
|
460
|
+
|
|
461
|
+
const currentWindow = getCurrent();
|
|
462
|
+
console.log('Current window label:', currentWindow.label);
|
|
463
|
+
|
|
464
|
+
// Window operations
|
|
465
|
+
await currentWindow.minimize();
|
|
466
|
+
await currentWindow.maximize();
|
|
467
|
+
await currentWindow.setTitle('New Title');
|
|
468
|
+
await currentWindow.close();
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Creating Windows from Frontend
|
|
472
|
+
|
|
473
|
+
```typescript
|
|
474
|
+
import { WebviewWindow } from '@tauri-apps/api/window';
|
|
475
|
+
|
|
476
|
+
async function createNewEditor() {
|
|
477
|
+
const webview = new WebviewWindow('editor-1', {
|
|
478
|
+
url: 'editor.html',
|
|
479
|
+
title: 'Editor',
|
|
480
|
+
width: 800,
|
|
481
|
+
height: 600,
|
|
482
|
+
center: true,
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
// Wait for window to load
|
|
486
|
+
await webview.once('tauri://created', () => {
|
|
487
|
+
console.log('Window created');
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
await webview.once('tauri://error', (e) => {
|
|
491
|
+
console.error('Window creation error:', e);
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Window Events
|
|
497
|
+
|
|
498
|
+
```typescript
|
|
499
|
+
import { getCurrent } from '@tauri-apps/api/window';
|
|
500
|
+
|
|
501
|
+
const window = getCurrent();
|
|
502
|
+
|
|
503
|
+
// Listen for window events
|
|
504
|
+
await window.listen('tauri://focus', () => {
|
|
505
|
+
console.log('Window focused');
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
await window.listen('tauri://blur', () => {
|
|
509
|
+
console.log('Window lost focus');
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
await window.listen('tauri://resize', (event) => {
|
|
513
|
+
console.log('Window resized:', event.payload);
|
|
514
|
+
});
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
## Best Practices
|
|
518
|
+
|
|
519
|
+
1. **Use unique window labels** - Prevents collisions
|
|
520
|
+
2. **Check window existence** - Before creating duplicates
|
|
521
|
+
3. **Clean up window state** - When windows close
|
|
522
|
+
4. **Focus existing windows** - Instead of creating duplicates
|
|
523
|
+
5. **Use parent windows** - For modal dialogs
|
|
524
|
+
6. **Handle close requests** - Prevent data loss
|
|
525
|
+
7. **Emit events for communication** - Not direct window access
|
|
526
|
+
8. **Store window-specific data** - In centralized state
|
|
527
|
+
9. **Use skip_taskbar for dialogs** - Better UX
|
|
528
|
+
10. **Center dialogs** - Always center modal windows
|
|
529
|
+
|
|
530
|
+
## Common Patterns
|
|
531
|
+
|
|
532
|
+
### Settings Window Pattern
|
|
533
|
+
|
|
534
|
+
```rust
|
|
535
|
+
#[tauri::command]
|
|
536
|
+
async fn toggle_settings(app: tauri::AppHandle) -> Result<(), String> {
|
|
537
|
+
if let Some(window) = app.get_window("settings") {
|
|
538
|
+
// Close if open
|
|
539
|
+
window.close().map_err(|e| e.to_string())?;
|
|
540
|
+
} else {
|
|
541
|
+
// Open if closed
|
|
542
|
+
WindowBuilder::new(&app, "settings", WindowUrl::App("settings.html".into()))
|
|
543
|
+
.title("Settings")
|
|
544
|
+
.inner_size(600.0, 400.0)
|
|
545
|
+
.center()
|
|
546
|
+
.build()
|
|
547
|
+
.map_err(|e| e.to_string())?;
|
|
548
|
+
}
|
|
549
|
+
Ok(())
|
|
550
|
+
}
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
### Multi-Document Interface (MDI)
|
|
554
|
+
|
|
555
|
+
```rust
|
|
556
|
+
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
557
|
+
|
|
558
|
+
static EDITOR_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
|
559
|
+
|
|
560
|
+
#[tauri::command]
|
|
561
|
+
async fn new_document(app: tauri::AppHandle) -> Result<String, String> {
|
|
562
|
+
let id = EDITOR_COUNTER.fetch_add(1, Ordering::SeqCst);
|
|
563
|
+
let label = format!("editor-{}", id);
|
|
564
|
+
|
|
565
|
+
WindowBuilder::new(
|
|
566
|
+
&app,
|
|
567
|
+
label.clone(),
|
|
568
|
+
WindowUrl::App("editor.html".into())
|
|
569
|
+
)
|
|
570
|
+
.title(format!("Untitled {}", id))
|
|
571
|
+
.inner_size(800.0, 600.0)
|
|
572
|
+
.build()
|
|
573
|
+
.map_err(|e| e.to_string())?;
|
|
574
|
+
|
|
575
|
+
Ok(label)
|
|
576
|
+
}
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
## Common Pitfalls
|
|
580
|
+
|
|
581
|
+
❌ **Creating duplicate windows without checking**:
|
|
582
|
+
```rust
|
|
583
|
+
// WRONG - may create multiple settings windows
|
|
584
|
+
WindowBuilder::new(&app, "settings", url).build()?;
|
|
585
|
+
|
|
586
|
+
// CORRECT - check first
|
|
587
|
+
if app.get_window("settings").is_none() {
|
|
588
|
+
WindowBuilder::new(&app, "settings", url).build()?;
|
|
589
|
+
}
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
❌ **Not cleaning up window state**:
|
|
593
|
+
```rust
|
|
594
|
+
// WRONG - state persists after window closes
|
|
595
|
+
|
|
596
|
+
// CORRECT - clean up in on_window_event
|
|
597
|
+
.on_window_event(|event| {
|
|
598
|
+
if let tauri::WindowEvent::Destroyed = event.event() {
|
|
599
|
+
let label = event.window().label();
|
|
600
|
+
// Clean up window-specific state
|
|
601
|
+
}
|
|
602
|
+
})
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
❌ **Forgetting to show hidden windows**:
|
|
606
|
+
```rust
|
|
607
|
+
// WRONG - window created but invisible
|
|
608
|
+
let window = WindowBuilder::new(&app, label, url)
|
|
609
|
+
.visible(false)
|
|
610
|
+
.build()?;
|
|
611
|
+
// User sees nothing!
|
|
612
|
+
|
|
613
|
+
// CORRECT - show after creation
|
|
614
|
+
window.show()?;
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
## Summary
|
|
618
|
+
|
|
619
|
+
- **WindowBuilder** creates new windows with configuration
|
|
620
|
+
- **Window labels** must be unique identifiers
|
|
621
|
+
- **get_window()** retrieves existing window by label
|
|
622
|
+
- **emit()** sends events to specific windows
|
|
623
|
+
- **emit_all()** broadcasts to all windows
|
|
624
|
+
- **Window lifecycle** handled via on_window_event
|
|
625
|
+
- **Window-specific state** stored in DashMap with label as key
|
|
626
|
+
- **Singleton pattern** prevents duplicate utility windows
|
|
627
|
+
- **Modal dialogs** use parent_window and always_on_top
|
|
628
|
+
- **Frontend API** provides window control from JavaScript
|
|
@@ -4,6 +4,25 @@ description: Replace arbitrary timeouts with condition polling for reliable asyn
|
|
|
4
4
|
when_to_use: when tests have race conditions, timing dependencies, or inconsistent pass/fail behavior
|
|
5
5
|
version: 1.1.0
|
|
6
6
|
languages: all
|
|
7
|
+
progressive_disclosure:
|
|
8
|
+
entry_point:
|
|
9
|
+
summary: "Replace arbitrary timeouts with condition polling for reliable async tests"
|
|
10
|
+
when_to_use: "Tests with setTimeout/sleep, flaky tests, or timing-dependent async operations"
|
|
11
|
+
quick_start: |
|
|
12
|
+
1. Identify arbitrary delays in tests (setTimeout, sleep, time.sleep())
|
|
13
|
+
2. Replace with condition-based waiting (waitFor pattern)
|
|
14
|
+
3. Use domain-specific helpers for common scenarios
|
|
15
|
+
See @example.ts for complete working implementation
|
|
16
|
+
core_pattern: |
|
|
17
|
+
// ❌ Guessing at timing
|
|
18
|
+
await new Promise(r => setTimeout(r, 50));
|
|
19
|
+
|
|
20
|
+
// ✅ Waiting for condition
|
|
21
|
+
await waitFor(() => getResult() !== undefined);
|
|
22
|
+
references:
|
|
23
|
+
- path: references/patterns-and-implementation.md
|
|
24
|
+
purpose: Detailed waiting patterns, implementation guide, and common mistakes
|
|
25
|
+
when_to_read: When implementing waitFor or debugging timing issues
|
|
7
26
|
---
|
|
8
27
|
|
|
9
28
|
# Condition-Based Waiting
|
|
@@ -87,32 +106,9 @@ async function waitFor<T>(
|
|
|
87
106
|
}
|
|
88
107
|
```
|
|
89
108
|
|
|
90
|
-
See @example.ts for complete implementation with domain-specific helpers (`waitForEvent`, `waitForEventCount`, `waitForEventMatch`)
|
|
109
|
+
See @example.ts for complete implementation with domain-specific helpers (`waitForEvent`, `waitForEventCount`, `waitForEventMatch`).
|
|
91
110
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
**❌ Polling too fast:** `setTimeout(check, 1)` - wastes CPU
|
|
95
|
-
**✅ Fix:** Poll every 10ms
|
|
96
|
-
|
|
97
|
-
**❌ No timeout:** Loop forever if condition never met
|
|
98
|
-
**✅ Fix:** Always include timeout with clear error
|
|
99
|
-
|
|
100
|
-
**❌ Stale data:** Cache state before loop
|
|
101
|
-
**✅ Fix:** Call getter inside loop for fresh data
|
|
102
|
-
|
|
103
|
-
## When Arbitrary Timeout IS Correct
|
|
104
|
-
|
|
105
|
-
```typescript
|
|
106
|
-
// Tool ticks every 100ms - need 2 ticks to verify partial output
|
|
107
|
-
await waitForEvent(manager, 'TOOL_STARTED'); // First: wait for condition
|
|
108
|
-
await new Promise(r => setTimeout(r, 200)); // Then: wait for timed behavior
|
|
109
|
-
// 200ms = 2 ticks at 100ms intervals - documented and justified
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
**Requirements:**
|
|
113
|
-
1. First wait for triggering condition
|
|
114
|
-
2. Based on known timing (not guessing)
|
|
115
|
-
3. Comment explaining WHY
|
|
111
|
+
For detailed patterns, implementation guide, and common mistakes, see @references/patterns-and-implementation.md
|
|
116
112
|
|
|
117
113
|
## Real-World Impact
|
|
118
114
|
|