claude-mpm 5.4.41__py3-none-any.whl → 5.6.23__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_OUTPUT_STYLE.md +66 -241
- claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
- claude_mpm/agents/PM_INSTRUCTIONS.md +161 -298
- claude_mpm/agents/WORKFLOW.md +2 -0
- claude_mpm/agents/templates/circuit-breakers.md +26 -17
- claude_mpm/cli/__init__.py +5 -1
- claude_mpm/cli/commands/agents.py +2 -4
- claude_mpm/cli/commands/agents_reconcile.py +197 -0
- claude_mpm/cli/commands/autotodos.py +566 -0
- claude_mpm/cli/commands/commander.py +216 -0
- claude_mpm/cli/commands/configure.py +620 -21
- claude_mpm/cli/commands/configure_agent_display.py +3 -1
- claude_mpm/cli/commands/hook_errors.py +60 -60
- claude_mpm/cli/commands/monitor.py +2 -2
- claude_mpm/cli/commands/mpm_init/core.py +15 -8
- claude_mpm/cli/commands/profile.py +9 -10
- claude_mpm/cli/commands/run.py +35 -3
- claude_mpm/cli/commands/skill_source.py +51 -2
- claude_mpm/cli/commands/skills.py +182 -32
- claude_mpm/cli/executor.py +120 -16
- claude_mpm/cli/interactive/__init__.py +10 -0
- claude_mpm/cli/interactive/agent_wizard.py +30 -50
- claude_mpm/cli/interactive/questionary_styles.py +65 -0
- claude_mpm/cli/interactive/skill_selector.py +481 -0
- claude_mpm/cli/parsers/base_parser.py +76 -1
- claude_mpm/cli/parsers/commander_parser.py +116 -0
- claude_mpm/cli/parsers/profile_parser.py +0 -1
- claude_mpm/cli/parsers/run_parser.py +10 -0
- claude_mpm/cli/parsers/skill_source_parser.py +4 -0
- claude_mpm/cli/parsers/skills_parser.py +2 -3
- claude_mpm/cli/startup.py +527 -506
- claude_mpm/cli/startup_display.py +74 -6
- claude_mpm/cli/startup_logging.py +2 -2
- claude_mpm/cli/utils.py +7 -3
- claude_mpm/commander/__init__.py +78 -0
- claude_mpm/commander/adapters/__init__.py +60 -0
- claude_mpm/commander/adapters/auggie.py +260 -0
- claude_mpm/commander/adapters/base.py +288 -0
- claude_mpm/commander/adapters/claude_code.py +392 -0
- claude_mpm/commander/adapters/codex.py +237 -0
- claude_mpm/commander/adapters/communication.py +366 -0
- claude_mpm/commander/adapters/example_usage.py +310 -0
- claude_mpm/commander/adapters/mpm.py +389 -0
- claude_mpm/commander/adapters/registry.py +204 -0
- claude_mpm/commander/api/__init__.py +16 -0
- claude_mpm/commander/api/app.py +121 -0
- claude_mpm/commander/api/errors.py +133 -0
- claude_mpm/commander/api/routes/__init__.py +8 -0
- claude_mpm/commander/api/routes/events.py +184 -0
- claude_mpm/commander/api/routes/inbox.py +171 -0
- claude_mpm/commander/api/routes/messages.py +148 -0
- claude_mpm/commander/api/routes/projects.py +271 -0
- claude_mpm/commander/api/routes/sessions.py +226 -0
- claude_mpm/commander/api/routes/work.py +296 -0
- claude_mpm/commander/api/schemas.py +186 -0
- claude_mpm/commander/chat/__init__.py +7 -0
- claude_mpm/commander/chat/cli.py +146 -0
- claude_mpm/commander/chat/commands.py +96 -0
- claude_mpm/commander/chat/repl.py +310 -0
- claude_mpm/commander/config.py +51 -0
- claude_mpm/commander/config_loader.py +115 -0
- claude_mpm/commander/core/__init__.py +10 -0
- claude_mpm/commander/core/block_manager.py +325 -0
- claude_mpm/commander/core/response_manager.py +323 -0
- claude_mpm/commander/daemon.py +603 -0
- claude_mpm/commander/env_loader.py +59 -0
- claude_mpm/commander/events/__init__.py +26 -0
- claude_mpm/commander/events/manager.py +332 -0
- claude_mpm/commander/frameworks/__init__.py +12 -0
- claude_mpm/commander/frameworks/base.py +146 -0
- claude_mpm/commander/frameworks/claude_code.py +58 -0
- claude_mpm/commander/frameworks/mpm.py +62 -0
- claude_mpm/commander/inbox/__init__.py +16 -0
- claude_mpm/commander/inbox/dedup.py +128 -0
- claude_mpm/commander/inbox/inbox.py +224 -0
- claude_mpm/commander/inbox/models.py +70 -0
- claude_mpm/commander/instance_manager.py +450 -0
- claude_mpm/commander/llm/__init__.py +6 -0
- claude_mpm/commander/llm/openrouter_client.py +167 -0
- claude_mpm/commander/llm/summarizer.py +70 -0
- claude_mpm/commander/memory/__init__.py +45 -0
- claude_mpm/commander/memory/compression.py +347 -0
- claude_mpm/commander/memory/embeddings.py +230 -0
- claude_mpm/commander/memory/entities.py +310 -0
- claude_mpm/commander/memory/example_usage.py +290 -0
- claude_mpm/commander/memory/integration.py +325 -0
- claude_mpm/commander/memory/search.py +381 -0
- claude_mpm/commander/memory/store.py +657 -0
- claude_mpm/commander/models/__init__.py +18 -0
- claude_mpm/commander/models/events.py +121 -0
- claude_mpm/commander/models/project.py +162 -0
- claude_mpm/commander/models/work.py +214 -0
- claude_mpm/commander/parsing/__init__.py +20 -0
- claude_mpm/commander/parsing/extractor.py +132 -0
- claude_mpm/commander/parsing/output_parser.py +270 -0
- claude_mpm/commander/parsing/patterns.py +100 -0
- claude_mpm/commander/persistence/__init__.py +11 -0
- claude_mpm/commander/persistence/event_store.py +274 -0
- claude_mpm/commander/persistence/state_store.py +309 -0
- claude_mpm/commander/persistence/work_store.py +164 -0
- claude_mpm/commander/polling/__init__.py +13 -0
- claude_mpm/commander/polling/event_detector.py +104 -0
- claude_mpm/commander/polling/output_buffer.py +49 -0
- claude_mpm/commander/polling/output_poller.py +153 -0
- claude_mpm/commander/project_session.py +268 -0
- claude_mpm/commander/proxy/__init__.py +12 -0
- claude_mpm/commander/proxy/formatter.py +89 -0
- claude_mpm/commander/proxy/output_handler.py +191 -0
- claude_mpm/commander/proxy/relay.py +155 -0
- claude_mpm/commander/registry.py +410 -0
- claude_mpm/commander/runtime/__init__.py +10 -0
- claude_mpm/commander/runtime/executor.py +191 -0
- claude_mpm/commander/runtime/monitor.py +346 -0
- claude_mpm/commander/session/__init__.py +6 -0
- claude_mpm/commander/session/context.py +81 -0
- claude_mpm/commander/session/manager.py +59 -0
- claude_mpm/commander/tmux_orchestrator.py +361 -0
- claude_mpm/commander/web/__init__.py +1 -0
- claude_mpm/commander/work/__init__.py +30 -0
- claude_mpm/commander/work/executor.py +207 -0
- claude_mpm/commander/work/queue.py +405 -0
- claude_mpm/commander/workflow/__init__.py +27 -0
- claude_mpm/commander/workflow/event_handler.py +241 -0
- claude_mpm/commander/workflow/notifier.py +146 -0
- claude_mpm/commands/mpm-config.md +8 -0
- claude_mpm/commands/mpm-doctor.md +8 -0
- claude_mpm/commands/mpm-help.md +8 -0
- claude_mpm/commands/mpm-init.md +8 -0
- claude_mpm/commands/mpm-monitor.md +8 -0
- claude_mpm/commands/mpm-organize.md +8 -0
- claude_mpm/commands/mpm-postmortem.md +8 -0
- claude_mpm/commands/mpm-session-resume.md +9 -1
- claude_mpm/commands/mpm-status.md +8 -0
- claude_mpm/commands/mpm-ticket-view.md +8 -0
- claude_mpm/commands/mpm-version.md +8 -0
- claude_mpm/commands/mpm.md +8 -0
- claude_mpm/config/agent_presets.py +8 -7
- claude_mpm/config/skill_sources.py +16 -0
- claude_mpm/constants.py +1 -0
- claude_mpm/core/claude_runner.py +154 -2
- claude_mpm/core/config.py +35 -22
- claude_mpm/core/config_constants.py +74 -9
- claude_mpm/core/constants.py +56 -12
- claude_mpm/core/hook_manager.py +51 -3
- claude_mpm/core/interactive_session.py +12 -11
- claude_mpm/core/logger.py +26 -9
- claude_mpm/core/logging_utils.py +35 -11
- claude_mpm/core/network_config.py +148 -0
- claude_mpm/core/oneshot_session.py +7 -6
- claude_mpm/core/optimized_startup.py +3 -1
- claude_mpm/core/output_style_manager.py +63 -18
- claude_mpm/core/shared/config_loader.py +3 -1
- claude_mpm/core/socketio_pool.py +13 -5
- claude_mpm/core/unified_config.py +54 -8
- claude_mpm/core/unified_paths.py +95 -90
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.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/BRcwIQNr.js +4 -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/BV6nKitt.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{N4qtv3Hx.js → DR8nis88.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -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/R8CEIRAd.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.CAGBuiOw.js → 0.RgBboRvH.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
- claude_mpm/dashboard/static/svelte-build/index.html +11 -11
- 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/experimental/cli_enhancements.py +2 -1
- claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
- claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
- claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +305 -87
- claude_mpm/hooks/claude_hooks/hook_handler.py +106 -89
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
- claude_mpm/hooks/claude_hooks/installer.py +116 -8
- claude_mpm/hooks/claude_hooks/memory_integration.py +51 -31
- claude_mpm/hooks/claude_hooks/response_tracking.py +42 -59
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +39 -24
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +36 -103
- claude_mpm/hooks/claude_hooks/services/state_manager.py +23 -36
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +73 -75
- claude_mpm/hooks/kuzu_memory_hook.py +5 -5
- claude_mpm/hooks/session_resume_hook.py +89 -1
- claude_mpm/hooks/templates/pre_tool_use_template.py +10 -2
- claude_mpm/init.py +215 -2
- claude_mpm/scripts/claude-hook-handler.sh +43 -16
- claude_mpm/services/agents/agent_recommendation_service.py +8 -8
- claude_mpm/services/agents/agent_selection_service.py +2 -2
- claude_mpm/services/agents/cache_git_manager.py +1 -1
- 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/deployment_reconciler.py +577 -0
- claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +36 -8
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +50 -26
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/git_source_manager.py +21 -2
- claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
- claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
- claude_mpm/services/agents/sources/git_source_sync_service.py +116 -5
- claude_mpm/services/agents/startup_sync.py +5 -2
- claude_mpm/services/cli/__init__.py +3 -0
- claude_mpm/services/cli/incremental_pause_manager.py +561 -0
- claude_mpm/services/cli/session_resume_helper.py +10 -2
- claude_mpm/services/delegation_detector.py +175 -0
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +30 -0
- claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
- claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
- claude_mpm/services/diagnostics/models.py +14 -1
- claude_mpm/services/event_log.py +325 -0
- claude_mpm/services/infrastructure/__init__.py +4 -0
- claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
- claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
- claude_mpm/services/monitor/daemon_manager.py +15 -4
- claude_mpm/services/monitor/management/lifecycle.py +8 -3
- claude_mpm/services/monitor/server.py +106 -16
- claude_mpm/services/pm_skills_deployer.py +302 -94
- claude_mpm/services/profile_manager.py +10 -4
- claude_mpm/services/skills/git_skill_source_manager.py +192 -29
- claude_mpm/services/skills/selective_skill_deployer.py +211 -46
- claude_mpm/services/skills/skill_discovery_service.py +74 -4
- claude_mpm/services/skills_deployer.py +192 -70
- claude_mpm/services/socketio/handlers/hook.py +14 -7
- claude_mpm/services/socketio/server/main.py +12 -4
- claude_mpm/skills/__init__.py +2 -1
- 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/mpm/SKILL.md +38 -0
- claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
- claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
- claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
- claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
- claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
- claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
- claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
- claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
- claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
- claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
- claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
- claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
- claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
- claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
- claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
- claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
- claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
- claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
- claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
- claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
- claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
- claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
- claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -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/registry.py +295 -90
- claude_mpm/skills/skill_manager.py +29 -23
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/utils/agent_dependency_loader.py +103 -4
- claude_mpm/utils/robust_installer.py +45 -24
- claude_mpm-5.6.23.dist-info/METADATA +393 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/RECORD +447 -149
- 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/CWc5urbQ.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/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
- claude_mpm-5.4.41.dist-info/METADATA +0 -998
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,668 @@
|
|
|
1
|
+
# Advanced Tracing Techniques
|
|
2
|
+
|
|
3
|
+
Advanced methods for tracing bugs when manual inspection isn't sufficient: instrumentation, stack traces, test pollution detection, and async tracing.
|
|
4
|
+
|
|
5
|
+
## When Manual Tracing Isn't Enough
|
|
6
|
+
|
|
7
|
+
Manual code inspection works well when:
|
|
8
|
+
- Code path is clear
|
|
9
|
+
- Stack traces are available
|
|
10
|
+
- Single-threaded execution
|
|
11
|
+
- You can identify all callers
|
|
12
|
+
|
|
13
|
+
**Use advanced techniques when:**
|
|
14
|
+
- Can't identify which code path triggers the issue
|
|
15
|
+
- Multiple async operations interleave
|
|
16
|
+
- Race conditions or timing issues
|
|
17
|
+
- Need to find which test causes pollution
|
|
18
|
+
- External code (libraries) involved
|
|
19
|
+
- Production issues you can't reproduce locally
|
|
20
|
+
|
|
21
|
+
## Stack Trace Instrumentation
|
|
22
|
+
|
|
23
|
+
### Purpose
|
|
24
|
+
|
|
25
|
+
Capture complete call stack at strategic points to understand execution flow.
|
|
26
|
+
|
|
27
|
+
### Basic Stack Trace Capture
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
function suspiciousOperation(param: string) {
|
|
31
|
+
// Capture stack trace BEFORE the operation
|
|
32
|
+
const stack = new Error().stack;
|
|
33
|
+
console.error('DEBUG suspiciousOperation:', {
|
|
34
|
+
param,
|
|
35
|
+
cwd: process.cwd(),
|
|
36
|
+
timestamp: Date.now(),
|
|
37
|
+
stack
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Now do the operation
|
|
41
|
+
performOperation(param);
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Key points:**
|
|
46
|
+
- Use `console.error()` in tests (regular logger may be suppressed)
|
|
47
|
+
- Log BEFORE the operation, not after it fails
|
|
48
|
+
- Include context: parameters, environment, state
|
|
49
|
+
- Capture stack with `new Error().stack`
|
|
50
|
+
|
|
51
|
+
### Analyzing Stack Traces
|
|
52
|
+
|
|
53
|
+
**Run and capture output:**
|
|
54
|
+
```bash
|
|
55
|
+
npm test 2>&1 | grep 'DEBUG suspiciousOperation'
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Look for:**
|
|
59
|
+
- Test file names in stack traces
|
|
60
|
+
- Line numbers that trigger the call
|
|
61
|
+
- Patterns: same test? same parameters?
|
|
62
|
+
- Call frequency: how many times called?
|
|
63
|
+
|
|
64
|
+
**Example output:**
|
|
65
|
+
```
|
|
66
|
+
DEBUG suspiciousOperation: {
|
|
67
|
+
param: '',
|
|
68
|
+
cwd: '/Users/jesse/project/packages/core',
|
|
69
|
+
stack: 'Error
|
|
70
|
+
at suspiciousOperation (file.ts:10)
|
|
71
|
+
at WorktreeManager.create (worktree.ts:45)
|
|
72
|
+
at Session.initialize (session.ts:78)
|
|
73
|
+
at Project.create (project.ts:23)
|
|
74
|
+
at Test.<anonymous> (project.test.ts:12)
|
|
75
|
+
at Test.run (node:internal/test)'
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Analysis:** The call originates from `project.test.ts:12` with empty parameter.
|
|
80
|
+
|
|
81
|
+
### Conditional Instrumentation
|
|
82
|
+
|
|
83
|
+
Only log when conditions are suspicious:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
function gitInit(directory: string) {
|
|
87
|
+
// Only log if directory is empty or equals cwd
|
|
88
|
+
if (!directory || directory === process.cwd()) {
|
|
89
|
+
console.error('SUSPICIOUS git init:', {
|
|
90
|
+
directory,
|
|
91
|
+
cwd: process.cwd(),
|
|
92
|
+
nodeEnv: process.env.NODE_ENV,
|
|
93
|
+
stack: new Error().stack
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
execFileAsync('git', ['init'], { cwd: directory });
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
This reduces noise while capturing problematic cases.
|
|
102
|
+
|
|
103
|
+
### Stack Trace in Production
|
|
104
|
+
|
|
105
|
+
**Warning:** Stack traces have performance cost. Use carefully in production.
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
class ErrorTracker {
|
|
109
|
+
private static captureInterval = 100; // Only capture 1% of calls
|
|
110
|
+
private static counter = 0;
|
|
111
|
+
|
|
112
|
+
static maybeCapture(operation: string, data: any) {
|
|
113
|
+
this.counter++;
|
|
114
|
+
if (this.counter % this.captureInterval === 0) {
|
|
115
|
+
// Sample 1% of operations
|
|
116
|
+
logger.warn('Sampled operation', {
|
|
117
|
+
operation,
|
|
118
|
+
data,
|
|
119
|
+
stack: new Error().stack
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Finding Test Pollution
|
|
127
|
+
|
|
128
|
+
### What is Test Pollution?
|
|
129
|
+
|
|
130
|
+
Tests that create files, directories, or state that persists after the test completes.
|
|
131
|
+
|
|
132
|
+
**Common polluters:**
|
|
133
|
+
- Creating files/directories outside temp dir
|
|
134
|
+
- Not cleaning up in afterEach
|
|
135
|
+
- Modifying global state
|
|
136
|
+
- Creating git repositories
|
|
137
|
+
- Writing to current directory
|
|
138
|
+
|
|
139
|
+
### Detection Strategy
|
|
140
|
+
|
|
141
|
+
**Symptoms:**
|
|
142
|
+
- Files appear in source code directory
|
|
143
|
+
- Tests fail when run together but pass individually
|
|
144
|
+
- Side effects from one test affect another
|
|
145
|
+
- Cleanup code not running
|
|
146
|
+
|
|
147
|
+
### Manual Detection
|
|
148
|
+
|
|
149
|
+
**Check for artifacts after test run:**
|
|
150
|
+
```bash
|
|
151
|
+
# Before tests
|
|
152
|
+
ls -la src/
|
|
153
|
+
|
|
154
|
+
# Run tests
|
|
155
|
+
npm test
|
|
156
|
+
|
|
157
|
+
# After tests - did anything appear?
|
|
158
|
+
ls -la src/
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Common artifacts:**
|
|
162
|
+
- `.git` directories
|
|
163
|
+
- `node_modules/` subdirectories
|
|
164
|
+
- Temp files not cleaned up
|
|
165
|
+
- Config files created
|
|
166
|
+
- Log files
|
|
167
|
+
|
|
168
|
+
### Automated Detection with Bisection
|
|
169
|
+
|
|
170
|
+
Use the `find-polluter.sh` script to automatically find which test creates pollution:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
#!/bin/bash
|
|
174
|
+
# find-polluter.sh
|
|
175
|
+
# Usage: ./find-polluter.sh <artifact> <test-pattern>
|
|
176
|
+
# Example: ./find-polluter.sh '.git' 'src/**/*.test.ts'
|
|
177
|
+
|
|
178
|
+
ARTIFACT=$1
|
|
179
|
+
TEST_PATTERN=$2
|
|
180
|
+
|
|
181
|
+
if [ -z "$ARTIFACT" ] || [ -z "$TEST_PATTERN" ]; then
|
|
182
|
+
echo "Usage: $0 <artifact> <test-pattern>"
|
|
183
|
+
echo "Example: $0 '.git' 'src/**/*.test.ts'"
|
|
184
|
+
exit 1
|
|
185
|
+
fi
|
|
186
|
+
|
|
187
|
+
# Get list of test files
|
|
188
|
+
TEST_FILES=($(ls $TEST_PATTERN))
|
|
189
|
+
|
|
190
|
+
echo "Testing ${#TEST_FILES[@]} files for artifact: $ARTIFACT"
|
|
191
|
+
|
|
192
|
+
for test_file in "${TEST_FILES[@]}"; do
|
|
193
|
+
echo "Testing: $test_file"
|
|
194
|
+
|
|
195
|
+
# Remove artifact if exists
|
|
196
|
+
rm -rf "$ARTIFACT" 2>/dev/null
|
|
197
|
+
|
|
198
|
+
# Run single test file
|
|
199
|
+
npm test -- "$test_file"
|
|
200
|
+
|
|
201
|
+
# Check if artifact was created
|
|
202
|
+
if [ -e "$ARTIFACT" ]; then
|
|
203
|
+
echo "FOUND POLLUTER: $test_file"
|
|
204
|
+
exit 0
|
|
205
|
+
fi
|
|
206
|
+
done
|
|
207
|
+
|
|
208
|
+
echo "No polluter found"
|
|
209
|
+
exit 1
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**Usage:**
|
|
213
|
+
```bash
|
|
214
|
+
# Find which test creates .git directory
|
|
215
|
+
./find-polluter.sh '.git' 'src/**/*.test.ts'
|
|
216
|
+
|
|
217
|
+
# Find which test creates node_modules
|
|
218
|
+
./find-polluter.sh 'node_modules' 'src/**/*.test.ts'
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Advanced version with binary search:**
|
|
222
|
+
```bash
|
|
223
|
+
#!/bin/bash
|
|
224
|
+
# find-polluter-fast.sh - Uses binary search for faster detection
|
|
225
|
+
|
|
226
|
+
ARTIFACT=$1
|
|
227
|
+
TEST_PATTERN=$2
|
|
228
|
+
TEST_FILES=($(ls $TEST_PATTERN))
|
|
229
|
+
|
|
230
|
+
function test_files() {
|
|
231
|
+
local files=("$@")
|
|
232
|
+
rm -rf "$ARTIFACT" 2>/dev/null
|
|
233
|
+
npm test -- "${files[@]}"
|
|
234
|
+
[ -e "$ARTIFACT" ]
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function binary_search() {
|
|
238
|
+
local files=("$@")
|
|
239
|
+
local count=${#files[@]}
|
|
240
|
+
|
|
241
|
+
if [ $count -eq 0 ]; then
|
|
242
|
+
echo "No polluter found"
|
|
243
|
+
return 1
|
|
244
|
+
fi
|
|
245
|
+
|
|
246
|
+
if [ $count -eq 1 ]; then
|
|
247
|
+
if test_files "${files[@]}"; then
|
|
248
|
+
echo "FOUND POLLUTER: ${files[0]}"
|
|
249
|
+
return 0
|
|
250
|
+
fi
|
|
251
|
+
return 1
|
|
252
|
+
fi
|
|
253
|
+
|
|
254
|
+
# Split in half
|
|
255
|
+
local mid=$((count / 2))
|
|
256
|
+
local left=("${files[@]:0:mid}")
|
|
257
|
+
local right=("${files[@]:mid}")
|
|
258
|
+
|
|
259
|
+
# Test left half
|
|
260
|
+
if test_files "${left[@]}"; then
|
|
261
|
+
binary_search "${left[@]}"
|
|
262
|
+
else
|
|
263
|
+
binary_search "${right[@]}"
|
|
264
|
+
fi
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
binary_search "${TEST_FILES[@]}"
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Preventing Test Pollution
|
|
271
|
+
|
|
272
|
+
**Best practices:**
|
|
273
|
+
1. **Always use temp directories:**
|
|
274
|
+
```typescript
|
|
275
|
+
let tempDir: string;
|
|
276
|
+
|
|
277
|
+
beforeEach(() => {
|
|
278
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-'));
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
afterEach(() => {
|
|
282
|
+
fs.rmSync(tempDir, { recursive: true });
|
|
283
|
+
});
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
2. **Validate test isolation:**
|
|
287
|
+
```typescript
|
|
288
|
+
// Guard against operations outside temp dir
|
|
289
|
+
if (process.env.NODE_ENV === 'test') {
|
|
290
|
+
if (!directory.includes(os.tmpdir())) {
|
|
291
|
+
throw new Error(`Test safety: operation outside tmpdir: ${directory}`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
3. **Use cleanup verification:**
|
|
297
|
+
```typescript
|
|
298
|
+
afterEach(() => {
|
|
299
|
+
// Clean up
|
|
300
|
+
fs.rmSync(tempDir, { recursive: true });
|
|
301
|
+
|
|
302
|
+
// Verify no artifacts in source
|
|
303
|
+
const gitInSource = fs.existsSync(path.join(__dirname, '.git'));
|
|
304
|
+
if (gitInSource) {
|
|
305
|
+
throw new Error('Test pollution: .git created in source directory');
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Async Operation Tracing
|
|
311
|
+
|
|
312
|
+
### The Challenge
|
|
313
|
+
|
|
314
|
+
Async operations obscure call chains:
|
|
315
|
+
```typescript
|
|
316
|
+
async function a() {
|
|
317
|
+
await b();
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
async function b() {
|
|
321
|
+
await c();
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
async function c() {
|
|
325
|
+
throw new Error('Something failed');
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Stack trace might only show:
|
|
330
|
+
```
|
|
331
|
+
Error: Something failed
|
|
332
|
+
at c (file.ts:10)
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Missing the full chain: `a → b → c`
|
|
336
|
+
|
|
337
|
+
### Node.js Async Stack Traces
|
|
338
|
+
|
|
339
|
+
**Enable async stack traces:**
|
|
340
|
+
```bash
|
|
341
|
+
node --async-stack-traces test.js
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Or in code:
|
|
345
|
+
```typescript
|
|
346
|
+
// At application entry point
|
|
347
|
+
Error.stackTraceLimit = 50; // Capture deeper stacks
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
**In package.json:**
|
|
351
|
+
```json
|
|
352
|
+
{
|
|
353
|
+
"scripts": {
|
|
354
|
+
"test": "node --async-stack-traces ./node_modules/.bin/jest"
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Trace IDs for Async Operations
|
|
360
|
+
|
|
361
|
+
When multiple async operations interleave, use trace IDs:
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
import { randomUUID } from 'crypto';
|
|
365
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
366
|
+
|
|
367
|
+
const asyncLocalStorage = new AsyncLocalStorage();
|
|
368
|
+
|
|
369
|
+
function withTraceId<T>(fn: () => T): T {
|
|
370
|
+
const traceId = randomUUID();
|
|
371
|
+
return asyncLocalStorage.run({ traceId }, fn);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function getTraceId(): string {
|
|
375
|
+
const store = asyncLocalStorage.getStore() as { traceId: string };
|
|
376
|
+
return store?.traceId || 'no-trace-id';
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Usage
|
|
380
|
+
async function operationA() {
|
|
381
|
+
console.log(`[${getTraceId()}] Starting operation A`);
|
|
382
|
+
await operationB();
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
async function operationB() {
|
|
386
|
+
console.log(`[${getTraceId()}] Starting operation B`);
|
|
387
|
+
await operationC();
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Run with trace ID
|
|
391
|
+
await withTraceId(async () => {
|
|
392
|
+
await operationA();
|
|
393
|
+
});
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**Output:**
|
|
397
|
+
```
|
|
398
|
+
[abc-123] Starting operation A
|
|
399
|
+
[abc-123] Starting operation B
|
|
400
|
+
[abc-123] Starting operation C
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
All operations from same call chain have same trace ID.
|
|
404
|
+
|
|
405
|
+
### Debugging Race Conditions
|
|
406
|
+
|
|
407
|
+
**Problem:** Operations complete in wrong order, causing bugs.
|
|
408
|
+
|
|
409
|
+
**Solution: Add timing instrumentation:**
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
class TimingTracer {
|
|
413
|
+
private events: Array<{ time: number; event: string; data: any }> = [];
|
|
414
|
+
|
|
415
|
+
record(event: string, data: any = {}) {
|
|
416
|
+
this.events.push({
|
|
417
|
+
time: Date.now(),
|
|
418
|
+
event,
|
|
419
|
+
data
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
dump() {
|
|
424
|
+
const sorted = this.events.sort((a, b) => a.time - b.time);
|
|
425
|
+
console.error('=== Timing Trace ===');
|
|
426
|
+
let start = sorted[0]?.time || 0;
|
|
427
|
+
sorted.forEach(({ time, event, data }) => {
|
|
428
|
+
console.error(`+${time - start}ms: ${event}`, data);
|
|
429
|
+
start = time;
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Usage
|
|
435
|
+
const tracer = new TimingTracer();
|
|
436
|
+
|
|
437
|
+
async function operation() {
|
|
438
|
+
tracer.record('start');
|
|
439
|
+
|
|
440
|
+
const promise1 = async1().then(() => tracer.record('async1 done'));
|
|
441
|
+
const promise2 = async2().then(() => tracer.record('async2 done'));
|
|
442
|
+
|
|
443
|
+
await Promise.all([promise1, promise2]);
|
|
444
|
+
|
|
445
|
+
tracer.record('both done');
|
|
446
|
+
tracer.dump();
|
|
447
|
+
}
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
**Output shows operation order:**
|
|
451
|
+
```
|
|
452
|
+
=== Timing Trace ===
|
|
453
|
+
+0ms: start {}
|
|
454
|
+
+45ms: async2 done {}
|
|
455
|
+
+67ms: async1 done {}
|
|
456
|
+
+67ms: both done {}
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
Shows async2 completed before async1.
|
|
460
|
+
|
|
461
|
+
## Debugging Third-Party Libraries
|
|
462
|
+
|
|
463
|
+
### When Library Behavior is Unexpected
|
|
464
|
+
|
|
465
|
+
**Strategy:**
|
|
466
|
+
1. Verify you're using the API correctly
|
|
467
|
+
2. Check library version and changelog
|
|
468
|
+
3. Read library source code
|
|
469
|
+
4. Add instrumentation around library calls
|
|
470
|
+
|
|
471
|
+
### Wrapping Library Calls
|
|
472
|
+
|
|
473
|
+
```typescript
|
|
474
|
+
// Wrap library function to add tracing
|
|
475
|
+
import { originalFunction } from 'third-party-lib';
|
|
476
|
+
|
|
477
|
+
const tracedFunction = (...args: any[]) => {
|
|
478
|
+
console.error('Calling library function:', {
|
|
479
|
+
args,
|
|
480
|
+
stack: new Error().stack
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
const result = originalFunction(...args);
|
|
484
|
+
|
|
485
|
+
console.error('Library function result:', result);
|
|
486
|
+
|
|
487
|
+
return result;
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
// Use traced version
|
|
491
|
+
export { tracedFunction as originalFunction };
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Checking Library Source
|
|
495
|
+
|
|
496
|
+
**When to read library source:**
|
|
497
|
+
- Documentation is unclear
|
|
498
|
+
- Behavior differs from documentation
|
|
499
|
+
- Need to understand edge cases
|
|
500
|
+
- Debugging library bug
|
|
501
|
+
|
|
502
|
+
**How to read library source:**
|
|
503
|
+
```bash
|
|
504
|
+
# Find library location
|
|
505
|
+
npm ls third-party-lib
|
|
506
|
+
|
|
507
|
+
# View source
|
|
508
|
+
code node_modules/third-party-lib/src/
|
|
509
|
+
|
|
510
|
+
# Or on GitHub
|
|
511
|
+
open https://github.com/author/third-party-lib
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
## Environment-Specific Issues
|
|
515
|
+
|
|
516
|
+
### Capturing Environment Context
|
|
517
|
+
|
|
518
|
+
```typescript
|
|
519
|
+
function captureEnvironment() {
|
|
520
|
+
return {
|
|
521
|
+
nodeVersion: process.version,
|
|
522
|
+
platform: process.platform,
|
|
523
|
+
arch: process.arch,
|
|
524
|
+
cwd: process.cwd(),
|
|
525
|
+
env: {
|
|
526
|
+
NODE_ENV: process.env.NODE_ENV,
|
|
527
|
+
CI: process.env.CI,
|
|
528
|
+
// Add relevant env vars
|
|
529
|
+
},
|
|
530
|
+
memory: process.memoryUsage(),
|
|
531
|
+
uptime: process.uptime()
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// Log with every error
|
|
536
|
+
try {
|
|
537
|
+
riskyOperation();
|
|
538
|
+
} catch (error) {
|
|
539
|
+
console.error('Operation failed:', {
|
|
540
|
+
error,
|
|
541
|
+
environment: captureEnvironment(),
|
|
542
|
+
stack: error.stack
|
|
543
|
+
});
|
|
544
|
+
throw error;
|
|
545
|
+
}
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### Reproducing Production Issues Locally
|
|
549
|
+
|
|
550
|
+
**Techniques:**
|
|
551
|
+
1. **Match environment:**
|
|
552
|
+
```bash
|
|
553
|
+
nvm use <production-node-version>
|
|
554
|
+
export NODE_ENV=production
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
2. **Use production data (sanitized):**
|
|
558
|
+
```bash
|
|
559
|
+
# Dump production DB to local
|
|
560
|
+
pg_dump production_db | psql local_db
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
3. **Enable production logging locally:**
|
|
564
|
+
```typescript
|
|
565
|
+
if (process.env.DEBUG_PROD) {
|
|
566
|
+
logger.level = 'debug';
|
|
567
|
+
}
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
4. **Replay production requests:**
|
|
571
|
+
```typescript
|
|
572
|
+
// Log requests in production
|
|
573
|
+
app.use((req, res, next) => {
|
|
574
|
+
logger.info('Request', {
|
|
575
|
+
method: req.method,
|
|
576
|
+
url: req.url,
|
|
577
|
+
headers: req.headers,
|
|
578
|
+
body: req.body
|
|
579
|
+
});
|
|
580
|
+
next();
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
// Replay locally
|
|
584
|
+
const productionRequest = loadFromLogs();
|
|
585
|
+
await fetch('http://localhost:3000' + productionRequest.url, {
|
|
586
|
+
method: productionRequest.method,
|
|
587
|
+
headers: productionRequest.headers,
|
|
588
|
+
body: productionRequest.body
|
|
589
|
+
});
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
## Performance Profiling for Root Cause
|
|
593
|
+
|
|
594
|
+
Sometimes "bug" is performance issue. Trace to find bottleneck.
|
|
595
|
+
|
|
596
|
+
### Node.js Built-in Profiler
|
|
597
|
+
|
|
598
|
+
```bash
|
|
599
|
+
# Generate CPU profile
|
|
600
|
+
node --cpu-prof app.js
|
|
601
|
+
|
|
602
|
+
# Analyze with Chrome DevTools
|
|
603
|
+
open chrome://inspect
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
### Custom Performance Tracing
|
|
607
|
+
|
|
608
|
+
```typescript
|
|
609
|
+
class PerformanceTracer {
|
|
610
|
+
private timers = new Map<string, number>();
|
|
611
|
+
|
|
612
|
+
start(label: string) {
|
|
613
|
+
this.timers.set(label, Date.now());
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
end(label: string): number {
|
|
617
|
+
const start = this.timers.get(label);
|
|
618
|
+
if (!start) throw new Error(`No timer: ${label}`);
|
|
619
|
+
|
|
620
|
+
const duration = Date.now() - start;
|
|
621
|
+
console.log(`${label}: ${duration}ms`);
|
|
622
|
+
this.timers.delete(label);
|
|
623
|
+
return duration;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
async measure<T>(label: string, fn: () => T): Promise<T> {
|
|
627
|
+
this.start(label);
|
|
628
|
+
try {
|
|
629
|
+
return await fn();
|
|
630
|
+
} finally {
|
|
631
|
+
this.end(label);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// Usage
|
|
637
|
+
const tracer = new PerformanceTracer();
|
|
638
|
+
|
|
639
|
+
await tracer.measure('database query', async () => {
|
|
640
|
+
return await db.query('SELECT ...');
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
await tracer.measure('API call', async () => {
|
|
644
|
+
return await fetch('https://api.example.com');
|
|
645
|
+
});
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
**Output:**
|
|
649
|
+
```
|
|
650
|
+
database query: 1243ms ← BOTTLENECK FOUND
|
|
651
|
+
API call: 89ms
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
## Summary
|
|
655
|
+
|
|
656
|
+
**Stack traces:** Capture call chains with `new Error().stack`
|
|
657
|
+
**Test pollution:** Use bisection to find polluting tests
|
|
658
|
+
**Async tracing:** Use trace IDs and async stack traces
|
|
659
|
+
**Library issues:** Wrap calls, read source, verify API usage
|
|
660
|
+
**Environment issues:** Match production environment, replay requests
|
|
661
|
+
**Performance:** Profile to find bottlenecks
|
|
662
|
+
|
|
663
|
+
**When to use:**
|
|
664
|
+
- Manual tracing hits dead end
|
|
665
|
+
- Multiple async operations involved
|
|
666
|
+
- Test pollution occurring
|
|
667
|
+
- Race conditions or timing issues
|
|
668
|
+
- Need production-level debugging
|