@stackmemoryai/stackmemory 0.5.59 → 0.5.61
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/README.md +105 -1
- package/dist/src/cli/claude-sm.js +130 -50
- package/dist/src/cli/claude-sm.js.map +2 -2
- package/dist/src/cli/index.js +18 -3
- package/dist/src/cli/index.js.map +3 -3
- package/dist/src/core/extensions/custom-tools.js +567 -0
- package/dist/src/core/extensions/custom-tools.js.map +7 -0
- package/dist/src/core/extensions/index.js +55 -0
- package/dist/src/core/extensions/index.js.map +7 -0
- package/dist/src/core/extensions/loader.js +709 -0
- package/dist/src/core/extensions/loader.js.map +7 -0
- package/dist/src/core/extensions/plugin-system.js +506 -0
- package/dist/src/core/extensions/plugin-system.js.map +7 -0
- package/dist/src/core/extensions/provider-adapter.js +617 -0
- package/dist/src/core/extensions/provider-adapter.js.map +7 -0
- package/dist/src/core/extensions/sandbox-runtime.js +664 -0
- package/dist/src/core/extensions/sandbox-runtime.js.map +7 -0
- package/dist/src/core/storage/chromadb-adapter.js +32 -6
- package/dist/src/core/storage/chromadb-adapter.js.map +2 -2
- package/dist/src/skills/repo-ingestion-skill.js +35 -12
- package/dist/src/skills/repo-ingestion-skill.js.map +2 -2
- package/package.json +11 -7
- package/scripts/background-sync-manager.js +145 -83
- package/scripts/claude-sm-autostart.js +17 -12
- package/scripts/gepa/README.md +275 -0
- package/scripts/gepa/config.json +53 -0
- package/scripts/gepa/evals/coding-tasks.jsonl +5 -0
- package/scripts/gepa/evals/fixtures/buggy-loop.js +18 -0
- package/scripts/gepa/evals/fixtures/callback-hell.js +53 -0
- package/scripts/gepa/generations/gen-000/baseline.md +124 -0
- package/scripts/gepa/hooks/auto-optimize.js +494 -0
- package/scripts/gepa/hooks/eval-tracker.js +203 -0
- package/scripts/gepa/hooks/reflect.js +311 -0
- package/scripts/gepa/optimize.js +611 -0
- package/scripts/gepa/state.json +14 -0
- package/scripts/test-pre-publish-quick.sh +1 -1
- package/dist/agents/core/agent-task-manager.js +0 -527
- package/dist/agents/core/agent-task-manager.js.map +0 -7
- package/dist/agents/testing-agent.js +0 -614
- package/dist/agents/testing-agent.js.map +0 -7
- package/dist/agents/verifiers/base-verifier.js +0 -133
- package/dist/agents/verifiers/base-verifier.js.map +0 -7
- package/dist/agents/verifiers/formatter-verifier.js +0 -130
- package/dist/agents/verifiers/formatter-verifier.js.map +0 -7
- package/dist/agents/verifiers/llm-judge.js +0 -252
- package/dist/agents/verifiers/llm-judge.js.map +0 -7
- package/dist/cli/auto-detect.js +0 -321
- package/dist/cli/auto-detect.js.map +0 -7
- package/dist/cli/browser-test.js +0 -33
- package/dist/cli/browser-test.js.map +0 -7
- package/dist/cli/claude-sm-danger.js +0 -21
- package/dist/cli/claude-sm-danger.js.map +0 -7
- package/dist/cli/claude-sm.js +0 -1156
- package/dist/cli/claude-sm.js.map +0 -7
- package/dist/cli/codex-sm-danger.js +0 -21
- package/dist/cli/codex-sm-danger.js.map +0 -7
- package/dist/cli/codex-sm.js +0 -349
- package/dist/cli/codex-sm.js.map +0 -7
- package/dist/cli/commands/api.js +0 -232
- package/dist/cli/commands/api.js.map +0 -7
- package/dist/cli/commands/auto-background.js +0 -180
- package/dist/cli/commands/auto-background.js.map +0 -7
- package/dist/cli/commands/cleanup-processes.js +0 -68
- package/dist/cli/commands/cleanup-processes.js.map +0 -7
- package/dist/cli/commands/clear.js +0 -202
- package/dist/cli/commands/clear.js.map +0 -7
- package/dist/cli/commands/config.js +0 -445
- package/dist/cli/commands/config.js.map +0 -7
- package/dist/cli/commands/context-rehydrate.js +0 -751
- package/dist/cli/commands/context-rehydrate.js.map +0 -7
- package/dist/cli/commands/context.js +0 -343
- package/dist/cli/commands/context.js.map +0 -7
- package/dist/cli/commands/daemon.js +0 -392
- package/dist/cli/commands/daemon.js.map +0 -7
- package/dist/cli/commands/dashboard.js +0 -210
- package/dist/cli/commands/dashboard.js.map +0 -7
- package/dist/cli/commands/db.js +0 -147
- package/dist/cli/commands/db.js.map +0 -7
- package/dist/cli/commands/decision.js +0 -266
- package/dist/cli/commands/decision.js.map +0 -7
- package/dist/cli/commands/discovery.js +0 -279
- package/dist/cli/commands/discovery.js.map +0 -7
- package/dist/cli/commands/handoff.js +0 -624
- package/dist/cli/commands/handoff.js.map +0 -7
- package/dist/cli/commands/hooks.js +0 -298
- package/dist/cli/commands/hooks.js.map +0 -7
- package/dist/cli/commands/linear-unified.js +0 -353
- package/dist/cli/commands/linear-unified.js.map +0 -7
- package/dist/cli/commands/linear.js +0 -529
- package/dist/cli/commands/linear.js.map +0 -7
- package/dist/cli/commands/log.js +0 -169
- package/dist/cli/commands/log.js.map +0 -7
- package/dist/cli/commands/login.js +0 -172
- package/dist/cli/commands/login.js.map +0 -7
- package/dist/cli/commands/migrate.js +0 -240
- package/dist/cli/commands/migrate.js.map +0 -7
- package/dist/cli/commands/model.js +0 -533
- package/dist/cli/commands/model.js.map +0 -7
- package/dist/cli/commands/monitor.js +0 -313
- package/dist/cli/commands/monitor.js.map +0 -7
- package/dist/cli/commands/onboard.js +0 -536
- package/dist/cli/commands/onboard.js.map +0 -7
- package/dist/cli/commands/projects.js +0 -199
- package/dist/cli/commands/projects.js.map +0 -7
- package/dist/cli/commands/quality.js +0 -413
- package/dist/cli/commands/quality.js.map +0 -7
- package/dist/cli/commands/ralph.js +0 -909
- package/dist/cli/commands/ralph.js.map +0 -7
- package/dist/cli/commands/retrieval.js +0 -248
- package/dist/cli/commands/retrieval.js.map +0 -7
- package/dist/cli/commands/search.js +0 -173
- package/dist/cli/commands/search.js.map +0 -7
- package/dist/cli/commands/service.js +0 -749
- package/dist/cli/commands/service.js.map +0 -7
- package/dist/cli/commands/session.js +0 -200
- package/dist/cli/commands/session.js.map +0 -7
- package/dist/cli/commands/settings.js +0 -306
- package/dist/cli/commands/settings.js.map +0 -7
- package/dist/cli/commands/setup.js +0 -701
- package/dist/cli/commands/setup.js.map +0 -7
- package/dist/cli/commands/shell.js +0 -249
- package/dist/cli/commands/shell.js.map +0 -7
- package/dist/cli/commands/signup.js +0 -50
- package/dist/cli/commands/signup.js.map +0 -7
- package/dist/cli/commands/skills.js +0 -470
- package/dist/cli/commands/skills.js.map +0 -7
- package/dist/cli/commands/sms-notify.js +0 -795
- package/dist/cli/commands/sms-notify.js.map +0 -7
- package/dist/cli/commands/storage-tier.js +0 -183
- package/dist/cli/commands/storage-tier.js.map +0 -7
- package/dist/cli/commands/storage.js +0 -360
- package/dist/cli/commands/storage.js.map +0 -7
- package/dist/cli/commands/sweep.js +0 -249
- package/dist/cli/commands/sweep.js.map +0 -7
- package/dist/cli/commands/tasks.js +0 -213
- package/dist/cli/commands/tasks.js.map +0 -7
- package/dist/cli/commands/test.js +0 -286
- package/dist/cli/commands/test.js.map +0 -7
- package/dist/cli/commands/workflow.js +0 -142
- package/dist/cli/commands/workflow.js.map +0 -7
- package/dist/cli/commands/worktree.js +0 -319
- package/dist/cli/commands/worktree.js.map +0 -7
- package/dist/cli/index.js +0 -594
- package/dist/cli/index.js.map +0 -7
- package/dist/cli/opencode-sm.js +0 -448
- package/dist/cli/opencode-sm.js.map +0 -7
- package/dist/cli/utils/viewer.js +0 -96
- package/dist/cli/utils/viewer.js.map +0 -7
- package/dist/core/analytics/team-analytics.js +0 -378
- package/dist/core/analytics/team-analytics.js.map +0 -7
- package/dist/core/config/config-manager.js +0 -398
- package/dist/core/config/config-manager.js.map +0 -7
- package/dist/core/config/feature-flags.js +0 -76
- package/dist/core/config/feature-flags.js.map +0 -7
- package/dist/core/config/storage-config.js +0 -115
- package/dist/core/config/storage-config.js.map +0 -7
- package/dist/core/config/types.js +0 -144
- package/dist/core/config/types.js.map +0 -7
- package/dist/core/context/auto-context.js +0 -80
- package/dist/core/context/auto-context.js.map +0 -7
- package/dist/core/context/dual-stack-manager.js +0 -870
- package/dist/core/context/dual-stack-manager.js.map +0 -7
- package/dist/core/context/enhanced-rehydration.js +0 -994
- package/dist/core/context/enhanced-rehydration.js.map +0 -7
- package/dist/core/context/frame-database.js +0 -479
- package/dist/core/context/frame-database.js.map +0 -7
- package/dist/core/context/frame-digest.js +0 -250
- package/dist/core/context/frame-digest.js.map +0 -7
- package/dist/core/context/frame-handoff-manager.js +0 -778
- package/dist/core/context/frame-handoff-manager.js.map +0 -7
- package/dist/core/context/frame-lifecycle-hooks.js +0 -119
- package/dist/core/context/frame-lifecycle-hooks.js.map +0 -7
- package/dist/core/context/frame-manager.js +0 -1069
- package/dist/core/context/frame-manager.js.map +0 -7
- package/dist/core/context/frame-recovery.js +0 -302
- package/dist/core/context/frame-recovery.js.map +0 -7
- package/dist/core/context/frame-stack.js +0 -314
- package/dist/core/context/frame-stack.js.map +0 -7
- package/dist/core/context/frame-types.js +0 -5
- package/dist/core/context/frame-types.js.map +0 -7
- package/dist/core/context/incremental-gc.js +0 -290
- package/dist/core/context/incremental-gc.js.map +0 -7
- package/dist/core/context/index.js +0 -25
- package/dist/core/context/index.js.map +0 -7
- package/dist/core/context/model-aware-compaction.js +0 -623
- package/dist/core/context/model-aware-compaction.js.map +0 -7
- package/dist/core/context/permission-manager.js +0 -185
- package/dist/core/context/permission-manager.js.map +0 -7
- package/dist/core/context/recursive-context-manager.js +0 -592
- package/dist/core/context/recursive-context-manager.js.map +0 -7
- package/dist/core/context/refactored-frame-manager.js +0 -754
- package/dist/core/context/refactored-frame-manager.js.map +0 -7
- package/dist/core/context/shared-context-layer.js +0 -621
- package/dist/core/context/shared-context-layer.js.map +0 -7
- package/dist/core/context/stack-merge-resolver.js +0 -749
- package/dist/core/context/stack-merge-resolver.js.map +0 -7
- package/dist/core/context/validation.js +0 -130
- package/dist/core/context/validation.js.map +0 -7
- package/dist/core/database/batch-operations.js +0 -384
- package/dist/core/database/batch-operations.js.map +0 -7
- package/dist/core/database/connection-pool.js +0 -330
- package/dist/core/database/connection-pool.js.map +0 -7
- package/dist/core/database/database-adapter.js +0 -60
- package/dist/core/database/database-adapter.js.map +0 -7
- package/dist/core/database/migration-manager.js +0 -614
- package/dist/core/database/migration-manager.js.map +0 -7
- package/dist/core/database/paradedb-adapter.js +0 -990
- package/dist/core/database/paradedb-adapter.js.map +0 -7
- package/dist/core/database/query-cache.js +0 -298
- package/dist/core/database/query-cache.js.map +0 -7
- package/dist/core/database/query-router.js +0 -430
- package/dist/core/database/query-router.js.map +0 -7
- package/dist/core/database/sqlite-adapter.js +0 -738
- package/dist/core/database/sqlite-adapter.js.map +0 -7
- package/dist/core/digest/enhanced-hybrid-digest.js +0 -277
- package/dist/core/digest/enhanced-hybrid-digest.js.map +0 -7
- package/dist/core/digest/frame-digest-integration.js +0 -176
- package/dist/core/digest/frame-digest-integration.js.map +0 -7
- package/dist/core/digest/hybrid-digest-generator.js +0 -553
- package/dist/core/digest/hybrid-digest-generator.js.map +0 -7
- package/dist/core/digest/index.js +0 -9
- package/dist/core/digest/index.js.map +0 -7
- package/dist/core/digest/types.js +0 -25
- package/dist/core/digest/types.js.map +0 -7
- package/dist/core/errors/error-utils.js +0 -208
- package/dist/core/errors/error-utils.js.map +0 -7
- package/dist/core/errors/index.js +0 -521
- package/dist/core/errors/index.js.map +0 -7
- package/dist/core/errors/recovery.js +0 -269
- package/dist/core/errors/recovery.js.map +0 -7
- package/dist/core/execution/parallel-executor.js +0 -258
- package/dist/core/execution/parallel-executor.js.map +0 -7
- package/dist/core/frame/workflow-templates.js +0 -319
- package/dist/core/frame/workflow-templates.js.map +0 -7
- package/dist/core/merge/conflict-detector.js +0 -431
- package/dist/core/merge/conflict-detector.js.map +0 -7
- package/dist/core/merge/index.js +0 -9
- package/dist/core/merge/index.js.map +0 -7
- package/dist/core/merge/resolution-engine.js +0 -558
- package/dist/core/merge/resolution-engine.js.map +0 -7
- package/dist/core/merge/stack-diff.js +0 -532
- package/dist/core/merge/stack-diff.js.map +0 -7
- package/dist/core/merge/unified-merge-resolver.js +0 -303
- package/dist/core/merge/unified-merge-resolver.js.map +0 -7
- package/dist/core/models/fallback-monitor.js +0 -232
- package/dist/core/models/fallback-monitor.js.map +0 -7
- package/dist/core/models/model-router.js +0 -340
- package/dist/core/models/model-router.js.map +0 -7
- package/dist/core/monitoring/error-handler.js +0 -49
- package/dist/core/monitoring/error-handler.js.map +0 -7
- package/dist/core/monitoring/logger.js +0 -202
- package/dist/core/monitoring/logger.js.map +0 -7
- package/dist/core/monitoring/metrics.js +0 -172
- package/dist/core/monitoring/metrics.js.map +0 -7
- package/dist/core/monitoring/progress-tracker.js +0 -189
- package/dist/core/monitoring/progress-tracker.js.map +0 -7
- package/dist/core/monitoring/session-monitor.js +0 -300
- package/dist/core/monitoring/session-monitor.js.map +0 -7
- package/dist/core/performance/context-cache.js +0 -273
- package/dist/core/performance/context-cache.js.map +0 -7
- package/dist/core/performance/index.js +0 -11
- package/dist/core/performance/index.js.map +0 -7
- package/dist/core/performance/lazy-context-loader.js +0 -327
- package/dist/core/performance/lazy-context-loader.js.map +0 -7
- package/dist/core/performance/monitor.js +0 -221
- package/dist/core/performance/monitor.js.map +0 -7
- package/dist/core/performance/optimized-frame-context.js +0 -345
- package/dist/core/performance/optimized-frame-context.js.map +0 -7
- package/dist/core/performance/performance-benchmark.js +0 -277
- package/dist/core/performance/performance-benchmark.js.map +0 -7
- package/dist/core/performance/performance-profiler.js +0 -370
- package/dist/core/performance/performance-profiler.js.map +0 -7
- package/dist/core/performance/streaming-jsonl-parser.js +0 -195
- package/dist/core/performance/streaming-jsonl-parser.js.map +0 -7
- package/dist/core/persistence/postgres-adapter.js +0 -349
- package/dist/core/persistence/postgres-adapter.js.map +0 -7
- package/dist/core/projects/project-isolation.js +0 -201
- package/dist/core/projects/project-isolation.js.map +0 -7
- package/dist/core/projects/project-manager.js +0 -697
- package/dist/core/projects/project-manager.js.map +0 -7
- package/dist/core/query/query-parser.js +0 -370
- package/dist/core/query/query-parser.js.map +0 -7
- package/dist/core/query/query-templates.js +0 -321
- package/dist/core/query/query-templates.js.map +0 -7
- package/dist/core/retrieval/context-retriever.js +0 -479
- package/dist/core/retrieval/context-retriever.js.map +0 -7
- package/dist/core/retrieval/graph-retrieval.js +0 -662
- package/dist/core/retrieval/graph-retrieval.js.map +0 -7
- package/dist/core/retrieval/hierarchical-retrieval.js +0 -656
- package/dist/core/retrieval/hierarchical-retrieval.js.map +0 -7
- package/dist/core/retrieval/index.js +0 -8
- package/dist/core/retrieval/index.js.map +0 -7
- package/dist/core/retrieval/llm-context-retrieval.js +0 -613
- package/dist/core/retrieval/llm-context-retrieval.js.map +0 -7
- package/dist/core/retrieval/llm-provider.js +0 -151
- package/dist/core/retrieval/llm-provider.js.map +0 -7
- package/dist/core/retrieval/retrieval-audit.js +0 -236
- package/dist/core/retrieval/retrieval-audit.js.map +0 -7
- package/dist/core/retrieval/retrieval-benchmarks.js +0 -521
- package/dist/core/retrieval/retrieval-benchmarks.js.map +0 -7
- package/dist/core/retrieval/summary-generator.js +0 -589
- package/dist/core/retrieval/summary-generator.js.map +0 -7
- package/dist/core/retrieval/types.js +0 -21
- package/dist/core/retrieval/types.js.map +0 -7
- package/dist/core/security/index.js +0 -35
- package/dist/core/security/index.js.map +0 -7
- package/dist/core/security/input-sanitizer.js +0 -321
- package/dist/core/security/input-sanitizer.js.map +0 -7
- package/dist/core/session/clear-survival.js +0 -465
- package/dist/core/session/clear-survival.js.map +0 -7
- package/dist/core/session/enhanced-handoff.js +0 -792
- package/dist/core/session/enhanced-handoff.js.map +0 -7
- package/dist/core/session/handoff-generator.js +0 -343
- package/dist/core/session/handoff-generator.js.map +0 -7
- package/dist/core/session/index.js +0 -15
- package/dist/core/session/index.js.map +0 -7
- package/dist/core/session/session-manager.js +0 -347
- package/dist/core/session/session-manager.js.map +0 -7
- package/dist/core/skills/index.js +0 -7
- package/dist/core/skills/index.js.map +0 -7
- package/dist/core/skills/skill-storage.js +0 -764
- package/dist/core/skills/skill-storage.js.map +0 -7
- package/dist/core/skills/types.js +0 -193
- package/dist/core/skills/types.js.map +0 -7
- package/dist/core/storage/chromadb-adapter.js +0 -354
- package/dist/core/storage/chromadb-adapter.js.map +0 -7
- package/dist/core/storage/infinite-storage.js +0 -510
- package/dist/core/storage/infinite-storage.js.map +0 -7
- package/dist/core/storage/railway-optimized-storage.js +0 -591
- package/dist/core/storage/railway-optimized-storage.js.map +0 -7
- package/dist/core/storage/remote-storage.js +0 -489
- package/dist/core/storage/remote-storage.js.map +0 -7
- package/dist/core/storage/two-tier-storage.js +0 -766
- package/dist/core/storage/two-tier-storage.js.map +0 -7
- package/dist/core/trace/cli-trace-wrapper.js +0 -132
- package/dist/core/trace/cli-trace-wrapper.js.map +0 -7
- package/dist/core/trace/db-trace-wrapper.js +0 -247
- package/dist/core/trace/db-trace-wrapper.js.map +0 -7
- package/dist/core/trace/debug-trace.js +0 -417
- package/dist/core/trace/debug-trace.js.map +0 -7
- package/dist/core/trace/index.js +0 -109
- package/dist/core/trace/index.js.map +0 -7
- package/dist/core/trace/linear-api-wrapper.js +0 -178
- package/dist/core/trace/linear-api-wrapper.js.map +0 -7
- package/dist/core/trace/trace-demo.js +0 -154
- package/dist/core/trace/trace-demo.js.map +0 -7
- package/dist/core/trace/trace-detector.demo.js +0 -142
- package/dist/core/trace/trace-detector.demo.js.map +0 -7
- package/dist/core/trace/trace-detector.js +0 -528
- package/dist/core/trace/trace-detector.js.map +0 -7
- package/dist/core/trace/trace-store.js +0 -345
- package/dist/core/trace/trace-store.js.map +0 -7
- package/dist/core/trace/types.js +0 -77
- package/dist/core/trace/types.js.map +0 -7
- package/dist/core/types.js +0 -5
- package/dist/core/types.js.map +0 -7
- package/dist/core/utils/async-mutex.js +0 -114
- package/dist/core/utils/async-mutex.js.map +0 -7
- package/dist/core/utils/compression.js +0 -83
- package/dist/core/utils/compression.js.map +0 -7
- package/dist/core/utils/update-checker.js +0 -218
- package/dist/core/utils/update-checker.js.map +0 -7
- package/dist/core/worktree/worktree-manager.js +0 -465
- package/dist/core/worktree/worktree-manager.js.map +0 -7
- package/dist/daemon/daemon-config.js +0 -149
- package/dist/daemon/daemon-config.js.map +0 -7
- package/dist/daemon/services/context-service.js +0 -122
- package/dist/daemon/services/context-service.js.map +0 -7
- package/dist/daemon/services/linear-service.js +0 -136
- package/dist/daemon/services/linear-service.js.map +0 -7
- package/dist/daemon/session-daemon.js +0 -312
- package/dist/daemon/session-daemon.js.map +0 -7
- package/dist/daemon/unified-daemon.js +0 -276
- package/dist/daemon/unified-daemon.js.map +0 -7
- package/dist/features/analytics/api/analytics-api.js +0 -287
- package/dist/features/analytics/api/analytics-api.js.map +0 -7
- package/dist/features/analytics/core/analytics-service.js +0 -282
- package/dist/features/analytics/core/analytics-service.js.map +0 -7
- package/dist/features/analytics/index.js +0 -18
- package/dist/features/analytics/index.js.map +0 -7
- package/dist/features/analytics/queries/metrics-queries.js +0 -277
- package/dist/features/analytics/queries/metrics-queries.js.map +0 -7
- package/dist/features/analytics/types/metrics.js +0 -5
- package/dist/features/analytics/types/metrics.js.map +0 -7
- package/dist/features/browser/browser-mcp.js +0 -492
- package/dist/features/browser/browser-mcp.js.map +0 -7
- package/dist/features/sweep/index.js +0 -20
- package/dist/features/sweep/index.js.map +0 -7
- package/dist/features/sweep/prediction-client.js +0 -155
- package/dist/features/sweep/prediction-client.js.map +0 -7
- package/dist/features/sweep/prompt-builder.js +0 -85
- package/dist/features/sweep/prompt-builder.js.map +0 -7
- package/dist/features/sweep/pty-wrapper.js +0 -171
- package/dist/features/sweep/pty-wrapper.js.map +0 -7
- package/dist/features/sweep/state-watcher.js +0 -87
- package/dist/features/sweep/state-watcher.js.map +0 -7
- package/dist/features/sweep/status-bar.js +0 -88
- package/dist/features/sweep/status-bar.js.map +0 -7
- package/dist/features/sweep/sweep-server-manager.js +0 -226
- package/dist/features/sweep/sweep-server-manager.js.map +0 -7
- package/dist/features/sweep/tab-interceptor.js +0 -38
- package/dist/features/sweep/tab-interceptor.js.map +0 -7
- package/dist/features/sweep/types.js +0 -18
- package/dist/features/sweep/types.js.map +0 -7
- package/dist/features/tasks/linear-task-manager.js +0 -487
- package/dist/features/tasks/linear-task-manager.js.map +0 -7
- package/dist/features/tasks/task-aware-context.js +0 -410
- package/dist/features/tasks/task-aware-context.js.map +0 -7
- package/dist/features/tui/simple-monitor.js +0 -116
- package/dist/features/tui/simple-monitor.js.map +0 -7
- package/dist/features/tui/swarm-monitor.js +0 -648
- package/dist/features/tui/swarm-monitor.js.map +0 -7
- package/dist/features/web/client/stores/task-store.js +0 -26
- package/dist/features/web/client/stores/task-store.js.map +0 -7
- package/dist/features/web/server/index.js +0 -194
- package/dist/features/web/server/index.js.map +0 -7
- package/dist/hooks/auto-background.js +0 -151
- package/dist/hooks/auto-background.js.map +0 -7
- package/dist/hooks/claude-code-whatsapp-hook.js +0 -197
- package/dist/hooks/claude-code-whatsapp-hook.js.map +0 -7
- package/dist/hooks/config.js +0 -150
- package/dist/hooks/config.js.map +0 -7
- package/dist/hooks/daemon.js +0 -364
- package/dist/hooks/daemon.js.map +0 -7
- package/dist/hooks/events.js +0 -58
- package/dist/hooks/events.js.map +0 -7
- package/dist/hooks/index.js +0 -12
- package/dist/hooks/index.js.map +0 -7
- package/dist/hooks/linear-task-picker.js +0 -186
- package/dist/hooks/linear-task-picker.js.map +0 -7
- package/dist/hooks/schemas.js +0 -197
- package/dist/hooks/schemas.js.map +0 -7
- package/dist/hooks/secure-fs.js +0 -49
- package/dist/hooks/secure-fs.js.map +0 -7
- package/dist/hooks/security-logger.js +0 -155
- package/dist/hooks/security-logger.js.map +0 -7
- package/dist/hooks/session-summary.js +0 -222
- package/dist/hooks/session-summary.js.map +0 -7
- package/dist/hooks/sms-action-runner.js +0 -371
- package/dist/hooks/sms-action-runner.js.map +0 -7
- package/dist/hooks/sms-notify.js +0 -506
- package/dist/hooks/sms-notify.js.map +0 -7
- package/dist/hooks/sms-watcher.js +0 -93
- package/dist/hooks/sms-watcher.js.map +0 -7
- package/dist/hooks/sms-webhook.js +0 -555
- package/dist/hooks/sms-webhook.js.map +0 -7
- package/dist/hooks/whatsapp-commands.js +0 -479
- package/dist/hooks/whatsapp-commands.js.map +0 -7
- package/dist/hooks/whatsapp-scheduler.js +0 -317
- package/dist/hooks/whatsapp-scheduler.js.map +0 -7
- package/dist/hooks/whatsapp-sync.js +0 -409
- package/dist/hooks/whatsapp-sync.js.map +0 -7
- package/dist/index.js +0 -25
- package/dist/index.js.map +0 -7
- package/dist/integrations/anthropic/client.js +0 -263
- package/dist/integrations/anthropic/client.js.map +0 -7
- package/dist/integrations/claude-code/agent-bridge.js +0 -768
- package/dist/integrations/claude-code/agent-bridge.js.map +0 -7
- package/dist/integrations/claude-code/enhanced-pre-clear-hooks.js +0 -459
- package/dist/integrations/claude-code/enhanced-pre-clear-hooks.js.map +0 -7
- package/dist/integrations/claude-code/lifecycle-hooks.js +0 -254
- package/dist/integrations/claude-code/lifecycle-hooks.js.map +0 -7
- package/dist/integrations/claude-code/post-task-hooks.js +0 -545
- package/dist/integrations/claude-code/post-task-hooks.js.map +0 -7
- package/dist/integrations/claude-code/subagent-client-stub.js +0 -20
- package/dist/integrations/claude-code/subagent-client-stub.js.map +0 -7
- package/dist/integrations/claude-code/subagent-client.js +0 -511
- package/dist/integrations/claude-code/subagent-client.js.map +0 -7
- package/dist/integrations/claude-code/task-coordinator.js +0 -360
- package/dist/integrations/claude-code/task-coordinator.js.map +0 -7
- package/dist/integrations/linear/auth.js +0 -337
- package/dist/integrations/linear/auth.js.map +0 -7
- package/dist/integrations/linear/auto-sync.js +0 -258
- package/dist/integrations/linear/auto-sync.js.map +0 -7
- package/dist/integrations/linear/client.js +0 -634
- package/dist/integrations/linear/client.js.map +0 -7
- package/dist/integrations/linear/config.js +0 -130
- package/dist/integrations/linear/config.js.map +0 -7
- package/dist/integrations/linear/migration.js +0 -361
- package/dist/integrations/linear/migration.js.map +0 -7
- package/dist/integrations/linear/oauth-server.js +0 -454
- package/dist/integrations/linear/oauth-server.js.map +0 -7
- package/dist/integrations/linear/rest-client.js +0 -213
- package/dist/integrations/linear/rest-client.js.map +0 -7
- package/dist/integrations/linear/sync-manager.js +0 -236
- package/dist/integrations/linear/sync-manager.js.map +0 -7
- package/dist/integrations/linear/sync-service.js +0 -231
- package/dist/integrations/linear/sync-service.js.map +0 -7
- package/dist/integrations/linear/sync.js +0 -782
- package/dist/integrations/linear/sync.js.map +0 -7
- package/dist/integrations/linear/types.js +0 -5
- package/dist/integrations/linear/types.js.map +0 -7
- package/dist/integrations/linear/unified-sync.js +0 -589
- package/dist/integrations/linear/unified-sync.js.map +0 -7
- package/dist/integrations/linear/webhook-handler.js +0 -219
- package/dist/integrations/linear/webhook-handler.js.map +0 -7
- package/dist/integrations/linear/webhook-server.js +0 -218
- package/dist/integrations/linear/webhook-server.js.map +0 -7
- package/dist/integrations/linear/webhook.js +0 -291
- package/dist/integrations/linear/webhook.js.map +0 -7
- package/dist/integrations/mcp/handlers/code-execution-handlers.js +0 -266
- package/dist/integrations/mcp/handlers/code-execution-handlers.js.map +0 -7
- package/dist/integrations/mcp/handlers/context-handlers.js +0 -257
- package/dist/integrations/mcp/handlers/context-handlers.js.map +0 -7
- package/dist/integrations/mcp/handlers/discovery-handlers.js +0 -497
- package/dist/integrations/mcp/handlers/discovery-handlers.js.map +0 -7
- package/dist/integrations/mcp/handlers/index.js +0 -166
- package/dist/integrations/mcp/handlers/index.js.map +0 -7
- package/dist/integrations/mcp/handlers/linear-handlers.js +0 -247
- package/dist/integrations/mcp/handlers/linear-handlers.js.map +0 -7
- package/dist/integrations/mcp/handlers/skill-handlers.js +0 -529
- package/dist/integrations/mcp/handlers/skill-handlers.js.map +0 -7
- package/dist/integrations/mcp/handlers/task-handlers.js +0 -239
- package/dist/integrations/mcp/handlers/task-handlers.js.map +0 -7
- package/dist/integrations/mcp/handlers/trace-handlers.js +0 -308
- package/dist/integrations/mcp/handlers/trace-handlers.js.map +0 -7
- package/dist/integrations/mcp/index.js +0 -23
- package/dist/integrations/mcp/index.js.map +0 -7
- package/dist/integrations/mcp/middleware/tool-scoring.js +0 -356
- package/dist/integrations/mcp/middleware/tool-scoring.js.map +0 -7
- package/dist/integrations/mcp/refactored-server.js +0 -374
- package/dist/integrations/mcp/refactored-server.js.map +0 -7
- package/dist/integrations/mcp/remote-server.js +0 -682
- package/dist/integrations/mcp/remote-server.js.map +0 -7
- package/dist/integrations/mcp/schemas.js +0 -147
- package/dist/integrations/mcp/schemas.js.map +0 -7
- package/dist/integrations/mcp/server.js +0 -1975
- package/dist/integrations/mcp/server.js.map +0 -7
- package/dist/integrations/mcp/tool-definitions-code.js +0 -125
- package/dist/integrations/mcp/tool-definitions-code.js.map +0 -7
- package/dist/integrations/mcp/tool-definitions.js +0 -702
- package/dist/integrations/mcp/tool-definitions.js.map +0 -7
- package/dist/integrations/mcp/trace-test.js +0 -48
- package/dist/integrations/mcp/trace-test.js.map +0 -7
- package/dist/integrations/pg-aiguide/embedding-provider.js +0 -189
- package/dist/integrations/pg-aiguide/embedding-provider.js.map +0 -7
- package/dist/integrations/pg-aiguide/semantic-search.js +0 -187
- package/dist/integrations/pg-aiguide/semantic-search.js.map +0 -7
- package/dist/integrations/pg-aiguide/timescale-analytics.js +0 -224
- package/dist/integrations/pg-aiguide/timescale-analytics.js.map +0 -7
- package/dist/integrations/ralph/bridge/ralph-stackmemory-bridge.js +0 -860
- package/dist/integrations/ralph/bridge/ralph-stackmemory-bridge.js.map +0 -7
- package/dist/integrations/ralph/context/context-budget-manager.js +0 -301
- package/dist/integrations/ralph/context/context-budget-manager.js.map +0 -7
- package/dist/integrations/ralph/context/stackmemory-context-loader.js +0 -360
- package/dist/integrations/ralph/context/stackmemory-context-loader.js.map +0 -7
- package/dist/integrations/ralph/coordination/enhanced-coordination.js +0 -410
- package/dist/integrations/ralph/coordination/enhanced-coordination.js.map +0 -7
- package/dist/integrations/ralph/index.js +0 -18
- package/dist/integrations/ralph/index.js.map +0 -7
- package/dist/integrations/ralph/learning/pattern-learner.js +0 -401
- package/dist/integrations/ralph/learning/pattern-learner.js.map +0 -7
- package/dist/integrations/ralph/lifecycle/iteration-lifecycle.js +0 -448
- package/dist/integrations/ralph/lifecycle/iteration-lifecycle.js.map +0 -7
- package/dist/integrations/ralph/monitoring/swarm-dashboard.js +0 -294
- package/dist/integrations/ralph/monitoring/swarm-dashboard.js.map +0 -7
- package/dist/integrations/ralph/monitoring/swarm-registry.js +0 -108
- package/dist/integrations/ralph/monitoring/swarm-registry.js.map +0 -7
- package/dist/integrations/ralph/orchestration/multi-loop-orchestrator.js +0 -463
- package/dist/integrations/ralph/orchestration/multi-loop-orchestrator.js.map +0 -7
- package/dist/integrations/ralph/patterns/compounding-engineering-pattern.js +0 -400
- package/dist/integrations/ralph/patterns/compounding-engineering-pattern.js.map +0 -7
- package/dist/integrations/ralph/patterns/extended-coherence-sessions.js +0 -473
- package/dist/integrations/ralph/patterns/extended-coherence-sessions.js.map +0 -7
- package/dist/integrations/ralph/patterns/oracle-worker-pattern.js +0 -388
- package/dist/integrations/ralph/patterns/oracle-worker-pattern.js.map +0 -7
- package/dist/integrations/ralph/performance/performance-optimizer.js +0 -358
- package/dist/integrations/ralph/performance/performance-optimizer.js.map +0 -7
- package/dist/integrations/ralph/ralph-integration-demo.js +0 -182
- package/dist/integrations/ralph/ralph-integration-demo.js.map +0 -7
- package/dist/integrations/ralph/recovery/crash-recovery.js +0 -462
- package/dist/integrations/ralph/recovery/crash-recovery.js.map +0 -7
- package/dist/integrations/ralph/state/state-reconciler.js +0 -404
- package/dist/integrations/ralph/state/state-reconciler.js.map +0 -7
- package/dist/integrations/ralph/swarm/git-workflow-manager.js +0 -428
- package/dist/integrations/ralph/swarm/git-workflow-manager.js.map +0 -7
- package/dist/integrations/ralph/swarm/swarm-coordinator.js +0 -996
- package/dist/integrations/ralph/swarm/swarm-coordinator.js.map +0 -7
- package/dist/integrations/ralph/types.js +0 -5
- package/dist/integrations/ralph/types.js.map +0 -7
- package/dist/integrations/ralph/visualization/ralph-debugger.js +0 -585
- package/dist/integrations/ralph/visualization/ralph-debugger.js.map +0 -7
- package/dist/mcp/stackmemory-mcp-server.js +0 -554
- package/dist/mcp/stackmemory-mcp-server.js.map +0 -7
- package/dist/middleware/exponential-rate-limiter.js +0 -289
- package/dist/middleware/exponential-rate-limiter.js.map +0 -7
- package/dist/models/user.model.js +0 -358
- package/dist/models/user.model.js.map +0 -7
- package/dist/servers/production/auth-middleware.js +0 -528
- package/dist/servers/production/auth-middleware.js.map +0 -7
- package/dist/servers/railway/config.js +0 -55
- package/dist/servers/railway/config.js.map +0 -7
- package/dist/servers/railway/index-enhanced.js +0 -160
- package/dist/servers/railway/index-enhanced.js.map +0 -7
- package/dist/servers/railway/index.js +0 -1349
- package/dist/servers/railway/index.js.map +0 -7
- package/dist/servers/railway/simple.js +0 -64
- package/dist/servers/railway/simple.js.map +0 -7
- package/dist/servers/railway/storage-test.js +0 -459
- package/dist/servers/railway/storage-test.js.map +0 -7
- package/dist/services/config-service.js +0 -65
- package/dist/services/config-service.js.map +0 -7
- package/dist/services/context-service.js +0 -194
- package/dist/services/context-service.js.map +0 -7
- package/dist/skills/api-discovery.js +0 -354
- package/dist/skills/api-discovery.js.map +0 -7
- package/dist/skills/api-skill.js +0 -475
- package/dist/skills/api-skill.js.map +0 -7
- package/dist/skills/claude-skills.js +0 -1061
- package/dist/skills/claude-skills.js.map +0 -7
- package/dist/skills/dashboard-launcher.js +0 -216
- package/dist/skills/dashboard-launcher.js.map +0 -7
- package/dist/skills/recursive-agent-orchestrator.js +0 -575
- package/dist/skills/recursive-agent-orchestrator.js.map +0 -7
- package/dist/skills/repo-ingestion-skill.js +0 -609
- package/dist/skills/repo-ingestion-skill.js.map +0 -7
- package/dist/skills/security-secrets-scanner.js +0 -284
- package/dist/skills/security-secrets-scanner.js.map +0 -7
- package/dist/skills/unified-rlm-orchestrator.js +0 -404
- package/dist/skills/unified-rlm-orchestrator.js.map +0 -7
- package/dist/types/task.js +0 -5
- package/dist/types/task.js.map +0 -7
- package/dist/utils/env.js +0 -50
- package/dist/utils/env.js.map +0 -7
- package/dist/utils/formatting.js +0 -62
- package/dist/utils/formatting.js.map +0 -7
- package/dist/utils/process-cleanup.js +0 -136
- package/dist/utils/process-cleanup.js.map +0 -7
- package/dist/validation/schemas.js +0 -222
- package/dist/validation/schemas.js.map +0 -7
- /package/dist/{core/merge → src/core/extensions}/types.js +0 -0
- /package/dist/{core/merge → src/core/extensions}/types.js.map +0 -0
|
@@ -1,219 +0,0 @@
|
|
|
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 { createHmac } from "crypto";
|
|
6
|
-
import { LinearSyncEngine } from "./sync.js";
|
|
7
|
-
import { LinearAuthManager } from "./auth.js";
|
|
8
|
-
import { IntegrationError, ErrorCode } from "../../core/errors/index.js";
|
|
9
|
-
import { logger } from "../../core/monitoring/logger.js";
|
|
10
|
-
function getEnv(key, defaultValue) {
|
|
11
|
-
const value = process.env[key];
|
|
12
|
-
if (value === void 0) {
|
|
13
|
-
if (defaultValue !== void 0) return defaultValue;
|
|
14
|
-
throw new IntegrationError(
|
|
15
|
-
`Environment variable ${key} is required`,
|
|
16
|
-
ErrorCode.LINEAR_WEBHOOK_FAILED
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
return value;
|
|
20
|
-
}
|
|
21
|
-
function getOptionalEnv(key) {
|
|
22
|
-
return process.env[key];
|
|
23
|
-
}
|
|
24
|
-
class LinearWebhookHandler {
|
|
25
|
-
taskStore;
|
|
26
|
-
syncEngine = null;
|
|
27
|
-
webhookSecret;
|
|
28
|
-
constructor(taskStore, webhookSecret) {
|
|
29
|
-
this.taskStore = taskStore;
|
|
30
|
-
this.webhookSecret = webhookSecret;
|
|
31
|
-
if (process.env["LINEAR_API_KEY"]) {
|
|
32
|
-
const authManager = new LinearAuthManager();
|
|
33
|
-
this.syncEngine = new LinearSyncEngine(taskStore, authManager, {
|
|
34
|
-
enabled: true,
|
|
35
|
-
direction: "from_linear",
|
|
36
|
-
autoSync: false,
|
|
37
|
-
conflictResolution: "linear_wins"
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Verify webhook signature
|
|
43
|
-
*/
|
|
44
|
-
verifySignature(payload, signature) {
|
|
45
|
-
const hmac = createHmac("sha256", this.webhookSecret);
|
|
46
|
-
hmac.update(payload);
|
|
47
|
-
const expectedSignature = hmac.digest("hex");
|
|
48
|
-
return signature === expectedSignature;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Handle incoming webhook from Linear
|
|
52
|
-
*/
|
|
53
|
-
async handleWebhook(req, res) {
|
|
54
|
-
try {
|
|
55
|
-
const rawBody = JSON.stringify(req.body);
|
|
56
|
-
const signature = req.headers["linear-signature"];
|
|
57
|
-
if (!this.verifySignature(rawBody, signature)) {
|
|
58
|
-
logger.error("Invalid webhook signature");
|
|
59
|
-
res.status(401).json({ error: "Invalid signature" });
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const payload = req.body;
|
|
63
|
-
if (payload.type !== "Issue") {
|
|
64
|
-
res.status(200).json({ message: "Ignored non-issue webhook" });
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
switch (payload.action) {
|
|
68
|
-
case "create":
|
|
69
|
-
await this.handleIssueCreate(payload);
|
|
70
|
-
break;
|
|
71
|
-
case "update":
|
|
72
|
-
await this.handleIssueUpdate(payload);
|
|
73
|
-
break;
|
|
74
|
-
case "remove":
|
|
75
|
-
await this.handleIssueRemove(payload);
|
|
76
|
-
break;
|
|
77
|
-
default:
|
|
78
|
-
logger.warn(`Unknown webhook action: ${payload.action}`);
|
|
79
|
-
}
|
|
80
|
-
res.status(200).json({ message: "Webhook processed successfully" });
|
|
81
|
-
} catch (error) {
|
|
82
|
-
logger.error("Failed to process webhook:", error);
|
|
83
|
-
res.status(500).json({ error: "Failed to process webhook" });
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Handle issue creation
|
|
88
|
-
*/
|
|
89
|
-
async handleIssueCreate(payload) {
|
|
90
|
-
const issue = payload.data;
|
|
91
|
-
const existingTasks = this.taskStore.getActiveTasks();
|
|
92
|
-
const exists = existingTasks.some(
|
|
93
|
-
(t) => t.title.includes(issue.identifier) || t.external_refs?.linear === issue.id
|
|
94
|
-
);
|
|
95
|
-
if (exists) {
|
|
96
|
-
logger.info(`Task ${issue.identifier} already exists locally`);
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
const taskId = this.taskStore.createTask({
|
|
100
|
-
title: `[${issue.identifier}] ${issue.title}`,
|
|
101
|
-
description: issue.description || "",
|
|
102
|
-
priority: this.mapLinearPriorityToLocal(issue.priority),
|
|
103
|
-
frameId: "linear-webhook",
|
|
104
|
-
tags: issue.labels?.map((l) => l.name) || ["linear"],
|
|
105
|
-
estimatedEffort: issue.estimate ? issue.estimate * 60 : void 0,
|
|
106
|
-
assignee: issue.assignee?.name
|
|
107
|
-
});
|
|
108
|
-
const status = this.mapLinearStateToLocalStatus(issue.state.type);
|
|
109
|
-
if (status !== "pending") {
|
|
110
|
-
this.taskStore.updateTaskStatus(
|
|
111
|
-
taskId,
|
|
112
|
-
status,
|
|
113
|
-
`Synced from Linear (${issue.state.name})`
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
await this.storeLinearMapping(taskId, issue.id, issue.identifier);
|
|
117
|
-
logger.info(`Created task ${taskId} from Linear issue ${issue.identifier}`);
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Handle issue update
|
|
121
|
-
*/
|
|
122
|
-
async handleIssueUpdate(payload) {
|
|
123
|
-
const issue = payload.data;
|
|
124
|
-
const tasks = this.taskStore.getActiveTasks();
|
|
125
|
-
const localTask = tasks.find(
|
|
126
|
-
(t) => t.title.includes(issue.identifier) || t.external_refs?.linear === issue.id
|
|
127
|
-
);
|
|
128
|
-
if (!localTask) {
|
|
129
|
-
await this.handleIssueCreate(payload);
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
const newStatus = this.mapLinearStateToLocalStatus(issue.state.type);
|
|
133
|
-
if (newStatus !== localTask.status) {
|
|
134
|
-
this.taskStore.updateTaskStatus(
|
|
135
|
-
localTask.id,
|
|
136
|
-
newStatus,
|
|
137
|
-
`Updated from Linear (${issue.state.name})`
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
const newPriority = this.mapLinearPriorityToLocal(issue.priority);
|
|
141
|
-
if (newPriority !== localTask.priority) {
|
|
142
|
-
logger.info(
|
|
143
|
-
`Priority changed for ${issue.identifier}: ${localTask.priority} -> ${newPriority}`
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
logger.info(
|
|
147
|
-
`Updated task ${localTask.id} from Linear issue ${issue.identifier}`
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Handle issue removal
|
|
152
|
-
*/
|
|
153
|
-
async handleIssueRemove(payload) {
|
|
154
|
-
const issue = payload.data;
|
|
155
|
-
const tasks = this.taskStore.getActiveTasks();
|
|
156
|
-
const localTask = tasks.find(
|
|
157
|
-
(t) => t.title.includes(issue.identifier) || t.external_refs?.linear === issue.id
|
|
158
|
-
);
|
|
159
|
-
if (localTask) {
|
|
160
|
-
this.taskStore.updateTaskStatus(
|
|
161
|
-
localTask.id,
|
|
162
|
-
"cancelled",
|
|
163
|
-
`Removed in Linear`
|
|
164
|
-
);
|
|
165
|
-
logger.info(
|
|
166
|
-
`Cancelled task ${localTask.id} (Linear issue ${issue.identifier} was removed)`
|
|
167
|
-
);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Store Linear mapping for a task
|
|
172
|
-
*/
|
|
173
|
-
async storeLinearMapping(taskId, linearId, linearIdentifier) {
|
|
174
|
-
logger.info(
|
|
175
|
-
`Mapped task ${taskId} to Linear ${linearIdentifier} (${linearId})`
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Map Linear priority to local priority
|
|
180
|
-
*/
|
|
181
|
-
mapLinearPriorityToLocal(priority) {
|
|
182
|
-
if (!priority) return "medium";
|
|
183
|
-
switch (priority) {
|
|
184
|
-
case 0:
|
|
185
|
-
return "urgent";
|
|
186
|
-
case 1:
|
|
187
|
-
return "high";
|
|
188
|
-
case 2:
|
|
189
|
-
return "medium";
|
|
190
|
-
case 3:
|
|
191
|
-
case 4:
|
|
192
|
-
return "low";
|
|
193
|
-
default:
|
|
194
|
-
return "medium";
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Map Linear state to local status
|
|
199
|
-
*/
|
|
200
|
-
mapLinearStateToLocalStatus(state) {
|
|
201
|
-
switch (state) {
|
|
202
|
-
case "backlog":
|
|
203
|
-
case "unstarted":
|
|
204
|
-
return "pending";
|
|
205
|
-
case "started":
|
|
206
|
-
return "in_progress";
|
|
207
|
-
case "completed":
|
|
208
|
-
return "completed";
|
|
209
|
-
case "cancelled":
|
|
210
|
-
return "cancelled";
|
|
211
|
-
default:
|
|
212
|
-
return "pending";
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
export {
|
|
217
|
-
LinearWebhookHandler
|
|
218
|
-
};
|
|
219
|
-
//# sourceMappingURL=webhook-handler.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/integrations/linear/webhook-handler.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Linear Webhook Handler\n * Processes incoming webhooks from Linear to update local task store\n */\n\nimport { createHmac } from 'crypto';\nimport { LinearTaskManager } from '../../features/tasks/linear-task-manager.js';\nimport { LinearSyncEngine } from './sync.js';\nimport { LinearAuthManager } from './auth.js';\nimport { LinearClient } from './client.js';\nimport { IntegrationError, ErrorCode } from '../../core/errors/index.js';\nimport { logger } from '../../core/monitoring/logger.js';\nimport type { Request, Response } from 'express';\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 IntegrationError(\n `Environment variable ${key} is required`,\n ErrorCode.LINEAR_WEBHOOK_FAILED\n );\n }\n return value;\n}\n\nfunction getOptionalEnv(key: string): string | undefined {\n return process.env[key];\n}\n\nexport interface LinearWebhookPayload {\n action: 'create' | 'update' | 'remove';\n createdAt: string;\n data: {\n id: string;\n identifier: string;\n title: string;\n description?: string;\n state: {\n id: string;\n name: string;\n type: 'backlog' | 'unstarted' | 'started' | 'completed' | 'cancelled';\n };\n priority?: number;\n estimate?: number;\n assignee?: {\n id: string;\n name: string;\n email: string;\n };\n labels?: Array<{ id: string; name: string }>;\n updatedAt: string;\n url: string;\n };\n type: 'Issue';\n organizationId: string;\n webhookId: string;\n}\n\nexport class LinearWebhookHandler {\n private taskStore: LinearTaskManager;\n private syncEngine: LinearSyncEngine | null = null;\n private webhookSecret: string;\n\n constructor(taskStore: LinearTaskManager, webhookSecret: string) {\n this.taskStore = taskStore;\n this.webhookSecret = webhookSecret;\n\n // Initialize sync engine if API key is available\n if (process.env['LINEAR_API_KEY']) {\n const authManager = new LinearAuthManager();\n this.syncEngine = new LinearSyncEngine(taskStore, authManager, {\n enabled: true,\n direction: 'from_linear',\n autoSync: false,\n conflictResolution: 'linear_wins',\n });\n }\n }\n\n /**\n * Verify webhook signature\n */\n private verifySignature(payload: string, signature: string): boolean {\n const hmac = createHmac('sha256', this.webhookSecret);\n hmac.update(payload);\n const expectedSignature = hmac.digest('hex');\n return signature === expectedSignature;\n }\n\n /**\n * Handle incoming webhook from Linear\n */\n async handleWebhook(req: Request, res: Response): Promise<void> {\n try {\n // Get raw body for signature verification\n const rawBody = JSON.stringify(req.body);\n const signature = req.headers['linear-signature'] as string;\n\n // Verify signature\n if (!this.verifySignature(rawBody, signature)) {\n logger.error('Invalid webhook signature');\n res.status(401).json({ error: 'Invalid signature' });\n return;\n }\n\n const payload = req.body as LinearWebhookPayload;\n\n // Only process Issue webhooks\n if (payload.type !== 'Issue') {\n res.status(200).json({ message: 'Ignored non-issue webhook' });\n return;\n }\n\n // Process based on action\n switch (payload.action) {\n case 'create':\n await this.handleIssueCreate(payload);\n break;\n case 'update':\n await this.handleIssueUpdate(payload);\n break;\n case 'remove':\n await this.handleIssueRemove(payload);\n break;\n default:\n logger.warn(`Unknown webhook action: ${payload.action}`);\n }\n\n res.status(200).json({ message: 'Webhook processed successfully' });\n } catch (error: unknown) {\n logger.error('Failed to process webhook:', error as Error);\n res.status(500).json({ error: 'Failed to process webhook' });\n }\n }\n\n /**\n * Handle issue creation\n */\n private async handleIssueCreate(\n payload: LinearWebhookPayload\n ): Promise<void> {\n const issue = payload.data;\n\n // Check if task already exists locally\n const existingTasks = this.taskStore.getActiveTasks();\n const exists = existingTasks.some(\n (t) =>\n t.title.includes(issue.identifier) ||\n t.external_refs?.linear === issue.id\n );\n\n if (exists) {\n logger.info(`Task ${issue.identifier} already exists locally`);\n return;\n }\n\n // Create local task\n const taskId = this.taskStore.createTask({\n title: `[${issue.identifier}] ${issue.title}`,\n description: issue.description || '',\n priority: this.mapLinearPriorityToLocal(issue.priority),\n frameId: 'linear-webhook',\n tags: issue.labels?.map((l) => l.name) || ['linear'],\n estimatedEffort: issue.estimate ? issue.estimate * 60 : undefined,\n assignee: issue.assignee?.name,\n });\n\n // Update task status if not pending\n const status = this.mapLinearStateToLocalStatus(issue.state.type);\n if (status !== 'pending') {\n this.taskStore.updateTaskStatus(\n taskId,\n status,\n `Synced from Linear (${issue.state.name})`\n );\n }\n\n // Store Linear mapping\n await this.storeLinearMapping(taskId, issue.id, issue.identifier);\n\n logger.info(`Created task ${taskId} from Linear issue ${issue.identifier}`);\n }\n\n /**\n * Handle issue update\n */\n private async handleIssueUpdate(\n payload: LinearWebhookPayload\n ): Promise<void> {\n const issue = payload.data;\n\n // Find local task by Linear ID or identifier\n const tasks = this.taskStore.getActiveTasks();\n const localTask = tasks.find(\n (t) =>\n t.title.includes(issue.identifier) ||\n t.external_refs?.linear === issue.id\n );\n\n if (!localTask) {\n // Task doesn't exist locally, create it\n await this.handleIssueCreate(payload);\n return;\n }\n\n // Update task status\n const newStatus = this.mapLinearStateToLocalStatus(issue.state.type);\n if (newStatus !== localTask.status) {\n this.taskStore.updateTaskStatus(\n localTask.id,\n newStatus,\n `Updated from Linear (${issue.state.name})`\n );\n }\n\n // Update priority if changed\n const newPriority = this.mapLinearPriorityToLocal(issue.priority);\n if (newPriority !== localTask.priority) {\n // Note: Would need to add updateTaskPriority method to taskStore\n logger.info(\n `Priority changed for ${issue.identifier}: ${localTask.priority} -> ${newPriority}`\n );\n }\n\n logger.info(\n `Updated task ${localTask.id} from Linear issue ${issue.identifier}`\n );\n }\n\n /**\n * Handle issue removal\n */\n private async handleIssueRemove(\n payload: LinearWebhookPayload\n ): Promise<void> {\n const issue = payload.data;\n\n // Find and cancel local task\n const tasks = this.taskStore.getActiveTasks();\n const localTask = tasks.find(\n (t) =>\n t.title.includes(issue.identifier) ||\n t.external_refs?.linear === issue.id\n );\n\n if (localTask) {\n this.taskStore.updateTaskStatus(\n localTask.id,\n 'cancelled',\n `Removed in Linear`\n );\n logger.info(\n `Cancelled task ${localTask.id} (Linear issue ${issue.identifier} was removed)`\n );\n }\n }\n\n /**\n * Store Linear mapping for a task\n */\n private async storeLinearMapping(\n taskId: string,\n linearId: string,\n linearIdentifier: string\n ): Promise<void> {\n // This would update the linear-mappings.json file\n // For now, just log it\n logger.info(\n `Mapped task ${taskId} to Linear ${linearIdentifier} (${linearId})`\n );\n }\n\n /**\n * Map Linear priority to local priority\n */\n private mapLinearPriorityToLocal(\n priority?: number\n ): 'urgent' | 'high' | 'medium' | 'low' {\n if (!priority) return 'medium';\n switch (priority) {\n case 0:\n return 'urgent';\n case 1:\n return 'high';\n case 2:\n return 'medium';\n case 3:\n case 4:\n return 'low';\n default:\n return 'medium';\n }\n }\n\n /**\n * Map Linear state to local status\n */\n private mapLinearStateToLocalStatus(\n state: string\n ): 'pending' | 'in_progress' | 'completed' | 'cancelled' | 'blocked' {\n switch (state) {\n case 'backlog':\n case 'unstarted':\n return 'pending';\n case 'started':\n return 'in_progress';\n case 'completed':\n return 'completed';\n case 'cancelled':\n return 'cancelled';\n default:\n return 'pending';\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
3
|
-
import { dirname as __pathDirname } from 'path';
|
|
4
|
-
const __filename = __fileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = __pathDirname(__filename);
|
|
6
|
-
import express from "express";
|
|
7
|
-
import crypto from "crypto";
|
|
8
|
-
import { LinearSyncService } from "./sync-service.js";
|
|
9
|
-
import { IntegrationError, ErrorCode } from "../../core/errors/index.js";
|
|
10
|
-
import { logger } from "../../core/monitoring/logger.js";
|
|
11
|
-
import chalk from "chalk";
|
|
12
|
-
function getEnv(key, defaultValue) {
|
|
13
|
-
const value = process.env[key];
|
|
14
|
-
if (value === void 0) {
|
|
15
|
-
if (defaultValue !== void 0) return defaultValue;
|
|
16
|
-
throw new IntegrationError(
|
|
17
|
-
`Environment variable ${key} is required`,
|
|
18
|
-
ErrorCode.LINEAR_WEBHOOK_FAILED
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
return value;
|
|
22
|
-
}
|
|
23
|
-
function getOptionalEnv(key) {
|
|
24
|
-
return process.env[key];
|
|
25
|
-
}
|
|
26
|
-
class LinearWebhookServer {
|
|
27
|
-
app;
|
|
28
|
-
server = null;
|
|
29
|
-
// Using singleton logger from monitoring
|
|
30
|
-
syncService;
|
|
31
|
-
config;
|
|
32
|
-
eventQueue = [];
|
|
33
|
-
isProcessing = false;
|
|
34
|
-
constructor(config) {
|
|
35
|
-
this.app = express();
|
|
36
|
-
this.syncService = new LinearSyncService();
|
|
37
|
-
this.config = {
|
|
38
|
-
port: config?.port || parseInt(process.env["WEBHOOK_PORT"] || "3456"),
|
|
39
|
-
host: config?.host || process.env["WEBHOOK_HOST"] || "localhost",
|
|
40
|
-
webhookSecret: config?.webhookSecret || process.env["LINEAR_WEBHOOK_SECRET"],
|
|
41
|
-
maxPayloadSize: config?.maxPayloadSize || "10mb",
|
|
42
|
-
rateLimit: {
|
|
43
|
-
windowMs: config?.rateLimit?.windowMs || 6e4,
|
|
44
|
-
max: config?.rateLimit?.max || 100
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
this.setupMiddleware();
|
|
48
|
-
this.setupRoutes();
|
|
49
|
-
}
|
|
50
|
-
setupMiddleware() {
|
|
51
|
-
this.app.use(
|
|
52
|
-
express.raw({
|
|
53
|
-
type: "application/json",
|
|
54
|
-
limit: this.config.maxPayloadSize
|
|
55
|
-
})
|
|
56
|
-
);
|
|
57
|
-
this.app.use((req, res, next) => {
|
|
58
|
-
res.setHeader("X-Powered-By", "StackMemory");
|
|
59
|
-
next();
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
setupRoutes() {
|
|
63
|
-
this.app.get("/health", (req, res) => {
|
|
64
|
-
res.json({
|
|
65
|
-
status: "healthy",
|
|
66
|
-
service: "linear-webhook",
|
|
67
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
68
|
-
queue: this.eventQueue.length,
|
|
69
|
-
processing: this.isProcessing
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
this.app.post("/webhook/linear", async (req, res) => {
|
|
73
|
-
try {
|
|
74
|
-
if (!this.verifyWebhookSignature(req)) {
|
|
75
|
-
logger.warn("Invalid webhook signature");
|
|
76
|
-
return res.status(401).json({ error: "Unauthorized" });
|
|
77
|
-
}
|
|
78
|
-
const payload = JSON.parse(req.body.toString());
|
|
79
|
-
logger.info(`Received webhook: ${payload.type} - ${payload.action}`);
|
|
80
|
-
this.eventQueue.push(payload);
|
|
81
|
-
this.processQueue();
|
|
82
|
-
return res.status(200).json({
|
|
83
|
-
status: "accepted",
|
|
84
|
-
queued: true
|
|
85
|
-
});
|
|
86
|
-
} catch (error) {
|
|
87
|
-
logger.error("Webhook processing error:", error);
|
|
88
|
-
return res.status(500).json({ error: "Internal server error" });
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
this.app.use((req, res) => {
|
|
92
|
-
res.status(404).json({ error: "Not found" });
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
verifyWebhookSignature(req) {
|
|
96
|
-
if (!this.config.webhookSecret) {
|
|
97
|
-
logger.warn("No webhook secret configured, accepting all webhooks");
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
const signature = req.headers["linear-signature"];
|
|
101
|
-
if (!signature) {
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
const hash = crypto.createHmac("sha256", this.config.webhookSecret).update(req.body).digest("hex");
|
|
105
|
-
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(hash));
|
|
106
|
-
}
|
|
107
|
-
async processQueue() {
|
|
108
|
-
if (this.isProcessing || this.eventQueue.length === 0) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
this.isProcessing = true;
|
|
112
|
-
while (this.eventQueue.length > 0) {
|
|
113
|
-
const event = this.eventQueue.shift();
|
|
114
|
-
try {
|
|
115
|
-
await this.handleWebhookEvent(event);
|
|
116
|
-
} catch (error) {
|
|
117
|
-
logger.error(`Failed to process event: ${event.type}`, error);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
this.isProcessing = false;
|
|
121
|
-
}
|
|
122
|
-
async handleWebhookEvent(payload) {
|
|
123
|
-
const { type, action, data } = payload;
|
|
124
|
-
switch (type) {
|
|
125
|
-
case "Issue":
|
|
126
|
-
await this.handleIssueEvent(action, data);
|
|
127
|
-
break;
|
|
128
|
-
case "Comment":
|
|
129
|
-
await this.handleCommentEvent(action, data);
|
|
130
|
-
break;
|
|
131
|
-
case "Project":
|
|
132
|
-
await this.handleProjectEvent(action, data);
|
|
133
|
-
break;
|
|
134
|
-
default:
|
|
135
|
-
logger.debug(`Unhandled event type: ${type}`);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
async handleIssueEvent(action, data) {
|
|
139
|
-
const issue = data;
|
|
140
|
-
switch (action) {
|
|
141
|
-
case "create":
|
|
142
|
-
logger.info(`New issue created: ${issue.identifier} - ${issue.title}`);
|
|
143
|
-
await this.syncService.syncIssueToLocal(issue);
|
|
144
|
-
break;
|
|
145
|
-
case "update":
|
|
146
|
-
logger.info(`Issue updated: ${issue.identifier} - ${issue.title}`);
|
|
147
|
-
await this.syncService.syncIssueToLocal(issue);
|
|
148
|
-
break;
|
|
149
|
-
case "remove":
|
|
150
|
-
logger.info(`Issue removed: ${issue.identifier}`);
|
|
151
|
-
await this.syncService.removeLocalIssue(issue.identifier);
|
|
152
|
-
break;
|
|
153
|
-
default:
|
|
154
|
-
logger.debug(`Unhandled issue action: ${action}`);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
async handleCommentEvent(action, data) {
|
|
158
|
-
logger.debug(`Comment event: ${action}`, { issueId: data.issue?.id });
|
|
159
|
-
}
|
|
160
|
-
async handleProjectEvent(action, data) {
|
|
161
|
-
logger.debug(`Project event: ${action}`, { projectId: data.id });
|
|
162
|
-
}
|
|
163
|
-
async start() {
|
|
164
|
-
return new Promise((resolve) => {
|
|
165
|
-
this.server = this.app.listen(
|
|
166
|
-
this.config.port,
|
|
167
|
-
this.config.host,
|
|
168
|
-
() => {
|
|
169
|
-
console.log(
|
|
170
|
-
chalk.green("\u2713") + chalk.bold(" Linear Webhook Server Started")
|
|
171
|
-
);
|
|
172
|
-
console.log(
|
|
173
|
-
chalk.cyan(" URL: ") + `http://${this.config.host}:${this.config.port}/webhook/linear`
|
|
174
|
-
);
|
|
175
|
-
console.log(
|
|
176
|
-
chalk.cyan(" Health: ") + `http://${this.config.host}:${this.config.port}/health`
|
|
177
|
-
);
|
|
178
|
-
if (!this.config.webhookSecret) {
|
|
179
|
-
console.log(
|
|
180
|
-
chalk.yellow(
|
|
181
|
-
" \u26A0 Warning: No webhook secret configured (insecure)"
|
|
182
|
-
)
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
resolve();
|
|
186
|
-
}
|
|
187
|
-
);
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
async stop() {
|
|
191
|
-
return new Promise((resolve) => {
|
|
192
|
-
if (this.server) {
|
|
193
|
-
this.server.close(() => {
|
|
194
|
-
logger.info("Webhook server stopped");
|
|
195
|
-
resolve();
|
|
196
|
-
});
|
|
197
|
-
} else {
|
|
198
|
-
resolve();
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
if (process.argv[1] === new URL(import.meta.url).pathname) {
|
|
204
|
-
const server = new LinearWebhookServer();
|
|
205
|
-
server.start().catch((error) => {
|
|
206
|
-
console.error(chalk.red("Failed to start webhook server:"), error);
|
|
207
|
-
process.exit(1);
|
|
208
|
-
});
|
|
209
|
-
process.on("SIGINT", async () => {
|
|
210
|
-
console.log(chalk.yellow("\n\nShutting down webhook server..."));
|
|
211
|
-
await server.stop();
|
|
212
|
-
process.exit(0);
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
export {
|
|
216
|
-
LinearWebhookServer
|
|
217
|
-
};
|
|
218
|
-
//# sourceMappingURL=webhook-server.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/integrations/linear/webhook-server.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n\nimport express from 'express';\nimport crypto from 'crypto';\nimport http from 'http';\nimport {\n LinearWebhookPayload,\n LinearIssue,\n LinearComment,\n LinearProject,\n} from './types.js';\nimport { LinearSyncService } from './sync-service.js';\nimport { LinearIssue as ClientLinearIssue } from './client.js';\nimport { IntegrationError, ErrorCode } from '../../core/errors/index.js';\nimport { logger } from '../../core/monitoring/logger.js';\nimport chalk from 'chalk';\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 IntegrationError(\n `Environment variable ${key} is required`,\n ErrorCode.LINEAR_WEBHOOK_FAILED\n );\n }\n return value;\n}\n\nfunction getOptionalEnv(key: string): string | undefined {\n return process.env[key];\n}\n\nexport interface WebhookServerConfig {\n port?: number;\n host?: string;\n webhookSecret?: string;\n maxPayloadSize?: string;\n rateLimit?: {\n windowMs?: number;\n max?: number;\n };\n}\n\nexport class LinearWebhookServer {\n private app: express.Application;\n private server: http.Server | null = null;\n // Using singleton logger from monitoring\n private syncService: LinearSyncService;\n private config: WebhookServerConfig;\n private eventQueue: LinearWebhookPayload[] = [];\n private isProcessing = false;\n\n constructor(config?: WebhookServerConfig) {\n this.app = express();\n // Use singleton logger\n this.syncService = new LinearSyncService();\n\n this.config = {\n port: config?.port || parseInt(process.env['WEBHOOK_PORT'] || '3456'),\n host: config?.host || process.env['WEBHOOK_HOST'] || 'localhost',\n webhookSecret:\n config?.webhookSecret || process.env['LINEAR_WEBHOOK_SECRET'],\n maxPayloadSize: config?.maxPayloadSize || '10mb',\n rateLimit: {\n windowMs: config?.rateLimit?.windowMs || 60000,\n max: config?.rateLimit?.max || 100,\n },\n };\n\n this.setupMiddleware();\n this.setupRoutes();\n }\n\n private setupMiddleware(): void {\n this.app.use(\n express.raw({\n type: 'application/json',\n limit: this.config.maxPayloadSize,\n })\n );\n\n this.app.use((req, res, next) => {\n res.setHeader('X-Powered-By', 'StackMemory');\n next();\n });\n }\n\n private setupRoutes(): void {\n this.app.get('/health', (req, res) => {\n res.json({\n status: 'healthy',\n service: 'linear-webhook',\n timestamp: new Date().toISOString(),\n queue: this.eventQueue.length,\n processing: this.isProcessing,\n });\n });\n\n this.app.post('/webhook/linear', async (req, res) => {\n try {\n if (!this.verifyWebhookSignature(req)) {\n logger.warn('Invalid webhook signature');\n return res.status(401).json({ error: 'Unauthorized' });\n }\n\n const payload = JSON.parse(req.body.toString()) as LinearWebhookPayload;\n\n logger.info(`Received webhook: ${payload.type} - ${payload.action}`);\n\n this.eventQueue.push(payload);\n this.processQueue();\n\n return res.status(200).json({\n status: 'accepted',\n queued: true,\n });\n } catch (error: unknown) {\n logger.error('Webhook processing error:', error);\n return res.status(500).json({ error: 'Internal server error' });\n }\n });\n\n this.app.use((req, res) => {\n res.status(404).json({ error: 'Not found' });\n });\n }\n\n private verifyWebhookSignature(req: express.Request): boolean {\n if (!this.config.webhookSecret) {\n logger.warn('No webhook secret configured, accepting all webhooks');\n return true;\n }\n\n const signature = req.headers['linear-signature'] as string;\n if (!signature) {\n return false;\n }\n\n const hash = crypto\n .createHmac('sha256', this.config.webhookSecret)\n .update(req.body)\n .digest('hex');\n\n return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(hash));\n }\n\n private async processQueue(): Promise<void> {\n if (this.isProcessing || this.eventQueue.length === 0) {\n return;\n }\n\n this.isProcessing = true;\n\n while (this.eventQueue.length > 0) {\n const event = this.eventQueue.shift()!;\n\n try {\n await this.handleWebhookEvent(event);\n } catch (error: unknown) {\n logger.error(`Failed to process event: ${event.type}`, error);\n }\n }\n\n this.isProcessing = false;\n }\n\n private async handleWebhookEvent(\n payload: LinearWebhookPayload\n ): Promise<void> {\n const { type, action, data } = payload;\n\n switch (type) {\n case 'Issue':\n await this.handleIssueEvent(action, data as LinearIssue);\n break;\n case 'Comment':\n await this.handleCommentEvent(action, data as LinearComment);\n break;\n case 'Project':\n await this.handleProjectEvent(action, data as LinearProject);\n break;\n default:\n logger.debug(`Unhandled event type: ${type}`);\n }\n }\n\n private async handleIssueEvent(\n action: string,\n data: LinearIssue\n ): Promise<void> {\n const issue = data as ClientLinearIssue;\n\n switch (action) {\n case 'create':\n logger.info(`New issue created: ${issue.identifier} - ${issue.title}`);\n await this.syncService.syncIssueToLocal(issue);\n break;\n case 'update':\n logger.info(`Issue updated: ${issue.identifier} - ${issue.title}`);\n await this.syncService.syncIssueToLocal(issue);\n break;\n case 'remove':\n logger.info(`Issue removed: ${issue.identifier}`);\n await this.syncService.removeLocalIssue(issue.identifier);\n break;\n default:\n logger.debug(`Unhandled issue action: ${action}`);\n }\n }\n\n private async handleCommentEvent(\n action: string,\n data: LinearComment\n ): Promise<void> {\n logger.debug(`Comment event: ${action}`, { issueId: data.issue?.id });\n }\n\n private async handleProjectEvent(\n action: string,\n data: LinearProject\n ): Promise<void> {\n logger.debug(`Project event: ${action}`, { projectId: data.id });\n }\n\n public async start(): Promise<void> {\n return new Promise((resolve) => {\n this.server = this.app.listen(\n this.config.port!,\n this.config.host!,\n () => {\n console.log(\n chalk.green('\u2713') + chalk.bold(' Linear Webhook Server Started')\n );\n console.log(\n chalk.cyan(' URL: ') +\n `http://${this.config.host}:${this.config.port}/webhook/linear`\n );\n console.log(\n chalk.cyan(' Health: ') +\n `http://${this.config.host}:${this.config.port}/health`\n );\n\n if (!this.config.webhookSecret) {\n console.log(\n chalk.yellow(\n ' \u26A0 Warning: No webhook secret configured (insecure)'\n )\n );\n }\n\n resolve();\n }\n );\n });\n }\n\n public async stop(): Promise<void> {\n return new Promise((resolve) => {\n if (this.server) {\n this.server.close(() => {\n logger.info('Webhook server stopped');\n resolve();\n });\n } else {\n resolve();\n }\n });\n }\n}\n\n// Standalone execution support\nif (process.argv[1] === new URL(import.meta.url).pathname) {\n const server = new LinearWebhookServer();\n\n server.start().catch((error) => {\n console.error(chalk.red('Failed to start webhook server:'), error);\n process.exit(1);\n });\n\n process.on('SIGINT', async () => {\n console.log(chalk.yellow('\\n\\nShutting down webhook server...'));\n await server.stop();\n process.exit(0);\n });\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|