@stackmemoryai/stackmemory 0.3.1 → 0.3.3
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 +52 -272
- package/dist/cli/commands/clear.js +191 -0
- package/dist/cli/commands/clear.js.map +7 -0
- package/dist/cli/commands/config.js +152 -1
- package/dist/cli/commands/config.js.map +2 -2
- package/dist/cli/commands/dashboard.js +178 -0
- package/dist/cli/commands/dashboard.js.map +7 -0
- package/dist/cli/commands/handoff.js +125 -8
- package/dist/cli/commands/handoff.js.map +2 -2
- package/dist/cli/commands/linear-create.js +132 -0
- package/dist/cli/commands/linear-create.js.map +7 -0
- package/dist/cli/commands/linear-list.js +69 -0
- package/dist/cli/commands/linear-list.js.map +7 -0
- package/dist/cli/commands/linear-migrate.js +40 -0
- package/dist/cli/commands/linear-migrate.js.map +7 -0
- package/dist/cli/commands/linear.js +185 -36
- package/dist/cli/commands/linear.js.map +2 -2
- package/dist/cli/commands/monitor.js +309 -0
- package/dist/cli/commands/monitor.js.map +7 -0
- package/dist/cli/commands/quality.js +414 -0
- package/dist/cli/commands/quality.js.map +7 -0
- package/dist/cli/commands/storage.js +275 -0
- package/dist/cli/commands/storage.js.map +7 -0
- package/dist/cli/commands/tui.js +66 -0
- package/dist/cli/commands/tui.js.map +7 -0
- package/dist/cli/commands/workflow.js +134 -0
- package/dist/cli/commands/workflow.js.map +7 -0
- package/dist/cli/index.js +104 -8
- package/dist/cli/index.js.map +3 -3
- package/dist/core/analytics/team-analytics.js +374 -0
- package/dist/core/analytics/team-analytics.js.map +7 -0
- package/dist/core/context/context-bridge.js +234 -0
- package/dist/core/context/context-bridge.js.map +7 -0
- package/dist/core/context/dual-stack-manager.js +850 -0
- package/dist/core/context/dual-stack-manager.js.map +7 -0
- package/dist/core/context/frame-handoff-manager.js +384 -0
- package/dist/core/context/frame-handoff-manager.js.map +7 -0
- package/dist/core/context/frame-manager.js +132 -12
- package/dist/core/context/frame-manager.js.map +2 -2
- package/dist/core/context/permission-manager.js +181 -0
- package/dist/core/context/permission-manager.js.map +7 -0
- package/dist/core/context/shared-context-layer.js +386 -0
- package/dist/core/context/shared-context-layer.js.map +7 -0
- package/dist/core/context/stack-merge-resolver.js +600 -0
- package/dist/core/context/stack-merge-resolver.js.map +7 -0
- package/dist/core/context/validation.js +121 -0
- package/dist/core/context/validation.js.map +7 -0
- package/dist/core/database/connection-pool.js +266 -175
- package/dist/core/database/connection-pool.js.map +2 -2
- package/dist/core/database/database-adapter.js +51 -0
- package/dist/core/database/database-adapter.js.map +7 -0
- package/dist/core/database/migration-manager.js +514 -0
- package/dist/core/database/migration-manager.js.map +7 -0
- package/dist/core/database/paradedb-adapter.js +970 -0
- package/dist/core/database/paradedb-adapter.js.map +7 -0
- package/dist/core/database/query-router.js +421 -0
- package/dist/core/database/query-router.js.map +7 -0
- package/dist/core/database/sqlite-adapter.js +547 -0
- package/dist/core/database/sqlite-adapter.js.map +7 -0
- package/dist/core/errors/index.js +21 -1
- package/dist/core/errors/index.js.map +2 -2
- package/dist/core/frame/workflow-templates-stub.js +42 -0
- package/dist/core/frame/workflow-templates-stub.js.map +7 -0
- package/dist/core/frame/workflow-templates.js +276 -0
- package/dist/core/frame/workflow-templates.js.map +7 -0
- package/dist/core/merge/conflict-detector.js +5 -2
- package/dist/core/merge/conflict-detector.js.map +2 -2
- package/dist/core/merge/resolution-engine.js +3 -14
- package/dist/core/merge/resolution-engine.js.map +2 -2
- package/dist/core/merge/stack-diff.js.map +2 -2
- package/dist/core/monitoring/logger.js +18 -3
- package/dist/core/monitoring/logger.js.map +2 -2
- package/dist/core/monitoring/session-monitor.js +296 -0
- package/dist/core/monitoring/session-monitor.js.map +7 -0
- package/dist/core/retrieval/context-retriever.js +475 -0
- package/dist/core/retrieval/context-retriever.js.map +7 -0
- package/dist/core/retrieval/graph-retrieval.js +658 -0
- package/dist/core/retrieval/graph-retrieval.js.map +7 -0
- package/dist/core/retrieval/hierarchical-retrieval.js +652 -0
- package/dist/core/retrieval/hierarchical-retrieval.js.map +7 -0
- package/dist/core/retrieval/retrieval-benchmarks.js +517 -0
- package/dist/core/retrieval/retrieval-benchmarks.js.map +7 -0
- package/dist/core/session/clear-survival-stub.js +49 -0
- package/dist/core/session/clear-survival-stub.js.map +7 -0
- package/dist/core/session/clear-survival.js +426 -0
- package/dist/core/session/clear-survival.js.map +7 -0
- package/dist/core/session/handoff-generator.js +339 -0
- package/dist/core/session/handoff-generator.js.map +7 -0
- package/dist/core/session/session-manager.js +61 -26
- package/dist/core/session/session-manager.js.map +3 -3
- package/dist/core/skills/index.js +3 -0
- package/dist/core/skills/index.js.map +7 -0
- package/dist/core/skills/skill-storage.js +749 -0
- package/dist/core/skills/skill-storage.js.map +7 -0
- package/dist/core/skills/types.js +189 -0
- package/dist/core/skills/types.js.map +7 -0
- package/dist/core/storage/railway-optimized-storage.js +550 -0
- package/dist/core/storage/railway-optimized-storage.js.map +7 -0
- package/dist/core/storage/remote-storage.js +456 -0
- package/dist/core/storage/remote-storage.js.map +7 -0
- package/dist/core/trace/trace-detector.js +136 -5
- package/dist/core/trace/trace-detector.js.map +2 -2
- package/dist/core/trace/trace-store.js.map +2 -2
- package/dist/features/tui/components/analytics-panel.js +136 -0
- package/dist/features/tui/components/analytics-panel.js.map +7 -0
- package/dist/features/tui/components/frame-visualizer.js +377 -0
- package/dist/features/tui/components/frame-visualizer.js.map +7 -0
- package/dist/features/tui/components/pr-tracker.js +123 -0
- package/dist/features/tui/components/pr-tracker.js.map +7 -0
- package/dist/features/tui/components/session-monitor.js +286 -0
- package/dist/features/tui/components/session-monitor.js.map +7 -0
- package/dist/features/tui/components/subagent-fleet.js +388 -0
- package/dist/features/tui/components/subagent-fleet.js.map +7 -0
- package/dist/features/tui/components/task-board.js +475 -0
- package/dist/features/tui/components/task-board.js.map +7 -0
- package/dist/features/tui/index.js +397 -0
- package/dist/features/tui/index.js.map +7 -0
- package/dist/features/tui/services/data-service.js +654 -0
- package/dist/features/tui/services/data-service.js.map +7 -0
- package/dist/features/tui/services/websocket-client.js +149 -0
- package/dist/features/tui/services/websocket-client.js.map +7 -0
- package/dist/features/tui/terminal-compat.js +205 -0
- package/dist/features/tui/terminal-compat.js.map +7 -0
- package/dist/features/tui/types.js +1 -0
- package/dist/features/tui/types.js.map +7 -0
- package/dist/integrations/claude-code/enhanced-pre-clear-hooks.js +455 -0
- package/dist/integrations/claude-code/enhanced-pre-clear-hooks.js.map +7 -0
- package/dist/integrations/claude-code/lifecycle-hooks.js +250 -0
- package/dist/integrations/claude-code/lifecycle-hooks.js.map +7 -0
- package/dist/integrations/claude-code/post-task-hooks.js +541 -0
- package/dist/integrations/claude-code/post-task-hooks.js.map +7 -0
- package/dist/integrations/linear/client.js +22 -4
- package/dist/integrations/linear/client.js.map +2 -2
- package/dist/integrations/linear/migration.js +299 -0
- package/dist/integrations/linear/migration.js.map +7 -0
- package/dist/integrations/linear/oauth-server.js +396 -0
- package/dist/integrations/linear/oauth-server.js.map +7 -0
- package/dist/integrations/linear/rest-client.js +199 -0
- package/dist/integrations/linear/rest-client.js.map +7 -0
- package/dist/integrations/linear/sync.js +14 -2
- package/dist/integrations/linear/sync.js.map +2 -2
- package/dist/integrations/linear/webhook-handler.js +200 -0
- package/dist/integrations/linear/webhook-handler.js.map +7 -0
- package/dist/integrations/mcp/handlers/skill-handlers.js +514 -0
- package/dist/integrations/mcp/handlers/skill-handlers.js.map +7 -0
- package/dist/integrations/mcp/middleware/tool-scoring.js +352 -0
- package/dist/integrations/mcp/middleware/tool-scoring.js.map +7 -0
- package/dist/integrations/mcp/refactored-server.js +31 -3
- package/dist/integrations/mcp/refactored-server.js.map +2 -2
- package/dist/integrations/mcp/server.js +25 -7
- package/dist/integrations/mcp/server.js.map +2 -2
- package/dist/mcp/stackmemory-mcp-server.js.map +1 -1
- package/dist/models/user.model.js +3 -0
- package/dist/models/user.model.js.map +2 -2
- package/dist/services/context-service.js.map +2 -2
- package/dist/utils/formatting.js +58 -0
- package/dist/utils/formatting.js.map +7 -0
- package/package.json +21 -5
- package/dist/cli/__tests__/index.test.js +0 -290
- package/dist/cli/__tests__/index.test.js.map +0 -7
- package/dist/core/config/__tests__/config-manager.test.js +0 -248
- package/dist/core/config/__tests__/config-manager.test.js.map +0 -7
- package/dist/core/context/__tests__/frame-manager.test.js +0 -879
- package/dist/core/context/__tests__/frame-manager.test.js.map +0 -7
- package/dist/core/digest/__tests__/enhanced-hybrid-digest.test.js +0 -379
- package/dist/core/digest/__tests__/enhanced-hybrid-digest.test.js.map +0 -7
- package/dist/core/digest/__tests__/frame-digest-integration.test.js +0 -230
- package/dist/core/digest/__tests__/frame-digest-integration.test.js.map +0 -7
- package/dist/core/errors/__tests__/error-handling.test.js +0 -270
- package/dist/core/errors/__tests__/error-handling.test.js.map +0 -7
- package/dist/core/merge/__tests__/conflict-scenarios.test.js +0 -414
- package/dist/core/merge/__tests__/conflict-scenarios.test.js.map +0 -7
- package/dist/core/query/__tests__/query-parser.test.js +0 -301
- package/dist/core/query/__tests__/query-parser.test.js.map +0 -7
- package/dist/core/query/__tests__/query-templates.test.js +0 -210
- package/dist/core/query/__tests__/query-templates.test.js.map +0 -7
- package/dist/core/trace/trace-detector.test.js +0 -401
- package/dist/core/trace/trace-detector.test.js.map +0 -7
- package/dist/features/tasks/__tests__/pebbles-task-store.test.js +0 -747
- package/dist/features/tasks/__tests__/pebbles-task-store.test.js.map +0 -7
- package/dist/integrations/linear/__tests__/auth.test.js +0 -558
- package/dist/integrations/linear/__tests__/auth.test.js.map +0 -7
- package/dist/integrations/linear/__tests__/sync-service.test.js +0 -760
- package/dist/integrations/linear/__tests__/sync-service.test.js.map +0 -7
- package/dist/integrations/mcp/__tests__/server.test.js +0 -798
- package/dist/integrations/mcp/__tests__/server.test.js.map +0 -7
- package/dist/scripts/benchmark-performance.d.ts +0 -7
- package/dist/scripts/benchmark-performance.d.ts.map +0 -1
- package/dist/scripts/benchmark-performance.js +0 -44
- package/dist/scripts/benchmark-performance.js.map +0 -1
- package/dist/scripts/cancel-duplicate-tasks.d.ts +0 -7
- package/dist/scripts/cancel-duplicate-tasks.d.ts.map +0 -1
- package/dist/scripts/cancel-duplicate-tasks.js +0 -172
- package/dist/scripts/cancel-duplicate-tasks.js.map +0 -1
- package/dist/scripts/cleanup-duplicate-tasks.d.ts +0 -12
- package/dist/scripts/cleanup-duplicate-tasks.d.ts.map +0 -1
- package/dist/scripts/cleanup-duplicate-tasks.js +0 -215
- package/dist/scripts/cleanup-duplicate-tasks.js.map +0 -1
- package/dist/scripts/initialize.d.ts +0 -6
- package/dist/scripts/initialize.d.ts.map +0 -1
- package/dist/scripts/initialize.js +0 -93
- package/dist/scripts/initialize.js.map +0 -1
- package/dist/scripts/list-linear-tasks.d.ts +0 -6
- package/dist/scripts/list-linear-tasks.d.ts.map +0 -1
- package/dist/scripts/list-linear-tasks.js +0 -121
- package/dist/scripts/list-linear-tasks.js.map +0 -1
- package/dist/scripts/merge-linear-duplicates-safe.d.ts +0 -7
- package/dist/scripts/merge-linear-duplicates-safe.d.ts.map +0 -1
- package/dist/scripts/merge-linear-duplicates-safe.js +0 -267
- package/dist/scripts/merge-linear-duplicates-safe.js.map +0 -1
- package/dist/scripts/show-linear-summary.d.ts +0 -6
- package/dist/scripts/show-linear-summary.d.ts.map +0 -1
- package/dist/scripts/show-linear-summary.js +0 -120
- package/dist/scripts/show-linear-summary.js.map +0 -1
- package/dist/scripts/status.d.ts +0 -6
- package/dist/scripts/status.d.ts.map +0 -1
- package/dist/scripts/status.js +0 -101
- package/dist/scripts/status.js.map +0 -1
- package/dist/src/agents/core/agent-task-manager.d.ts +0 -154
- package/dist/src/agents/core/agent-task-manager.d.ts.map +0 -1
- package/dist/src/agents/core/agent-task-manager.js +0 -504
- package/dist/src/agents/core/agent-task-manager.js.map +0 -1
- package/dist/src/agents/verifiers/base-verifier.d.ts +0 -112
- package/dist/src/agents/verifiers/base-verifier.d.ts.map +0 -1
- package/dist/src/agents/verifiers/base-verifier.js +0 -130
- package/dist/src/agents/verifiers/base-verifier.js.map +0 -1
- package/dist/src/agents/verifiers/formatter-verifier.d.ts +0 -14
- package/dist/src/agents/verifiers/formatter-verifier.d.ts.map +0 -1
- package/dist/src/agents/verifiers/formatter-verifier.js +0 -107
- package/dist/src/agents/verifiers/formatter-verifier.js.map +0 -1
- package/dist/src/agents/verifiers/llm-judge.d.ts +0 -46
- package/dist/src/agents/verifiers/llm-judge.d.ts.map +0 -1
- package/dist/src/agents/verifiers/llm-judge.js +0 -248
- package/dist/src/agents/verifiers/llm-judge.js.map +0 -1
- package/dist/src/cli/auto-detect.d.ts +0 -61
- package/dist/src/cli/auto-detect.d.ts.map +0 -1
- package/dist/src/cli/auto-detect.js +0 -350
- package/dist/src/cli/auto-detect.js.map +0 -1
- package/dist/src/cli/browser-test.d.ts +0 -6
- package/dist/src/cli/browser-test.d.ts.map +0 -1
- package/dist/src/cli/browser-test.js +0 -32
- package/dist/src/cli/browser-test.js.map +0 -1
- package/dist/src/cli/claude-sm.d.ts +0 -7
- package/dist/src/cli/claude-sm.d.ts.map +0 -1
- package/dist/src/cli/claude-sm.js +0 -412
- package/dist/src/cli/claude-sm.js.map +0 -1
- package/dist/src/cli/commands/agent.d.ts +0 -9
- package/dist/src/cli/commands/agent.d.ts.map +0 -1
- package/dist/src/cli/commands/agent.js +0 -303
- package/dist/src/cli/commands/agent.js.map +0 -1
- package/dist/src/cli/commands/config.d.ts +0 -6
- package/dist/src/cli/commands/config.d.ts.map +0 -1
- package/dist/src/cli/commands/config.js +0 -224
- package/dist/src/cli/commands/config.js.map +0 -1
- package/dist/src/cli/commands/context.d.ts +0 -7
- package/dist/src/cli/commands/context.d.ts.map +0 -1
- package/dist/src/cli/commands/context.js +0 -365
- package/dist/src/cli/commands/context.js.map +0 -1
- package/dist/src/cli/commands/handoff.d.ts +0 -6
- package/dist/src/cli/commands/handoff.d.ts.map +0 -1
- package/dist/src/cli/commands/handoff.js +0 -212
- package/dist/src/cli/commands/handoff.js.map +0 -1
- package/dist/src/cli/commands/linear-test.d.ts +0 -6
- package/dist/src/cli/commands/linear-test.d.ts.map +0 -1
- package/dist/src/cli/commands/linear-test.js +0 -123
- package/dist/src/cli/commands/linear-test.js.map +0 -1
- package/dist/src/cli/commands/linear.d.ts +0 -6
- package/dist/src/cli/commands/linear.d.ts.map +0 -1
- package/dist/src/cli/commands/linear.js +0 -393
- package/dist/src/cli/commands/linear.js.map +0 -1
- package/dist/src/cli/commands/log.d.ts +0 -7
- package/dist/src/cli/commands/log.d.ts.map +0 -1
- package/dist/src/cli/commands/log.js +0 -168
- package/dist/src/cli/commands/log.js.map +0 -1
- package/dist/src/cli/commands/onboard.d.ts +0 -8
- package/dist/src/cli/commands/onboard.d.ts.map +0 -1
- package/dist/src/cli/commands/onboard.js +0 -363
- package/dist/src/cli/commands/onboard.js.map +0 -1
- package/dist/src/cli/commands/projects.d.ts +0 -8
- package/dist/src/cli/commands/projects.d.ts.map +0 -1
- package/dist/src/cli/commands/projects.js +0 -220
- package/dist/src/cli/commands/projects.js.map +0 -1
- package/dist/src/cli/commands/search.d.ts +0 -7
- package/dist/src/cli/commands/search.d.ts.map +0 -1
- package/dist/src/cli/commands/search.js +0 -162
- package/dist/src/cli/commands/search.js.map +0 -1
- package/dist/src/cli/commands/session.d.ts +0 -7
- package/dist/src/cli/commands/session.d.ts.map +0 -1
- package/dist/src/cli/commands/session.js +0 -222
- package/dist/src/cli/commands/session.js.map +0 -1
- package/dist/src/cli/commands/tasks.d.ts +0 -7
- package/dist/src/cli/commands/tasks.d.ts.map +0 -1
- package/dist/src/cli/commands/tasks.js +0 -229
- package/dist/src/cli/commands/tasks.js.map +0 -1
- package/dist/src/cli/commands/webhook.d.ts +0 -3
- package/dist/src/cli/commands/webhook.d.ts.map +0 -1
- package/dist/src/cli/commands/webhook.js +0 -157
- package/dist/src/cli/commands/webhook.js.map +0 -1
- package/dist/src/cli/commands/worktree.d.ts +0 -8
- package/dist/src/cli/commands/worktree.d.ts.map +0 -1
- package/dist/src/cli/commands/worktree.js +0 -339
- package/dist/src/cli/commands/worktree.js.map +0 -1
- package/dist/src/cli/index.d.ts +0 -8
- package/dist/src/cli/index.d.ts.map +0 -1
- package/dist/src/cli/index.js +0 -995
- package/dist/src/cli/index.js.map +0 -1
- package/dist/src/cli/utils/viewer.d.ts +0 -3
- package/dist/src/cli/utils/viewer.d.ts.map +0 -1
- package/dist/src/cli/utils/viewer.js +0 -91
- package/dist/src/cli/utils/viewer.js.map +0 -1
- package/dist/src/core/config/config-manager.d.ts +0 -95
- package/dist/src/core/config/config-manager.d.ts.map +0 -1
- package/dist/src/core/config/config-manager.js +0 -359
- package/dist/src/core/config/config-manager.js.map +0 -1
- package/dist/src/core/config/types.d.ts +0 -72
- package/dist/src/core/config/types.d.ts.map +0 -1
- package/dist/src/core/config/types.js +0 -127
- package/dist/src/core/config/types.js.map +0 -1
- package/dist/src/core/context/auto-context.d.ts +0 -22
- package/dist/src/core/context/auto-context.d.ts.map +0 -1
- package/dist/src/core/context/auto-context.js +0 -77
- package/dist/src/core/context/auto-context.js.map +0 -1
- package/dist/src/core/context/compaction-handler.d.ts +0 -119
- package/dist/src/core/context/compaction-handler.d.ts.map +0 -1
- package/dist/src/core/context/compaction-handler.js +0 -306
- package/dist/src/core/context/compaction-handler.js.map +0 -1
- package/dist/src/core/context/frame-database.d.ts +0 -59
- package/dist/src/core/context/frame-database.d.ts.map +0 -1
- package/dist/src/core/context/frame-database.js +0 -333
- package/dist/src/core/context/frame-database.js.map +0 -1
- package/dist/src/core/context/frame-digest.d.ts +0 -59
- package/dist/src/core/context/frame-digest.d.ts.map +0 -1
- package/dist/src/core/context/frame-digest.js +0 -264
- package/dist/src/core/context/frame-digest.js.map +0 -1
- package/dist/src/core/context/frame-manager.d.ts +0 -112
- package/dist/src/core/context/frame-manager.d.ts.map +0 -1
- package/dist/src/core/context/frame-manager.js +0 -600
- package/dist/src/core/context/frame-manager.js.map +0 -1
- package/dist/src/core/context/frame-stack.d.ts +0 -85
- package/dist/src/core/context/frame-stack.d.ts.map +0 -1
- package/dist/src/core/context/frame-stack.js +0 -287
- package/dist/src/core/context/frame-stack.js.map +0 -1
- package/dist/src/core/context/frame-types.d.ts +0 -67
- package/dist/src/core/context/frame-types.d.ts.map +0 -1
- package/dist/src/core/context/frame-types.js +0 -6
- package/dist/src/core/context/frame-types.js.map +0 -1
- package/dist/src/core/context/index.d.ts +0 -11
- package/dist/src/core/context/index.d.ts.map +0 -1
- package/dist/src/core/context/index.js +0 -14
- package/dist/src/core/context/index.js.map +0 -1
- package/dist/src/core/context/model-aware-compaction.d.ts +0 -101
- package/dist/src/core/context/model-aware-compaction.d.ts.map +0 -1
- package/dist/src/core/context/model-aware-compaction.js +0 -616
- package/dist/src/core/context/model-aware-compaction.js.map +0 -1
- package/dist/src/core/context/refactored-frame-manager.d.ts +0 -99
- package/dist/src/core/context/refactored-frame-manager.d.ts.map +0 -1
- package/dist/src/core/context/refactored-frame-manager.js +0 -340
- package/dist/src/core/context/refactored-frame-manager.js.map +0 -1
- package/dist/src/core/database/batch-operations.d.ts +0 -118
- package/dist/src/core/database/batch-operations.d.ts.map +0 -1
- package/dist/src/core/database/batch-operations.js +0 -339
- package/dist/src/core/database/batch-operations.js.map +0 -1
- package/dist/src/core/database/connection-pool.d.ts +0 -79
- package/dist/src/core/database/connection-pool.d.ts.map +0 -1
- package/dist/src/core/database/connection-pool.js +0 -236
- package/dist/src/core/database/connection-pool.js.map +0 -1
- package/dist/src/core/database/query-cache.d.ts +0 -135
- package/dist/src/core/database/query-cache.d.ts.map +0 -1
- package/dist/src/core/database/query-cache.js +0 -294
- package/dist/src/core/database/query-cache.js.map +0 -1
- package/dist/src/core/digest/enhanced-hybrid-digest.d.ts +0 -125
- package/dist/src/core/digest/enhanced-hybrid-digest.d.ts.map +0 -1
- package/dist/src/core/digest/enhanced-hybrid-digest.js +0 -282
- package/dist/src/core/digest/enhanced-hybrid-digest.js.map +0 -1
- package/dist/src/core/digest/frame-digest-integration.d.ts +0 -67
- package/dist/src/core/digest/frame-digest-integration.d.ts.map +0 -1
- package/dist/src/core/digest/frame-digest-integration.js +0 -198
- package/dist/src/core/digest/frame-digest-integration.js.map +0 -1
- package/dist/src/core/digest/hybrid-digest-generator.d.ts +0 -76
- package/dist/src/core/digest/hybrid-digest-generator.d.ts.map +0 -1
- package/dist/src/core/digest/hybrid-digest-generator.js +0 -629
- package/dist/src/core/digest/hybrid-digest-generator.js.map +0 -1
- package/dist/src/core/digest/index.d.ts +0 -9
- package/dist/src/core/digest/index.d.ts.map +0 -1
- package/dist/src/core/digest/index.js +0 -9
- package/dist/src/core/digest/index.js.map +0 -1
- package/dist/src/core/digest/types.d.ts +0 -154
- package/dist/src/core/digest/types.d.ts.map +0 -1
- package/dist/src/core/digest/types.js +0 -18
- package/dist/src/core/digest/types.js.map +0 -1
- package/dist/src/core/errors/index.d.ts +0 -143
- package/dist/src/core/errors/index.d.ts.map +0 -1
- package/dist/src/core/errors/index.js +0 -282
- package/dist/src/core/errors/index.js.map +0 -1
- package/dist/src/core/errors/recovery.d.ts +0 -86
- package/dist/src/core/errors/recovery.d.ts.map +0 -1
- package/dist/src/core/errors/recovery.js +0 -274
- package/dist/src/core/errors/recovery.js.map +0 -1
- package/dist/src/core/merge/conflict-detector.d.ts +0 -122
- package/dist/src/core/merge/conflict-detector.d.ts.map +0 -1
- package/dist/src/core/merge/conflict-detector.js +0 -468
- package/dist/src/core/merge/conflict-detector.js.map +0 -1
- package/dist/src/core/merge/index.d.ts +0 -9
- package/dist/src/core/merge/index.d.ts.map +0 -1
- package/dist/src/core/merge/index.js +0 -9
- package/dist/src/core/merge/index.js.map +0 -1
- package/dist/src/core/merge/resolution-engine.d.ts +0 -120
- package/dist/src/core/merge/resolution-engine.d.ts.map +0 -1
- package/dist/src/core/merge/resolution-engine.js +0 -573
- package/dist/src/core/merge/resolution-engine.js.map +0 -1
- package/dist/src/core/merge/stack-diff.d.ts +0 -97
- package/dist/src/core/merge/stack-diff.d.ts.map +0 -1
- package/dist/src/core/merge/stack-diff.js +0 -516
- package/dist/src/core/merge/stack-diff.js.map +0 -1
- package/dist/src/core/merge/types.d.ts +0 -110
- package/dist/src/core/merge/types.d.ts.map +0 -1
- package/dist/src/core/merge/types.js +0 -6
- package/dist/src/core/merge/types.js.map +0 -1
- package/dist/src/core/monitoring/error-handler.d.ts +0 -46
- package/dist/src/core/monitoring/error-handler.d.ts.map +0 -1
- package/dist/src/core/monitoring/error-handler.js +0 -212
- package/dist/src/core/monitoring/error-handler.js.map +0 -1
- package/dist/src/core/monitoring/logger.d.ts +0 -24
- package/dist/src/core/monitoring/logger.d.ts.map +0 -1
- package/dist/src/core/monitoring/logger.js +0 -126
- package/dist/src/core/monitoring/logger.js.map +0 -1
- package/dist/src/core/monitoring/metrics.d.ts +0 -10
- package/dist/src/core/monitoring/metrics.d.ts.map +0 -1
- package/dist/src/core/monitoring/metrics.js +0 -152
- package/dist/src/core/monitoring/metrics.js.map +0 -1
- package/dist/src/core/monitoring/progress-tracker.d.ts +0 -95
- package/dist/src/core/monitoring/progress-tracker.d.ts.map +0 -1
- package/dist/src/core/monitoring/progress-tracker.js +0 -178
- package/dist/src/core/monitoring/progress-tracker.js.map +0 -1
- package/dist/src/core/performance/context-cache.d.ts +0 -109
- package/dist/src/core/performance/context-cache.d.ts.map +0 -1
- package/dist/src/core/performance/context-cache.js +0 -280
- package/dist/src/core/performance/context-cache.js.map +0 -1
- package/dist/src/core/performance/index.d.ts +0 -3
- package/dist/src/core/performance/index.d.ts.map +0 -1
- package/dist/src/core/performance/index.js +0 -3
- package/dist/src/core/performance/index.js.map +0 -1
- package/dist/src/core/performance/lazy-context-loader.d.ts +0 -93
- package/dist/src/core/performance/lazy-context-loader.d.ts.map +0 -1
- package/dist/src/core/performance/lazy-context-loader.js +0 -332
- package/dist/src/core/performance/lazy-context-loader.js.map +0 -1
- package/dist/src/core/performance/monitor.d.ts +0 -48
- package/dist/src/core/performance/monitor.d.ts.map +0 -1
- package/dist/src/core/performance/monitor.js +0 -226
- package/dist/src/core/performance/monitor.js.map +0 -1
- package/dist/src/core/performance/optimized-frame-context.d.ts +0 -74
- package/dist/src/core/performance/optimized-frame-context.d.ts.map +0 -1
- package/dist/src/core/performance/optimized-frame-context.js +0 -330
- package/dist/src/core/performance/optimized-frame-context.js.map +0 -1
- package/dist/src/core/performance/performance-benchmark.d.ts +0 -50
- package/dist/src/core/performance/performance-benchmark.d.ts.map +0 -1
- package/dist/src/core/performance/performance-benchmark.js +0 -290
- package/dist/src/core/performance/performance-benchmark.js.map +0 -1
- package/dist/src/core/performance/performance-profiler.d.ts +0 -151
- package/dist/src/core/performance/performance-profiler.d.ts.map +0 -1
- package/dist/src/core/performance/performance-profiler.js +0 -346
- package/dist/src/core/performance/performance-profiler.js.map +0 -1
- package/dist/src/core/performance/streaming-jsonl-parser.d.ts +0 -41
- package/dist/src/core/performance/streaming-jsonl-parser.d.ts.map +0 -1
- package/dist/src/core/performance/streaming-jsonl-parser.js +0 -193
- package/dist/src/core/performance/streaming-jsonl-parser.js.map +0 -1
- package/dist/src/core/persistence/postgres-adapter.d.ts +0 -31
- package/dist/src/core/persistence/postgres-adapter.d.ts.map +0 -1
- package/dist/src/core/persistence/postgres-adapter.js +0 -330
- package/dist/src/core/persistence/postgres-adapter.js.map +0 -1
- package/dist/src/core/projects/project-manager.d.ts +0 -130
- package/dist/src/core/projects/project-manager.d.ts.map +0 -1
- package/dist/src/core/projects/project-manager.js +0 -709
- package/dist/src/core/projects/project-manager.js.map +0 -1
- package/dist/src/core/query/query-parser.d.ts +0 -109
- package/dist/src/core/query/query-parser.d.ts.map +0 -1
- package/dist/src/core/query/query-parser.js +0 -415
- package/dist/src/core/query/query-parser.js.map +0 -1
- package/dist/src/core/query/query-templates.d.ts +0 -44
- package/dist/src/core/query/query-templates.d.ts.map +0 -1
- package/dist/src/core/query/query-templates.js +0 -326
- package/dist/src/core/query/query-templates.js.map +0 -1
- package/dist/src/core/retrieval/index.d.ts +0 -8
- package/dist/src/core/retrieval/index.d.ts.map +0 -1
- package/dist/src/core/retrieval/index.js +0 -8
- package/dist/src/core/retrieval/index.js.map +0 -1
- package/dist/src/core/retrieval/llm-context-retrieval.d.ts +0 -73
- package/dist/src/core/retrieval/llm-context-retrieval.d.ts.map +0 -1
- package/dist/src/core/retrieval/llm-context-retrieval.js +0 -597
- package/dist/src/core/retrieval/llm-context-retrieval.js.map +0 -1
- package/dist/src/core/retrieval/summary-generator.d.ts +0 -63
- package/dist/src/core/retrieval/summary-generator.d.ts.map +0 -1
- package/dist/src/core/retrieval/summary-generator.js +0 -622
- package/dist/src/core/retrieval/summary-generator.js.map +0 -1
- package/dist/src/core/retrieval/types.d.ts +0 -257
- package/dist/src/core/retrieval/types.d.ts.map +0 -1
- package/dist/src/core/retrieval/types.js +0 -18
- package/dist/src/core/retrieval/types.js.map +0 -1
- package/dist/src/core/session/index.d.ts +0 -2
- package/dist/src/core/session/index.d.ts.map +0 -1
- package/dist/src/core/session/index.js +0 -2
- package/dist/src/core/session/index.js.map +0 -1
- package/dist/src/core/session/session-manager.d.ts +0 -69
- package/dist/src/core/session/session-manager.d.ts.map +0 -1
- package/dist/src/core/session/session-manager.js +0 -311
- package/dist/src/core/session/session-manager.js.map +0 -1
- package/dist/src/core/trace/cli-trace-wrapper.d.ts +0 -23
- package/dist/src/core/trace/cli-trace-wrapper.d.ts.map +0 -1
- package/dist/src/core/trace/cli-trace-wrapper.js +0 -141
- package/dist/src/core/trace/cli-trace-wrapper.js.map +0 -1
- package/dist/src/core/trace/db-trace-wrapper.d.ts +0 -36
- package/dist/src/core/trace/db-trace-wrapper.d.ts.map +0 -1
- package/dist/src/core/trace/db-trace-wrapper.js +0 -252
- package/dist/src/core/trace/db-trace-wrapper.js.map +0 -1
- package/dist/src/core/trace/debug-trace.d.ts +0 -84
- package/dist/src/core/trace/debug-trace.d.ts.map +0 -1
- package/dist/src/core/trace/debug-trace.js +0 -402
- package/dist/src/core/trace/debug-trace.js.map +0 -1
- package/dist/src/core/trace/error-test.d.ts +0 -6
- package/dist/src/core/trace/error-test.d.ts.map +0 -1
- package/dist/src/core/trace/error-test.js +0 -128
- package/dist/src/core/trace/error-test.js.map +0 -1
- package/dist/src/core/trace/index.d.ts +0 -25
- package/dist/src/core/trace/index.d.ts.map +0 -1
- package/dist/src/core/trace/index.js +0 -121
- package/dist/src/core/trace/index.js.map +0 -1
- package/dist/src/core/trace/linear-api-wrapper.d.ts +0 -17
- package/dist/src/core/trace/linear-api-wrapper.d.ts.map +0 -1
- package/dist/src/core/trace/linear-api-wrapper.js +0 -205
- package/dist/src/core/trace/linear-api-wrapper.js.map +0 -1
- package/dist/src/core/trace/performance-test.d.ts +0 -6
- package/dist/src/core/trace/performance-test.d.ts.map +0 -1
- package/dist/src/core/trace/performance-test.js +0 -111
- package/dist/src/core/trace/performance-test.js.map +0 -1
- package/dist/src/core/trace/trace-demo.d.ts +0 -8
- package/dist/src/core/trace/trace-demo.d.ts.map +0 -1
- package/dist/src/core/trace/trace-demo.js +0 -154
- package/dist/src/core/trace/trace-demo.js.map +0 -1
- package/dist/src/core/trace/trace-detector.d.ts +0 -108
- package/dist/src/core/trace/trace-detector.d.ts.map +0 -1
- package/dist/src/core/trace/trace-detector.demo.d.ts +0 -5
- package/dist/src/core/trace/trace-detector.demo.d.ts.map +0 -1
- package/dist/src/core/trace/trace-detector.demo.js +0 -145
- package/dist/src/core/trace/trace-detector.demo.js.map +0 -1
- package/dist/src/core/trace/trace-detector.js +0 -425
- package/dist/src/core/trace/trace-detector.js.map +0 -1
- package/dist/src/core/trace/trace-store.d.ts +0 -60
- package/dist/src/core/trace/trace-store.d.ts.map +0 -1
- package/dist/src/core/trace/trace-store.js +0 -323
- package/dist/src/core/trace/trace-store.js.map +0 -1
- package/dist/src/core/trace/types.d.ts +0 -81
- package/dist/src/core/trace/types.d.ts.map +0 -1
- package/dist/src/core/trace/types.js +0 -70
- package/dist/src/core/trace/types.js.map +0 -1
- package/dist/src/core/types.d.ts +0 -35
- package/dist/src/core/types.d.ts.map +0 -1
- package/dist/src/core/types.js +0 -2
- package/dist/src/core/types.js.map +0 -1
- package/dist/src/core/utils/update-checker.d.ts +0 -38
- package/dist/src/core/utils/update-checker.d.ts.map +0 -1
- package/dist/src/core/utils/update-checker.js +0 -213
- package/dist/src/core/utils/update-checker.js.map +0 -1
- package/dist/src/core/worktree/worktree-manager.d.ts +0 -110
- package/dist/src/core/worktree/worktree-manager.d.ts.map +0 -1
- package/dist/src/core/worktree/worktree-manager.js +0 -456
- package/dist/src/core/worktree/worktree-manager.js.map +0 -1
- package/dist/src/features/analytics/api/analytics-api.d.ts +0 -24
- package/dist/src/features/analytics/api/analytics-api.d.ts.map +0 -1
- package/dist/src/features/analytics/api/analytics-api.js +0 -289
- package/dist/src/features/analytics/api/analytics-api.js.map +0 -1
- package/dist/src/features/analytics/core/analytics-service.d.ts +0 -29
- package/dist/src/features/analytics/core/analytics-service.d.ts.map +0 -1
- package/dist/src/features/analytics/core/analytics-service.js +0 -275
- package/dist/src/features/analytics/core/analytics-service.js.map +0 -1
- package/dist/src/features/analytics/index.d.ts +0 -12
- package/dist/src/features/analytics/index.d.ts.map +0 -1
- package/dist/src/features/analytics/index.js +0 -11
- package/dist/src/features/analytics/index.js.map +0 -1
- package/dist/src/features/analytics/queries/metrics-queries.d.ts +0 -11
- package/dist/src/features/analytics/queries/metrics-queries.d.ts.map +0 -1
- package/dist/src/features/analytics/queries/metrics-queries.js +0 -240
- package/dist/src/features/analytics/queries/metrics-queries.js.map +0 -1
- package/dist/src/features/analytics/types/metrics.d.ts +0 -60
- package/dist/src/features/analytics/types/metrics.d.ts.map +0 -1
- package/dist/src/features/analytics/types/metrics.js +0 -2
- package/dist/src/features/analytics/types/metrics.js.map +0 -1
- package/dist/src/features/browser/browser-mcp.d.ts +0 -94
- package/dist/src/features/browser/browser-mcp.d.ts.map +0 -1
- package/dist/src/features/browser/browser-mcp.js +0 -459
- package/dist/src/features/browser/browser-mcp.js.map +0 -1
- package/dist/src/features/tasks/pebbles-task-store.d.ts +0 -128
- package/dist/src/features/tasks/pebbles-task-store.d.ts.map +0 -1
- package/dist/src/features/tasks/pebbles-task-store.js +0 -572
- package/dist/src/features/tasks/pebbles-task-store.js.map +0 -1
- package/dist/src/features/tasks/task-aware-context.d.ts +0 -103
- package/dist/src/features/tasks/task-aware-context.d.ts.map +0 -1
- package/dist/src/features/tasks/task-aware-context.js +0 -412
- package/dist/src/features/tasks/task-aware-context.js.map +0 -1
- package/dist/src/index.d.ts +0 -21
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -9
- package/dist/src/index.js.map +0 -1
- package/dist/src/integrations/linear/auth.d.ts +0 -99
- package/dist/src/integrations/linear/auth.d.ts.map +0 -1
- package/dist/src/integrations/linear/auth.js +0 -319
- package/dist/src/integrations/linear/auth.js.map +0 -1
- package/dist/src/integrations/linear/auto-sync.d.ts +0 -77
- package/dist/src/integrations/linear/auto-sync.d.ts.map +0 -1
- package/dist/src/integrations/linear/auto-sync.js +0 -268
- package/dist/src/integrations/linear/auto-sync.js.map +0 -1
- package/dist/src/integrations/linear/client.d.ts +0 -127
- package/dist/src/integrations/linear/client.d.ts.map +0 -1
- package/dist/src/integrations/linear/client.js +0 -446
- package/dist/src/integrations/linear/client.js.map +0 -1
- package/dist/src/integrations/linear/config.d.ts +0 -51
- package/dist/src/integrations/linear/config.d.ts.map +0 -1
- package/dist/src/integrations/linear/config.js +0 -103
- package/dist/src/integrations/linear/config.js.map +0 -1
- package/dist/src/integrations/linear/sync-manager.d.ts +0 -78
- package/dist/src/integrations/linear/sync-manager.d.ts.map +0 -1
- package/dist/src/integrations/linear/sync-manager.js +0 -235
- package/dist/src/integrations/linear/sync-manager.js.map +0 -1
- package/dist/src/integrations/linear/sync-service.d.ts +0 -46
- package/dist/src/integrations/linear/sync-service.d.ts.map +0 -1
- package/dist/src/integrations/linear/sync-service.js +0 -217
- package/dist/src/integrations/linear/sync-service.js.map +0 -1
- package/dist/src/integrations/linear/sync.d.ts +0 -125
- package/dist/src/integrations/linear/sync.d.ts.map +0 -1
- package/dist/src/integrations/linear/sync.js +0 -563
- package/dist/src/integrations/linear/sync.js.map +0 -1
- package/dist/src/integrations/linear/types.d.ts +0 -90
- package/dist/src/integrations/linear/types.d.ts.map +0 -1
- package/dist/src/integrations/linear/types.js +0 -2
- package/dist/src/integrations/linear/types.js.map +0 -1
- package/dist/src/integrations/linear/webhook-server.d.ts +0 -32
- package/dist/src/integrations/linear/webhook-server.d.ts.map +0 -1
- package/dist/src/integrations/linear/webhook-server.js +0 -190
- package/dist/src/integrations/linear/webhook-server.js.map +0 -1
- package/dist/src/integrations/linear/webhook.d.ts +0 -108
- package/dist/src/integrations/linear/webhook.d.ts.map +0 -1
- package/dist/src/integrations/linear/webhook.js +0 -291
- package/dist/src/integrations/linear/webhook.js.map +0 -1
- package/dist/src/integrations/mcp/handlers/context-handlers.d.ts +0 -39
- package/dist/src/integrations/mcp/handlers/context-handlers.d.ts.map +0 -1
- package/dist/src/integrations/mcp/handlers/context-handlers.js +0 -266
- package/dist/src/integrations/mcp/handlers/context-handlers.js.map +0 -1
- package/dist/src/integrations/mcp/handlers/index.d.ts +0 -37
- package/dist/src/integrations/mcp/handlers/index.d.ts.map +0 -1
- package/dist/src/integrations/mcp/handlers/index.js +0 -134
- package/dist/src/integrations/mcp/handlers/index.js.map +0 -1
- package/dist/src/integrations/mcp/handlers/linear-handlers.d.ts +0 -33
- package/dist/src/integrations/mcp/handlers/linear-handlers.d.ts.map +0 -1
- package/dist/src/integrations/mcp/handlers/linear-handlers.js +0 -251
- package/dist/src/integrations/mcp/handlers/linear-handlers.js.map +0 -1
- package/dist/src/integrations/mcp/handlers/task-handlers.d.ts +0 -42
- package/dist/src/integrations/mcp/handlers/task-handlers.d.ts.map +0 -1
- package/dist/src/integrations/mcp/handlers/task-handlers.js +0 -238
- package/dist/src/integrations/mcp/handlers/task-handlers.js.map +0 -1
- package/dist/src/integrations/mcp/handlers/trace-handlers.d.ts +0 -41
- package/dist/src/integrations/mcp/handlers/trace-handlers.d.ts.map +0 -1
- package/dist/src/integrations/mcp/handlers/trace-handlers.js +0 -298
- package/dist/src/integrations/mcp/handlers/trace-handlers.js.map +0 -1
- package/dist/src/integrations/mcp/index.d.ts +0 -13
- package/dist/src/integrations/mcp/index.d.ts.map +0 -1
- package/dist/src/integrations/mcp/index.js +0 -17
- package/dist/src/integrations/mcp/index.js.map +0 -1
- package/dist/src/integrations/mcp/refactored-server.d.ts +0 -76
- package/dist/src/integrations/mcp/refactored-server.d.ts.map +0 -1
- package/dist/src/integrations/mcp/refactored-server.js +0 -351
- package/dist/src/integrations/mcp/refactored-server.js.map +0 -1
- package/dist/src/integrations/mcp/server.d.ts +0 -54
- package/dist/src/integrations/mcp/server.d.ts.map +0 -1
- package/dist/src/integrations/mcp/server.js +0 -1616
- package/dist/src/integrations/mcp/server.js.map +0 -1
- package/dist/src/integrations/mcp/tool-definitions.d.ts +0 -44
- package/dist/src/integrations/mcp/tool-definitions.d.ts.map +0 -1
- package/dist/src/integrations/mcp/tool-definitions.js +0 -563
- package/dist/src/integrations/mcp/tool-definitions.js.map +0 -1
- package/dist/src/integrations/mcp/trace-test.d.ts +0 -5
- package/dist/src/integrations/mcp/trace-test.d.ts.map +0 -1
- package/dist/src/integrations/mcp/trace-test.js +0 -54
- package/dist/src/integrations/mcp/trace-test.js.map +0 -1
- package/dist/src/integrations/pg-aiguide/embedding-provider.d.ts +0 -48
- package/dist/src/integrations/pg-aiguide/embedding-provider.d.ts.map +0 -1
- package/dist/src/integrations/pg-aiguide/embedding-provider.js +0 -190
- package/dist/src/integrations/pg-aiguide/embedding-provider.js.map +0 -1
- package/dist/src/integrations/pg-aiguide/semantic-search.d.ts +0 -34
- package/dist/src/integrations/pg-aiguide/semantic-search.d.ts.map +0 -1
- package/dist/src/integrations/pg-aiguide/semantic-search.js +0 -176
- package/dist/src/integrations/pg-aiguide/semantic-search.js.map +0 -1
- package/dist/src/integrations/pg-aiguide/timescale-analytics.d.ts +0 -44
- package/dist/src/integrations/pg-aiguide/timescale-analytics.d.ts.map +0 -1
- package/dist/src/integrations/pg-aiguide/timescale-analytics.js +0 -215
- package/dist/src/integrations/pg-aiguide/timescale-analytics.js.map +0 -1
- package/dist/src/mcp/stackmemory-mcp-server.d.ts +0 -9
- package/dist/src/mcp/stackmemory-mcp-server.d.ts.map +0 -1
- package/dist/src/mcp/stackmemory-mcp-server.js +0 -519
- package/dist/src/mcp/stackmemory-mcp-server.js.map +0 -1
- package/dist/src/middleware/exponential-rate-limiter.d.ts +0 -78
- package/dist/src/middleware/exponential-rate-limiter.d.ts.map +0 -1
- package/dist/src/middleware/exponential-rate-limiter.js +0 -293
- package/dist/src/middleware/exponential-rate-limiter.js.map +0 -1
- package/dist/src/models/user.model.d.ts +0 -62
- package/dist/src/models/user.model.d.ts.map +0 -1
- package/dist/src/models/user.model.js +0 -311
- package/dist/src/models/user.model.js.map +0 -1
- package/dist/src/servers/production/auth-middleware.d.ts +0 -76
- package/dist/src/servers/production/auth-middleware.d.ts.map +0 -1
- package/dist/src/servers/production/auth-middleware.js +0 -558
- package/dist/src/servers/production/auth-middleware.js.map +0 -1
- package/dist/src/servers/railway/index.d.ts +0 -7
- package/dist/src/servers/railway/index.d.ts.map +0 -1
- package/dist/src/servers/railway/index.js +0 -401
- package/dist/src/servers/railway/index.js.map +0 -1
- package/dist/src/services/config-service.d.ts +0 -44
- package/dist/src/services/config-service.d.ts.map +0 -1
- package/dist/src/services/config-service.js +0 -61
- package/dist/src/services/config-service.js.map +0 -1
- package/dist/src/services/context-service.d.ts +0 -17
- package/dist/src/services/context-service.d.ts.map +0 -1
- package/dist/src/services/context-service.js +0 -173
- package/dist/src/services/context-service.js.map +0 -1
- package/dist/src/types/task.d.ts +0 -27
- package/dist/src/types/task.d.ts.map +0 -1
- package/dist/src/types/task.js +0 -2
- package/dist/src/types/task.js.map +0 -1
- package/dist/src/utils/logger.d.ts +0 -13
- package/dist/src/utils/logger.d.ts.map +0 -1
- package/dist/src/utils/logger.js +0 -52
- package/dist/src/utils/logger.js.map +0 -1
- package/dist/src/validation/schemas.d.ts +0 -633
- package/dist/src/validation/schemas.d.ts.map +0 -1
- package/dist/src/validation/schemas.js +0 -347
- package/dist/src/validation/schemas.js.map +0 -1
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import * as fs from "fs/promises";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
class HandoffGenerator {
|
|
4
|
+
frameManager;
|
|
5
|
+
dbManager;
|
|
6
|
+
handoffDir;
|
|
7
|
+
constructor(frameManager, dbManager, projectRoot) {
|
|
8
|
+
this.frameManager = frameManager;
|
|
9
|
+
this.dbManager = dbManager;
|
|
10
|
+
this.handoffDir = path.join(projectRoot, ".stackmemory", "handoffs");
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Generate a handoff document for the current session
|
|
14
|
+
*/
|
|
15
|
+
async generateHandoff(sessionId) {
|
|
16
|
+
const session = await this.dbManager.getSession(sessionId);
|
|
17
|
+
if (!session) throw new Error(`Session ${sessionId} not found`);
|
|
18
|
+
const activeFramePath = await this.getActiveFramePath();
|
|
19
|
+
const recentTraces = await this.dbManager.getRecentTraces(sessionId, 100);
|
|
20
|
+
const recentFrames = await this.dbManager.getRecentFrames(sessionId, 20);
|
|
21
|
+
const tasks = await this.extractTasks(recentFrames);
|
|
22
|
+
const decisions = await this.extractDecisions(recentTraces);
|
|
23
|
+
const blockers = await this.extractBlockers(recentTraces, recentFrames);
|
|
24
|
+
const fileEdits = await this.extractFileEdits(recentTraces);
|
|
25
|
+
const commands = await this.extractCommands(recentTraces);
|
|
26
|
+
const errors = await this.extractErrors(recentTraces);
|
|
27
|
+
const patterns = await this.detectPatterns(recentTraces);
|
|
28
|
+
const approaches = await this.extractApproaches(recentFrames);
|
|
29
|
+
const sessionDuration = Math.floor(
|
|
30
|
+
(Date.now() - new Date(session.startedAt).getTime()) / 6e4
|
|
31
|
+
);
|
|
32
|
+
const handoff = {
|
|
33
|
+
session_id: sessionId,
|
|
34
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35
|
+
project: session.project,
|
|
36
|
+
branch: session.metadata?.branch,
|
|
37
|
+
active_frame_path: activeFramePath,
|
|
38
|
+
active_tasks: tasks,
|
|
39
|
+
pending_decisions: decisions.filter((d) => !d.resolved),
|
|
40
|
+
blockers,
|
|
41
|
+
recent_files: fileEdits.slice(0, 10),
|
|
42
|
+
recent_commands: commands.slice(0, 10),
|
|
43
|
+
recent_errors: errors.slice(0, 5),
|
|
44
|
+
patterns_detected: patterns,
|
|
45
|
+
approaches_tried: approaches,
|
|
46
|
+
successful_strategies: this.extractSuccessfulStrategies(approaches),
|
|
47
|
+
suggested_next_actions: await this.suggestNextActions(
|
|
48
|
+
tasks,
|
|
49
|
+
blockers,
|
|
50
|
+
activeFramePath
|
|
51
|
+
),
|
|
52
|
+
warnings: await this.generateWarnings(errors, blockers),
|
|
53
|
+
session_duration_minutes: sessionDuration,
|
|
54
|
+
frames_created: recentFrames.length,
|
|
55
|
+
tool_calls_made: recentTraces.filter((t) => t.type === "tool_call").length,
|
|
56
|
+
decisions_recorded: decisions.length
|
|
57
|
+
};
|
|
58
|
+
await this.saveHandoff(handoff);
|
|
59
|
+
return handoff;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Load the most recent handoff document
|
|
63
|
+
*/
|
|
64
|
+
async loadHandoff() {
|
|
65
|
+
try {
|
|
66
|
+
await fs.mkdir(this.handoffDir, { recursive: true });
|
|
67
|
+
const files = await fs.readdir(this.handoffDir);
|
|
68
|
+
const handoffFiles = files.filter((f) => f.endsWith(".json")).sort().reverse();
|
|
69
|
+
if (handoffFiles.length === 0) return null;
|
|
70
|
+
const mostRecent = handoffFiles[0];
|
|
71
|
+
const content = await fs.readFile(
|
|
72
|
+
path.join(this.handoffDir, mostRecent),
|
|
73
|
+
"utf-8"
|
|
74
|
+
);
|
|
75
|
+
return JSON.parse(content);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error("Error loading handoff:", error);
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Generate a markdown summary of the handoff
|
|
83
|
+
*/
|
|
84
|
+
async generateMarkdownSummary(handoff) {
|
|
85
|
+
const lines = [
|
|
86
|
+
`# Session Handoff`,
|
|
87
|
+
`**Generated**: ${new Date(handoff.timestamp).toLocaleString()}`,
|
|
88
|
+
`**Project**: ${handoff.project}`,
|
|
89
|
+
handoff.branch ? `**Branch**: ${handoff.branch}` : "",
|
|
90
|
+
`**Duration**: ${handoff.session_duration_minutes} minutes`,
|
|
91
|
+
"",
|
|
92
|
+
`## Current Context`,
|
|
93
|
+
`**Active Frame Path**: ${handoff.active_frame_path.join(" \u2192 ")}`,
|
|
94
|
+
"",
|
|
95
|
+
`## Active Tasks (${handoff.active_tasks.length})`,
|
|
96
|
+
...handoff.active_tasks.map(
|
|
97
|
+
(t) => `- [${t.status}] ${t.title} (${t.progress_percentage}%)${t.blocker ? ` \u26A0\uFE0F Blocked: ${t.blocker}` : ""}`
|
|
98
|
+
),
|
|
99
|
+
"",
|
|
100
|
+
handoff.blockers.length > 0 ? "## Blockers" : "",
|
|
101
|
+
...handoff.blockers.map(
|
|
102
|
+
(b) => `- **${b.severity}**: ${b.description}
|
|
103
|
+
Tried: ${b.attempted_solutions.join(
|
|
104
|
+
", "
|
|
105
|
+
)}`
|
|
106
|
+
),
|
|
107
|
+
"",
|
|
108
|
+
handoff.pending_decisions.length > 0 ? "## Pending Decisions" : "",
|
|
109
|
+
...handoff.pending_decisions.map(
|
|
110
|
+
(d) => `- **${d.decision}**
|
|
111
|
+
Rationale: ${d.rationale}`
|
|
112
|
+
),
|
|
113
|
+
"",
|
|
114
|
+
"## Recent Activity",
|
|
115
|
+
`- Files edited: ${handoff.recent_files.length}`,
|
|
116
|
+
`- Commands run: ${handoff.recent_commands.length}`,
|
|
117
|
+
`- Errors encountered: ${handoff.recent_errors.length}`,
|
|
118
|
+
"",
|
|
119
|
+
handoff.patterns_detected.length > 0 ? "## Patterns Detected" : "",
|
|
120
|
+
...handoff.patterns_detected.map((p) => `- ${p}`),
|
|
121
|
+
"",
|
|
122
|
+
handoff.successful_strategies.length > 0 ? "## Successful Strategies" : "",
|
|
123
|
+
...handoff.successful_strategies.map((s) => `- ${s}`),
|
|
124
|
+
"",
|
|
125
|
+
"## Suggested Next Actions",
|
|
126
|
+
...handoff.suggested_next_actions.map((a) => `1. ${a}`),
|
|
127
|
+
"",
|
|
128
|
+
handoff.warnings.length > 0 ? "## \u26A0\uFE0F Warnings" : "",
|
|
129
|
+
...handoff.warnings.map((w) => `- ${w}`)
|
|
130
|
+
];
|
|
131
|
+
return lines.filter((l) => l !== "").join("\n");
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Auto-detect session end and trigger handoff
|
|
135
|
+
*/
|
|
136
|
+
async detectSessionEnd(sessionId) {
|
|
137
|
+
const idleThreshold = 5 * 60 * 1e3;
|
|
138
|
+
const lastActivity = await this.dbManager.getLastActivityTime(sessionId);
|
|
139
|
+
if (!lastActivity) return false;
|
|
140
|
+
const idleTime = Date.now() - lastActivity.getTime();
|
|
141
|
+
if (idleTime > idleThreshold) {
|
|
142
|
+
await this.generateHandoff(sessionId);
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
// Private helper methods
|
|
148
|
+
async getActiveFramePath() {
|
|
149
|
+
const stack = await this.frameManager.getStack();
|
|
150
|
+
return stack.frames.map((f) => f.description || f.type);
|
|
151
|
+
}
|
|
152
|
+
async extractTasks(frames) {
|
|
153
|
+
return frames.filter((f) => f.type === "task").map((f) => ({
|
|
154
|
+
id: f.id,
|
|
155
|
+
title: f.description || "Untitled task",
|
|
156
|
+
status: this.getTaskStatus(f),
|
|
157
|
+
progress_percentage: f.metadata?.progress || 0,
|
|
158
|
+
blocker: f.metadata?.blocker
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
getTaskStatus(frame) {
|
|
162
|
+
if (frame.status === "closed") return "completed";
|
|
163
|
+
if (frame.metadata?.blocker) return "blocked";
|
|
164
|
+
if (frame.status === "open") return "in_progress";
|
|
165
|
+
return "pending";
|
|
166
|
+
}
|
|
167
|
+
async extractDecisions(traces) {
|
|
168
|
+
return traces.filter((t) => t.type === "decision").map((t) => ({
|
|
169
|
+
decision: t.content.decision || "",
|
|
170
|
+
rationale: t.content.rationale || "",
|
|
171
|
+
alternatives_considered: t.content.alternatives,
|
|
172
|
+
timestamp: t.timestamp,
|
|
173
|
+
resolved: t.metadata?.resolved || false
|
|
174
|
+
}));
|
|
175
|
+
}
|
|
176
|
+
async extractBlockers(traces, frames) {
|
|
177
|
+
const blockers = [];
|
|
178
|
+
const errorTraces = traces.filter(
|
|
179
|
+
(t) => t.type === "error" && !t.metadata?.resolved
|
|
180
|
+
);
|
|
181
|
+
for (const trace of errorTraces) {
|
|
182
|
+
blockers.push({
|
|
183
|
+
description: trace.content.error || "Unknown error",
|
|
184
|
+
attempted_solutions: trace.metadata?.attempts || [],
|
|
185
|
+
suggested_approach: trace.metadata?.suggestion,
|
|
186
|
+
severity: this.getErrorSeverity(trace)
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
const blockedFrames = frames.filter((f) => f.metadata?.blocker);
|
|
190
|
+
for (const frame of blockedFrames) {
|
|
191
|
+
blockers.push({
|
|
192
|
+
description: frame.metadata.blocker,
|
|
193
|
+
attempted_solutions: frame.metadata.attempts || [],
|
|
194
|
+
severity: "medium"
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return blockers;
|
|
198
|
+
}
|
|
199
|
+
getErrorSeverity(trace) {
|
|
200
|
+
const error = trace.content.error?.toLowerCase() || "";
|
|
201
|
+
if (error.includes("critical") || error.includes("fatal"))
|
|
202
|
+
return "critical";
|
|
203
|
+
if (error.includes("error") || error.includes("fail")) return "high";
|
|
204
|
+
if (error.includes("warning")) return "medium";
|
|
205
|
+
return "low";
|
|
206
|
+
}
|
|
207
|
+
async extractFileEdits(traces) {
|
|
208
|
+
const fileMap = /* @__PURE__ */ new Map();
|
|
209
|
+
const editTraces = traces.filter(
|
|
210
|
+
(t) => ["edit", "write", "create", "delete"].includes(t.type)
|
|
211
|
+
);
|
|
212
|
+
for (const trace of editTraces) {
|
|
213
|
+
const path2 = trace.content.file_path || trace.content.path;
|
|
214
|
+
if (!path2) continue;
|
|
215
|
+
if (!fileMap.has(path2)) {
|
|
216
|
+
fileMap.set(path2, {
|
|
217
|
+
path: path2,
|
|
218
|
+
operations: [],
|
|
219
|
+
line_changes: { added: 0, removed: 0 }
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
const file = fileMap.get(path2);
|
|
223
|
+
const op = this.getFileOperation(trace.type);
|
|
224
|
+
if (!file.operations.includes(op)) {
|
|
225
|
+
file.operations.push(op);
|
|
226
|
+
}
|
|
227
|
+
file.line_changes.added += trace.metadata?.lines_added || 0;
|
|
228
|
+
file.line_changes.removed += trace.metadata?.lines_removed || 0;
|
|
229
|
+
}
|
|
230
|
+
return Array.from(fileMap.values());
|
|
231
|
+
}
|
|
232
|
+
getFileOperation(traceType) {
|
|
233
|
+
switch (traceType) {
|
|
234
|
+
case "create":
|
|
235
|
+
case "write":
|
|
236
|
+
return "created";
|
|
237
|
+
case "edit":
|
|
238
|
+
return "modified";
|
|
239
|
+
case "delete":
|
|
240
|
+
return "deleted";
|
|
241
|
+
default:
|
|
242
|
+
return "modified";
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async extractCommands(traces) {
|
|
246
|
+
return traces.filter((t) => t.type === "bash" || t.type === "command").map((t) => ({
|
|
247
|
+
command: t.content.command || "",
|
|
248
|
+
success: !t.metadata?.error,
|
|
249
|
+
output_summary: t.content.output?.substring(0, 100)
|
|
250
|
+
}));
|
|
251
|
+
}
|
|
252
|
+
async extractErrors(traces) {
|
|
253
|
+
return traces.filter((t) => t.type === "error").map((t) => ({
|
|
254
|
+
error: t.content.error || "",
|
|
255
|
+
context: t.content.context || "",
|
|
256
|
+
resolved: t.metadata?.resolved || false,
|
|
257
|
+
resolution: t.metadata?.resolution
|
|
258
|
+
}));
|
|
259
|
+
}
|
|
260
|
+
async detectPatterns(traces) {
|
|
261
|
+
const patterns = [];
|
|
262
|
+
const testFirst = traces.some(
|
|
263
|
+
(t) => t.type === "test" && traces.some(
|
|
264
|
+
(t2) => t2.type === "implement" && t2.timestamp > t.timestamp
|
|
265
|
+
)
|
|
266
|
+
);
|
|
267
|
+
if (testFirst) patterns.push("Test-Driven Development");
|
|
268
|
+
const refactoring = traces.filter(
|
|
269
|
+
(t) => t.content.description?.includes("refactor") || t.metadata?.operation === "refactor"
|
|
270
|
+
).length > 3;
|
|
271
|
+
if (refactoring) patterns.push("Active Refactoring");
|
|
272
|
+
const debugging = traces.filter((t) => t.type === "error" || t.type === "debug").length > 5;
|
|
273
|
+
if (debugging) patterns.push("Deep Debugging Session");
|
|
274
|
+
return patterns;
|
|
275
|
+
}
|
|
276
|
+
async extractApproaches(frames) {
|
|
277
|
+
return frames.filter((f) => f.metadata?.approach).map((f) => ({
|
|
278
|
+
approach: f.metadata.approach,
|
|
279
|
+
outcome: this.getApproachOutcome(f),
|
|
280
|
+
learnings: f.metadata.learnings
|
|
281
|
+
}));
|
|
282
|
+
}
|
|
283
|
+
getApproachOutcome(frame) {
|
|
284
|
+
if (frame.status === "closed" && frame.metadata?.success)
|
|
285
|
+
return "successful";
|
|
286
|
+
if (frame.status === "closed" && !frame.metadata?.success) return "failed";
|
|
287
|
+
return "partial";
|
|
288
|
+
}
|
|
289
|
+
extractSuccessfulStrategies(approaches) {
|
|
290
|
+
return approaches.filter((a) => a.outcome === "successful").map((a) => a.approach);
|
|
291
|
+
}
|
|
292
|
+
async suggestNextActions(tasks, blockers, framePath) {
|
|
293
|
+
const suggestions = [];
|
|
294
|
+
const inProgress = tasks.filter((t) => t.status === "in_progress");
|
|
295
|
+
if (inProgress.length > 0) {
|
|
296
|
+
suggestions.push(`Resume task: ${inProgress[0].title}`);
|
|
297
|
+
}
|
|
298
|
+
const criticalBlockers = blockers.filter((b) => b.severity === "critical");
|
|
299
|
+
if (criticalBlockers.length > 0) {
|
|
300
|
+
suggestions.push(
|
|
301
|
+
`Resolve critical blocker: ${criticalBlockers[0].description}`
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
const nearlyDone = tasks.filter((t) => t.progress_percentage >= 80);
|
|
305
|
+
if (nearlyDone.length > 0) {
|
|
306
|
+
suggestions.push(
|
|
307
|
+
`Complete task: ${nearlyDone[0].title} (${nearlyDone[0].progress_percentage}% done)`
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
return suggestions;
|
|
311
|
+
}
|
|
312
|
+
async generateWarnings(errors, blockers) {
|
|
313
|
+
const warnings = [];
|
|
314
|
+
const unresolved = errors.filter((e) => !e.resolved);
|
|
315
|
+
if (unresolved.length > 0) {
|
|
316
|
+
warnings.push(`${unresolved.length} unresolved errors`);
|
|
317
|
+
}
|
|
318
|
+
const critical = blockers.filter((b) => b.severity === "critical");
|
|
319
|
+
if (critical.length > 0) {
|
|
320
|
+
warnings.push(
|
|
321
|
+
`${critical.length} critical blockers need immediate attention`
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
return warnings;
|
|
325
|
+
}
|
|
326
|
+
async saveHandoff(handoff) {
|
|
327
|
+
await fs.mkdir(this.handoffDir, { recursive: true });
|
|
328
|
+
const filename = `${handoff.timestamp.replace(/[:.]/g, "-")}.json`;
|
|
329
|
+
const filepath = path.join(this.handoffDir, filename);
|
|
330
|
+
await fs.writeFile(filepath, JSON.stringify(handoff, null, 2), "utf-8");
|
|
331
|
+
const markdown = await this.generateMarkdownSummary(handoff);
|
|
332
|
+
const mdPath = filepath.replace(".json", ".md");
|
|
333
|
+
await fs.writeFile(mdPath, markdown, "utf-8");
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
export {
|
|
337
|
+
HandoffGenerator
|
|
338
|
+
};
|
|
339
|
+
//# sourceMappingURL=handoff-generator.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/core/session/handoff-generator.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Session Handoff Generator for StackMemory\n * Inspired by Continuous-Claude's handoff documents\n *\n * Generates structured transfer documents when sessions end\n * and loads them when new sessions begin\n */\n\nimport { Frame, Trace, Context } from '../types';\nimport { FrameManager } from '../frame/frame-manager';\nimport { DatabaseManager } from '../storage/database-manager';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\n\nexport interface HandoffDocument {\n session_id: string;\n timestamp: string;\n project: string;\n branch?: string;\n\n // Current state\n active_frame_path: string[];\n active_tasks: TaskSummary[];\n pending_decisions: DecisionPoint[];\n blockers: Blocker[];\n\n // Recent context\n recent_files: FileEdit[];\n recent_commands: CommandExecution[];\n recent_errors: ErrorContext[];\n\n // Key insights\n patterns_detected: string[];\n approaches_tried: ApproachSummary[];\n successful_strategies: string[];\n\n // Next steps\n suggested_next_actions: string[];\n warnings: string[];\n\n // Metrics\n session_duration_minutes: number;\n frames_created: number;\n tool_calls_made: number;\n decisions_recorded: number;\n}\n\ninterface TaskSummary {\n id: string;\n title: string;\n status: 'pending' | 'in_progress' | 'blocked' | 'completed';\n progress_percentage: number;\n blocker?: string;\n}\n\ninterface DecisionPoint {\n decision: string;\n rationale: string;\n alternatives_considered?: string[];\n timestamp: string;\n}\n\ninterface Blocker {\n description: string;\n attempted_solutions: string[];\n suggested_approach?: string;\n severity: 'low' | 'medium' | 'high' | 'critical';\n}\n\ninterface FileEdit {\n path: string;\n operations: ('created' | 'modified' | 'deleted')[];\n line_changes: { added: number; removed: number };\n}\n\ninterface CommandExecution {\n command: string;\n success: boolean;\n output_summary?: string;\n}\n\ninterface ErrorContext {\n error: string;\n context: string;\n resolved: boolean;\n resolution?: string;\n}\n\ninterface ApproachSummary {\n approach: string;\n outcome: 'successful' | 'failed' | 'partial';\n learnings?: string;\n}\n\nexport class HandoffGenerator {\n private frameManager: FrameManager;\n private dbManager: DatabaseManager;\n private handoffDir: string;\n\n constructor(\n frameManager: FrameManager,\n dbManager: DatabaseManager,\n projectRoot: string\n ) {\n this.frameManager = frameManager;\n this.dbManager = dbManager;\n this.handoffDir = path.join(projectRoot, '.stackmemory', 'handoffs');\n }\n\n /**\n * Generate a handoff document for the current session\n */\n async generateHandoff(sessionId: string): Promise<HandoffDocument> {\n const session = await this.dbManager.getSession(sessionId);\n if (!session) throw new Error(`Session ${sessionId} not found`);\n\n // Get active frame stack\n const activeFramePath = await this.getActiveFramePath();\n\n // Get recent activity\n const recentTraces = await this.dbManager.getRecentTraces(sessionId, 100);\n const recentFrames = await this.dbManager.getRecentFrames(sessionId, 20);\n\n // Extract key information\n const tasks = await this.extractTasks(recentFrames);\n const decisions = await this.extractDecisions(recentTraces);\n const blockers = await this.extractBlockers(recentTraces, recentFrames);\n const fileEdits = await this.extractFileEdits(recentTraces);\n const commands = await this.extractCommands(recentTraces);\n const errors = await this.extractErrors(recentTraces);\n const patterns = await this.detectPatterns(recentTraces);\n const approaches = await this.extractApproaches(recentFrames);\n\n // Calculate metrics\n const sessionDuration = Math.floor(\n (Date.now() - new Date(session.startedAt).getTime()) / 60000\n );\n\n const handoff: HandoffDocument = {\n session_id: sessionId,\n timestamp: new Date().toISOString(),\n project: session.project,\n branch: session.metadata?.branch,\n\n active_frame_path: activeFramePath,\n active_tasks: tasks,\n pending_decisions: decisions.filter((d) => !d.resolved),\n blockers: blockers,\n\n recent_files: fileEdits.slice(0, 10),\n recent_commands: commands.slice(0, 10),\n recent_errors: errors.slice(0, 5),\n\n patterns_detected: patterns,\n approaches_tried: approaches,\n successful_strategies: this.extractSuccessfulStrategies(approaches),\n\n suggested_next_actions: await this.suggestNextActions(\n tasks,\n blockers,\n activeFramePath\n ),\n warnings: await this.generateWarnings(errors, blockers),\n\n session_duration_minutes: sessionDuration,\n frames_created: recentFrames.length,\n tool_calls_made: recentTraces.filter((t) => t.type === 'tool_call')\n .length,\n decisions_recorded: decisions.length,\n };\n\n // Save to file\n await this.saveHandoff(handoff);\n\n return handoff;\n }\n\n /**\n * Load the most recent handoff document\n */\n async loadHandoff(): Promise<HandoffDocument | null> {\n try {\n await fs.mkdir(this.handoffDir, { recursive: true });\n\n const files = await fs.readdir(this.handoffDir);\n const handoffFiles = files\n .filter((f) => f.endsWith('.json'))\n .sort()\n .reverse();\n\n if (handoffFiles.length === 0) return null;\n\n const mostRecent = handoffFiles[0];\n const content = await fs.readFile(\n path.join(this.handoffDir, mostRecent),\n 'utf-8'\n );\n\n return JSON.parse(content) as HandoffDocument;\n } catch (error) {\n console.error('Error loading handoff:', error);\n return null;\n }\n }\n\n /**\n * Generate a markdown summary of the handoff\n */\n async generateMarkdownSummary(handoff: HandoffDocument): Promise<string> {\n const lines: string[] = [\n `# Session Handoff`,\n `**Generated**: ${new Date(handoff.timestamp).toLocaleString()}`,\n `**Project**: ${handoff.project}`,\n handoff.branch ? `**Branch**: ${handoff.branch}` : '',\n `**Duration**: ${handoff.session_duration_minutes} minutes`,\n '',\n\n `## Current Context`,\n `**Active Frame Path**: ${handoff.active_frame_path.join(' \u2192 ')}`,\n '',\n\n `## Active Tasks (${handoff.active_tasks.length})`,\n ...handoff.active_tasks.map(\n (t) =>\n `- [${t.status}] ${t.title} (${t.progress_percentage}%)${\n t.blocker ? ` \u26A0\uFE0F Blocked: ${t.blocker}` : ''\n }`\n ),\n '',\n\n handoff.blockers.length > 0 ? '## Blockers' : '',\n ...handoff.blockers.map(\n (b) =>\n `- **${b.severity}**: ${b.description}\\n Tried: ${b.attempted_solutions.join(\n ', '\n )}`\n ),\n '',\n\n handoff.pending_decisions.length > 0 ? '## Pending Decisions' : '',\n ...handoff.pending_decisions.map(\n (d) => `- **${d.decision}**\\n Rationale: ${d.rationale}`\n ),\n '',\n\n '## Recent Activity',\n `- Files edited: ${handoff.recent_files.length}`,\n `- Commands run: ${handoff.recent_commands.length}`,\n `- Errors encountered: ${handoff.recent_errors.length}`,\n '',\n\n handoff.patterns_detected.length > 0 ? '## Patterns Detected' : '',\n ...handoff.patterns_detected.map((p) => `- ${p}`),\n '',\n\n handoff.successful_strategies.length > 0\n ? '## Successful Strategies'\n : '',\n ...handoff.successful_strategies.map((s) => `- ${s}`),\n '',\n\n '## Suggested Next Actions',\n ...handoff.suggested_next_actions.map((a) => `1. ${a}`),\n '',\n\n handoff.warnings.length > 0 ? '## \u26A0\uFE0F Warnings' : '',\n ...handoff.warnings.map((w) => `- ${w}`),\n ];\n\n return lines.filter((l) => l !== '').join('\\n');\n }\n\n /**\n * Auto-detect session end and trigger handoff\n */\n async detectSessionEnd(sessionId: string): Promise<boolean> {\n const idleThreshold = 5 * 60 * 1000; // 5 minutes\n const lastActivity = await this.dbManager.getLastActivityTime(sessionId);\n\n if (!lastActivity) return false;\n\n const idleTime = Date.now() - lastActivity.getTime();\n if (idleTime > idleThreshold) {\n await this.generateHandoff(sessionId);\n return true;\n }\n\n return false;\n }\n\n // Private helper methods\n\n private async getActiveFramePath(): Promise<string[]> {\n const stack = await this.frameManager.getStack();\n return stack.frames.map((f) => f.description || f.type);\n }\n\n private async extractTasks(frames: Frame[]): Promise<TaskSummary[]> {\n return frames\n .filter((f) => f.type === 'task')\n .map((f) => ({\n id: f.id,\n title: f.description || 'Untitled task',\n status: this.getTaskStatus(f),\n progress_percentage: f.metadata?.progress || 0,\n blocker: f.metadata?.blocker,\n }));\n }\n\n private getTaskStatus(frame: Frame): TaskSummary['status'] {\n if (frame.status === 'closed') return 'completed';\n if (frame.metadata?.blocker) return 'blocked';\n if (frame.status === 'open') return 'in_progress';\n return 'pending';\n }\n\n private async extractDecisions(traces: Trace[]): Promise<DecisionPoint[]> {\n return traces\n .filter((t) => t.type === 'decision')\n .map((t) => ({\n decision: t.content.decision || '',\n rationale: t.content.rationale || '',\n alternatives_considered: t.content.alternatives,\n timestamp: t.timestamp,\n resolved: t.metadata?.resolved || false,\n }));\n }\n\n private async extractBlockers(\n traces: Trace[],\n frames: Frame[]\n ): Promise<Blocker[]> {\n const blockers: Blocker[] = [];\n\n // Extract from error traces\n const errorTraces = traces.filter(\n (t) => t.type === 'error' && !t.metadata?.resolved\n );\n\n for (const trace of errorTraces) {\n blockers.push({\n description: trace.content.error || 'Unknown error',\n attempted_solutions: trace.metadata?.attempts || [],\n suggested_approach: trace.metadata?.suggestion,\n severity: this.getErrorSeverity(trace),\n });\n }\n\n // Extract from blocked frames\n const blockedFrames = frames.filter((f) => f.metadata?.blocker);\n for (const frame of blockedFrames) {\n blockers.push({\n description: frame.metadata.blocker,\n attempted_solutions: frame.metadata.attempts || [],\n severity: 'medium',\n });\n }\n\n return blockers;\n }\n\n private getErrorSeverity(trace: Trace): Blocker['severity'] {\n const error = trace.content.error?.toLowerCase() || '';\n if (error.includes('critical') || error.includes('fatal'))\n return 'critical';\n if (error.includes('error') || error.includes('fail')) return 'high';\n if (error.includes('warning')) return 'medium';\n return 'low';\n }\n\n private async extractFileEdits(traces: Trace[]): Promise<FileEdit[]> {\n const fileMap = new Map<string, FileEdit>();\n\n const editTraces = traces.filter((t) =>\n ['edit', 'write', 'create', 'delete'].includes(t.type)\n );\n\n for (const trace of editTraces) {\n const path = trace.content.file_path || trace.content.path;\n if (!path) continue;\n\n if (!fileMap.has(path)) {\n fileMap.set(path, {\n path,\n operations: [],\n line_changes: { added: 0, removed: 0 },\n });\n }\n\n const file = fileMap.get(path)!;\n const op = this.getFileOperation(trace.type);\n if (!file.operations.includes(op)) {\n file.operations.push(op);\n }\n\n file.line_changes.added += trace.metadata?.lines_added || 0;\n file.line_changes.removed += trace.metadata?.lines_removed || 0;\n }\n\n return Array.from(fileMap.values());\n }\n\n private getFileOperation(traceType: string): FileEdit['operations'][0] {\n switch (traceType) {\n case 'create':\n case 'write':\n return 'created';\n case 'edit':\n return 'modified';\n case 'delete':\n return 'deleted';\n default:\n return 'modified';\n }\n }\n\n private async extractCommands(traces: Trace[]): Promise<CommandExecution[]> {\n return traces\n .filter((t) => t.type === 'bash' || t.type === 'command')\n .map((t) => ({\n command: t.content.command || '',\n success: !t.metadata?.error,\n output_summary: t.content.output?.substring(0, 100),\n }));\n }\n\n private async extractErrors(traces: Trace[]): Promise<ErrorContext[]> {\n return traces\n .filter((t) => t.type === 'error')\n .map((t) => ({\n error: t.content.error || '',\n context: t.content.context || '',\n resolved: t.metadata?.resolved || false,\n resolution: t.metadata?.resolution,\n }));\n }\n\n private async detectPatterns(traces: Trace[]): Promise<string[]> {\n const patterns: string[] = [];\n\n // Detect TDD pattern\n const testFirst = traces.some(\n (t) =>\n t.type === 'test' &&\n traces.some(\n (t2) => t2.type === 'implement' && t2.timestamp > t.timestamp\n )\n );\n if (testFirst) patterns.push('Test-Driven Development');\n\n // Detect refactoring pattern\n const refactoring =\n traces.filter(\n (t) =>\n t.content.description?.includes('refactor') ||\n t.metadata?.operation === 'refactor'\n ).length > 3;\n if (refactoring) patterns.push('Active Refactoring');\n\n // Detect debugging pattern\n const debugging =\n traces.filter((t) => t.type === 'error' || t.type === 'debug').length > 5;\n if (debugging) patterns.push('Deep Debugging Session');\n\n return patterns;\n }\n\n private async extractApproaches(frames: Frame[]): Promise<ApproachSummary[]> {\n return frames\n .filter((f) => f.metadata?.approach)\n .map((f) => ({\n approach: f.metadata.approach,\n outcome: this.getApproachOutcome(f),\n learnings: f.metadata.learnings,\n }));\n }\n\n private getApproachOutcome(frame: Frame): ApproachSummary['outcome'] {\n if (frame.status === 'closed' && frame.metadata?.success)\n return 'successful';\n if (frame.status === 'closed' && !frame.metadata?.success) return 'failed';\n return 'partial';\n }\n\n private extractSuccessfulStrategies(approaches: ApproachSummary[]): string[] {\n return approaches\n .filter((a) => a.outcome === 'successful')\n .map((a) => a.approach);\n }\n\n private async suggestNextActions(\n tasks: TaskSummary[],\n blockers: Blocker[],\n framePath: string[]\n ): Promise<string[]> {\n const suggestions: string[] = [];\n\n // Resume in-progress tasks\n const inProgress = tasks.filter((t) => t.status === 'in_progress');\n if (inProgress.length > 0) {\n suggestions.push(`Resume task: ${inProgress[0].title}`);\n }\n\n // Address critical blockers\n const criticalBlockers = blockers.filter((b) => b.severity === 'critical');\n if (criticalBlockers.length > 0) {\n suggestions.push(\n `Resolve critical blocker: ${criticalBlockers[0].description}`\n );\n }\n\n // Complete nearly done tasks\n const nearlyDone = tasks.filter((t) => t.progress_percentage >= 80);\n if (nearlyDone.length > 0) {\n suggestions.push(\n `Complete task: ${nearlyDone[0].title} (${nearlyDone[0].progress_percentage}% done)`\n );\n }\n\n return suggestions;\n }\n\n private async generateWarnings(\n errors: ErrorContext[],\n blockers: Blocker[]\n ): Promise<string[]> {\n const warnings: string[] = [];\n\n // Unresolved errors\n const unresolved = errors.filter((e) => !e.resolved);\n if (unresolved.length > 0) {\n warnings.push(`${unresolved.length} unresolved errors`);\n }\n\n // Critical blockers\n const critical = blockers.filter((b) => b.severity === 'critical');\n if (critical.length > 0) {\n warnings.push(\n `${critical.length} critical blockers need immediate attention`\n );\n }\n\n return warnings;\n }\n\n private async saveHandoff(handoff: HandoffDocument): Promise<void> {\n await fs.mkdir(this.handoffDir, { recursive: true });\n\n const filename = `${handoff.timestamp.replace(/[:.]/g, '-')}.json`;\n const filepath = path.join(this.handoffDir, filename);\n\n await fs.writeFile(filepath, JSON.stringify(handoff, null, 2), 'utf-8');\n\n // Also save markdown summary\n const markdown = await this.generateMarkdownSummary(handoff);\n const mdPath = filepath.replace('.json', '.md');\n await fs.writeFile(mdPath, markdown, 'utf-8');\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["path"]
|
|
7
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { v4 as uuidv4 } from "uuid";
|
|
2
2
|
import * as fs from "fs/promises";
|
|
3
3
|
import * as path from "path";
|
|
4
|
-
import * as crypto from "crypto";
|
|
5
4
|
import { logger } from "../monitoring/logger.js";
|
|
6
5
|
import { SystemError, ErrorCode } from "../errors/index.js";
|
|
7
6
|
var FrameQueryMode = /* @__PURE__ */ ((FrameQueryMode2) => {
|
|
@@ -30,8 +29,12 @@ class SessionManager {
|
|
|
30
29
|
async initialize() {
|
|
31
30
|
try {
|
|
32
31
|
await fs.mkdir(this.sessionsDir, { recursive: true });
|
|
33
|
-
await fs.mkdir(path.join(this.sessionsDir, "projects"), {
|
|
34
|
-
|
|
32
|
+
await fs.mkdir(path.join(this.sessionsDir, "projects"), {
|
|
33
|
+
recursive: true
|
|
34
|
+
});
|
|
35
|
+
await fs.mkdir(path.join(this.sessionsDir, "history"), {
|
|
36
|
+
recursive: true
|
|
37
|
+
});
|
|
35
38
|
} catch (error) {
|
|
36
39
|
throw new SystemError(
|
|
37
40
|
"Failed to initialize session directories",
|
|
@@ -59,7 +62,10 @@ class SessionManager {
|
|
|
59
62
|
const projectHash = await this.getProjectHash(options?.projectPath);
|
|
60
63
|
const branch = options?.branch || await this.getGitBranch(options?.projectPath);
|
|
61
64
|
if (projectHash) {
|
|
62
|
-
const branchSession = await this.findProjectBranchSession(
|
|
65
|
+
const branchSession = await this.findProjectBranchSession(
|
|
66
|
+
projectHash,
|
|
67
|
+
branch
|
|
68
|
+
);
|
|
63
69
|
if (branchSession && this.isSessionRecent(branchSession)) {
|
|
64
70
|
await this.touchSession(branchSession);
|
|
65
71
|
this.currentSession = branchSession;
|
|
@@ -113,7 +119,11 @@ class SessionManager {
|
|
|
113
119
|
return JSON.parse(data);
|
|
114
120
|
} catch (error) {
|
|
115
121
|
try {
|
|
116
|
-
const historyPath = path.join(
|
|
122
|
+
const historyPath = path.join(
|
|
123
|
+
this.sessionsDir,
|
|
124
|
+
"history",
|
|
125
|
+
`${sessionId}.json`
|
|
126
|
+
);
|
|
117
127
|
const data = await fs.readFile(historyPath, "utf-8");
|
|
118
128
|
return JSON.parse(data);
|
|
119
129
|
} catch {
|
|
@@ -122,7 +132,10 @@ class SessionManager {
|
|
|
122
132
|
}
|
|
123
133
|
}
|
|
124
134
|
async saveSession(session) {
|
|
125
|
-
const sessionPath = path.join(
|
|
135
|
+
const sessionPath = path.join(
|
|
136
|
+
this.sessionsDir,
|
|
137
|
+
`${session.sessionId}.json`
|
|
138
|
+
);
|
|
126
139
|
await fs.writeFile(sessionPath, JSON.stringify(session, null, 2));
|
|
127
140
|
}
|
|
128
141
|
async suspendSession(sessionId) {
|
|
@@ -138,11 +151,9 @@ class SessionManager {
|
|
|
138
151
|
async resumeSession(sessionId) {
|
|
139
152
|
const session = await this.loadSession(sessionId);
|
|
140
153
|
if (!session) {
|
|
141
|
-
throw new SystemError(
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
{ sessionId }
|
|
145
|
-
);
|
|
154
|
+
throw new SystemError("Session not found", ErrorCode.NOT_FOUND, {
|
|
155
|
+
sessionId
|
|
156
|
+
});
|
|
146
157
|
}
|
|
147
158
|
session.state = "active";
|
|
148
159
|
session.lastActiveAt = Date.now();
|
|
@@ -157,8 +168,15 @@ class SessionManager {
|
|
|
157
168
|
if (session) {
|
|
158
169
|
session.state = "closed";
|
|
159
170
|
session.lastActiveAt = Date.now();
|
|
160
|
-
const sessionPath = path.join(
|
|
161
|
-
|
|
171
|
+
const sessionPath = path.join(
|
|
172
|
+
this.sessionsDir,
|
|
173
|
+
`${session.sessionId}.json`
|
|
174
|
+
);
|
|
175
|
+
const historyPath = path.join(
|
|
176
|
+
this.sessionsDir,
|
|
177
|
+
"history",
|
|
178
|
+
`${session.sessionId}.json`
|
|
179
|
+
);
|
|
162
180
|
await fs.rename(sessionPath, historyPath);
|
|
163
181
|
}
|
|
164
182
|
}
|
|
@@ -231,14 +249,20 @@ class SessionManager {
|
|
|
231
249
|
async getProjectHash(projectPath) {
|
|
232
250
|
try {
|
|
233
251
|
const cwd = projectPath || process.cwd();
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
252
|
+
const pathModule = await import("path");
|
|
253
|
+
let identifier;
|
|
254
|
+
try {
|
|
255
|
+
const { execSync } = await import("child_process");
|
|
256
|
+
identifier = execSync("git config --get remote.origin.url", {
|
|
257
|
+
cwd,
|
|
258
|
+
encoding: "utf-8",
|
|
259
|
+
timeout: 5e3
|
|
260
|
+
}).trim();
|
|
261
|
+
} catch {
|
|
262
|
+
identifier = cwd;
|
|
238
263
|
}
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
return hash.digest("hex").substring(0, 12);
|
|
264
|
+
const cleaned = identifier.replace(/\.git$/, "").replace(/[^a-zA-Z0-9-]/g, "-").toLowerCase();
|
|
265
|
+
return cleaned.substring(cleaned.length - 50);
|
|
242
266
|
} catch {
|
|
243
267
|
return null;
|
|
244
268
|
}
|
|
@@ -273,12 +297,23 @@ class SessionManager {
|
|
|
273
297
|
return sessions.sort((a, b) => b.lastActiveAt - a.lastActiveAt)[0] || null;
|
|
274
298
|
}
|
|
275
299
|
async setProjectActiveSession(projectId, sessionId) {
|
|
276
|
-
const projectFile = path.join(
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
300
|
+
const projectFile = path.join(
|
|
301
|
+
this.sessionsDir,
|
|
302
|
+
"projects",
|
|
303
|
+
`${projectId}.json`
|
|
304
|
+
);
|
|
305
|
+
await fs.writeFile(
|
|
306
|
+
projectFile,
|
|
307
|
+
JSON.stringify(
|
|
308
|
+
{
|
|
309
|
+
projectId,
|
|
310
|
+
activeSessionId: sessionId,
|
|
311
|
+
updatedAt: Date.now()
|
|
312
|
+
},
|
|
313
|
+
null,
|
|
314
|
+
2
|
|
315
|
+
)
|
|
316
|
+
);
|
|
282
317
|
}
|
|
283
318
|
isSessionRecent(session) {
|
|
284
319
|
return Date.now() - session.lastActiveAt < this.STALE_THRESHOLD;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/session/session-manager.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Session Management for StackMemory\n * Provides session persistence and recovery across CLI invocations\n */\n\nimport { v4 as uuidv4 } from 'uuid';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport * as crypto from 'crypto';\nimport { logger } from '../monitoring/logger.js';\nimport { SystemError, ErrorCode } from '../errors/index.js';\n\nexport interface Session {\n sessionId: string;\n runId: string;\n projectId: string;\n branch?: string;\n startedAt: number;\n lastActiveAt: number;\n metadata: {\n user?: string;\n environment?: string;\n tags?: string[];\n cliVersion?: string;\n };\n state: 'active' | 'suspended' | 'closed';\n}\n\nexport interface SessionOptions {\n sessionId?: string;\n projectPath?: string;\n branch?: string;\n metadata?: Session['metadata'];\n}\n\nexport enum FrameQueryMode {\n CURRENT_SESSION = 'current',\n PROJECT_ACTIVE = 'project',\n ALL_ACTIVE = 'all',\n HISTORICAL = 'historical'\n}\n\nexport class SessionManager {\n private static instance: SessionManager;\n private sessionsDir: string;\n private currentSession: Session | null = null;\n private readonly STALE_THRESHOLD = 24 * 60 * 60 * 1000; // 24 hours\n\n private constructor() {\n const homeDir = process.env.HOME || process.env.USERPROFILE || '';\n this.sessionsDir = path.join(homeDir, '.stackmemory', 'sessions');\n }\n\n static getInstance(): SessionManager {\n if (!SessionManager.instance) {\n SessionManager.instance = new SessionManager();\n }\n return SessionManager.instance;\n }\n\n async initialize(): Promise<void> {\n try {\n await fs.mkdir(this.sessionsDir, { recursive: true });\n await fs.mkdir(path.join(this.sessionsDir, 'projects'), { recursive: true });\n await fs.mkdir(path.join(this.sessionsDir, 'history'), { recursive: true });\n } catch (error) {\n throw new SystemError(\n 'Failed to initialize session directories',\n ErrorCode.INITIALIZATION_ERROR,\n { error, sessionsDir: this.sessionsDir }\n );\n }\n }\n\n async getOrCreateSession(options?: SessionOptions): Promise<Session> {\n // 1. Check explicit session ID\n if (options?.sessionId) {\n const session = await this.loadSession(options.sessionId);\n if (session) {\n this.currentSession = session;\n return session;\n }\n }\n\n // 2. Check environment variable\n const envSessionId = process.env.STACKMEMORY_SESSION;\n if (envSessionId) {\n const session = await this.loadSession(envSessionId);\n if (session) {\n this.currentSession = session;\n return session;\n }\n }\n\n // 3. Check project + branch context\n const projectHash = await this.getProjectHash(options?.projectPath);\n const branch = options?.branch || await this.getGitBranch(options?.projectPath);\n\n if (projectHash) {\n // Try project+branch session\n const branchSession = await this.findProjectBranchSession(projectHash, branch);\n if (branchSession && this.isSessionRecent(branchSession)) {\n await this.touchSession(branchSession);\n this.currentSession = branchSession;\n return branchSession;\n }\n\n // Try last active for project\n const lastActive = await this.findLastActiveSession(projectHash);\n if (lastActive && this.isSessionRecent(lastActive)) {\n await this.touchSession(lastActive);\n this.currentSession = lastActive;\n return lastActive;\n }\n }\n\n // 4. Create new session\n const newSession = await this.createSession({\n projectId: projectHash || 'global',\n branch,\n metadata: options?.metadata\n });\n \n this.currentSession = newSession;\n return newSession;\n }\n\n async createSession(params: {\n projectId: string;\n branch?: string;\n metadata?: Session['metadata'];\n }): Promise<Session> {\n const session: Session = {\n sessionId: uuidv4(),\n runId: uuidv4(),\n projectId: params.projectId,\n branch: params.branch,\n startedAt: Date.now(),\n lastActiveAt: Date.now(),\n metadata: {\n ...params.metadata,\n user: process.env.USER,\n environment: process.env.NODE_ENV || 'development',\n cliVersion: process.env.npm_package_version\n },\n state: 'active'\n };\n\n await this.saveSession(session);\n await this.setProjectActiveSession(params.projectId, session.sessionId);\n \n // Set as current session\n this.currentSession = session;\n \n logger.info('Created new session', {\n sessionId: session.sessionId,\n projectId: session.projectId,\n branch: session.branch\n });\n\n return session;\n }\n\n async loadSession(sessionId: string): Promise<Session | null> {\n try {\n const sessionPath = path.join(this.sessionsDir, `${sessionId}.json`);\n const data = await fs.readFile(sessionPath, 'utf-8');\n return JSON.parse(data) as Session;\n } catch (error) {\n // Check history\n try {\n const historyPath = path.join(this.sessionsDir, 'history', `${sessionId}.json`);\n const data = await fs.readFile(historyPath, 'utf-8');\n return JSON.parse(data) as Session;\n } catch {\n return null;\n }\n }\n }\n\n async saveSession(session: Session): Promise<void> {\n const sessionPath = path.join(this.sessionsDir, `${session.sessionId}.json`);\n await fs.writeFile(sessionPath, JSON.stringify(session, null, 2));\n }\n\n async suspendSession(sessionId?: string): Promise<void> {\n const id = sessionId || this.currentSession?.sessionId;\n if (!id) return;\n\n const session = await this.loadSession(id);\n if (session) {\n session.state = 'suspended';\n session.lastActiveAt = Date.now();\n await this.saveSession(session);\n }\n }\n\n async resumeSession(sessionId: string): Promise<Session> {\n const session = await this.loadSession(sessionId);\n if (!session) {\n throw new SystemError(\n 'Session not found',\n ErrorCode.NOT_FOUND,\n { sessionId }\n );\n }\n\n session.state = 'active';\n session.lastActiveAt = Date.now();\n await this.saveSession(session);\n \n this.currentSession = session;\n return session;\n }\n\n async closeSession(sessionId?: string): Promise<void> {\n const id = sessionId || this.currentSession?.sessionId;\n if (!id) return;\n\n const session = await this.loadSession(id);\n if (session) {\n session.state = 'closed';\n session.lastActiveAt = Date.now();\n \n // Move to history\n const sessionPath = path.join(this.sessionsDir, `${session.sessionId}.json`);\n const historyPath = path.join(this.sessionsDir, 'history', `${session.sessionId}.json`);\n \n await fs.rename(sessionPath, historyPath);\n }\n }\n\n async listSessions(filter?: {\n projectId?: string;\n state?: Session['state'];\n branch?: string;\n }): Promise<Session[]> {\n const sessions: Session[] = [];\n \n // Load active sessions\n const files = await fs.readdir(this.sessionsDir);\n for (const file of files) {\n if (file.endsWith('.json')) {\n const session = await this.loadSession(file.replace('.json', ''));\n if (session) {\n sessions.push(session);\n }\n }\n }\n\n // Apply filters\n return sessions.filter(s => {\n if (filter?.projectId && s.projectId !== filter.projectId) return false;\n if (filter?.state && s.state !== filter.state) return false;\n if (filter?.branch && s.branch !== filter.branch) return false;\n return true;\n });\n }\n\n async mergeSessions(sourceId: string, targetId: string): Promise<Session> {\n const source = await this.loadSession(sourceId);\n const target = await this.loadSession(targetId);\n\n if (!source || !target) {\n throw new SystemError(\n 'Session not found for merge',\n ErrorCode.NOT_FOUND,\n { sourceId, targetId }\n );\n }\n\n // Merge metadata\n target.metadata = {\n ...target.metadata,\n ...source.metadata,\n tags: [...(target.metadata.tags || []), ...(source.metadata.tags || [])]\n };\n\n // Update timestamps\n target.lastActiveAt = Date.now();\n\n // Close source session\n await this.closeSession(sourceId);\n await this.saveSession(target);\n\n logger.info('Merged sessions', {\n source: sourceId,\n target: targetId\n });\n\n return target;\n }\n\n async cleanupStaleSessions(maxAge: number = 30 * 24 * 60 * 60 * 1000): Promise<number> {\n const historyDir = path.join(this.sessionsDir, 'history');\n const files = await fs.readdir(historyDir);\n const cutoff = Date.now() - maxAge;\n let cleaned = 0;\n\n for (const file of files) {\n if (file.endsWith('.json')) {\n const filePath = path.join(historyDir, file);\n const stats = await fs.stat(filePath);\n \n if (stats.mtimeMs < cutoff) {\n await fs.unlink(filePath);\n cleaned++;\n }\n }\n }\n\n logger.info(`Cleaned up ${cleaned} stale sessions`);\n return cleaned;\n }\n\n getCurrentSession(): Session | null {\n return this.currentSession;\n }\n\n getSessionRunId(): string {\n return this.currentSession?.runId || uuidv4();\n }\n\n private async getProjectHash(projectPath?: string): Promise<string | null> {\n try {\n const cwd = projectPath || process.cwd();\n \n // Try to use the basename of the directory as project ID\n const path = await import('path');\n const projectName = path.basename(cwd);\n \n // Check if it looks like a demo/development project\n if (projectName === 'stackmemory') {\n return 'stackmemory-demo';\n }\n \n // Otherwise use hash for consistency\n const hash = crypto.createHash('sha256');\n hash.update(cwd);\n return hash.digest('hex').substring(0, 12);\n } catch {\n return null;\n }\n }\n\n private async getGitBranch(projectPath?: string): Promise<string | undefined> {\n try {\n const { execSync } = await import('child_process');\n const cwd = projectPath || process.cwd();\n const branch = execSync('git rev-parse --abbrev-ref HEAD', {\n cwd,\n encoding: 'utf-8'\n }).trim();\n return branch;\n } catch {\n return undefined;\n }\n }\n\n private async findProjectBranchSession(\n projectHash: string, \n branch?: string\n ): Promise<Session | null> {\n if (!branch) return null;\n\n const sessions = await this.listSessions({\n projectId: projectHash,\n state: 'active',\n branch\n });\n\n return sessions.sort((a, b) => b.lastActiveAt - a.lastActiveAt)[0] || null;\n }\n\n private async findLastActiveSession(projectHash: string): Promise<Session | null> {\n const sessions = await this.listSessions({\n projectId: projectHash,\n state: 'active'\n });\n\n return sessions.sort((a, b) => b.lastActiveAt - a.lastActiveAt)[0] || null;\n }\n\n private async setProjectActiveSession(projectId: string, sessionId: string): Promise<void> {\n const projectFile = path.join(this.sessionsDir, 'projects', `${projectId}.json`);\n await fs.writeFile(projectFile, JSON.stringify({\n projectId,\n activeSessionId: sessionId,\n updatedAt: Date.now()\n }, null, 2));\n }\n\n private isSessionRecent(session: Session): boolean {\n return Date.now() - session.lastActiveAt < this.STALE_THRESHOLD;\n }\n\n private async touchSession(session: Session): Promise<void> {\n session.lastActiveAt = Date.now();\n await this.saveSession(session);\n }\n}\n\nexport const sessionManager = SessionManager.getInstance();"],
|
|
5
|
-
"mappings": "AAKA,SAAS,MAAM,cAAc;AAC7B,YAAY,QAAQ;AACpB,YAAY,UAAU;
|
|
6
|
-
"names": ["FrameQueryMode"
|
|
4
|
+
"sourcesContent": ["/**\n * Session Management for StackMemory\n * Provides session persistence and recovery across CLI invocations\n */\n\nimport { v4 as uuidv4 } from 'uuid';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport * as crypto from 'crypto';\nimport { logger } from '../monitoring/logger.js';\nimport { SystemError, ErrorCode } from '../errors/index.js';\n\nexport interface Session {\n sessionId: string;\n runId: string;\n projectId: string;\n branch?: string;\n startedAt: number;\n lastActiveAt: number;\n metadata: {\n user?: string;\n environment?: string;\n tags?: string[];\n cliVersion?: string;\n };\n state: 'active' | 'suspended' | 'closed';\n}\n\nexport interface SessionOptions {\n sessionId?: string;\n projectPath?: string;\n branch?: string;\n metadata?: Session['metadata'];\n}\n\nexport enum FrameQueryMode {\n CURRENT_SESSION = 'current',\n PROJECT_ACTIVE = 'project',\n ALL_ACTIVE = 'all',\n HISTORICAL = 'historical',\n}\n\nexport class SessionManager {\n private static instance: SessionManager;\n private sessionsDir: string;\n private currentSession: Session | null = null;\n private readonly STALE_THRESHOLD = 24 * 60 * 60 * 1000; // 24 hours\n\n private constructor() {\n const homeDir = process.env.HOME || process.env.USERPROFILE || '';\n this.sessionsDir = path.join(homeDir, '.stackmemory', 'sessions');\n }\n\n static getInstance(): SessionManager {\n if (!SessionManager.instance) {\n SessionManager.instance = new SessionManager();\n }\n return SessionManager.instance;\n }\n\n async initialize(): Promise<void> {\n try {\n await fs.mkdir(this.sessionsDir, { recursive: true });\n await fs.mkdir(path.join(this.sessionsDir, 'projects'), {\n recursive: true,\n });\n await fs.mkdir(path.join(this.sessionsDir, 'history'), {\n recursive: true,\n });\n } catch (error) {\n throw new SystemError(\n 'Failed to initialize session directories',\n ErrorCode.INITIALIZATION_ERROR,\n { error, sessionsDir: this.sessionsDir }\n );\n }\n }\n\n async getOrCreateSession(options?: SessionOptions): Promise<Session> {\n // 1. Check explicit session ID\n if (options?.sessionId) {\n const session = await this.loadSession(options.sessionId);\n if (session) {\n this.currentSession = session;\n return session;\n }\n }\n\n // 2. Check environment variable\n const envSessionId = process.env.STACKMEMORY_SESSION;\n if (envSessionId) {\n const session = await this.loadSession(envSessionId);\n if (session) {\n this.currentSession = session;\n return session;\n }\n }\n\n // 3. Check project + branch context\n const projectHash = await this.getProjectHash(options?.projectPath);\n const branch =\n options?.branch || (await this.getGitBranch(options?.projectPath));\n\n if (projectHash) {\n // Try project+branch session\n const branchSession = await this.findProjectBranchSession(\n projectHash,\n branch\n );\n if (branchSession && this.isSessionRecent(branchSession)) {\n await this.touchSession(branchSession);\n this.currentSession = branchSession;\n return branchSession;\n }\n\n // Try last active for project\n const lastActive = await this.findLastActiveSession(projectHash);\n if (lastActive && this.isSessionRecent(lastActive)) {\n await this.touchSession(lastActive);\n this.currentSession = lastActive;\n return lastActive;\n }\n }\n\n // 4. Create new session\n const newSession = await this.createSession({\n projectId: projectHash || 'global',\n branch,\n metadata: options?.metadata,\n });\n\n this.currentSession = newSession;\n return newSession;\n }\n\n async createSession(params: {\n projectId: string;\n branch?: string;\n metadata?: Session['metadata'];\n }): Promise<Session> {\n const session: Session = {\n sessionId: uuidv4(),\n runId: uuidv4(),\n projectId: params.projectId,\n branch: params.branch,\n startedAt: Date.now(),\n lastActiveAt: Date.now(),\n metadata: {\n ...params.metadata,\n user: process.env.USER,\n environment: process.env.NODE_ENV || 'development',\n cliVersion: process.env.npm_package_version,\n },\n state: 'active',\n };\n\n await this.saveSession(session);\n await this.setProjectActiveSession(params.projectId, session.sessionId);\n\n // Set as current session\n this.currentSession = session;\n\n logger.info('Created new session', {\n sessionId: session.sessionId,\n projectId: session.projectId,\n branch: session.branch,\n });\n\n return session;\n }\n\n async loadSession(sessionId: string): Promise<Session | null> {\n try {\n const sessionPath = path.join(this.sessionsDir, `${sessionId}.json`);\n const data = await fs.readFile(sessionPath, 'utf-8');\n return JSON.parse(data) as Session;\n } catch (error) {\n // Check history\n try {\n const historyPath = path.join(\n this.sessionsDir,\n 'history',\n `${sessionId}.json`\n );\n const data = await fs.readFile(historyPath, 'utf-8');\n return JSON.parse(data) as Session;\n } catch {\n return null;\n }\n }\n }\n\n async saveSession(session: Session): Promise<void> {\n const sessionPath = path.join(\n this.sessionsDir,\n `${session.sessionId}.json`\n );\n await fs.writeFile(sessionPath, JSON.stringify(session, null, 2));\n }\n\n async suspendSession(sessionId?: string): Promise<void> {\n const id = sessionId || this.currentSession?.sessionId;\n if (!id) return;\n\n const session = await this.loadSession(id);\n if (session) {\n session.state = 'suspended';\n session.lastActiveAt = Date.now();\n await this.saveSession(session);\n }\n }\n\n async resumeSession(sessionId: string): Promise<Session> {\n const session = await this.loadSession(sessionId);\n if (!session) {\n throw new SystemError('Session not found', ErrorCode.NOT_FOUND, {\n sessionId,\n });\n }\n\n session.state = 'active';\n session.lastActiveAt = Date.now();\n await this.saveSession(session);\n\n this.currentSession = session;\n return session;\n }\n\n async closeSession(sessionId?: string): Promise<void> {\n const id = sessionId || this.currentSession?.sessionId;\n if (!id) return;\n\n const session = await this.loadSession(id);\n if (session) {\n session.state = 'closed';\n session.lastActiveAt = Date.now();\n\n // Move to history\n const sessionPath = path.join(\n this.sessionsDir,\n `${session.sessionId}.json`\n );\n const historyPath = path.join(\n this.sessionsDir,\n 'history',\n `${session.sessionId}.json`\n );\n\n await fs.rename(sessionPath, historyPath);\n }\n }\n\n async listSessions(filter?: {\n projectId?: string;\n state?: Session['state'];\n branch?: string;\n }): Promise<Session[]> {\n const sessions: Session[] = [];\n\n // Load active sessions\n const files = await fs.readdir(this.sessionsDir);\n for (const file of files) {\n if (file.endsWith('.json')) {\n const session = await this.loadSession(file.replace('.json', ''));\n if (session) {\n sessions.push(session);\n }\n }\n }\n\n // Apply filters\n return sessions.filter((s) => {\n if (filter?.projectId && s.projectId !== filter.projectId) return false;\n if (filter?.state && s.state !== filter.state) return false;\n if (filter?.branch && s.branch !== filter.branch) return false;\n return true;\n });\n }\n\n async mergeSessions(sourceId: string, targetId: string): Promise<Session> {\n const source = await this.loadSession(sourceId);\n const target = await this.loadSession(targetId);\n\n if (!source || !target) {\n throw new SystemError(\n 'Session not found for merge',\n ErrorCode.NOT_FOUND,\n { sourceId, targetId }\n );\n }\n\n // Merge metadata\n target.metadata = {\n ...target.metadata,\n ...source.metadata,\n tags: [...(target.metadata.tags || []), ...(source.metadata.tags || [])],\n };\n\n // Update timestamps\n target.lastActiveAt = Date.now();\n\n // Close source session\n await this.closeSession(sourceId);\n await this.saveSession(target);\n\n logger.info('Merged sessions', {\n source: sourceId,\n target: targetId,\n });\n\n return target;\n }\n\n async cleanupStaleSessions(\n maxAge: number = 30 * 24 * 60 * 60 * 1000\n ): Promise<number> {\n const historyDir = path.join(this.sessionsDir, 'history');\n const files = await fs.readdir(historyDir);\n const cutoff = Date.now() - maxAge;\n let cleaned = 0;\n\n for (const file of files) {\n if (file.endsWith('.json')) {\n const filePath = path.join(historyDir, file);\n const stats = await fs.stat(filePath);\n\n if (stats.mtimeMs < cutoff) {\n await fs.unlink(filePath);\n cleaned++;\n }\n }\n }\n\n logger.info(`Cleaned up ${cleaned} stale sessions`);\n return cleaned;\n }\n\n getCurrentSession(): Session | null {\n return this.currentSession;\n }\n\n getSessionRunId(): string {\n return this.currentSession?.runId || uuidv4();\n }\n\n private async getProjectHash(projectPath?: string): Promise<string | null> {\n try {\n const cwd = projectPath || process.cwd();\n const pathModule = await import('path');\n\n // Try to get git remote first (consistent with project-manager)\n let identifier: string;\n try {\n const { execSync } = await import('child_process');\n identifier = execSync('git config --get remote.origin.url', {\n cwd,\n encoding: 'utf-8',\n timeout: 5000,\n }).trim();\n } catch {\n // Fall back to directory path\n identifier = cwd;\n }\n\n // Use same algorithm as project-manager.generateProjectId\n const cleaned = identifier\n .replace(/\\.git$/, '')\n .replace(/[^a-zA-Z0-9-]/g, '-')\n .toLowerCase();\n\n return cleaned.substring(cleaned.length - 50);\n } catch {\n return null;\n }\n }\n\n private async getGitBranch(\n projectPath?: string\n ): Promise<string | undefined> {\n try {\n const { execSync } = await import('child_process');\n const cwd = projectPath || process.cwd();\n const branch = execSync('git rev-parse --abbrev-ref HEAD', {\n cwd,\n encoding: 'utf-8',\n }).trim();\n return branch;\n } catch {\n return undefined;\n }\n }\n\n private async findProjectBranchSession(\n projectHash: string,\n branch?: string\n ): Promise<Session | null> {\n if (!branch) return null;\n\n const sessions = await this.listSessions({\n projectId: projectHash,\n state: 'active',\n branch,\n });\n\n return sessions.sort((a, b) => b.lastActiveAt - a.lastActiveAt)[0] || null;\n }\n\n private async findLastActiveSession(\n projectHash: string\n ): Promise<Session | null> {\n const sessions = await this.listSessions({\n projectId: projectHash,\n state: 'active',\n });\n\n return sessions.sort((a, b) => b.lastActiveAt - a.lastActiveAt)[0] || null;\n }\n\n private async setProjectActiveSession(\n projectId: string,\n sessionId: string\n ): Promise<void> {\n const projectFile = path.join(\n this.sessionsDir,\n 'projects',\n `${projectId}.json`\n );\n await fs.writeFile(\n projectFile,\n JSON.stringify(\n {\n projectId,\n activeSessionId: sessionId,\n updatedAt: Date.now(),\n },\n null,\n 2\n )\n );\n }\n\n private isSessionRecent(session: Session): boolean {\n return Date.now() - session.lastActiveAt < this.STALE_THRESHOLD;\n }\n\n private async touchSession(session: Session): Promise<void> {\n session.lastActiveAt = Date.now();\n await this.saveSession(session);\n }\n}\n\nexport const sessionManager = SessionManager.getInstance();\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["FrameQueryMode"]
|
|
7
7
|
}
|