@stackmemoryai/stackmemory 0.5.58 → 0.5.59
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.
- package/dist/cli/commands/search.js +20 -3
- package/dist/cli/commands/search.js.map +2 -2
- package/dist/core/database/sqlite-adapter.js +13 -3
- package/dist/core/database/sqlite-adapter.js.map +2 -2
- package/dist/core/errors/error-utils.js +208 -0
- package/dist/core/errors/error-utils.js.map +7 -0
- package/dist/core/errors/index.js +13 -4
- package/dist/core/errors/index.js.map +2 -2
- package/dist/core/merge/unified-merge-resolver.js +303 -0
- package/dist/core/merge/unified-merge-resolver.js.map +7 -0
- package/dist/core/monitoring/logger.js +61 -9
- package/dist/core/monitoring/logger.js.map +2 -2
- package/dist/core/security/index.js +35 -0
- package/dist/core/security/index.js.map +7 -0
- package/dist/core/security/input-sanitizer.js +321 -0
- package/dist/core/security/input-sanitizer.js.map +7 -0
- package/dist/integrations/linear/client.js +5 -1
- package/dist/integrations/linear/client.js.map +2 -2
- package/dist/integrations/mcp/remote-server.js +27 -36
- package/dist/integrations/mcp/remote-server.js.map +2 -2
- package/dist/integrations/mcp/server.js +44 -29
- package/dist/integrations/mcp/server.js.map +3 -3
- package/dist/scripts/benchmark-performance.js +48 -0
- package/dist/scripts/benchmark-performance.js.map +7 -0
- package/dist/scripts/check-redis.js +42 -0
- package/dist/scripts/check-redis.js.map +7 -0
- package/dist/scripts/initialize.js +116 -0
- package/dist/scripts/initialize.js.map +7 -0
- package/dist/scripts/list-linear-tasks.js +124 -0
- package/dist/scripts/list-linear-tasks.js.map +7 -0
- package/dist/scripts/measure-handoff-impact.js +340 -0
- package/dist/scripts/measure-handoff-impact.js.map +7 -0
- package/dist/scripts/query-chromadb.js +160 -0
- package/dist/scripts/query-chromadb.js.map +7 -0
- package/dist/scripts/show-linear-summary.js +119 -0
- package/dist/scripts/show-linear-summary.js.map +7 -0
- package/dist/scripts/simple-swarm-demo.js +90 -0
- package/dist/scripts/simple-swarm-demo.js.map +7 -0
- package/dist/scripts/status.js +155 -0
- package/dist/scripts/status.js.map +7 -0
- package/dist/scripts/test-chromadb-sync.js +192 -0
- package/dist/scripts/test-chromadb-sync.js.map +7 -0
- package/dist/scripts/test-ralph-iteration-fix.js +86 -0
- package/dist/scripts/test-ralph-iteration-fix.js.map +7 -0
- package/dist/scripts/test-ralph-iterations.js +121 -0
- package/dist/scripts/test-ralph-iterations.js.map +7 -0
- package/dist/scripts/test-redis-storage.js +389 -0
- package/dist/scripts/test-redis-storage.js.map +7 -0
- package/dist/scripts/test-simple-ralph-state-sync.js +115 -0
- package/dist/scripts/test-simple-ralph-state-sync.js.map +7 -0
- package/dist/scripts/test-swarm-fixes.js +125 -0
- package/dist/scripts/test-swarm-fixes.js.map +7 -0
- package/dist/scripts/test-swarm-tui.js +23 -0
- package/dist/scripts/test-swarm-tui.js.map +7 -0
- package/dist/scripts/test-tui-shortcuts.js +52 -0
- package/dist/scripts/test-tui-shortcuts.js.map +7 -0
- package/dist/scripts/validate-tui-shortcuts.js +60 -0
- package/dist/scripts/validate-tui-shortcuts.js.map +7 -0
- package/dist/src/agents/core/agent-task-manager.js +527 -0
- package/dist/src/agents/core/agent-task-manager.js.map +7 -0
- package/dist/src/agents/verifiers/base-verifier.js +133 -0
- package/dist/src/agents/verifiers/base-verifier.js.map +7 -0
- package/dist/src/agents/verifiers/formatter-verifier.js +130 -0
- package/dist/src/agents/verifiers/formatter-verifier.js.map +7 -0
- package/dist/src/agents/verifiers/llm-judge.js +252 -0
- package/dist/src/agents/verifiers/llm-judge.js.map +7 -0
- package/dist/src/cli/auto-detect.js +321 -0
- package/dist/src/cli/auto-detect.js.map +7 -0
- package/dist/src/cli/claude-sm-danger.js +21 -0
- package/dist/src/cli/claude-sm-danger.js.map +7 -0
- package/dist/src/cli/claude-sm.js +1156 -0
- package/dist/src/cli/claude-sm.js.map +7 -0
- package/dist/src/cli/codex-sm-danger.js +21 -0
- package/dist/src/cli/codex-sm-danger.js.map +7 -0
- package/dist/src/cli/codex-sm.js +349 -0
- package/dist/src/cli/codex-sm.js.map +7 -0
- package/dist/src/cli/commands/api.js +232 -0
- package/dist/src/cli/commands/api.js.map +7 -0
- package/dist/src/cli/commands/auto-background.js +180 -0
- package/dist/src/cli/commands/auto-background.js.map +7 -0
- package/dist/src/cli/commands/cleanup-processes.js +68 -0
- package/dist/src/cli/commands/cleanup-processes.js.map +7 -0
- package/dist/src/cli/commands/clear.js +202 -0
- package/dist/src/cli/commands/clear.js.map +7 -0
- package/dist/src/cli/commands/config.js +445 -0
- package/dist/src/cli/commands/config.js.map +7 -0
- package/dist/src/cli/commands/context-rehydrate.js +751 -0
- package/dist/src/cli/commands/context-rehydrate.js.map +7 -0
- package/dist/src/cli/commands/context.js +343 -0
- package/dist/src/cli/commands/context.js.map +7 -0
- package/dist/src/cli/commands/daemon.js +392 -0
- package/dist/src/cli/commands/daemon.js.map +7 -0
- package/dist/src/cli/commands/dashboard.js +210 -0
- package/dist/src/cli/commands/dashboard.js.map +7 -0
- package/dist/src/cli/commands/db.js +147 -0
- package/dist/src/cli/commands/db.js.map +7 -0
- package/dist/src/cli/commands/decision.js +266 -0
- package/dist/src/cli/commands/decision.js.map +7 -0
- package/dist/src/cli/commands/discovery.js +279 -0
- package/dist/src/cli/commands/discovery.js.map +7 -0
- package/dist/src/cli/commands/handoff.js +624 -0
- package/dist/src/cli/commands/handoff.js.map +7 -0
- package/dist/src/cli/commands/hooks.js +298 -0
- package/dist/src/cli/commands/hooks.js.map +7 -0
- package/dist/src/cli/commands/linear.js +529 -0
- package/dist/src/cli/commands/linear.js.map +7 -0
- package/dist/src/cli/commands/log.js +169 -0
- package/dist/src/cli/commands/log.js.map +7 -0
- package/dist/src/cli/commands/login.js +172 -0
- package/dist/src/cli/commands/login.js.map +7 -0
- package/dist/src/cli/commands/migrate.js +240 -0
- package/dist/src/cli/commands/migrate.js.map +7 -0
- package/dist/src/cli/commands/model.js +533 -0
- package/dist/src/cli/commands/model.js.map +7 -0
- package/dist/src/cli/commands/onboard.js +536 -0
- package/dist/src/cli/commands/onboard.js.map +7 -0
- package/dist/src/cli/commands/projects.js +199 -0
- package/dist/src/cli/commands/projects.js.map +7 -0
- package/dist/src/cli/commands/ralph.js +909 -0
- package/dist/src/cli/commands/ralph.js.map +7 -0
- package/dist/src/cli/commands/retrieval.js +248 -0
- package/dist/src/cli/commands/retrieval.js.map +7 -0
- package/dist/src/cli/commands/search.js +173 -0
- package/dist/src/cli/commands/search.js.map +7 -0
- package/dist/src/cli/commands/service.js +749 -0
- package/dist/src/cli/commands/service.js.map +7 -0
- package/dist/src/cli/commands/session.js +200 -0
- package/dist/src/cli/commands/session.js.map +7 -0
- package/dist/src/cli/commands/settings.js +306 -0
- package/dist/src/cli/commands/settings.js.map +7 -0
- package/dist/src/cli/commands/setup.js +701 -0
- package/dist/src/cli/commands/setup.js.map +7 -0
- package/dist/src/cli/commands/shell.js +249 -0
- package/dist/src/cli/commands/shell.js.map +7 -0
- package/dist/src/cli/commands/signup.js +50 -0
- package/dist/src/cli/commands/signup.js.map +7 -0
- package/dist/src/cli/commands/skills.js +470 -0
- package/dist/src/cli/commands/skills.js.map +7 -0
- package/dist/src/cli/commands/sms-notify.js +795 -0
- package/dist/src/cli/commands/sms-notify.js.map +7 -0
- package/dist/src/cli/commands/storage-tier.js +183 -0
- package/dist/src/cli/commands/storage-tier.js.map +7 -0
- package/dist/src/cli/commands/sweep.js +249 -0
- package/dist/src/cli/commands/sweep.js.map +7 -0
- package/dist/src/cli/commands/tasks.js +213 -0
- package/dist/src/cli/commands/tasks.js.map +7 -0
- package/dist/src/cli/commands/worktree.js +319 -0
- package/dist/src/cli/commands/worktree.js.map +7 -0
- package/dist/src/cli/index.js +594 -0
- package/dist/src/cli/index.js.map +7 -0
- package/dist/src/cli/opencode-sm.js +448 -0
- package/dist/src/cli/opencode-sm.js.map +7 -0
- package/dist/src/cli/utils/viewer.js +96 -0
- package/dist/src/cli/utils/viewer.js.map +7 -0
- package/dist/src/core/config/config-manager.js +398 -0
- package/dist/src/core/config/config-manager.js.map +7 -0
- package/dist/src/core/config/feature-flags.js +76 -0
- package/dist/src/core/config/feature-flags.js.map +7 -0
- package/dist/src/core/config/storage-config.js +115 -0
- package/dist/src/core/config/storage-config.js.map +7 -0
- package/dist/src/core/config/types.js +144 -0
- package/dist/src/core/config/types.js.map +7 -0
- package/dist/src/core/context/auto-context.js +80 -0
- package/dist/src/core/context/auto-context.js.map +7 -0
- package/dist/src/core/context/dual-stack-manager.js +870 -0
- package/dist/src/core/context/dual-stack-manager.js.map +7 -0
- package/dist/src/core/context/enhanced-rehydration.js +994 -0
- package/dist/src/core/context/enhanced-rehydration.js.map +7 -0
- package/dist/src/core/context/frame-database.js +479 -0
- package/dist/src/core/context/frame-database.js.map +7 -0
- package/dist/src/core/context/frame-digest.js +250 -0
- package/dist/src/core/context/frame-digest.js.map +7 -0
- package/dist/src/core/context/frame-handoff-manager.js +778 -0
- package/dist/src/core/context/frame-handoff-manager.js.map +7 -0
- package/dist/src/core/context/frame-lifecycle-hooks.js +119 -0
- package/dist/src/core/context/frame-lifecycle-hooks.js.map +7 -0
- package/dist/src/core/context/frame-recovery.js +302 -0
- package/dist/src/core/context/frame-recovery.js.map +7 -0
- package/dist/src/core/context/frame-stack.js +314 -0
- package/dist/src/core/context/frame-stack.js.map +7 -0
- package/dist/src/core/context/frame-types.js +5 -0
- package/dist/src/core/context/frame-types.js.map +7 -0
- package/dist/src/core/context/index.js +25 -0
- package/dist/src/core/context/index.js.map +7 -0
- package/dist/src/core/context/permission-manager.js +185 -0
- package/dist/src/core/context/permission-manager.js.map +7 -0
- package/dist/src/core/context/recursive-context-manager.js +592 -0
- package/dist/src/core/context/recursive-context-manager.js.map +7 -0
- package/dist/src/core/context/refactored-frame-manager.js +754 -0
- package/dist/src/core/context/refactored-frame-manager.js.map +7 -0
- package/dist/src/core/context/shared-context-layer.js +621 -0
- package/dist/src/core/context/shared-context-layer.js.map +7 -0
- package/dist/src/core/context/stack-merge-resolver.js +749 -0
- package/dist/src/core/context/stack-merge-resolver.js.map +7 -0
- package/dist/src/core/context/validation.js +130 -0
- package/dist/src/core/context/validation.js.map +7 -0
- package/dist/src/core/database/batch-operations.js +384 -0
- package/dist/src/core/database/batch-operations.js.map +7 -0
- package/dist/src/core/database/connection-pool.js +330 -0
- package/dist/src/core/database/connection-pool.js.map +7 -0
- package/dist/src/core/database/database-adapter.js +60 -0
- package/dist/src/core/database/database-adapter.js.map +7 -0
- package/dist/src/core/database/migration-manager.js +614 -0
- package/dist/src/core/database/migration-manager.js.map +7 -0
- package/dist/src/core/database/query-cache.js +298 -0
- package/dist/src/core/database/query-cache.js.map +7 -0
- package/dist/src/core/database/query-router.js +430 -0
- package/dist/src/core/database/query-router.js.map +7 -0
- package/dist/src/core/database/sqlite-adapter.js +738 -0
- package/dist/src/core/database/sqlite-adapter.js.map +7 -0
- package/dist/src/core/digest/enhanced-hybrid-digest.js +277 -0
- package/dist/src/core/digest/enhanced-hybrid-digest.js.map +7 -0
- package/dist/src/core/digest/frame-digest-integration.js +176 -0
- package/dist/src/core/digest/frame-digest-integration.js.map +7 -0
- package/dist/src/core/digest/hybrid-digest-generator.js +553 -0
- package/dist/src/core/digest/hybrid-digest-generator.js.map +7 -0
- package/dist/src/core/digest/index.js +9 -0
- package/dist/src/core/digest/index.js.map +7 -0
- package/dist/src/core/digest/types.js +25 -0
- package/dist/src/core/digest/types.js.map +7 -0
- package/dist/src/core/errors/error-utils.js +208 -0
- package/dist/src/core/errors/error-utils.js.map +7 -0
- package/dist/src/core/errors/index.js +521 -0
- package/dist/src/core/errors/index.js.map +7 -0
- package/dist/src/core/errors/recovery.js +269 -0
- package/dist/src/core/errors/recovery.js.map +7 -0
- package/dist/src/core/execution/parallel-executor.js +258 -0
- package/dist/src/core/execution/parallel-executor.js.map +7 -0
- package/dist/src/core/frame/workflow-templates.js +319 -0
- package/dist/src/core/frame/workflow-templates.js.map +7 -0
- package/dist/src/core/merge/conflict-detector.js +431 -0
- package/dist/src/core/merge/conflict-detector.js.map +7 -0
- package/dist/src/core/merge/index.js +9 -0
- package/dist/src/core/merge/index.js.map +7 -0
- package/dist/src/core/merge/resolution-engine.js +558 -0
- package/dist/src/core/merge/resolution-engine.js.map +7 -0
- package/dist/src/core/merge/stack-diff.js +532 -0
- package/dist/src/core/merge/stack-diff.js.map +7 -0
- package/dist/src/core/merge/types.js +5 -0
- package/dist/src/core/merge/types.js.map +7 -0
- package/dist/src/core/merge/unified-merge-resolver.js +303 -0
- package/dist/src/core/merge/unified-merge-resolver.js.map +7 -0
- package/dist/src/core/models/fallback-monitor.js +232 -0
- package/dist/src/core/models/fallback-monitor.js.map +7 -0
- package/dist/src/core/models/model-router.js +340 -0
- package/dist/src/core/models/model-router.js.map +7 -0
- package/dist/src/core/monitoring/error-handler.js +49 -0
- package/dist/src/core/monitoring/error-handler.js.map +7 -0
- package/dist/src/core/monitoring/logger.js +202 -0
- package/dist/src/core/monitoring/logger.js.map +7 -0
- package/dist/src/core/monitoring/metrics.js +172 -0
- package/dist/src/core/monitoring/metrics.js.map +7 -0
- package/dist/src/core/monitoring/progress-tracker.js +189 -0
- package/dist/src/core/monitoring/progress-tracker.js.map +7 -0
- package/dist/src/core/monitoring/session-monitor.js +300 -0
- package/dist/src/core/monitoring/session-monitor.js.map +7 -0
- package/dist/src/core/performance/context-cache.js +273 -0
- package/dist/src/core/performance/context-cache.js.map +7 -0
- package/dist/src/core/performance/index.js +11 -0
- package/dist/src/core/performance/index.js.map +7 -0
- package/dist/src/core/performance/lazy-context-loader.js +327 -0
- package/dist/src/core/performance/lazy-context-loader.js.map +7 -0
- package/dist/src/core/performance/monitor.js +221 -0
- package/dist/src/core/performance/monitor.js.map +7 -0
- package/dist/src/core/performance/optimized-frame-context.js +345 -0
- package/dist/src/core/performance/optimized-frame-context.js.map +7 -0
- package/dist/src/core/performance/performance-benchmark.js +277 -0
- package/dist/src/core/performance/performance-benchmark.js.map +7 -0
- package/dist/src/core/performance/performance-profiler.js +370 -0
- package/dist/src/core/performance/performance-profiler.js.map +7 -0
- package/dist/src/core/performance/streaming-jsonl-parser.js +195 -0
- package/dist/src/core/performance/streaming-jsonl-parser.js.map +7 -0
- package/dist/src/core/persistence/postgres-adapter.js +349 -0
- package/dist/src/core/persistence/postgres-adapter.js.map +7 -0
- package/dist/src/core/projects/project-isolation.js +201 -0
- package/dist/src/core/projects/project-isolation.js.map +7 -0
- package/dist/src/core/projects/project-manager.js +697 -0
- package/dist/src/core/projects/project-manager.js.map +7 -0
- package/dist/src/core/query/query-parser.js +370 -0
- package/dist/src/core/query/query-parser.js.map +7 -0
- package/dist/src/core/query/query-templates.js +321 -0
- package/dist/src/core/query/query-templates.js.map +7 -0
- package/dist/src/core/retrieval/context-retriever.js +479 -0
- package/dist/src/core/retrieval/context-retriever.js.map +7 -0
- package/dist/src/core/retrieval/index.js +8 -0
- package/dist/src/core/retrieval/index.js.map +7 -0
- package/dist/src/core/retrieval/llm-context-retrieval.js +613 -0
- package/dist/src/core/retrieval/llm-context-retrieval.js.map +7 -0
- package/dist/src/core/retrieval/llm-provider.js +151 -0
- package/dist/src/core/retrieval/llm-provider.js.map +7 -0
- package/dist/src/core/retrieval/retrieval-audit.js +236 -0
- package/dist/src/core/retrieval/retrieval-audit.js.map +7 -0
- package/dist/src/core/retrieval/summary-generator.js +589 -0
- package/dist/src/core/retrieval/summary-generator.js.map +7 -0
- package/dist/src/core/retrieval/types.js +21 -0
- package/dist/src/core/retrieval/types.js.map +7 -0
- package/dist/src/core/security/index.js +35 -0
- package/dist/src/core/security/index.js.map +7 -0
- package/dist/src/core/security/input-sanitizer.js +321 -0
- package/dist/src/core/security/input-sanitizer.js.map +7 -0
- package/dist/src/core/session/clear-survival.js +465 -0
- package/dist/src/core/session/clear-survival.js.map +7 -0
- package/dist/src/core/session/enhanced-handoff.js +792 -0
- package/dist/src/core/session/enhanced-handoff.js.map +7 -0
- package/dist/src/core/session/handoff-generator.js +343 -0
- package/dist/src/core/session/handoff-generator.js.map +7 -0
- package/dist/src/core/session/index.js +15 -0
- package/dist/src/core/session/index.js.map +7 -0
- package/dist/src/core/session/session-manager.js +347 -0
- package/dist/src/core/session/session-manager.js.map +7 -0
- package/dist/src/core/skills/index.js +7 -0
- package/dist/src/core/skills/index.js.map +7 -0
- package/dist/src/core/skills/skill-storage.js +764 -0
- package/dist/src/core/skills/skill-storage.js.map +7 -0
- package/dist/src/core/skills/types.js +193 -0
- package/dist/src/core/skills/types.js.map +7 -0
- package/dist/src/core/storage/chromadb-adapter.js +354 -0
- package/dist/src/core/storage/chromadb-adapter.js.map +7 -0
- package/dist/src/core/storage/infinite-storage.js +510 -0
- package/dist/src/core/storage/infinite-storage.js.map +7 -0
- package/dist/src/core/storage/remote-storage.js +489 -0
- package/dist/src/core/storage/remote-storage.js.map +7 -0
- package/dist/src/core/storage/two-tier-storage.js +766 -0
- package/dist/src/core/storage/two-tier-storage.js.map +7 -0
- package/dist/src/core/trace/cli-trace-wrapper.js +132 -0
- package/dist/src/core/trace/cli-trace-wrapper.js.map +7 -0
- package/dist/src/core/trace/db-trace-wrapper.js +247 -0
- package/dist/src/core/trace/db-trace-wrapper.js.map +7 -0
- package/dist/src/core/trace/debug-trace.js +417 -0
- package/dist/src/core/trace/debug-trace.js.map +7 -0
- package/dist/src/core/trace/index.js +109 -0
- package/dist/src/core/trace/index.js.map +7 -0
- package/dist/src/core/trace/linear-api-wrapper.js +178 -0
- package/dist/src/core/trace/linear-api-wrapper.js.map +7 -0
- package/dist/src/core/trace/trace-detector.js +528 -0
- package/dist/src/core/trace/trace-detector.js.map +7 -0
- package/dist/src/core/trace/trace-store.js +345 -0
- package/dist/src/core/trace/trace-store.js.map +7 -0
- package/dist/src/core/trace/types.js +77 -0
- package/dist/src/core/trace/types.js.map +7 -0
- package/dist/src/core/types.js +5 -0
- package/dist/src/core/types.js.map +7 -0
- package/dist/src/core/utils/async-mutex.js +114 -0
- package/dist/src/core/utils/async-mutex.js.map +7 -0
- package/dist/src/core/utils/compression.js +83 -0
- package/dist/src/core/utils/compression.js.map +7 -0
- package/dist/src/core/utils/update-checker.js +218 -0
- package/dist/src/core/utils/update-checker.js.map +7 -0
- package/dist/src/core/worktree/worktree-manager.js +465 -0
- package/dist/src/core/worktree/worktree-manager.js.map +7 -0
- package/dist/src/daemon/daemon-config.js +149 -0
- package/dist/src/daemon/daemon-config.js.map +7 -0
- package/dist/src/daemon/services/context-service.js +122 -0
- package/dist/src/daemon/services/context-service.js.map +7 -0
- package/dist/src/daemon/services/linear-service.js +136 -0
- package/dist/src/daemon/services/linear-service.js.map +7 -0
- package/dist/src/daemon/session-daemon.js +312 -0
- package/dist/src/daemon/session-daemon.js.map +7 -0
- package/dist/src/daemon/unified-daemon.js +276 -0
- package/dist/src/daemon/unified-daemon.js.map +7 -0
- package/dist/src/features/analytics/api/analytics-api.js +287 -0
- package/dist/src/features/analytics/api/analytics-api.js.map +7 -0
- package/dist/src/features/analytics/core/analytics-service.js +282 -0
- package/dist/src/features/analytics/core/analytics-service.js.map +7 -0
- package/dist/src/features/analytics/index.js +18 -0
- package/dist/src/features/analytics/index.js.map +7 -0
- package/dist/src/features/analytics/queries/metrics-queries.js +277 -0
- package/dist/src/features/analytics/queries/metrics-queries.js.map +7 -0
- package/dist/src/features/analytics/types/metrics.js +5 -0
- package/dist/src/features/analytics/types/metrics.js.map +7 -0
- package/dist/src/features/browser/browser-mcp.js +492 -0
- package/dist/src/features/browser/browser-mcp.js.map +7 -0
- package/dist/src/features/sweep/index.js +20 -0
- package/dist/src/features/sweep/index.js.map +7 -0
- package/dist/src/features/sweep/prediction-client.js +155 -0
- package/dist/src/features/sweep/prediction-client.js.map +7 -0
- package/dist/src/features/sweep/prompt-builder.js +85 -0
- package/dist/src/features/sweep/prompt-builder.js.map +7 -0
- package/dist/src/features/sweep/pty-wrapper.js +171 -0
- package/dist/src/features/sweep/pty-wrapper.js.map +7 -0
- package/dist/src/features/sweep/state-watcher.js +87 -0
- package/dist/src/features/sweep/state-watcher.js.map +7 -0
- package/dist/src/features/sweep/status-bar.js +88 -0
- package/dist/src/features/sweep/status-bar.js.map +7 -0
- package/dist/src/features/sweep/sweep-server-manager.js +226 -0
- package/dist/src/features/sweep/sweep-server-manager.js.map +7 -0
- package/dist/src/features/sweep/tab-interceptor.js +38 -0
- package/dist/src/features/sweep/tab-interceptor.js.map +7 -0
- package/dist/src/features/sweep/types.js +18 -0
- package/dist/src/features/sweep/types.js.map +7 -0
- package/dist/src/features/tasks/linear-task-manager.js +487 -0
- package/dist/src/features/tasks/linear-task-manager.js.map +7 -0
- package/dist/src/features/tasks/task-aware-context.js +410 -0
- package/dist/src/features/tasks/task-aware-context.js.map +7 -0
- package/dist/src/features/tui/simple-monitor.js +116 -0
- package/dist/src/features/tui/simple-monitor.js.map +7 -0
- package/dist/src/features/tui/swarm-monitor.js +648 -0
- package/dist/src/features/tui/swarm-monitor.js.map +7 -0
- package/dist/src/features/web/client/stores/task-store.js +26 -0
- package/dist/src/features/web/client/stores/task-store.js.map +7 -0
- package/dist/src/features/web/server/index.js +194 -0
- package/dist/src/features/web/server/index.js.map +7 -0
- package/dist/src/hooks/auto-background.js +151 -0
- package/dist/src/hooks/auto-background.js.map +7 -0
- package/dist/src/hooks/claude-code-whatsapp-hook.js +197 -0
- package/dist/src/hooks/claude-code-whatsapp-hook.js.map +7 -0
- package/dist/src/hooks/config.js +150 -0
- package/dist/src/hooks/config.js.map +7 -0
- package/dist/src/hooks/daemon.js +364 -0
- package/dist/src/hooks/daemon.js.map +7 -0
- package/dist/src/hooks/events.js +58 -0
- package/dist/src/hooks/events.js.map +7 -0
- package/dist/src/hooks/index.js +12 -0
- package/dist/src/hooks/index.js.map +7 -0
- package/dist/src/hooks/linear-task-picker.js +186 -0
- package/dist/src/hooks/linear-task-picker.js.map +7 -0
- package/dist/src/hooks/schemas.js +197 -0
- package/dist/src/hooks/schemas.js.map +7 -0
- package/dist/src/hooks/secure-fs.js +49 -0
- package/dist/src/hooks/secure-fs.js.map +7 -0
- package/dist/src/hooks/security-logger.js +155 -0
- package/dist/src/hooks/security-logger.js.map +7 -0
- package/dist/src/hooks/session-summary.js +222 -0
- package/dist/src/hooks/session-summary.js.map +7 -0
- package/dist/src/hooks/sms-action-runner.js +371 -0
- package/dist/src/hooks/sms-action-runner.js.map +7 -0
- package/dist/src/hooks/sms-notify.js +506 -0
- package/dist/src/hooks/sms-notify.js.map +7 -0
- package/dist/src/hooks/sms-watcher.js +93 -0
- package/dist/src/hooks/sms-watcher.js.map +7 -0
- package/dist/src/hooks/sms-webhook.js +555 -0
- package/dist/src/hooks/sms-webhook.js.map +7 -0
- package/dist/src/hooks/whatsapp-commands.js +479 -0
- package/dist/src/hooks/whatsapp-commands.js.map +7 -0
- package/dist/src/hooks/whatsapp-scheduler.js +317 -0
- package/dist/src/hooks/whatsapp-scheduler.js.map +7 -0
- package/dist/src/hooks/whatsapp-sync.js +409 -0
- package/dist/src/hooks/whatsapp-sync.js.map +7 -0
- package/dist/src/index.js +25 -0
- package/dist/src/index.js.map +7 -0
- package/dist/src/integrations/anthropic/client.js +263 -0
- package/dist/src/integrations/anthropic/client.js.map +7 -0
- package/dist/src/integrations/claude-code/agent-bridge.js +768 -0
- package/dist/src/integrations/claude-code/agent-bridge.js.map +7 -0
- package/dist/src/integrations/claude-code/enhanced-pre-clear-hooks.js +459 -0
- package/dist/src/integrations/claude-code/enhanced-pre-clear-hooks.js.map +7 -0
- package/dist/src/integrations/claude-code/lifecycle-hooks.js +254 -0
- package/dist/src/integrations/claude-code/lifecycle-hooks.js.map +7 -0
- package/dist/src/integrations/claude-code/post-task-hooks.js +545 -0
- package/dist/src/integrations/claude-code/post-task-hooks.js.map +7 -0
- package/dist/src/integrations/claude-code/subagent-client-stub.js +20 -0
- package/dist/src/integrations/claude-code/subagent-client-stub.js.map +7 -0
- package/dist/src/integrations/claude-code/subagent-client.js +511 -0
- package/dist/src/integrations/claude-code/subagent-client.js.map +7 -0
- package/dist/src/integrations/claude-code/task-coordinator.js +360 -0
- package/dist/src/integrations/claude-code/task-coordinator.js.map +7 -0
- package/dist/src/integrations/linear/auth.js +337 -0
- package/dist/src/integrations/linear/auth.js.map +7 -0
- package/dist/src/integrations/linear/auto-sync.js +258 -0
- package/dist/src/integrations/linear/auto-sync.js.map +7 -0
- package/dist/src/integrations/linear/client.js +634 -0
- package/dist/src/integrations/linear/client.js.map +7 -0
- package/dist/src/integrations/linear/config.js +130 -0
- package/dist/src/integrations/linear/config.js.map +7 -0
- package/dist/src/integrations/linear/migration.js +361 -0
- package/dist/src/integrations/linear/migration.js.map +7 -0
- package/dist/src/integrations/linear/oauth-server.js +454 -0
- package/dist/src/integrations/linear/oauth-server.js.map +7 -0
- package/dist/src/integrations/linear/rest-client.js +213 -0
- package/dist/src/integrations/linear/rest-client.js.map +7 -0
- package/dist/src/integrations/linear/sync-manager.js +236 -0
- package/dist/src/integrations/linear/sync-manager.js.map +7 -0
- package/dist/src/integrations/linear/sync-service.js +231 -0
- package/dist/src/integrations/linear/sync-service.js.map +7 -0
- package/dist/src/integrations/linear/sync.js +782 -0
- package/dist/src/integrations/linear/sync.js.map +7 -0
- package/dist/src/integrations/linear/types.js +5 -0
- package/dist/src/integrations/linear/types.js.map +7 -0
- package/dist/src/integrations/linear/unified-sync.js +589 -0
- package/dist/src/integrations/linear/unified-sync.js.map +7 -0
- package/dist/src/integrations/linear/webhook-handler.js +219 -0
- package/dist/src/integrations/linear/webhook-handler.js.map +7 -0
- package/dist/src/integrations/linear/webhook-server.js +218 -0
- package/dist/src/integrations/linear/webhook-server.js.map +7 -0
- package/dist/src/integrations/linear/webhook.js +291 -0
- package/dist/src/integrations/linear/webhook.js.map +7 -0
- package/dist/src/integrations/mcp/handlers/code-execution-handlers.js +266 -0
- package/dist/src/integrations/mcp/handlers/code-execution-handlers.js.map +7 -0
- package/dist/src/integrations/mcp/handlers/context-handlers.js +257 -0
- package/dist/src/integrations/mcp/handlers/context-handlers.js.map +7 -0
- package/dist/src/integrations/mcp/handlers/discovery-handlers.js +497 -0
- package/dist/src/integrations/mcp/handlers/discovery-handlers.js.map +7 -0
- package/dist/src/integrations/mcp/handlers/index.js +166 -0
- package/dist/src/integrations/mcp/handlers/index.js.map +7 -0
- package/dist/src/integrations/mcp/handlers/linear-handlers.js +247 -0
- package/dist/src/integrations/mcp/handlers/linear-handlers.js.map +7 -0
- package/dist/src/integrations/mcp/handlers/skill-handlers.js +529 -0
- package/dist/src/integrations/mcp/handlers/skill-handlers.js.map +7 -0
- package/dist/src/integrations/mcp/handlers/task-handlers.js +239 -0
- package/dist/src/integrations/mcp/handlers/task-handlers.js.map +7 -0
- package/dist/src/integrations/mcp/handlers/trace-handlers.js +308 -0
- package/dist/src/integrations/mcp/handlers/trace-handlers.js.map +7 -0
- package/dist/src/integrations/mcp/index.js +23 -0
- package/dist/src/integrations/mcp/index.js.map +7 -0
- package/dist/src/integrations/mcp/middleware/tool-scoring.js +356 -0
- package/dist/src/integrations/mcp/middleware/tool-scoring.js.map +7 -0
- package/dist/src/integrations/mcp/refactored-server.js +374 -0
- package/dist/src/integrations/mcp/refactored-server.js.map +7 -0
- package/dist/src/integrations/mcp/remote-server.js +682 -0
- package/dist/src/integrations/mcp/remote-server.js.map +7 -0
- package/dist/src/integrations/mcp/schemas.js +147 -0
- package/dist/src/integrations/mcp/schemas.js.map +7 -0
- package/dist/src/integrations/mcp/server.js +1975 -0
- package/dist/src/integrations/mcp/server.js.map +7 -0
- package/dist/src/integrations/mcp/tool-definitions-code.js +125 -0
- package/dist/src/integrations/mcp/tool-definitions-code.js.map +7 -0
- package/dist/src/integrations/mcp/tool-definitions.js +702 -0
- package/dist/src/integrations/mcp/tool-definitions.js.map +7 -0
- package/dist/src/integrations/ralph/bridge/ralph-stackmemory-bridge.js +860 -0
- package/dist/src/integrations/ralph/bridge/ralph-stackmemory-bridge.js.map +7 -0
- package/dist/src/integrations/ralph/context/context-budget-manager.js +301 -0
- package/dist/src/integrations/ralph/context/context-budget-manager.js.map +7 -0
- package/dist/src/integrations/ralph/context/stackmemory-context-loader.js +360 -0
- package/dist/src/integrations/ralph/context/stackmemory-context-loader.js.map +7 -0
- package/dist/src/integrations/ralph/coordination/enhanced-coordination.js +410 -0
- package/dist/src/integrations/ralph/coordination/enhanced-coordination.js.map +7 -0
- package/dist/src/integrations/ralph/index.js +18 -0
- package/dist/src/integrations/ralph/index.js.map +7 -0
- package/dist/src/integrations/ralph/learning/pattern-learner.js +401 -0
- package/dist/src/integrations/ralph/learning/pattern-learner.js.map +7 -0
- package/dist/src/integrations/ralph/lifecycle/iteration-lifecycle.js +448 -0
- package/dist/src/integrations/ralph/lifecycle/iteration-lifecycle.js.map +7 -0
- package/dist/src/integrations/ralph/monitoring/swarm-dashboard.js +294 -0
- package/dist/src/integrations/ralph/monitoring/swarm-dashboard.js.map +7 -0
- package/dist/src/integrations/ralph/monitoring/swarm-registry.js +108 -0
- package/dist/src/integrations/ralph/monitoring/swarm-registry.js.map +7 -0
- package/dist/src/integrations/ralph/orchestration/multi-loop-orchestrator.js +463 -0
- package/dist/src/integrations/ralph/orchestration/multi-loop-orchestrator.js.map +7 -0
- package/dist/src/integrations/ralph/patterns/compounding-engineering-pattern.js +400 -0
- package/dist/src/integrations/ralph/patterns/compounding-engineering-pattern.js.map +7 -0
- package/dist/src/integrations/ralph/patterns/extended-coherence-sessions.js +473 -0
- package/dist/src/integrations/ralph/patterns/extended-coherence-sessions.js.map +7 -0
- package/dist/src/integrations/ralph/patterns/oracle-worker-pattern.js +388 -0
- package/dist/src/integrations/ralph/patterns/oracle-worker-pattern.js.map +7 -0
- package/dist/src/integrations/ralph/performance/performance-optimizer.js +358 -0
- package/dist/src/integrations/ralph/performance/performance-optimizer.js.map +7 -0
- package/dist/src/integrations/ralph/recovery/crash-recovery.js +462 -0
- package/dist/src/integrations/ralph/recovery/crash-recovery.js.map +7 -0
- package/dist/src/integrations/ralph/state/state-reconciler.js +404 -0
- package/dist/src/integrations/ralph/state/state-reconciler.js.map +7 -0
- package/dist/src/integrations/ralph/swarm/git-workflow-manager.js +428 -0
- package/dist/src/integrations/ralph/swarm/git-workflow-manager.js.map +7 -0
- package/dist/src/integrations/ralph/swarm/swarm-coordinator.js +996 -0
- package/dist/src/integrations/ralph/swarm/swarm-coordinator.js.map +7 -0
- package/dist/src/integrations/ralph/types.js +5 -0
- package/dist/src/integrations/ralph/types.js.map +7 -0
- package/dist/src/integrations/ralph/visualization/ralph-debugger.js +585 -0
- package/dist/src/integrations/ralph/visualization/ralph-debugger.js.map +7 -0
- package/dist/src/mcp/stackmemory-mcp-server.js +554 -0
- package/dist/src/mcp/stackmemory-mcp-server.js.map +7 -0
- package/dist/src/middleware/exponential-rate-limiter.js +289 -0
- package/dist/src/middleware/exponential-rate-limiter.js.map +7 -0
- package/dist/src/models/user.model.js +358 -0
- package/dist/src/models/user.model.js.map +7 -0
- package/dist/src/servers/production/auth-middleware.js +528 -0
- package/dist/src/servers/production/auth-middleware.js.map +7 -0
- package/dist/src/services/config-service.js +65 -0
- package/dist/src/services/config-service.js.map +7 -0
- package/dist/src/services/context-service.js +194 -0
- package/dist/src/services/context-service.js.map +7 -0
- package/dist/src/skills/api-discovery.js +354 -0
- package/dist/src/skills/api-discovery.js.map +7 -0
- package/dist/src/skills/api-skill.js +475 -0
- package/dist/src/skills/api-skill.js.map +7 -0
- package/dist/src/skills/claude-skills.js +1061 -0
- package/dist/src/skills/claude-skills.js.map +7 -0
- package/dist/src/skills/dashboard-launcher.js +216 -0
- package/dist/src/skills/dashboard-launcher.js.map +7 -0
- package/dist/src/skills/recursive-agent-orchestrator.js +575 -0
- package/dist/src/skills/recursive-agent-orchestrator.js.map +7 -0
- package/dist/src/skills/repo-ingestion-skill.js +609 -0
- package/dist/src/skills/repo-ingestion-skill.js.map +7 -0
- package/dist/src/skills/unified-rlm-orchestrator.js +404 -0
- package/dist/src/skills/unified-rlm-orchestrator.js.map +7 -0
- package/dist/src/types/task.js +5 -0
- package/dist/src/types/task.js.map +7 -0
- package/dist/src/utils/env.js +50 -0
- package/dist/src/utils/env.js.map +7 -0
- package/dist/src/utils/formatting.js +62 -0
- package/dist/src/utils/formatting.js.map +7 -0
- package/dist/src/utils/process-cleanup.js +136 -0
- package/dist/src/utils/process-cleanup.js.map +7 -0
- package/package.json +3 -3
- package/scripts/initialize.ts +16 -7
- package/scripts/install.sh +14 -62
- package/scripts/status.ts +111 -46
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/core/performance/performance-benchmark.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Performance Benchmark Suite\n * Measure improvements from optimization efforts\n */\n\nimport { performance } from 'perf_hooks';\nimport { logger } from '../monitoring/logger.js';\nimport { StreamingJSONLParser } from './streaming-jsonl-parser.js';\nimport { ContextCache } from './context-cache.js';\nimport { LazyContextLoader } from './lazy-context-loader.js';\nimport { readFileSync } from 'fs';\nimport { join } from 'path';\n\nexport interface BenchmarkResult {\n name: string;\n duration: number;\n memoryUsed: number;\n itemsProcessed: number;\n throughput: number;\n improvement?: number;\n}\n\nexport interface BenchmarkSuite {\n name: string;\n results: BenchmarkResult[];\n totalDuration: number;\n averageImprovement: number;\n}\n\nexport class PerformanceBenchmark {\n private results: BenchmarkResult[] = [];\n\n /**\n * Benchmark JSONL parsing performance\n */\n async benchmarkJSONLParsing(\n filePath: string,\n iterations = 3\n ): Promise<BenchmarkResult> {\n const parser = new StreamingJSONLParser();\n\n // Baseline: traditional sync parsing\n const baselineStart = performance.now();\n const baselineMemStart = process.memoryUsage().heapUsed;\n\n let baselineCount = 0;\n for (let i = 0; i < iterations; i++) {\n const content = readFileSync(filePath, 'utf8');\n const lines = content.split('\\n').filter((l: any) => l.trim());\n for (const line of lines) {\n try {\n JSON.parse(line);\n baselineCount++;\n } catch {}\n }\n }\n\n const baselineDuration = performance.now() - baselineStart;\n const baselineMemUsed = process.memoryUsage().heapUsed - baselineMemStart;\n\n // Optimized: streaming parser\n const optimizedStart = performance.now();\n const optimizedMemStart = process.memoryUsage().heapUsed;\n\n let optimizedCount = 0;\n for (let i = 0; i < iterations; i++) {\n for await (const batch of parser.parseStream(filePath)) {\n optimizedCount += batch.length;\n }\n }\n\n const optimizedDuration = performance.now() - optimizedStart;\n const optimizedMemUsed = process.memoryUsage().heapUsed - optimizedMemStart;\n\n const improvement =\n ((baselineDuration - optimizedDuration) / baselineDuration) * 100;\n const memImprovement =\n ((baselineMemUsed - optimizedMemUsed) / baselineMemUsed) * 100;\n\n const result: BenchmarkResult = {\n name: 'JSONL Parsing',\n duration: optimizedDuration / iterations,\n memoryUsed: optimizedMemUsed,\n itemsProcessed: optimizedCount / iterations,\n throughput:\n optimizedCount / iterations / (optimizedDuration / 1000 / iterations),\n improvement,\n };\n\n logger.info('JSONL Parsing Benchmark', {\n baseline: {\n duration: baselineDuration / iterations,\n memory: baselineMemUsed,\n throughput:\n baselineCount / iterations / (baselineDuration / 1000 / iterations),\n },\n optimized: result,\n improvements: {\n speed: `${improvement.toFixed(1)}%`,\n memory: `${memImprovement.toFixed(1)}%`,\n },\n });\n\n this.results.push(result);\n return result;\n }\n\n /**\n * Benchmark context caching performance\n */\n async benchmarkContextCache(\n itemCount = 1000,\n accessPatterns = 10000\n ): Promise<BenchmarkResult> {\n const cache = new ContextCache<any>({\n maxSize: 50 * 1024 * 1024,\n maxItems: itemCount,\n });\n\n // Prepare test data\n const testData = Array.from({ length: itemCount }, (_, i) => ({\n key: `item-${i}`,\n value: {\n id: i,\n data: 'x'.repeat(Math.floor(Math.random() * 1000)),\n timestamp: Date.now(),\n },\n }));\n\n // Populate cache\n const populateStart = performance.now();\n for (const item of testData) {\n cache.set(item.key, item.value);\n }\n const populateDuration = performance.now() - populateStart;\n\n // Benchmark cache access\n const accessStart = performance.now();\n let hits = 0;\n let misses = 0;\n\n for (let i = 0; i < accessPatterns; i++) {\n const index = Math.floor(Math.random() * itemCount * 1.2); // Some will miss\n const key = `item-${index}`;\n const result = cache.get(key);\n if (result) hits++;\n else misses++;\n }\n\n const accessDuration = performance.now() - accessStart;\n const stats = cache.getStats();\n\n const result: BenchmarkResult = {\n name: 'Context Cache',\n duration: accessDuration,\n memoryUsed: cache.getSize().bytes,\n itemsProcessed: accessPatterns,\n throughput: accessPatterns / (accessDuration / 1000),\n improvement: stats.hitRate * 100,\n };\n\n logger.info('Context Cache Benchmark', {\n populate: {\n duration: populateDuration,\n items: itemCount,\n },\n access: {\n duration: accessDuration,\n patterns: accessPatterns,\n hitRate: `${(stats.hitRate * 100).toFixed(1)}%`,\n },\n performance: {\n throughput: `${result.throughput.toFixed(0)} ops/sec`,\n avgAccessTime: `${stats.avgAccessTime.toFixed(2)}ms`,\n },\n });\n\n this.results.push(result);\n return result;\n }\n\n /**\n * Benchmark lazy loading performance\n */\n async benchmarkLazyLoading(\n db: any,\n projectId: string,\n frameCount = 100\n ): Promise<BenchmarkResult> {\n const loader = new LazyContextLoader(db, projectId);\n\n // Check if frames table exists, if not use a mock test\n let frames: any[] = [];\n try {\n frames = db\n .prepare('SELECT id FROM frames ORDER BY updated_at DESC LIMIT ?')\n .all(frameCount) as any[];\n } catch (error: unknown) {\n // Create mock frame IDs if table doesn't exist\n logger.warn('Frames table not found, using mock data for benchmark');\n frames = Array.from({ length: Math.min(frameCount, 10) }, (_, i) => ({\n id: `frame-${i}`,\n }));\n }\n\n const frameIds = frames.map((f: any) => f.id);\n\n // Benchmark eager loading (baseline)\n const eagerStart = performance.now();\n const eagerMemStart = process.memoryUsage().heapUsed;\n\n const eagerData = [];\n for (const id of frameIds) {\n try {\n const frame = db.prepare('SELECT * FROM frames WHERE id = ?').get(id);\n const anchors = db\n .prepare('SELECT * FROM anchors WHERE frame_id = ?')\n .all(id);\n const events = db\n .prepare('SELECT * FROM events WHERE frame_id = ? LIMIT 10')\n .all(id);\n eagerData.push({ frame, anchors, events });\n } catch {\n // Use mock data if tables don't exist\n eagerData.push({\n frame: { id, type: 'mock', name: `Mock ${id}` },\n anchors: [],\n events: [],\n });\n }\n }\n\n const eagerDuration = performance.now() - eagerStart;\n const eagerMemUsed = process.memoryUsage().heapUsed - eagerMemStart;\n\n // Benchmark lazy loading\n const lazyStart = performance.now();\n const lazyMemStart = process.memoryUsage().heapUsed;\n\n // Preload with lazy loading\n await loader.preloadContext(frameIds, { parallel: true, depth: 2 });\n\n // Access data lazily\n let accessedCount = 0;\n for (const id of frameIds.slice(0, frameCount / 2)) {\n const frame = await loader.lazyFrame(id).get();\n if (frame) accessedCount++;\n }\n\n const lazyDuration = performance.now() - lazyStart;\n const lazyMemUsed = process.memoryUsage().heapUsed - lazyMemStart;\n\n const improvement = ((eagerDuration - lazyDuration) / eagerDuration) * 100;\n const memImprovement = ((eagerMemUsed - lazyMemUsed) / eagerMemUsed) * 100;\n\n const result: BenchmarkResult = {\n name: 'Lazy Loading',\n duration: lazyDuration,\n memoryUsed: lazyMemUsed,\n itemsProcessed: frameCount,\n throughput: frameCount / (lazyDuration / 1000),\n improvement,\n };\n\n logger.info('Lazy Loading Benchmark', {\n eager: {\n duration: eagerDuration,\n memory: eagerMemUsed,\n },\n lazy: {\n duration: lazyDuration,\n memory: lazyMemUsed,\n accessed: accessedCount,\n },\n improvements: {\n speed: `${improvement.toFixed(1)}%`,\n memory: `${memImprovement.toFixed(1)}%`,\n },\n });\n\n this.results.push(result);\n return result;\n }\n\n /**\n * Run full benchmark suite\n */\n async runFullSuite(\n projectRoot: string,\n db: any,\n projectId: string\n ): Promise<BenchmarkSuite> {\n const suiteStart = performance.now();\n\n logger.info('Starting Performance Benchmark Suite');\n\n // Run benchmarks\n const tasksFile = join(projectRoot, '.stackmemory', 'tasks.jsonl');\n\n const jsonlResult = await this.benchmarkJSONLParsing(tasksFile);\n const cacheResult = await this.benchmarkContextCache();\n const lazyResult = await this.benchmarkLazyLoading(db, projectId);\n\n const totalDuration = performance.now() - suiteStart;\n const averageImprovement =\n this.results\n .filter((r: any) => r.improvement !== undefined)\n .reduce((sum, r) => sum + (r.improvement || 0), 0) /\n this.results.filter((r: any) => r.improvement !== undefined).length;\n\n const suite: BenchmarkSuite = {\n name: 'Performance Optimization Suite',\n results: this.results,\n totalDuration,\n averageImprovement,\n };\n\n // Generate summary report\n this.generateReport(suite);\n\n return suite;\n }\n\n /**\n * Generate performance report\n */\n private generateReport(suite: BenchmarkSuite): void {\n console.log('\\n\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557');\n console.log('\u2551 Performance Benchmark Results \u2551');\n console.log('\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D\\n');\n\n for (const result of suite.results) {\n console.log(`\uD83D\uDCCA ${result.name}`);\n console.log(` Duration: ${result.duration.toFixed(2)}ms`);\n console.log(\n ` Memory: ${(result.memoryUsed / 1024 / 1024).toFixed(2)}MB`\n );\n console.log(` Throughput: ${result.throughput.toFixed(0)} items/sec`);\n if (result.improvement !== undefined) {\n const icon = result.improvement > 0 ? '\uD83D\uDE80' : '\u26A0\uFE0F';\n console.log(\n ` ${icon} Improvement: ${result.improvement.toFixed(1)}%`\n );\n }\n console.log('');\n }\n\n console.log('\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550');\n console.log(`\u23F1\uFE0F Total Duration: ${suite.totalDuration.toFixed(2)}ms`);\n console.log(\n `\uD83D\uDCC8 Average Improvement: ${suite.averageImprovement.toFixed(1)}%`\n );\n console.log('');\n\n logger.info('Performance Benchmark Complete', {\n suite: suite.name,\n duration: suite.totalDuration,\n avgImprovement: suite.averageImprovement,\n results: suite.results.map((r: any) => ({\n name: r.name,\n improvement: r.improvement,\n throughput: r.throughput,\n })),\n });\n }\n\n /**\n * Get benchmark results\n */\n getResults(): BenchmarkResult[] {\n return this.results;\n }\n\n /**\n * Clear results\n */\n clearResults(): void {\n this.results = [];\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["result"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
2
|
+
import { dirname as __pathDirname } from 'path';
|
|
3
|
+
const __filename = __fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = __pathDirname(__filename);
|
|
5
|
+
import { logger } from "../monitoring/logger.js";
|
|
6
|
+
import { getQueryStatistics } from "../trace/db-trace-wrapper.js";
|
|
7
|
+
function getEnv(key, defaultValue) {
|
|
8
|
+
const value = process.env[key];
|
|
9
|
+
if (value === void 0) {
|
|
10
|
+
if (defaultValue !== void 0) return defaultValue;
|
|
11
|
+
throw new Error(`Environment variable ${key} is required`);
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
function getOptionalEnv(key) {
|
|
16
|
+
return process.env[key];
|
|
17
|
+
}
|
|
18
|
+
class PerformanceProfiler {
|
|
19
|
+
metrics = /* @__PURE__ */ new Map();
|
|
20
|
+
hotPaths = /* @__PURE__ */ new Map();
|
|
21
|
+
samples = /* @__PURE__ */ new Map();
|
|
22
|
+
isEnabled = true;
|
|
23
|
+
sampleLimit = 1e3;
|
|
24
|
+
hotPathThreshold = 5;
|
|
25
|
+
// Operations taking > 5ms are considered hot
|
|
26
|
+
constructor(options = {}) {
|
|
27
|
+
this.isEnabled = options.enabled ?? true;
|
|
28
|
+
this.sampleLimit = options.sampleLimit ?? 1e3;
|
|
29
|
+
this.hotPathThreshold = options.hotPathThreshold ?? 5;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Start timing an operation
|
|
33
|
+
*/
|
|
34
|
+
startTiming(operationName) {
|
|
35
|
+
if (!this.isEnabled) {
|
|
36
|
+
return () => {
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const startTime = performance.now();
|
|
40
|
+
return (metadata) => {
|
|
41
|
+
this.endTiming(operationName, startTime, metadata);
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Time a function execution
|
|
46
|
+
*/
|
|
47
|
+
async timeFunction(operationName, fn, metadata) {
|
|
48
|
+
if (!this.isEnabled) {
|
|
49
|
+
return await fn();
|
|
50
|
+
}
|
|
51
|
+
const endTimer = this.startTiming(operationName);
|
|
52
|
+
try {
|
|
53
|
+
const result = await fn();
|
|
54
|
+
endTimer(metadata);
|
|
55
|
+
return result;
|
|
56
|
+
} catch (error) {
|
|
57
|
+
endTimer({ ...metadata, error: true });
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Record timing manually
|
|
63
|
+
*/
|
|
64
|
+
recordTiming(operationName, durationMs, metadata) {
|
|
65
|
+
if (!this.isEnabled) return;
|
|
66
|
+
this.endTiming(operationName, performance.now() - durationMs, metadata);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get performance metrics for an operation
|
|
70
|
+
*/
|
|
71
|
+
getMetrics(operationName) {
|
|
72
|
+
return this.metrics.get(operationName);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get all performance metrics
|
|
76
|
+
*/
|
|
77
|
+
getAllMetrics() {
|
|
78
|
+
return new Map(this.metrics);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get hot paths sorted by impact
|
|
82
|
+
*/
|
|
83
|
+
getHotPaths(limit = 10) {
|
|
84
|
+
return Array.from(this.hotPaths.values()).sort((a, b) => b.frequency * b.avgDuration - a.frequency * a.avgDuration).slice(0, limit);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Generate comprehensive performance report
|
|
88
|
+
*/
|
|
89
|
+
generateReport(db) {
|
|
90
|
+
const hotPaths = this.getHotPaths(20);
|
|
91
|
+
const recommendations = this.generateRecommendations(hotPaths);
|
|
92
|
+
const report = {
|
|
93
|
+
timestamp: Date.now(),
|
|
94
|
+
hotPaths,
|
|
95
|
+
databaseMetrics: db ? getQueryStatistics(db) : null,
|
|
96
|
+
memoryUsage: process.memoryUsage(),
|
|
97
|
+
cacheMetrics: null,
|
|
98
|
+
// Will be filled by query cache if available
|
|
99
|
+
recommendations
|
|
100
|
+
};
|
|
101
|
+
logger.info("Performance report generated", {
|
|
102
|
+
hotPathsCount: hotPaths.length,
|
|
103
|
+
recommendationsCount: recommendations.length,
|
|
104
|
+
topHotPath: hotPaths[0]?.path
|
|
105
|
+
});
|
|
106
|
+
return report;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Reset all metrics
|
|
110
|
+
*/
|
|
111
|
+
reset() {
|
|
112
|
+
this.metrics.clear();
|
|
113
|
+
this.hotPaths.clear();
|
|
114
|
+
this.samples.clear();
|
|
115
|
+
logger.info("Performance metrics reset");
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Export metrics to JSON
|
|
119
|
+
*/
|
|
120
|
+
exportMetrics() {
|
|
121
|
+
const data = {
|
|
122
|
+
timestamp: Date.now(),
|
|
123
|
+
metrics: Object.fromEntries(this.metrics),
|
|
124
|
+
hotPaths: Object.fromEntries(this.hotPaths),
|
|
125
|
+
config: {
|
|
126
|
+
sampleLimit: this.sampleLimit,
|
|
127
|
+
hotPathThreshold: this.hotPathThreshold,
|
|
128
|
+
enabled: this.isEnabled
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
return JSON.stringify(data, null, 2);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Enable/disable profiling
|
|
135
|
+
*/
|
|
136
|
+
setEnabled(enabled) {
|
|
137
|
+
this.isEnabled = enabled;
|
|
138
|
+
logger.info(`Performance profiling ${enabled ? "enabled" : "disabled"}`);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* End timing for an operation
|
|
142
|
+
*/
|
|
143
|
+
endTiming(operationName, startTime, metadata) {
|
|
144
|
+
const duration = performance.now() - startTime;
|
|
145
|
+
const timestamp = Date.now();
|
|
146
|
+
this.updateMetrics(operationName, duration, timestamp);
|
|
147
|
+
if (duration > this.hotPathThreshold) {
|
|
148
|
+
this.trackHotPath(operationName, duration, timestamp, metadata);
|
|
149
|
+
}
|
|
150
|
+
this.storeSample(operationName, duration, timestamp, metadata);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Update performance metrics for an operation
|
|
154
|
+
*/
|
|
155
|
+
updateMetrics(operationName, duration, timestamp) {
|
|
156
|
+
const existing = this.metrics.get(operationName);
|
|
157
|
+
if (!existing) {
|
|
158
|
+
this.metrics.set(operationName, {
|
|
159
|
+
operationName,
|
|
160
|
+
callCount: 1,
|
|
161
|
+
totalTimeMs: duration,
|
|
162
|
+
avgTimeMs: duration,
|
|
163
|
+
minTimeMs: duration,
|
|
164
|
+
maxTimeMs: duration,
|
|
165
|
+
p95TimeMs: duration,
|
|
166
|
+
lastExecuted: timestamp
|
|
167
|
+
});
|
|
168
|
+
} else {
|
|
169
|
+
existing.callCount++;
|
|
170
|
+
existing.totalTimeMs += duration;
|
|
171
|
+
existing.avgTimeMs = existing.totalTimeMs / existing.callCount;
|
|
172
|
+
existing.minTimeMs = Math.min(existing.minTimeMs, duration);
|
|
173
|
+
existing.maxTimeMs = Math.max(existing.maxTimeMs, duration);
|
|
174
|
+
existing.lastExecuted = timestamp;
|
|
175
|
+
existing.p95TimeMs = this.calculateP95(operationName);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Track hot path
|
|
180
|
+
*/
|
|
181
|
+
trackHotPath(operationName, duration, timestamp, metadata) {
|
|
182
|
+
const existing = this.hotPaths.get(operationName);
|
|
183
|
+
if (!existing) {
|
|
184
|
+
this.hotPaths.set(operationName, {
|
|
185
|
+
path: operationName,
|
|
186
|
+
frequency: 1,
|
|
187
|
+
avgDuration: duration,
|
|
188
|
+
totalDuration: duration,
|
|
189
|
+
lastSeen: timestamp,
|
|
190
|
+
samples: [{ timestamp, duration, metadata }]
|
|
191
|
+
});
|
|
192
|
+
} else {
|
|
193
|
+
existing.frequency++;
|
|
194
|
+
existing.totalDuration += duration;
|
|
195
|
+
existing.avgDuration = existing.totalDuration / existing.frequency;
|
|
196
|
+
existing.lastSeen = timestamp;
|
|
197
|
+
existing.samples.push({ timestamp, duration, metadata });
|
|
198
|
+
if (existing.samples.length > 100) {
|
|
199
|
+
existing.samples = existing.samples.slice(-100);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Store performance sample
|
|
205
|
+
*/
|
|
206
|
+
storeSample(operationName, duration, timestamp, metadata) {
|
|
207
|
+
if (!this.samples.has(operationName)) {
|
|
208
|
+
this.samples.set(operationName, []);
|
|
209
|
+
}
|
|
210
|
+
const samples = this.samples.get(operationName);
|
|
211
|
+
samples.push({ timestamp, duration, metadata });
|
|
212
|
+
if (samples.length > this.sampleLimit) {
|
|
213
|
+
samples.splice(0, samples.length - this.sampleLimit);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Calculate 95th percentile from samples
|
|
218
|
+
*/
|
|
219
|
+
calculateP95(operationName) {
|
|
220
|
+
const samples = this.samples.get(operationName);
|
|
221
|
+
if (!samples || samples.length === 0) return 0;
|
|
222
|
+
const durations = samples.map((s) => s.duration).sort((a, b) => a - b);
|
|
223
|
+
const index = Math.floor(durations.length * 0.95);
|
|
224
|
+
return durations[index] || 0;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Generate optimization recommendations
|
|
228
|
+
*/
|
|
229
|
+
generateRecommendations(hotPaths) {
|
|
230
|
+
const recommendations = [];
|
|
231
|
+
for (const hotPath of hotPaths.slice(0, 5)) {
|
|
232
|
+
const impact = hotPath.frequency * hotPath.avgDuration;
|
|
233
|
+
if (hotPath.path.includes("getFrameContext") && hotPath.avgDuration > 10) {
|
|
234
|
+
recommendations.push(
|
|
235
|
+
`Consider caching frame context for ${hotPath.path} (avg: ${hotPath.avgDuration.toFixed(1)}ms)`
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
if (hotPath.path.includes("getFrameEvents") && hotPath.frequency > 100) {
|
|
239
|
+
recommendations.push(
|
|
240
|
+
`High frequency event queries detected in ${hotPath.path} (${hotPath.frequency} calls). Consider pagination or caching.`
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
if (hotPath.path.includes("bulkInsert") && hotPath.avgDuration > 50) {
|
|
244
|
+
recommendations.push(
|
|
245
|
+
`Slow bulk insertion in ${hotPath.path}. Consider increasing batch size or using prepared statements.`
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
if (impact > 1e3) {
|
|
249
|
+
recommendations.push(
|
|
250
|
+
`High impact operation: ${hotPath.path} (${impact.toFixed(0)}ms total impact). Consider optimization.`
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
const memUsage = process.memoryUsage();
|
|
255
|
+
if (memUsage.heapUsed / memUsage.heapTotal > 0.8) {
|
|
256
|
+
recommendations.push(
|
|
257
|
+
"High memory usage detected. Consider implementing cleanup routines or reducing cache sizes."
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
if (recommendations.length === 0) {
|
|
261
|
+
recommendations.push("No significant performance issues detected.");
|
|
262
|
+
}
|
|
263
|
+
return recommendations;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
let globalProfiler = null;
|
|
267
|
+
function getProfiler() {
|
|
268
|
+
if (!globalProfiler) {
|
|
269
|
+
globalProfiler = new PerformanceProfiler({
|
|
270
|
+
enabled: process.env["NODE_ENV"] !== "production" || process.env["STACKMEMORY_PROFILING"] === "true"
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
return globalProfiler;
|
|
274
|
+
}
|
|
275
|
+
async function timeOperation(operationName, fn, metadata) {
|
|
276
|
+
return getProfiler().timeFunction(operationName, fn, metadata);
|
|
277
|
+
}
|
|
278
|
+
function performanceMonitor(operationName) {
|
|
279
|
+
return function(target, propertyKey, descriptor) {
|
|
280
|
+
const originalMethod = descriptor.value;
|
|
281
|
+
const finalOperationName = operationName || `${target.constructor.name}.${propertyKey}`;
|
|
282
|
+
descriptor.value = async function(...args) {
|
|
283
|
+
return getProfiler().timeFunction(
|
|
284
|
+
finalOperationName,
|
|
285
|
+
() => originalMethod.apply(this, args)
|
|
286
|
+
);
|
|
287
|
+
};
|
|
288
|
+
return descriptor;
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
class StackMemoryPerformanceMonitor {
|
|
292
|
+
profiler = getProfiler();
|
|
293
|
+
/**
|
|
294
|
+
* Monitor frame operations
|
|
295
|
+
*/
|
|
296
|
+
monitorFrameOperations(frameManager) {
|
|
297
|
+
this.wrapMethod(frameManager, "getFrame", "FrameManager.getFrame");
|
|
298
|
+
this.wrapMethod(
|
|
299
|
+
frameManager,
|
|
300
|
+
"getFrameEvents",
|
|
301
|
+
"FrameManager.getFrameEvents"
|
|
302
|
+
);
|
|
303
|
+
this.wrapMethod(
|
|
304
|
+
frameManager,
|
|
305
|
+
"getFrameAnchors",
|
|
306
|
+
"FrameManager.getFrameAnchors"
|
|
307
|
+
);
|
|
308
|
+
this.wrapMethod(
|
|
309
|
+
frameManager,
|
|
310
|
+
"getHotStackContext",
|
|
311
|
+
"FrameManager.getHotStackContext"
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Monitor database operations
|
|
316
|
+
*/
|
|
317
|
+
monitorDatabaseOperations(db) {
|
|
318
|
+
const originalPrepare = db.prepare;
|
|
319
|
+
db.prepare = function(sql) {
|
|
320
|
+
const stmt = originalPrepare.call(this, sql);
|
|
321
|
+
return wrapStatement(stmt, sql);
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Wrap a method with performance monitoring
|
|
326
|
+
*/
|
|
327
|
+
wrapMethod(obj, methodName, operationName) {
|
|
328
|
+
const original = obj[methodName];
|
|
329
|
+
if (typeof original !== "function") return;
|
|
330
|
+
obj[methodName] = async function(...args) {
|
|
331
|
+
return getProfiler().timeFunction(
|
|
332
|
+
operationName,
|
|
333
|
+
() => original.apply(this, args)
|
|
334
|
+
);
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
function wrapStatement(stmt, sql) {
|
|
339
|
+
const operationName = `SQL.${sql.trim().split(" ")[0].toUpperCase()}`;
|
|
340
|
+
const originalRun = stmt.run;
|
|
341
|
+
const originalGet = stmt.get;
|
|
342
|
+
const originalAll = stmt.all;
|
|
343
|
+
stmt.run = function(...args) {
|
|
344
|
+
return getProfiler().timeFunction(
|
|
345
|
+
`${operationName}.run`,
|
|
346
|
+
() => originalRun.apply(this, args)
|
|
347
|
+
);
|
|
348
|
+
};
|
|
349
|
+
stmt.get = function(...args) {
|
|
350
|
+
return getProfiler().timeFunction(
|
|
351
|
+
`${operationName}.get`,
|
|
352
|
+
() => originalGet.apply(this, args)
|
|
353
|
+
);
|
|
354
|
+
};
|
|
355
|
+
stmt.all = function(...args) {
|
|
356
|
+
return getProfiler().timeFunction(
|
|
357
|
+
`${operationName}.all`,
|
|
358
|
+
() => originalAll.apply(this, args)
|
|
359
|
+
);
|
|
360
|
+
};
|
|
361
|
+
return stmt;
|
|
362
|
+
}
|
|
363
|
+
export {
|
|
364
|
+
PerformanceProfiler,
|
|
365
|
+
StackMemoryPerformanceMonitor,
|
|
366
|
+
getProfiler,
|
|
367
|
+
performanceMonitor,
|
|
368
|
+
timeOperation
|
|
369
|
+
};
|
|
370
|
+
//# sourceMappingURL=performance-profiler.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/core/performance/performance-profiler.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Performance Profiler\n * Identifies and optimizes hot paths in StackMemory operations\n */\n\nimport { logger } from '../monitoring/logger.js';\nimport { getQueryStatistics } from '../trace/db-trace-wrapper.js';\nimport Database from 'better-sqlite3';\n// Type-safe environment variable access\nfunction getEnv(key: string, defaultValue?: string): string {\n const value = process.env[key];\n if (value === undefined) {\n if (defaultValue !== undefined) return defaultValue;\n throw new Error(`Environment variable ${key} is required`);\n }\n return value;\n}\n\nfunction getOptionalEnv(key: string): string | undefined {\n return process.env[key];\n}\n\nexport interface PerformanceMetrics {\n operationName: string;\n callCount: number;\n totalTimeMs: number;\n avgTimeMs: number;\n minTimeMs: number;\n maxTimeMs: number;\n p95TimeMs: number;\n lastExecuted: number;\n}\n\nexport interface HotPath {\n path: string;\n frequency: number;\n avgDuration: number;\n totalDuration: number;\n lastSeen: number;\n samples: PerformanceSample[];\n}\n\nexport interface PerformanceSample {\n timestamp: number;\n duration: number;\n metadata?: Record<string, any>;\n}\n\nexport interface SystemPerformanceReport {\n timestamp: number;\n hotPaths: HotPath[];\n databaseMetrics: any;\n memoryUsage: {\n heapUsed: number;\n heapTotal: number;\n external: number;\n };\n cacheMetrics: any;\n recommendations: string[];\n}\n\n/**\n * Performance profiler with hot path detection\n */\nexport class PerformanceProfiler {\n private metrics = new Map<string, PerformanceMetrics>();\n private hotPaths = new Map<string, HotPath>();\n private samples = new Map<string, PerformanceSample[]>();\n private isEnabled = true;\n private sampleLimit = 1000;\n private hotPathThreshold = 5; // Operations taking > 5ms are considered hot\n\n constructor(\n options: {\n enabled?: boolean;\n sampleLimit?: number;\n hotPathThreshold?: number;\n } = {}\n ) {\n this.isEnabled = options.enabled ?? true;\n this.sampleLimit = options.sampleLimit ?? 1000;\n this.hotPathThreshold = options.hotPathThreshold ?? 5;\n }\n\n /**\n * Start timing an operation\n */\n startTiming(operationName: string): (metadata?: Record<string, any>) => void {\n if (!this.isEnabled) {\n return () => {}; // No-op\n }\n\n const startTime = performance.now();\n\n return (metadata?: Record<string, any>) => {\n this.endTiming(operationName, startTime, metadata);\n };\n }\n\n /**\n * Time a function execution\n */\n async timeFunction<T>(\n operationName: string,\n fn: () => T | Promise<T>,\n metadata?: Record<string, any>\n ): Promise<T> {\n if (!this.isEnabled) {\n return await fn();\n }\n\n const endTimer = this.startTiming(operationName);\n try {\n const result = await fn();\n endTimer(metadata);\n return result;\n } catch (error: unknown) {\n endTimer({ ...metadata, error: true });\n throw error;\n }\n }\n\n /**\n * Record timing manually\n */\n recordTiming(\n operationName: string,\n durationMs: number,\n metadata?: Record<string, any>\n ): void {\n if (!this.isEnabled) return;\n\n this.endTiming(operationName, performance.now() - durationMs, metadata);\n }\n\n /**\n * Get performance metrics for an operation\n */\n getMetrics(operationName: string): PerformanceMetrics | undefined {\n return this.metrics.get(operationName);\n }\n\n /**\n * Get all performance metrics\n */\n getAllMetrics(): Map<string, PerformanceMetrics> {\n return new Map(this.metrics);\n }\n\n /**\n * Get hot paths sorted by impact\n */\n getHotPaths(limit = 10): HotPath[] {\n return Array.from(this.hotPaths.values())\n .sort((a, b) => b.frequency * b.avgDuration - a.frequency * a.avgDuration)\n .slice(0, limit);\n }\n\n /**\n * Generate comprehensive performance report\n */\n generateReport(db?: Database.Database): SystemPerformanceReport {\n const hotPaths = this.getHotPaths(20);\n const recommendations = this.generateRecommendations(hotPaths);\n\n const report: SystemPerformanceReport = {\n timestamp: Date.now(),\n hotPaths,\n databaseMetrics: db ? getQueryStatistics(db) : null,\n memoryUsage: process.memoryUsage(),\n cacheMetrics: null, // Will be filled by query cache if available\n recommendations,\n };\n\n logger.info('Performance report generated', {\n hotPathsCount: hotPaths.length,\n recommendationsCount: recommendations.length,\n topHotPath: hotPaths[0]?.path,\n });\n\n return report;\n }\n\n /**\n * Reset all metrics\n */\n reset(): void {\n this.metrics.clear();\n this.hotPaths.clear();\n this.samples.clear();\n logger.info('Performance metrics reset');\n }\n\n /**\n * Export metrics to JSON\n */\n exportMetrics(): string {\n const data = {\n timestamp: Date.now(),\n metrics: Object.fromEntries(this.metrics),\n hotPaths: Object.fromEntries(this.hotPaths),\n config: {\n sampleLimit: this.sampleLimit,\n hotPathThreshold: this.hotPathThreshold,\n enabled: this.isEnabled,\n },\n };\n\n return JSON.stringify(data, null, 2);\n }\n\n /**\n * Enable/disable profiling\n */\n setEnabled(enabled: boolean): void {\n this.isEnabled = enabled;\n logger.info(`Performance profiling ${enabled ? 'enabled' : 'disabled'}`);\n }\n\n /**\n * End timing for an operation\n */\n private endTiming(\n operationName: string,\n startTime: number,\n metadata?: Record<string, any>\n ): void {\n const duration = performance.now() - startTime;\n const timestamp = Date.now();\n\n // Update metrics\n this.updateMetrics(operationName, duration, timestamp);\n\n // Track hot paths\n if (duration > this.hotPathThreshold) {\n this.trackHotPath(operationName, duration, timestamp, metadata);\n }\n\n // Store sample\n this.storeSample(operationName, duration, timestamp, metadata);\n }\n\n /**\n * Update performance metrics for an operation\n */\n private updateMetrics(\n operationName: string,\n duration: number,\n timestamp: number\n ): void {\n const existing = this.metrics.get(operationName);\n\n if (!existing) {\n this.metrics.set(operationName, {\n operationName,\n callCount: 1,\n totalTimeMs: duration,\n avgTimeMs: duration,\n minTimeMs: duration,\n maxTimeMs: duration,\n p95TimeMs: duration,\n lastExecuted: timestamp,\n });\n } else {\n existing.callCount++;\n existing.totalTimeMs += duration;\n existing.avgTimeMs = existing.totalTimeMs / existing.callCount;\n existing.minTimeMs = Math.min(existing.minTimeMs, duration);\n existing.maxTimeMs = Math.max(existing.maxTimeMs, duration);\n existing.lastExecuted = timestamp;\n\n // Update p95 from samples\n existing.p95TimeMs = this.calculateP95(operationName);\n }\n }\n\n /**\n * Track hot path\n */\n private trackHotPath(\n operationName: string,\n duration: number,\n timestamp: number,\n metadata?: Record<string, any>\n ): void {\n const existing = this.hotPaths.get(operationName);\n\n if (!existing) {\n this.hotPaths.set(operationName, {\n path: operationName,\n frequency: 1,\n avgDuration: duration,\n totalDuration: duration,\n lastSeen: timestamp,\n samples: [{ timestamp, duration, metadata }],\n });\n } else {\n existing.frequency++;\n existing.totalDuration += duration;\n existing.avgDuration = existing.totalDuration / existing.frequency;\n existing.lastSeen = timestamp;\n\n // Keep limited samples\n existing.samples.push({ timestamp, duration, metadata });\n if (existing.samples.length > 100) {\n existing.samples = existing.samples.slice(-100);\n }\n }\n }\n\n /**\n * Store performance sample\n */\n private storeSample(\n operationName: string,\n duration: number,\n timestamp: number,\n metadata?: Record<string, any>\n ): void {\n if (!this.samples.has(operationName)) {\n this.samples.set(operationName, []);\n }\n\n const samples = this.samples.get(operationName)!;\n samples.push({ timestamp, duration, metadata });\n\n // Limit samples to prevent memory growth\n if (samples.length > this.sampleLimit) {\n samples.splice(0, samples.length - this.sampleLimit);\n }\n }\n\n /**\n * Calculate 95th percentile from samples\n */\n private calculateP95(operationName: string): number {\n const samples = this.samples.get(operationName);\n if (!samples || samples.length === 0) return 0;\n\n const durations = samples.map((s: any) => s.duration).sort((a, b) => a - b);\n const index = Math.floor(durations.length * 0.95);\n return durations[index] || 0;\n }\n\n /**\n * Generate optimization recommendations\n */\n private generateRecommendations(hotPaths: HotPath[]): string[] {\n const recommendations: string[] = [];\n\n for (const hotPath of hotPaths.slice(0, 5)) {\n const impact = hotPath.frequency * hotPath.avgDuration;\n\n if (\n hotPath.path.includes('getFrameContext') &&\n hotPath.avgDuration > 10\n ) {\n recommendations.push(\n `Consider caching frame context for ${hotPath.path} (avg: ${hotPath.avgDuration.toFixed(1)}ms)`\n );\n }\n\n if (hotPath.path.includes('getFrameEvents') && hotPath.frequency > 100) {\n recommendations.push(\n `High frequency event queries detected in ${hotPath.path} (${hotPath.frequency} calls). Consider pagination or caching.`\n );\n }\n\n if (hotPath.path.includes('bulkInsert') && hotPath.avgDuration > 50) {\n recommendations.push(\n `Slow bulk insertion in ${hotPath.path}. Consider increasing batch size or using prepared statements.`\n );\n }\n\n if (impact > 1000) {\n recommendations.push(\n `High impact operation: ${hotPath.path} (${impact.toFixed(0)}ms total impact). Consider optimization.`\n );\n }\n }\n\n // Memory recommendations\n const memUsage = process.memoryUsage();\n if (memUsage.heapUsed / memUsage.heapTotal > 0.8) {\n recommendations.push(\n 'High memory usage detected. Consider implementing cleanup routines or reducing cache sizes.'\n );\n }\n\n if (recommendations.length === 0) {\n recommendations.push('No significant performance issues detected.');\n }\n\n return recommendations;\n }\n}\n\n// Global profiler instance\nlet globalProfiler: PerformanceProfiler | null = null;\n\n/**\n * Get or create global profiler\n */\nexport function getProfiler(): PerformanceProfiler {\n if (!globalProfiler) {\n globalProfiler = new PerformanceProfiler({\n enabled:\n process.env['NODE_ENV'] !== 'production' ||\n process.env['STACKMEMORY_PROFILING'] === 'true',\n });\n }\n return globalProfiler;\n}\n\n/**\n * Convenience function to time operations\n */\nexport async function timeOperation<T>(\n operationName: string,\n fn: () => T | Promise<T>,\n metadata?: Record<string, any>\n): Promise<T> {\n return getProfiler().timeFunction(operationName, fn, metadata);\n}\n\n/**\n * Create a performance monitoring decorator\n */\nexport function performanceMonitor(operationName?: string) {\n return function (\n target: any,\n propertyKey: string,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value;\n const finalOperationName =\n operationName || `${target.constructor.name}.${propertyKey}`;\n\n descriptor.value = async function (...args: any[]) {\n return getProfiler().timeFunction(finalOperationName, () =>\n originalMethod.apply(this, args)\n );\n };\n\n return descriptor;\n };\n}\n\n/**\n * Monitor specific StackMemory operations\n */\nexport class StackMemoryPerformanceMonitor {\n private profiler = getProfiler();\n\n /**\n * Monitor frame operations\n */\n monitorFrameOperations(frameManager: any): void {\n this.wrapMethod(frameManager, 'getFrame', 'FrameManager.getFrame');\n this.wrapMethod(\n frameManager,\n 'getFrameEvents',\n 'FrameManager.getFrameEvents'\n );\n this.wrapMethod(\n frameManager,\n 'getFrameAnchors',\n 'FrameManager.getFrameAnchors'\n );\n this.wrapMethod(\n frameManager,\n 'getHotStackContext',\n 'FrameManager.getHotStackContext'\n );\n }\n\n /**\n * Monitor database operations\n */\n monitorDatabaseOperations(db: Database.Database): void {\n const originalPrepare = db.prepare;\n db.prepare = function <T = any>(sql: string): Database.Statement<T[], T> {\n const stmt = originalPrepare.call(this, sql);\n return wrapStatement(stmt, sql);\n };\n }\n\n /**\n * Wrap a method with performance monitoring\n */\n private wrapMethod(\n obj: any,\n methodName: string,\n operationName: string\n ): void {\n const original = obj[methodName];\n if (typeof original !== 'function') return;\n\n obj[methodName] = async function (...args: any[]) {\n return getProfiler().timeFunction(operationName, () =>\n original.apply(this, args)\n );\n };\n }\n}\n\n/**\n * Wrap a database statement with performance monitoring\n */\nfunction wrapStatement(\n stmt: Database.Statement,\n sql: string\n): Database.Statement {\n const operationName = `SQL.${sql.trim().split(' ')[0].toUpperCase()}`;\n\n const originalRun = stmt.run;\n const originalGet = stmt.get;\n const originalAll = stmt.all;\n\n stmt.run = function (this: Database.Statement, ...args: any[]) {\n return getProfiler().timeFunction(`${operationName}.run`, () =>\n originalRun.apply(this, args)\n );\n } as any;\n\n stmt.get = function (this: Database.Statement, ...args: any[]) {\n return getProfiler().timeFunction(`${operationName}.get`, () =>\n originalGet.apply(this, args)\n );\n } as any;\n\n stmt.all = function (this: Database.Statement, ...args: any[]) {\n return getProfiler().timeFunction(`${operationName}.all`, () =>\n originalAll.apply(this, args)\n );\n } as any;\n\n return stmt;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
2
|
+
import { dirname as __pathDirname } from 'path';
|
|
3
|
+
const __filename = __fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = __pathDirname(__filename);
|
|
5
|
+
import { createReadStream } from "fs";
|
|
6
|
+
import { createInterface } from "readline";
|
|
7
|
+
import { Transform, pipeline } from "stream";
|
|
8
|
+
import { promisify } from "util";
|
|
9
|
+
import { logger } from "../monitoring/logger.js";
|
|
10
|
+
const pipelineAsync = promisify(pipeline);
|
|
11
|
+
class StreamingJSONLParser {
|
|
12
|
+
DEFAULT_BATCH_SIZE = 100;
|
|
13
|
+
DEFAULT_MAX_LINE_LENGTH = 1024 * 1024;
|
|
14
|
+
// 1MB per line
|
|
15
|
+
/**
|
|
16
|
+
* Stream-parse a JSONL file with batching and backpressure handling
|
|
17
|
+
*/
|
|
18
|
+
async *parseStream(filePath, options = {}) {
|
|
19
|
+
const {
|
|
20
|
+
batchSize = this.DEFAULT_BATCH_SIZE,
|
|
21
|
+
maxLineLength = this.DEFAULT_MAX_LINE_LENGTH,
|
|
22
|
+
filter,
|
|
23
|
+
transform,
|
|
24
|
+
onProgress
|
|
25
|
+
} = options;
|
|
26
|
+
const stream = createReadStream(filePath, {
|
|
27
|
+
encoding: "utf8",
|
|
28
|
+
highWaterMark: 64 * 1024
|
|
29
|
+
// 64KB chunks
|
|
30
|
+
});
|
|
31
|
+
const rl = createInterface({
|
|
32
|
+
input: stream,
|
|
33
|
+
crlfDelay: Infinity,
|
|
34
|
+
historySize: 0
|
|
35
|
+
// Disable history for memory efficiency
|
|
36
|
+
});
|
|
37
|
+
let batch = [];
|
|
38
|
+
let lineCount = 0;
|
|
39
|
+
let processedCount = 0;
|
|
40
|
+
let errorCount = 0;
|
|
41
|
+
try {
|
|
42
|
+
for await (const line of rl) {
|
|
43
|
+
lineCount++;
|
|
44
|
+
if (line.length > maxLineLength) {
|
|
45
|
+
logger.warn("Skipping oversized line", {
|
|
46
|
+
lineNumber: lineCount,
|
|
47
|
+
length: line.length,
|
|
48
|
+
maxLength: maxLineLength
|
|
49
|
+
});
|
|
50
|
+
errorCount++;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (!line.trim()) continue;
|
|
54
|
+
try {
|
|
55
|
+
let obj = JSON.parse(line);
|
|
56
|
+
if (filter && !filter(obj)) continue;
|
|
57
|
+
if (transform) obj = transform(obj);
|
|
58
|
+
batch.push(obj);
|
|
59
|
+
processedCount++;
|
|
60
|
+
if (batch.length >= batchSize) {
|
|
61
|
+
yield batch;
|
|
62
|
+
batch = [];
|
|
63
|
+
onProgress?.(processedCount);
|
|
64
|
+
}
|
|
65
|
+
} catch (parseError) {
|
|
66
|
+
errorCount++;
|
|
67
|
+
logger.debug("Failed to parse JSONL line", {
|
|
68
|
+
lineNumber: lineCount,
|
|
69
|
+
error: parseError,
|
|
70
|
+
preview: line.substring(0, 100)
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (batch.length > 0) {
|
|
75
|
+
yield batch;
|
|
76
|
+
onProgress?.(processedCount);
|
|
77
|
+
}
|
|
78
|
+
} finally {
|
|
79
|
+
rl.close();
|
|
80
|
+
stream.destroy();
|
|
81
|
+
logger.debug("JSONL parsing complete", {
|
|
82
|
+
filePath,
|
|
83
|
+
totalLines: lineCount,
|
|
84
|
+
processed: processedCount,
|
|
85
|
+
errors: errorCount
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Parse entire file into memory (use for smaller files)
|
|
91
|
+
*/
|
|
92
|
+
async parseAll(filePath, options = {}) {
|
|
93
|
+
const results = [];
|
|
94
|
+
for await (const batch of this.parseStream(filePath, {
|
|
95
|
+
...options,
|
|
96
|
+
batchSize: Number.MAX_SAFE_INTEGER
|
|
97
|
+
})) {
|
|
98
|
+
results.push(...batch);
|
|
99
|
+
}
|
|
100
|
+
return results;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Process JSONL file with a custom processor function
|
|
104
|
+
*/
|
|
105
|
+
async process(filePath, processor, options = {}) {
|
|
106
|
+
const results = [];
|
|
107
|
+
for await (const batch of this.parseStream(filePath, options)) {
|
|
108
|
+
const result = await processor(batch);
|
|
109
|
+
results.push(result);
|
|
110
|
+
}
|
|
111
|
+
return results;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Create a transform stream for JSONL parsing
|
|
115
|
+
*/
|
|
116
|
+
createTransformStream(options = {}) {
|
|
117
|
+
const {
|
|
118
|
+
filter,
|
|
119
|
+
transform,
|
|
120
|
+
maxLineLength = this.DEFAULT_MAX_LINE_LENGTH
|
|
121
|
+
} = options;
|
|
122
|
+
let buffer = "";
|
|
123
|
+
let lineCount = 0;
|
|
124
|
+
return new Transform({
|
|
125
|
+
objectMode: true,
|
|
126
|
+
transform(chunk, encoding, callback) {
|
|
127
|
+
buffer += chunk.toString();
|
|
128
|
+
const lines = buffer.split("\n");
|
|
129
|
+
buffer = lines.pop() || "";
|
|
130
|
+
for (const line of lines) {
|
|
131
|
+
lineCount++;
|
|
132
|
+
if (!line.trim()) continue;
|
|
133
|
+
if (line.length > maxLineLength) {
|
|
134
|
+
logger.warn("Skipping oversized line in transform", { lineCount });
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
let obj = JSON.parse(line);
|
|
139
|
+
if (filter && !filter(obj)) continue;
|
|
140
|
+
if (transform) obj = transform(obj);
|
|
141
|
+
this.push(obj);
|
|
142
|
+
} catch (error) {
|
|
143
|
+
logger.debug("Transform parse error", { lineCount, error });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
callback();
|
|
147
|
+
},
|
|
148
|
+
flush(callback) {
|
|
149
|
+
if (buffer.trim()) {
|
|
150
|
+
try {
|
|
151
|
+
let obj = JSON.parse(buffer);
|
|
152
|
+
if (!filter || filter(obj)) {
|
|
153
|
+
if (transform) obj = transform(obj);
|
|
154
|
+
this.push(obj);
|
|
155
|
+
}
|
|
156
|
+
} catch (error) {
|
|
157
|
+
logger.debug("Flush parse error", { error });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
callback();
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Count lines in JSONL file without parsing
|
|
166
|
+
*/
|
|
167
|
+
async countLines(filePath) {
|
|
168
|
+
const stream = createReadStream(filePath, { encoding: "utf8" });
|
|
169
|
+
const rl = createInterface({ input: stream, historySize: 0 });
|
|
170
|
+
let count = 0;
|
|
171
|
+
for await (const _ of rl) {
|
|
172
|
+
count++;
|
|
173
|
+
}
|
|
174
|
+
return count;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Sample random lines from JSONL file
|
|
178
|
+
*/
|
|
179
|
+
async *sampleLines(filePath, sampleRate, options = {}) {
|
|
180
|
+
if (sampleRate <= 0 || sampleRate > 1) {
|
|
181
|
+
throw new Error("Sample rate must be between 0 and 1");
|
|
182
|
+
}
|
|
183
|
+
for await (const batch of this.parseStream(filePath, options)) {
|
|
184
|
+
for (const item of batch) {
|
|
185
|
+
if (Math.random() < sampleRate) {
|
|
186
|
+
yield item;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
export {
|
|
193
|
+
StreamingJSONLParser
|
|
194
|
+
};
|
|
195
|
+
//# sourceMappingURL=streaming-jsonl-parser.js.map
|