claude-mpm 5.4.36__py3-none-any.whl → 5.4.62__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/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +5 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +489 -177
- claude_mpm/agents/base_agent.json +1 -1
- claude_mpm/agents/frontmatter_validator.py +2 -2
- claude_mpm/cli/commands/configure_agent_display.py +12 -0
- claude_mpm/cli/commands/mpm_init/core.py +72 -0
- claude_mpm/cli/commands/profile.py +276 -0
- claude_mpm/cli/commands/skills.py +14 -18
- claude_mpm/cli/executor.py +10 -0
- claude_mpm/cli/parsers/base_parser.py +7 -0
- claude_mpm/cli/parsers/profile_parser.py +147 -0
- claude_mpm/cli/parsers/skills_parser.py +0 -6
- claude_mpm/cli/startup.py +433 -147
- claude_mpm/commands/mpm-config.md +13 -250
- claude_mpm/commands/mpm-doctor.md +9 -22
- claude_mpm/commands/mpm-help.md +5 -206
- claude_mpm/commands/mpm-init.md +81 -507
- claude_mpm/commands/mpm-monitor.md +15 -402
- claude_mpm/commands/mpm-organize.md +61 -441
- claude_mpm/commands/mpm-postmortem.md +6 -108
- claude_mpm/commands/mpm-session-resume.md +12 -363
- claude_mpm/commands/mpm-status.md +5 -69
- claude_mpm/commands/mpm-ticket-view.md +52 -495
- claude_mpm/commands/mpm-version.md +5 -107
- claude_mpm/core/optimized_startup.py +61 -0
- claude_mpm/core/shared/config_loader.py +3 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CWc5urbQ.js → 4TdZjIqw.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uj46x2Wr.js → BSNlmTZj.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DjhvlsAc.js → NqQ1dWOy.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{N4qtv3Hx.js → Vzk33B_K.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.CAGBuiOw.js → 0.m1gL8KXf.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
- claude_mpm/dashboard/static/svelte-build/index.html +10 -10
- claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
- claude_mpm/hooks/kuzu_memory_hook.py +5 -5
- claude_mpm/init.py +276 -0
- claude_mpm/services/agents/agent_builder.py +3 -3
- claude_mpm/services/agents/deployment/agent_deployment.py +22 -0
- claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -1
- claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
- claude_mpm/services/agents/deployment/agent_template_builder.py +37 -17
- claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
- claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +149 -4
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +47 -26
- claude_mpm/services/agents/git_source_manager.py +21 -2
- claude_mpm/services/agents/sources/git_source_sync_service.py +116 -5
- claude_mpm/services/monitor/management/lifecycle.py +7 -1
- claude_mpm/services/pm_skills_deployer.py +711 -0
- claude_mpm/services/profile_manager.py +337 -0
- claude_mpm/services/skills/git_skill_source_manager.py +148 -11
- claude_mpm/services/skills/selective_skill_deployer.py +97 -48
- claude_mpm/services/skills_deployer.py +161 -65
- 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/git-worktrees.md +317 -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/stacked-prs.md +251 -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/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/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/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/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/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/pm/pm-delegation-patterns/SKILL.md +167 -0
- claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md +113 -0
- claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md +124 -0
- claude_mpm/skills/bundled/pm/pm-ticketing-integration/SKILL.md +154 -0
- claude_mpm/skills/bundled/pm/pm-verification-protocols/SKILL.md +198 -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/security-scanning.md +112 -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 +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/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 +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/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -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/skill_manager.py +98 -3
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/METADATA +3 -2
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/RECORD +244 -68
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +0 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +0 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +0 -10
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,758 @@
|
|
|
1
|
+
# Server Management Reference
|
|
2
|
+
|
|
3
|
+
Complete guide to server lifecycle management, port management, and process control for webapp testing.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Server Lifecycle](#server-lifecycle)
|
|
8
|
+
- [Port Management](#port-management)
|
|
9
|
+
- [Process Management](#process-management)
|
|
10
|
+
- [Environment Configuration](#environment-configuration)
|
|
11
|
+
- [Health Checks](#health-checks)
|
|
12
|
+
- [Graceful Shutdown](#graceful-shutdown)
|
|
13
|
+
- [Multi-Server Configurations](#multi-server-configurations)
|
|
14
|
+
- [Troubleshooting](#troubleshooting)
|
|
15
|
+
|
|
16
|
+
## Server Lifecycle
|
|
17
|
+
|
|
18
|
+
### Using with_server.py Helper Script
|
|
19
|
+
|
|
20
|
+
The `with_server.py` script manages the complete server lifecycle:
|
|
21
|
+
- Starts server(s)
|
|
22
|
+
- Waits for server(s) to be ready
|
|
23
|
+
- Runs your automation script
|
|
24
|
+
- Cleans up server(s) automatically
|
|
25
|
+
|
|
26
|
+
**Always run with `--help` first:**
|
|
27
|
+
```bash
|
|
28
|
+
python scripts/with_server.py --help
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Single Server Management
|
|
32
|
+
|
|
33
|
+
**Basic usage:**
|
|
34
|
+
```bash
|
|
35
|
+
python scripts/with_server.py --server "npm run dev" --port 5173 -- python automation.py
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**With custom timeout:**
|
|
39
|
+
```bash
|
|
40
|
+
python scripts/with_server.py --server "npm start" --port 3000 --timeout 60 -- python test.py
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Django example:**
|
|
44
|
+
```bash
|
|
45
|
+
python scripts/with_server.py --server "python manage.py runserver 8000" --port 8000 -- python test.py
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Flask example:**
|
|
49
|
+
```bash
|
|
50
|
+
python scripts/with_server.py --server "flask run --port 5000" --port 5000 -- python test.py
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Node.js Express example:**
|
|
54
|
+
```bash
|
|
55
|
+
python scripts/with_server.py --server "node server.js" --port 3000 -- python test.py
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Multiple Server Management
|
|
59
|
+
|
|
60
|
+
**Frontend + Backend:**
|
|
61
|
+
```bash
|
|
62
|
+
python scripts/with_server.py \
|
|
63
|
+
--server "cd backend && python server.py" --port 3000 \
|
|
64
|
+
--server "cd frontend && npm run dev" --port 5173 \
|
|
65
|
+
-- python test.py
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Microservices:**
|
|
69
|
+
```bash
|
|
70
|
+
python scripts/with_server.py \
|
|
71
|
+
--server "cd auth-service && npm start" --port 3001 \
|
|
72
|
+
--server "cd api-service && npm start" --port 3002 \
|
|
73
|
+
--server "cd frontend && npm start" --port 3000 \
|
|
74
|
+
-- python test.py
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Database + API + Frontend:**
|
|
78
|
+
```bash
|
|
79
|
+
python scripts/with_server.py \
|
|
80
|
+
--server "docker-compose up db" --port 5432 \
|
|
81
|
+
--server "cd api && npm start" --port 4000 \
|
|
82
|
+
--server "cd web && npm start" --port 3000 \
|
|
83
|
+
-- python test.py
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Manual Server Management
|
|
87
|
+
|
|
88
|
+
When you need more control than `with_server.py` provides:
|
|
89
|
+
|
|
90
|
+
**Start server in background:**
|
|
91
|
+
```bash
|
|
92
|
+
# Node.js
|
|
93
|
+
npm run dev > /tmp/server.log 2>&1 &
|
|
94
|
+
echo $! > /tmp/server.pid
|
|
95
|
+
|
|
96
|
+
# Python
|
|
97
|
+
python manage.py runserver > /tmp/server.log 2>&1 &
|
|
98
|
+
echo $! > /tmp/server.pid
|
|
99
|
+
|
|
100
|
+
# Flask
|
|
101
|
+
FLASK_APP=app.py flask run > /tmp/server.log 2>&1 &
|
|
102
|
+
echo $! > /tmp/server.pid
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Check if server is ready:**
|
|
106
|
+
```bash
|
|
107
|
+
# Using curl
|
|
108
|
+
curl -f http://localhost:3000/health
|
|
109
|
+
if [ $? -eq 0 ]; then echo "Server ready"; fi
|
|
110
|
+
|
|
111
|
+
# Using lsof
|
|
112
|
+
lsof -i :3000 -sTCP:LISTEN
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Stop server:**
|
|
116
|
+
```bash
|
|
117
|
+
# Using saved PID
|
|
118
|
+
kill $(cat /tmp/server.pid)
|
|
119
|
+
|
|
120
|
+
# Using port
|
|
121
|
+
lsof -t -i :3000 | xargs kill
|
|
122
|
+
|
|
123
|
+
# Force kill if not responding
|
|
124
|
+
lsof -t -i :3000 | xargs kill -9
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Port Management
|
|
128
|
+
|
|
129
|
+
### Check Port Availability
|
|
130
|
+
|
|
131
|
+
**Using lsof (macOS/Linux):**
|
|
132
|
+
```bash
|
|
133
|
+
# Check if port is in use
|
|
134
|
+
lsof -i :3000
|
|
135
|
+
|
|
136
|
+
# Check specific protocol
|
|
137
|
+
lsof -i TCP:3000
|
|
138
|
+
lsof -i UDP:3000
|
|
139
|
+
|
|
140
|
+
# List all listening ports
|
|
141
|
+
lsof -i -sTCP:LISTEN
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Using netstat (cross-platform):**
|
|
145
|
+
```bash
|
|
146
|
+
# Check specific port
|
|
147
|
+
netstat -an | grep :3000
|
|
148
|
+
|
|
149
|
+
# List all listening TCP ports
|
|
150
|
+
netstat -an | grep LISTEN
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Using nc (netcat):**
|
|
154
|
+
```bash
|
|
155
|
+
# Check if port is open
|
|
156
|
+
nc -zv localhost 3000
|
|
157
|
+
|
|
158
|
+
# Check range of ports
|
|
159
|
+
nc -zv localhost 3000-3010
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Python check:**
|
|
163
|
+
```python
|
|
164
|
+
import socket
|
|
165
|
+
|
|
166
|
+
def is_port_available(port):
|
|
167
|
+
try:
|
|
168
|
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
169
|
+
s.bind(('localhost', port))
|
|
170
|
+
return True
|
|
171
|
+
except OSError:
|
|
172
|
+
return False
|
|
173
|
+
|
|
174
|
+
print(f"Port 3000 available: {is_port_available(3000)}")
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Find Process Using Port
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
# Get PID of process using port
|
|
181
|
+
lsof -t -i :3000
|
|
182
|
+
|
|
183
|
+
# Get detailed info
|
|
184
|
+
lsof -i :3000
|
|
185
|
+
|
|
186
|
+
# Output example:
|
|
187
|
+
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
|
|
188
|
+
# node 12345 user 20u IPv4 0x1234 0t0 TCP *:3000 (LISTEN)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Kill Process on Port
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# Kill process (graceful)
|
|
195
|
+
lsof -t -i :3000 | xargs kill
|
|
196
|
+
|
|
197
|
+
# Force kill if not responding
|
|
198
|
+
lsof -t -i :3000 | xargs kill -9
|
|
199
|
+
|
|
200
|
+
# Alternative using port number
|
|
201
|
+
kill $(lsof -t -i :3000)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Choose Alternative Port
|
|
205
|
+
|
|
206
|
+
**Check multiple ports:**
|
|
207
|
+
```bash
|
|
208
|
+
for port in 3000 3001 3002 3003; do
|
|
209
|
+
if ! lsof -i :$port > /dev/null; then
|
|
210
|
+
echo "Port $port is available"
|
|
211
|
+
break
|
|
212
|
+
fi
|
|
213
|
+
done
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Python find available port:**
|
|
217
|
+
```python
|
|
218
|
+
import socket
|
|
219
|
+
|
|
220
|
+
def find_available_port(start=3000, end=3100):
|
|
221
|
+
for port in range(start, end):
|
|
222
|
+
try:
|
|
223
|
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
224
|
+
s.bind(('localhost', port))
|
|
225
|
+
return port
|
|
226
|
+
except OSError:
|
|
227
|
+
continue
|
|
228
|
+
return None
|
|
229
|
+
|
|
230
|
+
port = find_available_port()
|
|
231
|
+
print(f"Available port: {port}")
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Process Management
|
|
235
|
+
|
|
236
|
+
### pm2 (Node.js Process Manager)
|
|
237
|
+
|
|
238
|
+
**Install pm2:**
|
|
239
|
+
```bash
|
|
240
|
+
npm install -g pm2
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**Basic commands:**
|
|
244
|
+
```bash
|
|
245
|
+
# Start server
|
|
246
|
+
pm2 start npm --name "my-app" -- start
|
|
247
|
+
|
|
248
|
+
# Start with environment
|
|
249
|
+
pm2 start npm --name "my-app" -- start --update-env
|
|
250
|
+
|
|
251
|
+
# List running processes
|
|
252
|
+
pm2 list
|
|
253
|
+
|
|
254
|
+
# Monitor processes
|
|
255
|
+
pm2 monit
|
|
256
|
+
|
|
257
|
+
# Show logs
|
|
258
|
+
pm2 logs my-app
|
|
259
|
+
|
|
260
|
+
# Stop process
|
|
261
|
+
pm2 stop my-app
|
|
262
|
+
|
|
263
|
+
# Restart process
|
|
264
|
+
pm2 restart my-app
|
|
265
|
+
|
|
266
|
+
# Delete process
|
|
267
|
+
pm2 delete my-app
|
|
268
|
+
|
|
269
|
+
# Stop all
|
|
270
|
+
pm2 stop all
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**Ecosystem file (pm2.config.js):**
|
|
274
|
+
```javascript
|
|
275
|
+
module.exports = {
|
|
276
|
+
apps: [{
|
|
277
|
+
name: 'frontend',
|
|
278
|
+
script: 'npm',
|
|
279
|
+
args: 'start',
|
|
280
|
+
cwd: './frontend',
|
|
281
|
+
env: {
|
|
282
|
+
PORT: 3000,
|
|
283
|
+
NODE_ENV: 'development'
|
|
284
|
+
}
|
|
285
|
+
}, {
|
|
286
|
+
name: 'backend',
|
|
287
|
+
script: 'npm',
|
|
288
|
+
args: 'start',
|
|
289
|
+
cwd: './backend',
|
|
290
|
+
env: {
|
|
291
|
+
PORT: 4000,
|
|
292
|
+
NODE_ENV: 'development'
|
|
293
|
+
}
|
|
294
|
+
}]
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Start from ecosystem:**
|
|
299
|
+
```bash
|
|
300
|
+
pm2 start pm2.config.js
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### systemd (Linux System Service)
|
|
304
|
+
|
|
305
|
+
**Create service file (/etc/systemd/system/myapp.service):**
|
|
306
|
+
```ini
|
|
307
|
+
[Unit]
|
|
308
|
+
Description=My Web Application
|
|
309
|
+
After=network.target
|
|
310
|
+
|
|
311
|
+
[Service]
|
|
312
|
+
Type=simple
|
|
313
|
+
User=www-data
|
|
314
|
+
WorkingDirectory=/var/www/myapp
|
|
315
|
+
ExecStart=/usr/bin/node server.js
|
|
316
|
+
Restart=on-failure
|
|
317
|
+
Environment=NODE_ENV=production
|
|
318
|
+
Environment=PORT=3000
|
|
319
|
+
|
|
320
|
+
[Install]
|
|
321
|
+
WantedBy=multi-user.target
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**Service commands:**
|
|
325
|
+
```bash
|
|
326
|
+
# Reload systemd
|
|
327
|
+
sudo systemctl daemon-reload
|
|
328
|
+
|
|
329
|
+
# Start service
|
|
330
|
+
sudo systemctl start myapp
|
|
331
|
+
|
|
332
|
+
# Stop service
|
|
333
|
+
sudo systemctl stop myapp
|
|
334
|
+
|
|
335
|
+
# Restart service
|
|
336
|
+
sudo systemctl restart myapp
|
|
337
|
+
|
|
338
|
+
# Enable on boot
|
|
339
|
+
sudo systemctl enable myapp
|
|
340
|
+
|
|
341
|
+
# Check status
|
|
342
|
+
sudo systemctl status myapp
|
|
343
|
+
|
|
344
|
+
# View logs
|
|
345
|
+
sudo journalctl -u myapp -f
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Docker Container Management
|
|
349
|
+
|
|
350
|
+
**Run server in container:**
|
|
351
|
+
```bash
|
|
352
|
+
# Start container
|
|
353
|
+
docker run -d -p 3000:3000 --name myapp myapp:latest
|
|
354
|
+
|
|
355
|
+
# Check if container is running
|
|
356
|
+
docker ps | grep myapp
|
|
357
|
+
|
|
358
|
+
# Stop container
|
|
359
|
+
docker stop myapp
|
|
360
|
+
|
|
361
|
+
# Remove container
|
|
362
|
+
docker rm myapp
|
|
363
|
+
|
|
364
|
+
# View logs
|
|
365
|
+
docker logs -f myapp
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
**Docker Compose:**
|
|
369
|
+
```yaml
|
|
370
|
+
# docker-compose.yml
|
|
371
|
+
version: '3'
|
|
372
|
+
services:
|
|
373
|
+
frontend:
|
|
374
|
+
build: ./frontend
|
|
375
|
+
ports:
|
|
376
|
+
- "3000:3000"
|
|
377
|
+
environment:
|
|
378
|
+
- NODE_ENV=development
|
|
379
|
+
|
|
380
|
+
backend:
|
|
381
|
+
build: ./backend
|
|
382
|
+
ports:
|
|
383
|
+
- "4000:4000"
|
|
384
|
+
environment:
|
|
385
|
+
- NODE_ENV=development
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Compose commands:**
|
|
389
|
+
```bash
|
|
390
|
+
# Start all services
|
|
391
|
+
docker-compose up -d
|
|
392
|
+
|
|
393
|
+
# Stop all services
|
|
394
|
+
docker-compose down
|
|
395
|
+
|
|
396
|
+
# View logs
|
|
397
|
+
docker-compose logs -f
|
|
398
|
+
|
|
399
|
+
# Restart service
|
|
400
|
+
docker-compose restart frontend
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## Environment Configuration
|
|
404
|
+
|
|
405
|
+
### Environment Variables
|
|
406
|
+
|
|
407
|
+
**Setting environment variables:**
|
|
408
|
+
```bash
|
|
409
|
+
# Linux/macOS
|
|
410
|
+
export PORT=3000
|
|
411
|
+
export NODE_ENV=development
|
|
412
|
+
|
|
413
|
+
# Windows (cmd)
|
|
414
|
+
set PORT=3000
|
|
415
|
+
set NODE_ENV=development
|
|
416
|
+
|
|
417
|
+
# Windows (PowerShell)
|
|
418
|
+
$env:PORT=3000
|
|
419
|
+
$env:NODE_ENV="development"
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
**Using .env file:**
|
|
423
|
+
```bash
|
|
424
|
+
# .env
|
|
425
|
+
PORT=3000
|
|
426
|
+
NODE_ENV=development
|
|
427
|
+
DATABASE_URL=postgresql://localhost/mydb
|
|
428
|
+
API_KEY=secret123
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
**Load .env in Python:**
|
|
432
|
+
```python
|
|
433
|
+
from dotenv import load_dotenv
|
|
434
|
+
import os
|
|
435
|
+
|
|
436
|
+
load_dotenv()
|
|
437
|
+
port = os.getenv('PORT', 3000)
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
**Load .env in Node.js:**
|
|
441
|
+
```javascript
|
|
442
|
+
require('dotenv').config();
|
|
443
|
+
const port = process.env.PORT || 3000;
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### Configuration Files
|
|
447
|
+
|
|
448
|
+
**Package.json scripts:**
|
|
449
|
+
```json
|
|
450
|
+
{
|
|
451
|
+
"scripts": {
|
|
452
|
+
"start": "node server.js",
|
|
453
|
+
"dev": "nodemon server.js",
|
|
454
|
+
"test": "NODE_ENV=test jest",
|
|
455
|
+
"start:prod": "NODE_ENV=production node server.js"
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
**Python settings.py:**
|
|
461
|
+
```python
|
|
462
|
+
import os
|
|
463
|
+
|
|
464
|
+
PORT = int(os.getenv('PORT', 8000))
|
|
465
|
+
DEBUG = os.getenv('DEBUG', 'False') == 'True'
|
|
466
|
+
DATABASE_URL = os.getenv('DATABASE_URL', 'sqlite:///db.sqlite3')
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
## Health Checks
|
|
470
|
+
|
|
471
|
+
### Implementing Health Check Endpoint
|
|
472
|
+
|
|
473
|
+
**Express.js:**
|
|
474
|
+
```javascript
|
|
475
|
+
app.get('/health', (req, res) => {
|
|
476
|
+
res.status(200).json({
|
|
477
|
+
status: 'ok',
|
|
478
|
+
timestamp: new Date().toISOString(),
|
|
479
|
+
uptime: process.uptime()
|
|
480
|
+
});
|
|
481
|
+
});
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
**Flask:**
|
|
485
|
+
```python
|
|
486
|
+
@app.route('/health')
|
|
487
|
+
def health():
|
|
488
|
+
return jsonify({
|
|
489
|
+
'status': 'ok',
|
|
490
|
+
'timestamp': datetime.now().isoformat()
|
|
491
|
+
})
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
**Django:**
|
|
495
|
+
```python
|
|
496
|
+
from django.http import JsonResponse
|
|
497
|
+
from datetime import datetime
|
|
498
|
+
|
|
499
|
+
def health_check(request):
|
|
500
|
+
return JsonResponse({
|
|
501
|
+
'status': 'ok',
|
|
502
|
+
'timestamp': datetime.now().isoformat()
|
|
503
|
+
})
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### Checking Health from Tests
|
|
507
|
+
|
|
508
|
+
**Using curl:**
|
|
509
|
+
```bash
|
|
510
|
+
curl -f http://localhost:3000/health
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
**Using Python requests:**
|
|
514
|
+
```python
|
|
515
|
+
import requests
|
|
516
|
+
|
|
517
|
+
def wait_for_server(url, timeout=30):
|
|
518
|
+
start = time.time()
|
|
519
|
+
while time.time() - start < timeout:
|
|
520
|
+
try:
|
|
521
|
+
response = requests.get(f"{url}/health", timeout=1)
|
|
522
|
+
if response.status_code == 200:
|
|
523
|
+
return True
|
|
524
|
+
except requests.RequestException:
|
|
525
|
+
time.sleep(0.5)
|
|
526
|
+
return False
|
|
527
|
+
|
|
528
|
+
if wait_for_server('http://localhost:3000'):
|
|
529
|
+
print("Server is ready")
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
**Using Playwright:**
|
|
533
|
+
```python
|
|
534
|
+
def wait_for_server_ready(page, url, timeout=30000):
|
|
535
|
+
page.goto(f"{url}/health", timeout=timeout)
|
|
536
|
+
response = page.wait_for_response(f"{url}/health")
|
|
537
|
+
return response.status == 200
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
## Graceful Shutdown
|
|
541
|
+
|
|
542
|
+
### Signal Handling
|
|
543
|
+
|
|
544
|
+
**Node.js graceful shutdown:**
|
|
545
|
+
```javascript
|
|
546
|
+
const server = app.listen(3000);
|
|
547
|
+
|
|
548
|
+
process.on('SIGTERM', () => {
|
|
549
|
+
console.log('SIGTERM received, closing server...');
|
|
550
|
+
server.close(() => {
|
|
551
|
+
console.log('Server closed');
|
|
552
|
+
process.exit(0);
|
|
553
|
+
});
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
process.on('SIGINT', () => {
|
|
557
|
+
console.log('SIGINT received, closing server...');
|
|
558
|
+
server.close(() => {
|
|
559
|
+
console.log('Server closed');
|
|
560
|
+
process.exit(0);
|
|
561
|
+
});
|
|
562
|
+
});
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
**Python graceful shutdown:**
|
|
566
|
+
```python
|
|
567
|
+
import signal
|
|
568
|
+
import sys
|
|
569
|
+
|
|
570
|
+
def signal_handler(sig, frame):
|
|
571
|
+
print('Shutting down gracefully...')
|
|
572
|
+
# Clean up resources
|
|
573
|
+
sys.exit(0)
|
|
574
|
+
|
|
575
|
+
signal.signal(signal.SIGTERM, signal_handler)
|
|
576
|
+
signal.signal(signal.SIGINT, signal_handler)
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### Cleanup Tasks
|
|
580
|
+
|
|
581
|
+
**Close database connections:**
|
|
582
|
+
```javascript
|
|
583
|
+
process.on('SIGTERM', async () => {
|
|
584
|
+
await db.close();
|
|
585
|
+
await cache.disconnect();
|
|
586
|
+
server.close(() => process.exit(0));
|
|
587
|
+
});
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
**Finish in-flight requests:**
|
|
591
|
+
```javascript
|
|
592
|
+
server.close(() => {
|
|
593
|
+
console.log('All requests finished');
|
|
594
|
+
process.exit(0);
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
// Force exit after timeout
|
|
598
|
+
setTimeout(() => {
|
|
599
|
+
console.error('Forcing shutdown');
|
|
600
|
+
process.exit(1);
|
|
601
|
+
}, 10000);
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
## Multi-Server Configurations
|
|
605
|
+
|
|
606
|
+
### Development Stack
|
|
607
|
+
|
|
608
|
+
**Full-stack development:**
|
|
609
|
+
```bash
|
|
610
|
+
# Terminal 1: Database
|
|
611
|
+
docker run -d -p 5432:5432 postgres
|
|
612
|
+
|
|
613
|
+
# Terminal 2: Backend API
|
|
614
|
+
cd backend && npm run dev
|
|
615
|
+
|
|
616
|
+
# Terminal 3: Frontend
|
|
617
|
+
cd frontend && npm start
|
|
618
|
+
|
|
619
|
+
# Or use with_server.py for all at once
|
|
620
|
+
python scripts/with_server.py \
|
|
621
|
+
--server "docker run -p 5432:5432 postgres" --port 5432 \
|
|
622
|
+
--server "cd backend && npm run dev" --port 4000 \
|
|
623
|
+
--server "cd frontend && npm start" --port 3000 \
|
|
624
|
+
-- python test.py
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
### Microservices Testing
|
|
628
|
+
|
|
629
|
+
**Multiple independent services:**
|
|
630
|
+
```bash
|
|
631
|
+
python scripts/with_server.py \
|
|
632
|
+
--server "cd auth-service && npm start" --port 3001 \
|
|
633
|
+
--server "cd user-service && npm start" --port 3002 \
|
|
634
|
+
--server "cd payment-service && npm start" --port 3003 \
|
|
635
|
+
--server "cd gateway && npm start" --port 3000 \
|
|
636
|
+
-- python integration_test.py
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
### Reverse Proxy Setup
|
|
640
|
+
|
|
641
|
+
**Nginx configuration:**
|
|
642
|
+
```nginx
|
|
643
|
+
server {
|
|
644
|
+
listen 80;
|
|
645
|
+
|
|
646
|
+
location /api {
|
|
647
|
+
proxy_pass http://localhost:4000;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
location / {
|
|
651
|
+
proxy_pass http://localhost:3000;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
## Troubleshooting
|
|
657
|
+
|
|
658
|
+
### Server Won't Start
|
|
659
|
+
|
|
660
|
+
**Port already in use:**
|
|
661
|
+
```bash
|
|
662
|
+
# Find what's using the port
|
|
663
|
+
lsof -i :3000
|
|
664
|
+
|
|
665
|
+
# Kill the process
|
|
666
|
+
lsof -t -i :3000 | xargs kill
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
**Permission denied:**
|
|
670
|
+
```bash
|
|
671
|
+
# Ports < 1024 require root (avoid if possible)
|
|
672
|
+
sudo node server.js # NOT RECOMMENDED
|
|
673
|
+
|
|
674
|
+
# Use port >= 1024 instead
|
|
675
|
+
PORT=3000 node server.js
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
**Missing dependencies:**
|
|
679
|
+
```bash
|
|
680
|
+
# Node.js
|
|
681
|
+
npm install
|
|
682
|
+
|
|
683
|
+
# Python
|
|
684
|
+
pip install -r requirements.txt
|
|
685
|
+
|
|
686
|
+
# Check for errors
|
|
687
|
+
npm start 2>&1 | tee server.log
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
### Server Crashes During Test
|
|
691
|
+
|
|
692
|
+
**Check logs:**
|
|
693
|
+
```bash
|
|
694
|
+
# If using with_server.py, check stderr
|
|
695
|
+
python scripts/with_server.py --server "npm start" --port 3000 -- python test.py 2>&1
|
|
696
|
+
|
|
697
|
+
# Check application logs
|
|
698
|
+
tail -f server.log
|
|
699
|
+
|
|
700
|
+
# Docker logs
|
|
701
|
+
docker logs -f container_name
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
**Memory issues:**
|
|
705
|
+
```bash
|
|
706
|
+
# Increase Node.js memory
|
|
707
|
+
NODE_OPTIONS="--max-old-space-size=4096" npm start
|
|
708
|
+
|
|
709
|
+
# Monitor memory
|
|
710
|
+
top -pid $(lsof -t -i :3000)
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
### Server Not Responding
|
|
714
|
+
|
|
715
|
+
**Check if process is alive:**
|
|
716
|
+
```bash
|
|
717
|
+
ps aux | grep node
|
|
718
|
+
ps aux | grep python
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
**Check network connectivity:**
|
|
722
|
+
```bash
|
|
723
|
+
# Test localhost
|
|
724
|
+
curl http://localhost:3000
|
|
725
|
+
|
|
726
|
+
# Test network interface
|
|
727
|
+
curl http://127.0.0.1:3000
|
|
728
|
+
|
|
729
|
+
# Check if listening on correct interface
|
|
730
|
+
lsof -i -sTCP:LISTEN | grep 3000
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
**Firewall issues:**
|
|
734
|
+
```bash
|
|
735
|
+
# macOS
|
|
736
|
+
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
|
|
737
|
+
|
|
738
|
+
# Linux
|
|
739
|
+
sudo ufw status
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
### Timeout Issues
|
|
743
|
+
|
|
744
|
+
**Increase timeout in with_server.py:**
|
|
745
|
+
```bash
|
|
746
|
+
python scripts/with_server.py --server "npm start" --port 3000 --timeout 60 -- python test.py
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
**Check server startup time:**
|
|
750
|
+
```bash
|
|
751
|
+
time npm start
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
**Optimize startup:**
|
|
755
|
+
- Reduce initial data loading
|
|
756
|
+
- Use lazy initialization
|
|
757
|
+
- Optimize dependency loading
|
|
758
|
+
- Use production builds for testing
|