@stackmemoryai/stackmemory 0.2.9 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/core/agent-task-manager.js +512 -0
- package/dist/agents/core/agent-task-manager.js.map +7 -0
- package/dist/agents/verifiers/base-verifier.js +129 -0
- package/dist/agents/verifiers/base-verifier.js.map +7 -0
- package/dist/agents/verifiers/formatter-verifier.js +126 -0
- package/dist/agents/verifiers/formatter-verifier.js.map +7 -0
- package/dist/agents/verifiers/llm-judge.js +248 -0
- package/dist/agents/verifiers/llm-judge.js.map +7 -0
- package/dist/cli/__tests__/index.test.js +290 -0
- package/dist/cli/__tests__/index.test.js.map +7 -0
- package/dist/cli/auto-detect.js +317 -0
- package/dist/cli/auto-detect.js.map +7 -0
- package/dist/cli/browser-test.js +29 -0
- package/dist/cli/browser-test.js.map +7 -0
- package/dist/cli/claude-sm.js +369 -0
- package/dist/cli/claude-sm.js.map +7 -0
- package/dist/cli/codex-sm.js +283 -0
- package/dist/cli/codex-sm.js.map +7 -0
- package/dist/cli/commands/agent.js +286 -0
- package/dist/cli/commands/agent.js.map +7 -0
- package/dist/cli/commands/config.js +199 -0
- package/dist/cli/commands/config.js.map +7 -0
- package/dist/cli/commands/context.js +327 -0
- package/dist/cli/commands/context.js.map +7 -0
- package/dist/cli/commands/handoff.js +191 -0
- package/dist/cli/commands/handoff.js.map +7 -0
- package/dist/cli/commands/linear-test.js +115 -0
- package/dist/cli/commands/linear-test.js.map +7 -0
- package/dist/cli/commands/linear.js +378 -0
- package/dist/cli/commands/linear.js.map +7 -0
- package/dist/cli/commands/log.js +165 -0
- package/dist/cli/commands/log.js.map +7 -0
- package/dist/cli/commands/onboard.js +349 -0
- package/dist/cli/commands/onboard.js.map +7 -0
- package/dist/cli/commands/projects.js +195 -0
- package/dist/cli/commands/projects.js.map +7 -0
- package/dist/cli/commands/search.js +152 -0
- package/dist/cli/commands/search.js.map +7 -0
- package/dist/cli/commands/session.js +179 -0
- package/dist/cli/commands/session.js.map +7 -0
- package/dist/cli/commands/tasks.js +205 -0
- package/dist/cli/commands/tasks.js.map +7 -0
- package/dist/cli/commands/webhook.js +131 -0
- package/dist/cli/commands/webhook.js.map +7 -0
- package/dist/cli/commands/worktree.js +276 -0
- package/dist/cli/commands/worktree.js.map +7 -0
- package/dist/cli/index.js +953 -0
- package/dist/cli/index.js.map +7 -0
- package/dist/cli/utils/viewer.js +92 -0
- package/dist/cli/utils/viewer.js.map +7 -0
- package/dist/core/config/__tests__/config-manager.test.js +248 -0
- package/dist/core/config/__tests__/config-manager.test.js.map +7 -0
- package/dist/core/config/config-manager.js +368 -0
- package/dist/core/config/config-manager.js.map +7 -0
- package/dist/core/config/types.js +140 -0
- package/dist/core/config/types.js.map +7 -0
- package/dist/core/context/__tests__/frame-manager.test.js +879 -0
- package/dist/core/context/__tests__/frame-manager.test.js.map +7 -0
- package/dist/core/context/auto-context.js +72 -0
- package/dist/core/context/auto-context.js.map +7 -0
- package/dist/core/context/compaction-handler.js +326 -0
- package/dist/core/context/compaction-handler.js.map +7 -0
- package/dist/core/context/frame-database.js +376 -0
- package/dist/core/context/frame-database.js.map +7 -0
- package/dist/core/context/frame-digest.js +239 -0
- package/dist/core/context/frame-digest.js.map +7 -0
- package/dist/core/context/frame-manager.js +682 -0
- package/dist/core/context/frame-manager.js.map +7 -0
- package/dist/core/context/frame-stack.js +270 -0
- package/dist/core/context/frame-stack.js.map +7 -0
- package/dist/core/context/frame-types.js +1 -0
- package/dist/core/context/frame-types.js.map +7 -0
- package/dist/core/context/index.js +33 -0
- package/dist/core/context/index.js.map +7 -0
- package/dist/core/context/model-aware-compaction.js +619 -0
- package/dist/core/context/model-aware-compaction.js.map +7 -0
- package/dist/core/context/refactored-frame-manager.js +393 -0
- package/dist/core/context/refactored-frame-manager.js.map +7 -0
- package/dist/core/database/batch-operations.js +329 -0
- package/dist/core/database/batch-operations.js.map +7 -0
- package/dist/core/database/connection-pool.js +224 -0
- package/dist/core/database/connection-pool.js.map +7 -0
- package/dist/core/database/query-cache.js +284 -0
- package/dist/core/database/query-cache.js.map +7 -0
- package/dist/core/digest/__tests__/enhanced-hybrid-digest.test.js +379 -0
- package/dist/core/digest/__tests__/enhanced-hybrid-digest.test.js.map +7 -0
- package/dist/core/digest/__tests__/frame-digest-integration.test.js +230 -0
- package/dist/core/digest/__tests__/frame-digest-integration.test.js.map +7 -0
- package/dist/core/digest/enhanced-hybrid-digest.js +267 -0
- package/dist/core/digest/enhanced-hybrid-digest.js.map +7 -0
- package/dist/core/digest/frame-digest-integration.js +172 -0
- package/dist/core/digest/frame-digest-integration.js.map +7 -0
- package/dist/core/digest/hybrid-digest-generator.js +549 -0
- package/dist/core/digest/hybrid-digest-generator.js.map +7 -0
- package/dist/core/digest/index.js +5 -0
- package/dist/core/digest/index.js.map +7 -0
- package/dist/core/digest/types.js +21 -0
- package/dist/core/digest/types.js.map +7 -0
- package/dist/core/errors/__tests__/error-handling.test.js +270 -0
- package/dist/core/errors/__tests__/error-handling.test.js.map +7 -0
- package/dist/core/errors/index.js +239 -0
- package/dist/core/errors/index.js.map +7 -0
- package/dist/core/errors/recovery.js +258 -0
- package/dist/core/errors/recovery.js.map +7 -0
- package/dist/core/merge/__tests__/conflict-scenarios.test.js +414 -0
- package/dist/core/merge/__tests__/conflict-scenarios.test.js.map +7 -0
- package/dist/core/merge/conflict-detector.js +424 -0
- package/dist/core/merge/conflict-detector.js.map +7 -0
- package/dist/core/merge/index.js +5 -0
- package/dist/core/merge/index.js.map +7 -0
- package/dist/core/merge/resolution-engine.js +565 -0
- package/dist/core/merge/resolution-engine.js.map +7 -0
- package/dist/core/merge/stack-diff.js +528 -0
- package/dist/core/merge/stack-diff.js.map +7 -0
- package/dist/core/merge/types.js +1 -0
- package/dist/core/merge/types.js.map +7 -0
- package/dist/core/monitoring/error-handler.js +278 -0
- package/dist/core/monitoring/error-handler.js.map +7 -0
- package/dist/core/monitoring/logger.js +115 -0
- package/dist/core/monitoring/logger.js.map +7 -0
- package/dist/core/monitoring/metrics.js +157 -0
- package/dist/core/monitoring/metrics.js.map +7 -0
- package/dist/core/monitoring/progress-tracker.js +174 -0
- package/dist/core/monitoring/progress-tracker.js.map +7 -0
- package/dist/core/performance/context-cache.js +269 -0
- package/dist/core/performance/context-cache.js.map +7 -0
- package/dist/core/performance/index.js +7 -0
- package/dist/core/performance/index.js.map +7 -0
- package/dist/core/performance/lazy-context-loader.js +319 -0
- package/dist/core/performance/lazy-context-loader.js.map +7 -0
- package/dist/core/performance/monitor.js +217 -0
- package/dist/core/performance/monitor.js.map +7 -0
- package/dist/core/performance/optimized-frame-context.js +326 -0
- package/dist/core/performance/optimized-frame-context.js.map +7 -0
- package/dist/core/performance/performance-benchmark.js +269 -0
- package/dist/core/performance/performance-benchmark.js.map +7 -0
- package/dist/core/performance/performance-profiler.js +318 -0
- package/dist/core/performance/performance-profiler.js.map +7 -0
- package/dist/core/performance/streaming-jsonl-parser.js +187 -0
- package/dist/core/performance/streaming-jsonl-parser.js.map +7 -0
- package/dist/core/persistence/postgres-adapter.js +345 -0
- package/dist/core/persistence/postgres-adapter.js.map +7 -0
- package/dist/core/projects/project-manager.js +699 -0
- package/dist/core/projects/project-manager.js.map +7 -0
- package/dist/core/query/__tests__/query-parser.test.js +301 -0
- package/dist/core/query/__tests__/query-parser.test.js.map +7 -0
- package/dist/core/query/__tests__/query-templates.test.js +210 -0
- package/dist/core/query/__tests__/query-templates.test.js.map +7 -0
- package/dist/core/query/query-parser.js +366 -0
- package/dist/core/query/query-parser.js.map +7 -0
- package/dist/core/query/query-templates.js +317 -0
- package/dist/core/query/query-templates.js.map +7 -0
- package/dist/core/retrieval/index.js +4 -0
- package/dist/core/retrieval/index.js.map +7 -0
- package/dist/core/retrieval/llm-context-retrieval.js +577 -0
- package/dist/core/retrieval/llm-context-retrieval.js.map +7 -0
- package/dist/core/retrieval/summary-generator.js +585 -0
- package/dist/core/retrieval/summary-generator.js.map +7 -0
- package/dist/core/retrieval/types.js +17 -0
- package/dist/core/retrieval/types.js.map +7 -0
- package/dist/core/session/index.js +11 -0
- package/dist/core/session/index.js.map +7 -0
- package/dist/core/session/session-manager.js +297 -0
- package/dist/core/session/session-manager.js.map +7 -0
- package/dist/core/trace/cli-trace-wrapper.js +110 -0
- package/dist/core/trace/cli-trace-wrapper.js.map +7 -0
- package/dist/core/trace/db-trace-wrapper.js +215 -0
- package/dist/core/trace/db-trace-wrapper.js.map +7 -0
- package/dist/core/trace/debug-trace.js +385 -0
- package/dist/core/trace/debug-trace.js.map +7 -0
- package/dist/core/trace/index.js +158 -0
- package/dist/core/trace/index.js.map +7 -0
- package/dist/core/trace/linear-api-wrapper.js +169 -0
- package/dist/core/trace/linear-api-wrapper.js.map +7 -0
- package/dist/core/trace/trace-demo.js +135 -0
- package/dist/core/trace/trace-demo.js.map +7 -0
- package/dist/core/trace/trace-detector.demo.js +138 -0
- package/dist/core/trace/trace-detector.demo.js.map +7 -0
- package/dist/core/trace/trace-detector.js +386 -0
- package/dist/core/trace/trace-detector.js.map +7 -0
- package/dist/core/trace/trace-detector.test.js +401 -0
- package/dist/core/trace/trace-detector.test.js.map +7 -0
- package/dist/core/trace/trace-store.js +341 -0
- package/dist/core/trace/trace-store.js.map +7 -0
- package/dist/core/trace/types.js +73 -0
- package/dist/core/trace/types.js.map +7 -0
- package/dist/core/types.js +1 -0
- package/dist/core/types.js.map +7 -0
- package/dist/core/utils/update-checker.js +214 -0
- package/dist/core/utils/update-checker.js.map +7 -0
- package/dist/core/worktree/worktree-manager.js +450 -0
- package/dist/core/worktree/worktree-manager.js.map +7 -0
- package/dist/features/analytics/api/analytics-api.js +283 -0
- package/dist/features/analytics/api/analytics-api.js.map +7 -0
- package/dist/features/analytics/core/analytics-service.js +267 -0
- package/dist/features/analytics/core/analytics-service.js.map +7 -0
- package/dist/features/analytics/index.js +14 -0
- package/dist/features/analytics/index.js.map +7 -0
- package/dist/features/analytics/queries/metrics-queries.js +273 -0
- package/dist/features/analytics/queries/metrics-queries.js.map +7 -0
- package/dist/features/analytics/types/metrics.js +1 -0
- package/dist/features/analytics/types/metrics.js.map +7 -0
- package/dist/features/browser/browser-mcp.js +488 -0
- package/dist/features/browser/browser-mcp.js.map +7 -0
- package/dist/features/tasks/__tests__/pebbles-task-store.test.js +747 -0
- package/dist/features/tasks/__tests__/pebbles-task-store.test.js.map +7 -0
- package/dist/features/tasks/pebbles-task-store.js +647 -0
- package/dist/features/tasks/pebbles-task-store.js.map +7 -0
- package/dist/features/tasks/task-aware-context.js +406 -0
- package/dist/features/tasks/task-aware-context.js.map +7 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +7 -0
- package/dist/integrations/linear/__tests__/auth.test.js +558 -0
- package/dist/integrations/linear/__tests__/auth.test.js.map +7 -0
- package/dist/integrations/linear/__tests__/sync-service.test.js +760 -0
- package/dist/integrations/linear/__tests__/sync-service.test.js.map +7 -0
- package/dist/integrations/linear/auth.js +308 -0
- package/dist/integrations/linear/auth.js.map +7 -0
- package/dist/integrations/linear/auto-sync.js +244 -0
- package/dist/integrations/linear/auto-sync.js.map +7 -0
- package/dist/integrations/linear/client.js +448 -0
- package/dist/integrations/linear/client.js.map +7 -0
- package/dist/integrations/linear/config.js +115 -0
- package/dist/integrations/linear/config.js.map +7 -0
- package/dist/integrations/linear/sync-manager.js +233 -0
- package/dist/integrations/linear/sync-manager.js.map +7 -0
- package/dist/integrations/linear/sync-service.js +214 -0
- package/dist/integrations/linear/sync-service.js.map +7 -0
- package/dist/integrations/linear/sync.js +565 -0
- package/dist/integrations/linear/sync.js.map +7 -0
- package/dist/integrations/linear/types.js +1 -0
- package/dist/integrations/linear/types.js.map +7 -0
- package/dist/integrations/linear/webhook-server.js +204 -0
- package/dist/integrations/linear/webhook-server.js.map +7 -0
- package/dist/integrations/linear/webhook.js +269 -0
- package/dist/integrations/linear/webhook.js.map +7 -0
- package/dist/integrations/mcp/__tests__/server.test.js +798 -0
- package/dist/integrations/mcp/__tests__/server.test.js.map +7 -0
- package/dist/integrations/mcp/handlers/context-handlers.js +253 -0
- package/dist/integrations/mcp/handlers/context-handlers.js.map +7 -0
- package/dist/integrations/mcp/handlers/index.js +134 -0
- package/dist/integrations/mcp/handlers/index.js.map +7 -0
- package/dist/integrations/mcp/handlers/linear-handlers.js +243 -0
- package/dist/integrations/mcp/handlers/linear-handlers.js.map +7 -0
- package/dist/integrations/mcp/handlers/task-handlers.js +235 -0
- package/dist/integrations/mcp/handlers/task-handlers.js.map +7 -0
- package/dist/integrations/mcp/handlers/trace-handlers.js +304 -0
- package/dist/integrations/mcp/handlers/trace-handlers.js.map +7 -0
- package/dist/integrations/mcp/index.js +19 -0
- package/dist/integrations/mcp/index.js.map +7 -0
- package/dist/integrations/mcp/refactored-server.js +331 -0
- package/dist/integrations/mcp/refactored-server.js.map +7 -0
- package/dist/integrations/mcp/server.js +1621 -0
- package/dist/integrations/mcp/server.js.map +7 -0
- package/dist/integrations/mcp/tool-definitions.js +562 -0
- package/dist/integrations/mcp/tool-definitions.js.map +7 -0
- package/dist/integrations/mcp/trace-test.js +44 -0
- package/dist/integrations/mcp/trace-test.js.map +7 -0
- package/dist/integrations/pg-aiguide/embedding-provider.js +174 -0
- package/dist/integrations/pg-aiguide/embedding-provider.js.map +7 -0
- package/dist/integrations/pg-aiguide/semantic-search.js +183 -0
- package/dist/integrations/pg-aiguide/semantic-search.js.map +7 -0
- package/dist/integrations/pg-aiguide/timescale-analytics.js +220 -0
- package/dist/integrations/pg-aiguide/timescale-analytics.js.map +7 -0
- package/dist/mcp/stackmemory-mcp-server.js +550 -0
- package/dist/mcp/stackmemory-mcp-server.js.map +7 -0
- package/dist/middleware/exponential-rate-limiter.js +285 -0
- package/dist/middleware/exponential-rate-limiter.js.map +7 -0
- package/dist/models/user.model.js +351 -0
- package/dist/models/user.model.js.map +7 -0
- package/dist/scripts/benchmark-performance.d.ts +7 -0
- package/dist/scripts/benchmark-performance.d.ts.map +1 -0
- package/dist/scripts/benchmark-performance.js +44 -0
- package/dist/scripts/benchmark-performance.js.map +1 -0
- package/dist/scripts/cleanup-duplicate-tasks.d.ts +12 -0
- package/dist/scripts/cleanup-duplicate-tasks.d.ts.map +1 -0
- package/dist/scripts/cleanup-duplicate-tasks.js +215 -0
- package/dist/scripts/cleanup-duplicate-tasks.js.map +1 -0
- package/dist/servers/production/auth-middleware.js +513 -0
- package/dist/servers/production/auth-middleware.js.map +7 -0
- package/dist/servers/railway/index.js +390 -0
- package/dist/servers/railway/index.js.map +7 -0
- package/dist/services/config-service.js +62 -0
- package/dist/services/config-service.js.map +7 -0
- package/dist/services/context-service.js +191 -0
- package/dist/services/context-service.js.map +7 -0
- package/dist/src/agents/core/agent-task-manager.d.ts +154 -0
- package/dist/src/agents/core/agent-task-manager.d.ts.map +1 -0
- package/dist/src/agents/core/agent-task-manager.js +504 -0
- package/dist/src/agents/core/agent-task-manager.js.map +1 -0
- package/dist/src/agents/verifiers/base-verifier.d.ts +112 -0
- package/dist/src/agents/verifiers/base-verifier.d.ts.map +1 -0
- package/dist/src/agents/verifiers/base-verifier.js +130 -0
- package/dist/src/agents/verifiers/base-verifier.js.map +1 -0
- package/dist/src/agents/verifiers/formatter-verifier.d.ts +14 -0
- package/dist/src/agents/verifiers/formatter-verifier.d.ts.map +1 -0
- package/dist/src/agents/verifiers/formatter-verifier.js +107 -0
- package/dist/src/agents/verifiers/formatter-verifier.js.map +1 -0
- package/dist/src/agents/verifiers/llm-judge.d.ts +46 -0
- package/dist/src/agents/verifiers/llm-judge.d.ts.map +1 -0
- package/dist/src/agents/verifiers/llm-judge.js +248 -0
- package/dist/src/agents/verifiers/llm-judge.js.map +1 -0
- package/dist/src/cli/claude-sm.js +55 -0
- package/dist/src/cli/claude-sm.js.map +1 -1
- package/dist/src/cli/commands/agent.d.ts +9 -0
- package/dist/src/cli/commands/agent.d.ts.map +1 -0
- package/dist/src/cli/commands/agent.js +303 -0
- package/dist/src/cli/commands/agent.js.map +1 -0
- package/dist/src/cli/commands/handoff.d.ts +6 -0
- package/dist/src/cli/commands/handoff.d.ts.map +1 -0
- package/dist/src/cli/commands/handoff.js +212 -0
- package/dist/src/cli/commands/handoff.js.map +1 -0
- package/dist/src/cli/index.d.ts.map +1 -1
- package/dist/src/cli/index.js +4 -0
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/core/context/frame-database.d.ts +59 -0
- package/dist/src/core/context/frame-database.d.ts.map +1 -0
- package/dist/src/core/context/frame-database.js +333 -0
- package/dist/src/core/context/frame-database.js.map +1 -0
- package/dist/src/core/context/frame-digest.d.ts +59 -0
- package/dist/src/core/context/frame-digest.d.ts.map +1 -0
- package/dist/src/core/context/frame-digest.js +264 -0
- package/dist/src/core/context/frame-digest.js.map +1 -0
- package/dist/src/core/context/frame-manager.d.ts +2 -0
- package/dist/src/core/context/frame-manager.d.ts.map +1 -1
- package/dist/src/core/context/frame-manager.js +7 -0
- package/dist/src/core/context/frame-manager.js.map +1 -1
- package/dist/src/core/context/frame-stack.d.ts +85 -0
- package/dist/src/core/context/frame-stack.d.ts.map +1 -0
- package/dist/src/core/context/frame-stack.js +287 -0
- package/dist/src/core/context/frame-stack.js.map +1 -0
- package/dist/src/core/context/frame-types.d.ts +67 -0
- package/dist/src/core/context/frame-types.d.ts.map +1 -0
- package/dist/src/core/context/frame-types.js +6 -0
- package/dist/src/core/context/frame-types.js.map +1 -0
- package/dist/src/core/context/index.d.ts +11 -0
- package/dist/src/core/context/index.d.ts.map +1 -0
- package/dist/src/core/context/index.js +14 -0
- package/dist/src/core/context/index.js.map +1 -0
- package/dist/src/core/context/refactored-frame-manager.d.ts +99 -0
- package/dist/src/core/context/refactored-frame-manager.d.ts.map +1 -0
- package/dist/src/core/context/refactored-frame-manager.js +340 -0
- package/dist/src/core/context/refactored-frame-manager.js.map +1 -0
- package/dist/src/core/database/batch-operations.d.ts +118 -0
- package/dist/src/core/database/batch-operations.d.ts.map +1 -0
- package/dist/src/core/database/batch-operations.js +339 -0
- package/dist/src/core/database/batch-operations.js.map +1 -0
- package/dist/src/core/database/connection-pool.d.ts +79 -0
- package/dist/src/core/database/connection-pool.d.ts.map +1 -0
- package/dist/src/core/database/connection-pool.js +236 -0
- package/dist/src/core/database/connection-pool.js.map +1 -0
- package/dist/src/core/database/query-cache.d.ts +135 -0
- package/dist/src/core/database/query-cache.d.ts.map +1 -0
- package/dist/src/core/database/query-cache.js +294 -0
- package/dist/src/core/database/query-cache.js.map +1 -0
- package/dist/src/core/digest/enhanced-hybrid-digest.d.ts +125 -0
- package/dist/src/core/digest/enhanced-hybrid-digest.d.ts.map +1 -0
- package/dist/src/core/digest/enhanced-hybrid-digest.js +282 -0
- package/dist/src/core/digest/enhanced-hybrid-digest.js.map +1 -0
- package/dist/src/core/digest/frame-digest-integration.d.ts +67 -0
- package/dist/src/core/digest/frame-digest-integration.d.ts.map +1 -0
- package/dist/src/core/digest/frame-digest-integration.js +198 -0
- package/dist/src/core/digest/frame-digest-integration.js.map +1 -0
- package/dist/src/core/digest/hybrid-digest-generator.d.ts +3 -3
- package/dist/src/core/digest/hybrid-digest-generator.d.ts.map +1 -1
- package/dist/src/core/digest/hybrid-digest-generator.js.map +1 -1
- package/dist/src/core/digest/index.d.ts +3 -1
- package/dist/src/core/digest/index.d.ts.map +1 -1
- package/dist/src/core/digest/index.js +3 -1
- package/dist/src/core/digest/index.js.map +1 -1
- package/dist/src/core/errors/index.d.ts +13 -5
- package/dist/src/core/errors/index.d.ts.map +1 -1
- package/dist/src/core/errors/index.js +13 -5
- package/dist/src/core/errors/index.js.map +1 -1
- package/dist/src/core/merge/conflict-detector.d.ts +122 -0
- package/dist/src/core/merge/conflict-detector.d.ts.map +1 -0
- package/dist/src/core/merge/conflict-detector.js +468 -0
- package/dist/src/core/merge/conflict-detector.js.map +1 -0
- package/dist/src/core/merge/index.d.ts +9 -0
- package/dist/src/core/merge/index.d.ts.map +1 -0
- package/dist/src/core/merge/index.js +9 -0
- package/dist/src/core/merge/index.js.map +1 -0
- package/dist/src/core/merge/resolution-engine.d.ts +120 -0
- package/dist/src/core/merge/resolution-engine.d.ts.map +1 -0
- package/dist/src/core/merge/resolution-engine.js +573 -0
- package/dist/src/core/merge/resolution-engine.js.map +1 -0
- package/dist/src/core/merge/stack-diff.d.ts +97 -0
- package/dist/src/core/merge/stack-diff.d.ts.map +1 -0
- package/dist/src/core/merge/stack-diff.js +516 -0
- package/dist/src/core/merge/stack-diff.js.map +1 -0
- package/dist/src/core/merge/types.d.ts +110 -0
- package/dist/src/core/merge/types.d.ts.map +1 -0
- package/dist/src/core/merge/types.js +6 -0
- package/dist/src/core/merge/types.js.map +1 -0
- package/dist/src/core/performance/context-cache.d.ts +109 -0
- package/dist/src/core/performance/context-cache.d.ts.map +1 -0
- package/dist/src/core/performance/context-cache.js +280 -0
- package/dist/src/core/performance/context-cache.js.map +1 -0
- package/dist/src/core/performance/index.d.ts +3 -0
- package/dist/src/core/performance/index.d.ts.map +1 -0
- package/dist/src/core/performance/index.js +3 -0
- package/dist/src/core/performance/index.js.map +1 -0
- package/dist/src/core/performance/lazy-context-loader.d.ts +93 -0
- package/dist/src/core/performance/lazy-context-loader.d.ts.map +1 -0
- package/dist/src/core/performance/lazy-context-loader.js +332 -0
- package/dist/src/core/performance/lazy-context-loader.js.map +1 -0
- package/dist/src/core/performance/monitor.d.ts +48 -0
- package/dist/src/core/performance/monitor.d.ts.map +1 -0
- package/dist/src/core/performance/monitor.js +226 -0
- package/dist/src/core/performance/monitor.js.map +1 -0
- package/dist/src/core/performance/optimized-frame-context.d.ts +74 -0
- package/dist/src/core/performance/optimized-frame-context.d.ts.map +1 -0
- package/dist/src/core/performance/optimized-frame-context.js +330 -0
- package/dist/src/core/performance/optimized-frame-context.js.map +1 -0
- package/dist/src/core/performance/performance-benchmark.d.ts +50 -0
- package/dist/src/core/performance/performance-benchmark.d.ts.map +1 -0
- package/dist/src/core/performance/performance-benchmark.js +290 -0
- package/dist/src/core/performance/performance-benchmark.js.map +1 -0
- package/dist/src/core/performance/performance-profiler.d.ts +151 -0
- package/dist/src/core/performance/performance-profiler.d.ts.map +1 -0
- package/dist/src/core/performance/performance-profiler.js +346 -0
- package/dist/src/core/performance/performance-profiler.js.map +1 -0
- package/dist/src/core/performance/streaming-jsonl-parser.d.ts +41 -0
- package/dist/src/core/performance/streaming-jsonl-parser.d.ts.map +1 -0
- package/dist/src/core/performance/streaming-jsonl-parser.js +193 -0
- package/dist/src/core/performance/streaming-jsonl-parser.js.map +1 -0
- package/dist/src/core/persistence/postgres-adapter.d.ts.map +1 -1
- package/dist/src/core/persistence/postgres-adapter.js +18 -4
- package/dist/src/core/persistence/postgres-adapter.js.map +1 -1
- package/dist/src/core/query/query-parser.d.ts +5 -0
- package/dist/src/core/query/query-parser.d.ts.map +1 -1
- package/dist/src/core/query/query-parser.js +86 -18
- package/dist/src/core/query/query-parser.js.map +1 -1
- package/dist/src/core/query/query-templates.d.ts +44 -0
- package/dist/src/core/query/query-templates.d.ts.map +1 -0
- package/dist/src/core/query/query-templates.js +326 -0
- package/dist/src/core/query/query-templates.js.map +1 -0
- package/dist/src/core/retrieval/llm-context-retrieval.d.ts +5 -3
- package/dist/src/core/retrieval/llm-context-retrieval.d.ts.map +1 -1
- package/dist/src/core/retrieval/llm-context-retrieval.js +73 -21
- package/dist/src/core/retrieval/llm-context-retrieval.js.map +1 -1
- package/dist/src/core/trace/cli-trace-wrapper.d.ts +23 -0
- package/dist/src/core/trace/cli-trace-wrapper.d.ts.map +1 -0
- package/dist/src/core/trace/cli-trace-wrapper.js +141 -0
- package/dist/src/core/trace/cli-trace-wrapper.js.map +1 -0
- package/dist/src/core/trace/db-trace-wrapper.d.ts +36 -0
- package/dist/src/core/trace/db-trace-wrapper.d.ts.map +1 -0
- package/dist/src/core/trace/db-trace-wrapper.js +252 -0
- package/dist/src/core/trace/db-trace-wrapper.js.map +1 -0
- package/dist/src/core/trace/debug-trace.d.ts +84 -0
- package/dist/src/core/trace/debug-trace.d.ts.map +1 -0
- package/dist/src/core/trace/debug-trace.js +402 -0
- package/dist/src/core/trace/debug-trace.js.map +1 -0
- package/dist/src/core/trace/error-test.d.ts +6 -0
- package/dist/src/core/trace/error-test.d.ts.map +1 -0
- package/dist/src/core/trace/error-test.js +128 -0
- package/dist/src/core/trace/error-test.js.map +1 -0
- package/dist/src/core/trace/index.d.ts +25 -0
- package/dist/src/core/trace/index.d.ts.map +1 -0
- package/dist/src/core/trace/index.js +121 -0
- package/dist/src/core/trace/index.js.map +1 -0
- package/dist/src/core/trace/linear-api-wrapper.d.ts +17 -0
- package/dist/src/core/trace/linear-api-wrapper.d.ts.map +1 -0
- package/dist/src/core/trace/linear-api-wrapper.js +205 -0
- package/dist/src/core/trace/linear-api-wrapper.js.map +1 -0
- package/dist/src/core/trace/performance-test.d.ts +6 -0
- package/dist/src/core/trace/performance-test.d.ts.map +1 -0
- package/dist/src/core/trace/performance-test.js +111 -0
- package/dist/src/core/trace/performance-test.js.map +1 -0
- package/dist/src/core/trace/trace-demo.d.ts +8 -0
- package/dist/src/core/trace/trace-demo.d.ts.map +1 -0
- package/dist/src/core/trace/trace-demo.js +154 -0
- package/dist/src/core/trace/trace-demo.js.map +1 -0
- package/dist/src/core/trace/trace-detector.d.ts +2 -2
- package/dist/src/core/trace/trace-detector.d.ts.map +1 -1
- package/dist/src/core/trace/trace-detector.demo.js +1 -1
- package/dist/src/core/trace/trace-detector.demo.js.map +1 -1
- package/dist/src/core/trace/trace-detector.js +3 -3
- package/dist/src/core/trace/trace-detector.js.map +1 -1
- package/dist/src/features/tasks/pebbles-task-store.d.ts +9 -2
- package/dist/src/features/tasks/pebbles-task-store.d.ts.map +1 -1
- package/dist/src/features/tasks/pebbles-task-store.js +97 -18
- package/dist/src/features/tasks/pebbles-task-store.js.map +1 -1
- package/dist/src/integrations/linear/auth.d.ts.map +1 -1
- package/dist/src/integrations/linear/auth.js.map +1 -1
- package/dist/src/integrations/linear/client.d.ts +15 -1
- package/dist/src/integrations/linear/client.d.ts.map +1 -1
- package/dist/src/integrations/linear/client.js +85 -3
- package/dist/src/integrations/linear/client.js.map +1 -1
- package/dist/src/integrations/linear/sync-manager.d.ts +2 -0
- package/dist/src/integrations/linear/sync-manager.d.ts.map +1 -1
- package/dist/src/integrations/linear/sync-manager.js +16 -4
- package/dist/src/integrations/linear/sync-manager.js.map +1 -1
- package/dist/src/integrations/linear/sync-service.d.ts +23 -2
- package/dist/src/integrations/linear/sync-service.d.ts.map +1 -1
- package/dist/src/integrations/linear/sync-service.js +44 -25
- package/dist/src/integrations/linear/sync-service.js.map +1 -1
- package/dist/src/integrations/linear/sync.d.ts +6 -0
- package/dist/src/integrations/linear/sync.d.ts.map +1 -1
- package/dist/src/integrations/linear/sync.js +27 -2
- package/dist/src/integrations/linear/sync.js.map +1 -1
- package/dist/src/integrations/linear/types.d.ts +16 -1
- package/dist/src/integrations/linear/types.d.ts.map +1 -1
- package/dist/src/integrations/linear/webhook-server.d.ts.map +1 -1
- package/dist/src/integrations/linear/webhook-server.js +10 -8
- package/dist/src/integrations/linear/webhook-server.js.map +1 -1
- package/dist/src/integrations/linear/webhook.d.ts +13 -0
- package/dist/src/integrations/linear/webhook.d.ts.map +1 -1
- package/dist/src/integrations/linear/webhook.js +101 -14
- package/dist/src/integrations/linear/webhook.js.map +1 -1
- package/dist/src/integrations/mcp/handlers/context-handlers.d.ts +39 -0
- package/dist/src/integrations/mcp/handlers/context-handlers.d.ts.map +1 -0
- package/dist/src/integrations/mcp/handlers/context-handlers.js +266 -0
- package/dist/src/integrations/mcp/handlers/context-handlers.js.map +1 -0
- package/dist/src/integrations/mcp/handlers/index.d.ts +37 -0
- package/dist/src/integrations/mcp/handlers/index.d.ts.map +1 -0
- package/dist/src/integrations/mcp/handlers/index.js +134 -0
- package/dist/src/integrations/mcp/handlers/index.js.map +1 -0
- package/dist/src/integrations/mcp/handlers/linear-handlers.d.ts +33 -0
- package/dist/src/integrations/mcp/handlers/linear-handlers.d.ts.map +1 -0
- package/dist/src/integrations/mcp/handlers/linear-handlers.js +251 -0
- package/dist/src/integrations/mcp/handlers/linear-handlers.js.map +1 -0
- package/dist/src/integrations/mcp/handlers/task-handlers.d.ts +42 -0
- package/dist/src/integrations/mcp/handlers/task-handlers.d.ts.map +1 -0
- package/dist/src/integrations/mcp/handlers/task-handlers.js +238 -0
- package/dist/src/integrations/mcp/handlers/task-handlers.js.map +1 -0
- package/dist/src/integrations/mcp/handlers/trace-handlers.d.ts +41 -0
- package/dist/src/integrations/mcp/handlers/trace-handlers.d.ts.map +1 -0
- package/dist/src/integrations/mcp/handlers/trace-handlers.js +298 -0
- package/dist/src/integrations/mcp/handlers/trace-handlers.js.map +1 -0
- package/dist/src/integrations/mcp/index.d.ts +13 -0
- package/dist/src/integrations/mcp/index.d.ts.map +1 -0
- package/dist/src/integrations/mcp/index.js +17 -0
- package/dist/src/integrations/mcp/index.js.map +1 -0
- package/dist/src/integrations/mcp/refactored-server.d.ts +76 -0
- package/dist/src/integrations/mcp/refactored-server.d.ts.map +1 -0
- package/dist/src/integrations/mcp/refactored-server.js +351 -0
- package/dist/src/integrations/mcp/refactored-server.js.map +1 -0
- package/dist/src/integrations/mcp/tool-definitions.d.ts +44 -0
- package/dist/src/integrations/mcp/tool-definitions.d.ts.map +1 -0
- package/dist/src/integrations/mcp/tool-definitions.js +563 -0
- package/dist/src/integrations/mcp/tool-definitions.js.map +1 -0
- package/dist/src/integrations/pg-aiguide/semantic-search.d.ts.map +1 -1
- package/dist/src/integrations/pg-aiguide/semantic-search.js +43 -21
- package/dist/src/integrations/pg-aiguide/semantic-search.js.map +1 -1
- package/dist/src/mcp/stackmemory-mcp-server.d.ts +9 -0
- package/dist/src/mcp/stackmemory-mcp-server.d.ts.map +1 -0
- package/dist/src/mcp/stackmemory-mcp-server.js +519 -0
- package/dist/src/mcp/stackmemory-mcp-server.js.map +1 -0
- package/dist/src/middleware/exponential-rate-limiter.d.ts +78 -0
- package/dist/src/middleware/exponential-rate-limiter.d.ts.map +1 -0
- package/dist/src/middleware/exponential-rate-limiter.js +293 -0
- package/dist/src/middleware/exponential-rate-limiter.js.map +1 -0
- package/dist/src/models/user.model.d.ts +8 -1
- package/dist/src/models/user.model.d.ts.map +1 -1
- package/dist/src/models/user.model.js +62 -14
- package/dist/src/models/user.model.js.map +1 -1
- package/dist/src/servers/production/auth-middleware.d.ts +5 -2
- package/dist/src/servers/production/auth-middleware.d.ts.map +1 -1
- package/dist/src/servers/production/auth-middleware.js +71 -34
- package/dist/src/servers/production/auth-middleware.js.map +1 -1
- package/dist/src/services/context-service.d.ts.map +1 -1
- package/dist/src/services/context-service.js +86 -1
- package/dist/src/services/context-service.js.map +1 -1
- package/dist/src/validation/schemas.d.ts +633 -0
- package/dist/src/validation/schemas.d.ts.map +1 -0
- package/dist/src/validation/schemas.js +347 -0
- package/dist/src/validation/schemas.js.map +1 -0
- package/dist/types/task.js +1 -0
- package/dist/types/task.js.map +7 -0
- package/dist/utils/logger.js +52 -0
- package/dist/utils/logger.js.map +7 -0
- package/dist/validation/schemas.js +218 -0
- package/dist/validation/schemas.js.map +7 -0
- package/package.json +7 -3
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import Database from "better-sqlite3";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { existsSync } from "fs";
|
|
5
|
+
function createSearchCommand() {
|
|
6
|
+
const search = new Command("search").alias("find").description("Search across tasks and context").argument("<query>", "Search query").option("-t, --tasks", "Search only tasks").option("-c, --context", "Search only context").option("-l, --limit <n>", "Limit results", "20").action(async (query, options) => {
|
|
7
|
+
const projectRoot = process.cwd();
|
|
8
|
+
const dbPath = join(projectRoot, ".stackmemory", "context.db");
|
|
9
|
+
if (!existsSync(dbPath)) {
|
|
10
|
+
console.log(
|
|
11
|
+
'\u274C StackMemory not initialized. Run "stackmemory init" first.'
|
|
12
|
+
);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const db = new Database(dbPath);
|
|
16
|
+
const limit = parseInt(options.limit);
|
|
17
|
+
const searchTasks = !options.context || options.tasks;
|
|
18
|
+
const searchContext = !options.tasks || options.context;
|
|
19
|
+
console.log(`
|
|
20
|
+
\u{1F50D} Searching for "${query}"...
|
|
21
|
+
`);
|
|
22
|
+
let totalResults = 0;
|
|
23
|
+
if (searchTasks) {
|
|
24
|
+
try {
|
|
25
|
+
const tasks = db.prepare(
|
|
26
|
+
`
|
|
27
|
+
SELECT id, title, description, status, priority, created_at
|
|
28
|
+
FROM task_cache
|
|
29
|
+
WHERE title LIKE ? OR description LIKE ?
|
|
30
|
+
ORDER BY created_at DESC
|
|
31
|
+
LIMIT ?
|
|
32
|
+
`
|
|
33
|
+
).all(`%${query}%`, `%${query}%`, limit);
|
|
34
|
+
if (tasks.length > 0) {
|
|
35
|
+
console.log(`\u{1F4CB} Tasks (${tasks.length})
|
|
36
|
+
`);
|
|
37
|
+
const priorityIcon = {
|
|
38
|
+
urgent: "\u{1F534}",
|
|
39
|
+
high: "\u{1F7E0}",
|
|
40
|
+
medium: "\u{1F7E1}",
|
|
41
|
+
low: "\u{1F7E2}"
|
|
42
|
+
};
|
|
43
|
+
const statusIcon = {
|
|
44
|
+
pending: "\u23F3",
|
|
45
|
+
in_progress: "\u{1F504}",
|
|
46
|
+
completed: "\u2705",
|
|
47
|
+
blocked: "\u{1F6AB}"
|
|
48
|
+
};
|
|
49
|
+
tasks.forEach((task) => {
|
|
50
|
+
const pIcon = priorityIcon[task.priority] || "\u26AA";
|
|
51
|
+
const sIcon = statusIcon[task.status] || "\u26AA";
|
|
52
|
+
console.log(`${sIcon} ${pIcon} ${task.title}`);
|
|
53
|
+
if (task.description) {
|
|
54
|
+
const desc = task.description.split("\n")[0];
|
|
55
|
+
const matchIdx = desc.toLowerCase().indexOf(query.toLowerCase());
|
|
56
|
+
if (matchIdx >= 0) {
|
|
57
|
+
const start = Math.max(0, matchIdx - 20);
|
|
58
|
+
const end = Math.min(
|
|
59
|
+
desc.length,
|
|
60
|
+
matchIdx + query.length + 20
|
|
61
|
+
);
|
|
62
|
+
const snippet = (start > 0 ? "..." : "") + desc.slice(start, end) + (end < desc.length ? "..." : "");
|
|
63
|
+
console.log(` ${snippet}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
console.log("");
|
|
68
|
+
totalResults += tasks.length;
|
|
69
|
+
}
|
|
70
|
+
} catch (error) {
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (searchContext) {
|
|
74
|
+
try {
|
|
75
|
+
const contexts = db.prepare(
|
|
76
|
+
`
|
|
77
|
+
SELECT id, type, name, metadata, created_at
|
|
78
|
+
FROM frames
|
|
79
|
+
WHERE name LIKE ? OR metadata LIKE ?
|
|
80
|
+
ORDER BY created_at DESC
|
|
81
|
+
LIMIT ?
|
|
82
|
+
`
|
|
83
|
+
).all(`%${query}%`, `%${query}%`, limit);
|
|
84
|
+
if (contexts.length > 0) {
|
|
85
|
+
console.log(`\u{1F4C1} Context Frames (${contexts.length})
|
|
86
|
+
`);
|
|
87
|
+
const typeIcon = {
|
|
88
|
+
session: "\u{1F537}",
|
|
89
|
+
task: "\u{1F4CB}",
|
|
90
|
+
command: "\u26A1",
|
|
91
|
+
file: "\u{1F4C4}",
|
|
92
|
+
decision: "\u{1F4A1}"
|
|
93
|
+
};
|
|
94
|
+
contexts.forEach((ctx) => {
|
|
95
|
+
const icon = typeIcon[ctx.type] || "\u{1F4E6}";
|
|
96
|
+
const date = new Date(ctx.created_at * 1e3).toLocaleDateString();
|
|
97
|
+
console.log(
|
|
98
|
+
`${icon} [${ctx.type}] ${ctx.name || ctx.id.slice(0, 10)}`
|
|
99
|
+
);
|
|
100
|
+
console.log(` Created: ${date}`);
|
|
101
|
+
});
|
|
102
|
+
console.log("");
|
|
103
|
+
totalResults += contexts.length;
|
|
104
|
+
}
|
|
105
|
+
} catch (error) {
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (searchContext) {
|
|
109
|
+
try {
|
|
110
|
+
const events = db.prepare(
|
|
111
|
+
`
|
|
112
|
+
SELECT id, type, data, timestamp
|
|
113
|
+
FROM events
|
|
114
|
+
WHERE data LIKE ?
|
|
115
|
+
ORDER BY timestamp DESC
|
|
116
|
+
LIMIT ?
|
|
117
|
+
`
|
|
118
|
+
).all(`%${query}%`, limit);
|
|
119
|
+
if (events.length > 0) {
|
|
120
|
+
console.log(`\u{1F4DD} Events (${events.length})
|
|
121
|
+
`);
|
|
122
|
+
events.forEach((evt) => {
|
|
123
|
+
const date = new Date(evt.timestamp * 1e3).toLocaleDateString();
|
|
124
|
+
let data = {};
|
|
125
|
+
try {
|
|
126
|
+
data = JSON.parse(evt.data);
|
|
127
|
+
} catch {
|
|
128
|
+
}
|
|
129
|
+
const summary = data.content || data.message || data.decision || evt.type;
|
|
130
|
+
console.log(`\u26A1 [${evt.type}] ${String(summary).slice(0, 60)}`);
|
|
131
|
+
console.log(` ${date}`);
|
|
132
|
+
});
|
|
133
|
+
console.log("");
|
|
134
|
+
totalResults += events.length;
|
|
135
|
+
}
|
|
136
|
+
} catch (error) {
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
db.close();
|
|
140
|
+
if (totalResults === 0) {
|
|
141
|
+
console.log("No results found.\n");
|
|
142
|
+
} else {
|
|
143
|
+
console.log(`Found ${totalResults} results.
|
|
144
|
+
`);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
return search;
|
|
148
|
+
}
|
|
149
|
+
export {
|
|
150
|
+
createSearchCommand
|
|
151
|
+
};
|
|
152
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/cli/commands/search.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Search Command for StackMemory CLI\n * Search across tasks and context\n */\n\nimport { Command } from 'commander';\nimport Database from 'better-sqlite3';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\n\nexport function createSearchCommand(): Command {\n const search = new Command('search')\n .alias('find')\n .description('Search across tasks and context')\n .argument('<query>', 'Search query')\n .option('-t, --tasks', 'Search only tasks')\n .option('-c, --context', 'Search only context')\n .option('-l, --limit <n>', 'Limit results', '20')\n .action(async (query, options) => {\n const projectRoot = process.cwd();\n const dbPath = join(projectRoot, '.stackmemory', 'context.db');\n\n if (!existsSync(dbPath)) {\n console.log(\n '\u274C StackMemory not initialized. Run \"stackmemory init\" first.'\n );\n return;\n }\n\n const db = new Database(dbPath);\n const limit = parseInt(options.limit);\n const searchTasks = !options.context || options.tasks;\n const searchContext = !options.tasks || options.context;\n\n console.log(`\\n\uD83D\uDD0D Searching for \"${query}\"...\\n`);\n\n let totalResults = 0;\n\n // Search tasks\n if (searchTasks) {\n try {\n const tasks = db\n .prepare(\n `\n SELECT id, title, description, status, priority, created_at\n FROM task_cache \n WHERE title LIKE ? OR description LIKE ?\n ORDER BY created_at DESC\n LIMIT ?\n `\n )\n .all(`%${query}%`, `%${query}%`, limit) as any[];\n\n if (tasks.length > 0) {\n console.log(`\uD83D\uDCCB Tasks (${tasks.length})\\n`);\n\n const priorityIcon: Record<string, string> = {\n urgent: '\uD83D\uDD34',\n high: '\uD83D\uDFE0',\n medium: '\uD83D\uDFE1',\n low: '\uD83D\uDFE2',\n };\n const statusIcon: Record<string, string> = {\n pending: '\u23F3',\n in_progress: '\uD83D\uDD04',\n completed: '\u2705',\n blocked: '\uD83D\uDEAB',\n };\n\n tasks.forEach((task) => {\n const pIcon = priorityIcon[task.priority] || '\u26AA';\n const sIcon = statusIcon[task.status] || '\u26AA';\n console.log(`${sIcon} ${pIcon} ${task.title}`);\n\n // Highlight match in description\n if (task.description) {\n const desc = task.description.split('\\n')[0];\n const matchIdx = desc\n .toLowerCase()\n .indexOf(query.toLowerCase());\n if (matchIdx >= 0) {\n const start = Math.max(0, matchIdx - 20);\n const end = Math.min(\n desc.length,\n matchIdx + query.length + 20\n );\n const snippet =\n (start > 0 ? '...' : '') +\n desc.slice(start, end) +\n (end < desc.length ? '...' : '');\n console.log(` ${snippet}`);\n }\n }\n });\n console.log('');\n totalResults += tasks.length;\n }\n } catch (error) {\n // Task table might not exist\n }\n }\n\n // Search context/frames\n if (searchContext) {\n try {\n const contexts = db\n .prepare(\n `\n SELECT id, type, name, metadata, created_at\n FROM frames \n WHERE name LIKE ? OR metadata LIKE ?\n ORDER BY created_at DESC\n LIMIT ?\n `\n )\n .all(`%${query}%`, `%${query}%`, limit) as any[];\n\n if (contexts.length > 0) {\n console.log(`\uD83D\uDCC1 Context Frames (${contexts.length})\\n`);\n\n const typeIcon: Record<string, string> = {\n session: '\uD83D\uDD37',\n task: '\uD83D\uDCCB',\n command: '\u26A1',\n file: '\uD83D\uDCC4',\n decision: '\uD83D\uDCA1',\n };\n\n contexts.forEach((ctx) => {\n const icon = typeIcon[ctx.type] || '\uD83D\uDCE6';\n const date = new Date(ctx.created_at * 1000).toLocaleDateString();\n console.log(\n `${icon} [${ctx.type}] ${ctx.name || ctx.id.slice(0, 10)}`\n );\n console.log(` Created: ${date}`);\n });\n console.log('');\n totalResults += contexts.length;\n }\n } catch (error) {\n // Frames table might not exist\n }\n }\n\n // Search decisions/observations in events\n if (searchContext) {\n try {\n const events = db\n .prepare(\n `\n SELECT id, type, data, timestamp\n FROM events \n WHERE data LIKE ?\n ORDER BY timestamp DESC\n LIMIT ?\n `\n )\n .all(`%${query}%`, limit) as any[];\n\n if (events.length > 0) {\n console.log(`\uD83D\uDCDD Events (${events.length})\\n`);\n\n events.forEach((evt) => {\n const date = new Date(evt.timestamp * 1000).toLocaleDateString();\n let data: any = {};\n try {\n data = JSON.parse(evt.data);\n } catch {}\n\n const summary =\n data.content || data.message || data.decision || evt.type;\n console.log(`\u26A1 [${evt.type}] ${String(summary).slice(0, 60)}`);\n console.log(` ${date}`);\n });\n console.log('');\n totalResults += events.length;\n }\n } catch (error) {\n // Events table might not exist\n }\n }\n\n db.close();\n\n if (totalResults === 0) {\n console.log('No results found.\\n');\n } else {\n console.log(`Found ${totalResults} results.\\n`);\n }\n });\n\n return search;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { sessionManager } from "../../core/session/index.js";
|
|
3
|
+
import { logger } from "../../core/monitoring/logger.js";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
function createSessionCommands() {
|
|
6
|
+
const sessionCommand = new Command("session").description("Manage StackMemory sessions");
|
|
7
|
+
sessionCommand.command("list").description("List all sessions").option("--project", "Show only sessions for current project").option("--active", "Show only active sessions").option("--all", "Show all sessions including closed").action(async (options) => {
|
|
8
|
+
try {
|
|
9
|
+
await sessionManager.initialize();
|
|
10
|
+
const filter = {};
|
|
11
|
+
if (options.project) {
|
|
12
|
+
const projectHash = await getProjectHash();
|
|
13
|
+
filter.projectId = projectHash;
|
|
14
|
+
}
|
|
15
|
+
if (options.active && !options.all) {
|
|
16
|
+
filter.state = "active";
|
|
17
|
+
}
|
|
18
|
+
const sessions = await sessionManager.listSessions(filter);
|
|
19
|
+
if (sessions.length === 0) {
|
|
20
|
+
console.log("No sessions found");
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
console.log(chalk.bold("\n\u{1F4CB} StackMemory Sessions:\n"));
|
|
24
|
+
sessions.forEach((session) => {
|
|
25
|
+
const age = formatAge(Date.now() - session.lastActiveAt);
|
|
26
|
+
const status = session.state === "active" ? chalk.green("\u25CF") : session.state === "suspended" ? chalk.yellow("\u25CF") : chalk.gray("\u25CF");
|
|
27
|
+
console.log(`${status} ${chalk.bold(session.sessionId.slice(0, 8))}`);
|
|
28
|
+
console.log(` Project: ${session.projectId}`);
|
|
29
|
+
if (session.branch) {
|
|
30
|
+
console.log(` Branch: ${session.branch}`);
|
|
31
|
+
}
|
|
32
|
+
console.log(` State: ${session.state}`);
|
|
33
|
+
console.log(` Last active: ${age} ago`);
|
|
34
|
+
console.log("");
|
|
35
|
+
});
|
|
36
|
+
console.log(chalk.gray(`Total: ${sessions.length} session(s)`));
|
|
37
|
+
} catch (error) {
|
|
38
|
+
logger.error("Failed to list sessions", error);
|
|
39
|
+
console.error("\u274C Failed to list sessions:", error.message);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
sessionCommand.command("current").description("Show current session information").action(async () => {
|
|
44
|
+
try {
|
|
45
|
+
await sessionManager.initialize();
|
|
46
|
+
const session = sessionManager.getCurrentSession();
|
|
47
|
+
if (!session) {
|
|
48
|
+
console.log("No active session");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const duration = formatDuration(Date.now() - session.startedAt);
|
|
52
|
+
console.log(chalk.bold("\n\u{1F50D} Current Session:\n"));
|
|
53
|
+
console.log(`Session ID: ${chalk.cyan(session.sessionId)}`);
|
|
54
|
+
console.log(`Run ID: ${session.runId}`);
|
|
55
|
+
console.log(`Project: ${session.projectId}`);
|
|
56
|
+
if (session.branch) {
|
|
57
|
+
console.log(`Branch: ${session.branch}`);
|
|
58
|
+
}
|
|
59
|
+
console.log(`State: ${session.state}`);
|
|
60
|
+
console.log(`Duration: ${duration}`);
|
|
61
|
+
if (session.metadata.user) {
|
|
62
|
+
console.log(`User: ${session.metadata.user}`);
|
|
63
|
+
}
|
|
64
|
+
if (session.metadata.tags && session.metadata.tags.length > 0) {
|
|
65
|
+
console.log(`Tags: ${session.metadata.tags.join(", ")}`);
|
|
66
|
+
}
|
|
67
|
+
} catch (error) {
|
|
68
|
+
logger.error("Failed to show current session", error);
|
|
69
|
+
console.error("\u274C Failed to show current session:", error.message);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
sessionCommand.command("switch <sessionId>").description("Switch to a different session").action(async (sessionId) => {
|
|
74
|
+
try {
|
|
75
|
+
await sessionManager.initialize();
|
|
76
|
+
const current = sessionManager.getCurrentSession();
|
|
77
|
+
if (current) {
|
|
78
|
+
await sessionManager.suspendSession();
|
|
79
|
+
console.log(`Suspended session: ${current.sessionId.slice(0, 8)}`);
|
|
80
|
+
}
|
|
81
|
+
const session = await sessionManager.resumeSession(sessionId);
|
|
82
|
+
console.log(chalk.green(`\u2705 Switched to session: ${session.sessionId.slice(0, 8)}`));
|
|
83
|
+
console.log(` Project: ${session.projectId}`);
|
|
84
|
+
if (session.branch) {
|
|
85
|
+
console.log(` Branch: ${session.branch}`);
|
|
86
|
+
}
|
|
87
|
+
} catch (error) {
|
|
88
|
+
logger.error("Failed to switch session", error);
|
|
89
|
+
console.error("\u274C Failed to switch session:", error.message);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
sessionCommand.command("suspend [sessionId]").description("Suspend a session (current if not specified)").action(async (sessionId) => {
|
|
94
|
+
try {
|
|
95
|
+
await sessionManager.initialize();
|
|
96
|
+
await sessionManager.suspendSession(sessionId);
|
|
97
|
+
const id = sessionId || sessionManager.getCurrentSession()?.sessionId;
|
|
98
|
+
console.log(chalk.yellow(`\u23F8\uFE0F Suspended session: ${id?.slice(0, 8)}`));
|
|
99
|
+
} catch (error) {
|
|
100
|
+
logger.error("Failed to suspend session", error);
|
|
101
|
+
console.error("\u274C Failed to suspend session:", error.message);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
sessionCommand.command("resume <sessionId>").description("Resume a suspended session").action(async (sessionId) => {
|
|
106
|
+
try {
|
|
107
|
+
await sessionManager.initialize();
|
|
108
|
+
const session = await sessionManager.resumeSession(sessionId);
|
|
109
|
+
console.log(chalk.green(`\u25B6\uFE0F Resumed session: ${session.sessionId.slice(0, 8)}`));
|
|
110
|
+
console.log(` Project: ${session.projectId}`);
|
|
111
|
+
if (session.branch) {
|
|
112
|
+
console.log(` Branch: ${session.branch}`);
|
|
113
|
+
}
|
|
114
|
+
} catch (error) {
|
|
115
|
+
logger.error("Failed to resume session", error);
|
|
116
|
+
console.error("\u274C Failed to resume session:", error.message);
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
sessionCommand.command("merge <sourceId> <targetId>").description("Merge two sessions").action(async (sourceId, targetId) => {
|
|
121
|
+
try {
|
|
122
|
+
await sessionManager.initialize();
|
|
123
|
+
const merged = await sessionManager.mergeSessions(sourceId, targetId);
|
|
124
|
+
console.log(chalk.green(`\u2705 Merged sessions successfully`));
|
|
125
|
+
console.log(` Target: ${merged.sessionId.slice(0, 8)}`);
|
|
126
|
+
console.log(` Source ${sourceId.slice(0, 8)} has been closed`);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
logger.error("Failed to merge sessions", error);
|
|
129
|
+
console.error("\u274C Failed to merge sessions:", error.message);
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
sessionCommand.command("cleanup").description("Clean up old closed sessions").option("--days <days>", "Remove sessions older than N days", "30").action(async (options) => {
|
|
134
|
+
try {
|
|
135
|
+
await sessionManager.initialize();
|
|
136
|
+
const days = parseInt(options.days);
|
|
137
|
+
const maxAge = days * 24 * 60 * 60 * 1e3;
|
|
138
|
+
const cleaned = await sessionManager.cleanupStaleSessions(maxAge);
|
|
139
|
+
console.log(chalk.green(`\u2705 Cleaned up ${cleaned} old session(s)`));
|
|
140
|
+
} catch (error) {
|
|
141
|
+
logger.error("Failed to cleanup sessions", error);
|
|
142
|
+
console.error("\u274C Failed to cleanup sessions:", error.message);
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
return sessionCommand;
|
|
147
|
+
}
|
|
148
|
+
async function getProjectHash() {
|
|
149
|
+
const crypto = await import("crypto");
|
|
150
|
+
const cwd = process.cwd();
|
|
151
|
+
const hash = crypto.createHash("sha256");
|
|
152
|
+
hash.update(cwd);
|
|
153
|
+
return hash.digest("hex").substring(0, 12);
|
|
154
|
+
}
|
|
155
|
+
function formatAge(ms) {
|
|
156
|
+
const seconds = Math.floor(ms / 1e3);
|
|
157
|
+
const minutes = Math.floor(seconds / 60);
|
|
158
|
+
const hours = Math.floor(minutes / 60);
|
|
159
|
+
const days = Math.floor(hours / 24);
|
|
160
|
+
if (days > 0) return `${days}d`;
|
|
161
|
+
if (hours > 0) return `${hours}h`;
|
|
162
|
+
if (minutes > 0) return `${minutes}m`;
|
|
163
|
+
return `${seconds}s`;
|
|
164
|
+
}
|
|
165
|
+
function formatDuration(ms) {
|
|
166
|
+
const seconds = Math.floor(ms / 1e3);
|
|
167
|
+
const minutes = Math.floor(seconds / 60);
|
|
168
|
+
const hours = Math.floor(minutes / 60);
|
|
169
|
+
const h = hours;
|
|
170
|
+
const m = minutes % 60;
|
|
171
|
+
const s = seconds % 60;
|
|
172
|
+
if (h > 0) return `${h}h ${m}m ${s}s`;
|
|
173
|
+
if (m > 0) return `${m}m ${s}s`;
|
|
174
|
+
return `${s}s`;
|
|
175
|
+
}
|
|
176
|
+
export {
|
|
177
|
+
createSessionCommands
|
|
178
|
+
};
|
|
179
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/cli/commands/session.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Session Management CLI Commands\n * Provides commands for managing StackMemory sessions\n */\n\nimport { Command } from 'commander';\nimport { sessionManager } from '../../core/session/index.js';\nimport { logger } from '../../core/monitoring/logger.js';\nimport chalk from 'chalk';\n\nexport function createSessionCommands(): Command {\n const sessionCommand = new Command('session')\n .description('Manage StackMemory sessions');\n\n sessionCommand\n .command('list')\n .description('List all sessions')\n .option('--project', 'Show only sessions for current project')\n .option('--active', 'Show only active sessions')\n .option('--all', 'Show all sessions including closed')\n .action(async (options) => {\n try {\n await sessionManager.initialize();\n \n const filter: any = {};\n if (options.project) {\n const projectHash = await getProjectHash();\n filter.projectId = projectHash;\n }\n if (options.active && !options.all) {\n filter.state = 'active';\n }\n\n const sessions = await sessionManager.listSessions(filter);\n \n if (sessions.length === 0) {\n console.log('No sessions found');\n return;\n }\n\n console.log(chalk.bold('\\n\uD83D\uDCCB StackMemory Sessions:\\n'));\n \n sessions.forEach(session => {\n const age = formatAge(Date.now() - session.lastActiveAt);\n const status = session.state === 'active' ? chalk.green('\u25CF') : \n session.state === 'suspended' ? chalk.yellow('\u25CF') : chalk.gray('\u25CF');\n \n console.log(`${status} ${chalk.bold(session.sessionId.slice(0, 8))}`);\n console.log(` Project: ${session.projectId}`);\n if (session.branch) {\n console.log(` Branch: ${session.branch}`);\n }\n console.log(` State: ${session.state}`);\n console.log(` Last active: ${age} ago`);\n console.log('');\n });\n\n console.log(chalk.gray(`Total: ${sessions.length} session(s)`));\n } catch (error) {\n logger.error('Failed to list sessions', error as Error);\n console.error('\u274C Failed to list sessions:', (error as Error).message);\n process.exit(1);\n }\n });\n\n sessionCommand\n .command('current')\n .description('Show current session information')\n .action(async () => {\n try {\n await sessionManager.initialize();\n const session = sessionManager.getCurrentSession();\n \n if (!session) {\n console.log('No active session');\n return;\n }\n\n const duration = formatDuration(Date.now() - session.startedAt);\n \n console.log(chalk.bold('\\n\uD83D\uDD0D Current Session:\\n'));\n console.log(`Session ID: ${chalk.cyan(session.sessionId)}`);\n console.log(`Run ID: ${session.runId}`);\n console.log(`Project: ${session.projectId}`);\n if (session.branch) {\n console.log(`Branch: ${session.branch}`);\n }\n console.log(`State: ${session.state}`);\n console.log(`Duration: ${duration}`);\n \n if (session.metadata.user) {\n console.log(`User: ${session.metadata.user}`);\n }\n if (session.metadata.tags && session.metadata.tags.length > 0) {\n console.log(`Tags: ${session.metadata.tags.join(', ')}`);\n }\n } catch (error) {\n logger.error('Failed to show current session', error as Error);\n console.error('\u274C Failed to show current session:', (error as Error).message);\n process.exit(1);\n }\n });\n\n sessionCommand\n .command('switch <sessionId>')\n .description('Switch to a different session')\n .action(async (sessionId) => {\n try {\n await sessionManager.initialize();\n \n // Suspend current session\n const current = sessionManager.getCurrentSession();\n if (current) {\n await sessionManager.suspendSession();\n console.log(`Suspended session: ${current.sessionId.slice(0, 8)}`);\n }\n\n // Resume target session\n const session = await sessionManager.resumeSession(sessionId);\n console.log(chalk.green(`\u2705 Switched to session: ${session.sessionId.slice(0, 8)}`));\n console.log(` Project: ${session.projectId}`);\n if (session.branch) {\n console.log(` Branch: ${session.branch}`);\n }\n } catch (error) {\n logger.error('Failed to switch session', error as Error);\n console.error('\u274C Failed to switch session:', (error as Error).message);\n process.exit(1);\n }\n });\n\n sessionCommand\n .command('suspend [sessionId]')\n .description('Suspend a session (current if not specified)')\n .action(async (sessionId) => {\n try {\n await sessionManager.initialize();\n await sessionManager.suspendSession(sessionId);\n \n const id = sessionId || sessionManager.getCurrentSession()?.sessionId;\n console.log(chalk.yellow(`\u23F8\uFE0F Suspended session: ${id?.slice(0, 8)}`));\n } catch (error) {\n logger.error('Failed to suspend session', error as Error);\n console.error('\u274C Failed to suspend session:', (error as Error).message);\n process.exit(1);\n }\n });\n\n sessionCommand\n .command('resume <sessionId>')\n .description('Resume a suspended session')\n .action(async (sessionId) => {\n try {\n await sessionManager.initialize();\n const session = await sessionManager.resumeSession(sessionId);\n \n console.log(chalk.green(`\u25B6\uFE0F Resumed session: ${session.sessionId.slice(0, 8)}`));\n console.log(` Project: ${session.projectId}`);\n if (session.branch) {\n console.log(` Branch: ${session.branch}`);\n }\n } catch (error) {\n logger.error('Failed to resume session', error as Error);\n console.error('\u274C Failed to resume session:', (error as Error).message);\n process.exit(1);\n }\n });\n\n sessionCommand\n .command('merge <sourceId> <targetId>')\n .description('Merge two sessions')\n .action(async (sourceId, targetId) => {\n try {\n await sessionManager.initialize();\n const merged = await sessionManager.mergeSessions(sourceId, targetId);\n \n console.log(chalk.green(`\u2705 Merged sessions successfully`));\n console.log(` Target: ${merged.sessionId.slice(0, 8)}`);\n console.log(` Source ${sourceId.slice(0, 8)} has been closed`);\n } catch (error) {\n logger.error('Failed to merge sessions', error as Error);\n console.error('\u274C Failed to merge sessions:', (error as Error).message);\n process.exit(1);\n }\n });\n\n sessionCommand\n .command('cleanup')\n .description('Clean up old closed sessions')\n .option('--days <days>', 'Remove sessions older than N days', '30')\n .action(async (options) => {\n try {\n await sessionManager.initialize();\n \n const days = parseInt(options.days);\n const maxAge = days * 24 * 60 * 60 * 1000;\n const cleaned = await sessionManager.cleanupStaleSessions(maxAge);\n \n console.log(chalk.green(`\u2705 Cleaned up ${cleaned} old session(s)`));\n } catch (error) {\n logger.error('Failed to cleanup sessions', error as Error);\n console.error('\u274C Failed to cleanup sessions:', (error as Error).message);\n process.exit(1);\n }\n });\n\n return sessionCommand;\n}\n\n// Helper functions\nasync function getProjectHash(): Promise<string> {\n const crypto = await import('crypto');\n const cwd = process.cwd();\n const hash = crypto.createHash('sha256');\n hash.update(cwd);\n return hash.digest('hex').substring(0, 12);\n}\n\nfunction formatAge(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n \n if (days > 0) return `${days}d`;\n if (hours > 0) return `${hours}h`;\n if (minutes > 0) return `${minutes}m`;\n return `${seconds}s`;\n}\n\nfunction formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n \n const h = hours;\n const m = minutes % 60;\n const s = seconds % 60;\n \n if (h > 0) return `${h}h ${m}m ${s}s`;\n if (m > 0) return `${m}m ${s}s`;\n return `${s}s`;\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import Database from "better-sqlite3";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { existsSync } from "fs";
|
|
5
|
+
import {
|
|
6
|
+
PebblesTaskStore
|
|
7
|
+
} from "../../features/tasks/pebbles-task-store.js";
|
|
8
|
+
function getTaskStore(projectRoot) {
|
|
9
|
+
const dbPath = join(projectRoot, ".stackmemory", "context.db");
|
|
10
|
+
if (!existsSync(dbPath)) {
|
|
11
|
+
console.log(
|
|
12
|
+
'\u274C StackMemory not initialized. Run "stackmemory init" first.'
|
|
13
|
+
);
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
const db = new Database(dbPath);
|
|
17
|
+
return new PebblesTaskStore(projectRoot, db);
|
|
18
|
+
}
|
|
19
|
+
function createTaskCommands() {
|
|
20
|
+
const tasks = new Command("tasks").alias("task").description("Manage tasks from command line");
|
|
21
|
+
tasks.command("list").alias("ls").description("List tasks").option(
|
|
22
|
+
"-s, --status <status>",
|
|
23
|
+
"Filter by status (pending, in_progress, completed, blocked)"
|
|
24
|
+
).option(
|
|
25
|
+
"-p, --priority <priority>",
|
|
26
|
+
"Filter by priority (urgent, high, medium, low)"
|
|
27
|
+
).option("-q, --query <text>", "Search in title/description").option("-l, --limit <n>", "Limit results", "20").option("-a, --all", "Include completed tasks").action(async (options) => {
|
|
28
|
+
const projectRoot = process.cwd();
|
|
29
|
+
const taskStore = getTaskStore(projectRoot);
|
|
30
|
+
if (!taskStore) return;
|
|
31
|
+
try {
|
|
32
|
+
const db = new Database(
|
|
33
|
+
join(projectRoot, ".stackmemory", "context.db")
|
|
34
|
+
);
|
|
35
|
+
let query = "SELECT * FROM task_cache WHERE 1=1";
|
|
36
|
+
const params = [];
|
|
37
|
+
if (!options.all && !options.status) {
|
|
38
|
+
query += " AND status NOT IN ('completed', 'cancelled')";
|
|
39
|
+
}
|
|
40
|
+
if (options.status) {
|
|
41
|
+
query += " AND status = ?";
|
|
42
|
+
params.push(options.status);
|
|
43
|
+
}
|
|
44
|
+
if (options.priority) {
|
|
45
|
+
query += " AND priority = ?";
|
|
46
|
+
params.push(options.priority);
|
|
47
|
+
}
|
|
48
|
+
if (options.query) {
|
|
49
|
+
query += " AND (title LIKE ? OR description LIKE ?)";
|
|
50
|
+
params.push(`%${options.query}%`, `%${options.query}%`);
|
|
51
|
+
}
|
|
52
|
+
query += " ORDER BY priority ASC, created_at DESC LIMIT ?";
|
|
53
|
+
params.push(parseInt(options.limit));
|
|
54
|
+
const rows = db.prepare(query).all(...params);
|
|
55
|
+
db.close();
|
|
56
|
+
if (rows.length === 0) {
|
|
57
|
+
console.log("\u{1F4DD} No tasks found");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
console.log(`
|
|
61
|
+
\u{1F4CB} Tasks (${rows.length})
|
|
62
|
+
`);
|
|
63
|
+
const priorityIcon = {
|
|
64
|
+
urgent: "\u{1F534}",
|
|
65
|
+
high: "\u{1F7E0}",
|
|
66
|
+
medium: "\u{1F7E1}",
|
|
67
|
+
low: "\u{1F7E2}"
|
|
68
|
+
};
|
|
69
|
+
const statusIcon = {
|
|
70
|
+
pending: "\u23F3",
|
|
71
|
+
in_progress: "\u{1F504}",
|
|
72
|
+
completed: "\u2705",
|
|
73
|
+
blocked: "\u{1F6AB}",
|
|
74
|
+
cancelled: "\u274C"
|
|
75
|
+
};
|
|
76
|
+
rows.forEach((row, i) => {
|
|
77
|
+
const pIcon = priorityIcon[row.priority] || "\u26AA";
|
|
78
|
+
const sIcon = statusIcon[row.status] || "\u26AA";
|
|
79
|
+
const id = row.id.slice(0, 10);
|
|
80
|
+
console.log(`${sIcon} ${pIcon} [${id}] ${row.title}`);
|
|
81
|
+
if (row.description) {
|
|
82
|
+
const desc = row.description.split("\n")[0].slice(0, 60);
|
|
83
|
+
console.log(
|
|
84
|
+
` ${desc}${row.description.length > 60 ? "..." : ""}`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
console.log("");
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.error("\u274C Failed to list tasks:", error.message);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
tasks.command("add <title>").description("Add a new task").option("-d, --description <text>", "Task description").option(
|
|
94
|
+
"-p, --priority <priority>",
|
|
95
|
+
"Priority (urgent, high, medium, low)",
|
|
96
|
+
"medium"
|
|
97
|
+
).option("-t, --tags <tags>", "Comma-separated tags").action(async (title, options) => {
|
|
98
|
+
const projectRoot = process.cwd();
|
|
99
|
+
const taskStore = getTaskStore(projectRoot);
|
|
100
|
+
if (!taskStore) return;
|
|
101
|
+
try {
|
|
102
|
+
const taskId = taskStore.createTask({
|
|
103
|
+
title,
|
|
104
|
+
description: options.description,
|
|
105
|
+
priority: options.priority,
|
|
106
|
+
frameId: "cli",
|
|
107
|
+
tags: options.tags ? options.tags.split(",").map((t) => t.trim()) : []
|
|
108
|
+
});
|
|
109
|
+
console.log(`\u2705 Created task: ${taskId.slice(0, 10)}`);
|
|
110
|
+
console.log(` Title: ${title}`);
|
|
111
|
+
console.log(` Priority: ${options.priority}`);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
console.error("\u274C Failed to add task:", error.message);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
tasks.command("start <taskId>").description("Start working on a task").action(async (taskId) => {
|
|
117
|
+
const projectRoot = process.cwd();
|
|
118
|
+
const taskStore = getTaskStore(projectRoot);
|
|
119
|
+
if (!taskStore) return;
|
|
120
|
+
try {
|
|
121
|
+
const task = findTaskByPartialId(projectRoot, taskId);
|
|
122
|
+
if (!task) {
|
|
123
|
+
console.log(`\u274C Task not found: ${taskId}`);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
taskStore.updateTaskStatus(task.id, "in_progress", "Started from CLI");
|
|
127
|
+
console.log(`\u{1F504} Started: ${task.title}`);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error("\u274C Failed to start task:", error.message);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
tasks.command("done <taskId>").alias("complete").description("Mark task as completed").action(async (taskId) => {
|
|
133
|
+
const projectRoot = process.cwd();
|
|
134
|
+
const taskStore = getTaskStore(projectRoot);
|
|
135
|
+
if (!taskStore) return;
|
|
136
|
+
try {
|
|
137
|
+
const task = findTaskByPartialId(projectRoot, taskId);
|
|
138
|
+
if (!task) {
|
|
139
|
+
console.log(`\u274C Task not found: ${taskId}`);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
taskStore.updateTaskStatus(task.id, "completed", "Completed from CLI");
|
|
143
|
+
console.log(`\u2705 Completed: ${task.title}`);
|
|
144
|
+
} catch (error) {
|
|
145
|
+
console.error("\u274C Failed to complete task:", error.message);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
tasks.command("show <taskId>").description("Show task details").action(async (taskId) => {
|
|
149
|
+
const projectRoot = process.cwd();
|
|
150
|
+
try {
|
|
151
|
+
const task = findTaskByPartialId(projectRoot, taskId);
|
|
152
|
+
if (!task) {
|
|
153
|
+
console.log(`\u274C Task not found: ${taskId}`);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
console.log(`
|
|
157
|
+
\u{1F4CB} Task Details
|
|
158
|
+
`);
|
|
159
|
+
console.log(`ID: ${task.id}`);
|
|
160
|
+
console.log(`Title: ${task.title}`);
|
|
161
|
+
console.log(`Status: ${task.status}`);
|
|
162
|
+
console.log(`Priority: ${task.priority}`);
|
|
163
|
+
console.log(
|
|
164
|
+
`Created: ${new Date(task.created_at * 1e3).toLocaleString()}`
|
|
165
|
+
);
|
|
166
|
+
if (task.completed_at) {
|
|
167
|
+
console.log(
|
|
168
|
+
`Completed: ${new Date(task.completed_at * 1e3).toLocaleString()}`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
if (task.description) {
|
|
172
|
+
console.log(`
|
|
173
|
+
Description:
|
|
174
|
+
${task.description}`);
|
|
175
|
+
}
|
|
176
|
+
const tags = JSON.parse(task.tags || "[]");
|
|
177
|
+
if (tags.length > 0) {
|
|
178
|
+
console.log(`
|
|
179
|
+
Tags: ${tags.join(", ")}`);
|
|
180
|
+
}
|
|
181
|
+
console.log("");
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error("\u274C Failed to show task:", error.message);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
return tasks;
|
|
187
|
+
}
|
|
188
|
+
function findTaskByPartialId(projectRoot, partialId) {
|
|
189
|
+
const dbPath = join(projectRoot, ".stackmemory", "context.db");
|
|
190
|
+
if (!existsSync(dbPath)) return null;
|
|
191
|
+
const db = new Database(dbPath);
|
|
192
|
+
let row = db.prepare("SELECT * FROM task_cache WHERE id = ?").get(partialId);
|
|
193
|
+
if (!row) {
|
|
194
|
+
row = db.prepare("SELECT * FROM task_cache WHERE id LIKE ?").get(`${partialId}%`);
|
|
195
|
+
}
|
|
196
|
+
if (!row && partialId.match(/^ENG-\d+$/i)) {
|
|
197
|
+
row = db.prepare("SELECT * FROM task_cache WHERE title LIKE ?").get(`%[${partialId.toUpperCase()}]%`);
|
|
198
|
+
}
|
|
199
|
+
db.close();
|
|
200
|
+
return row || null;
|
|
201
|
+
}
|
|
202
|
+
export {
|
|
203
|
+
createTaskCommands
|
|
204
|
+
};
|
|
205
|
+
//# sourceMappingURL=tasks.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/cli/commands/tasks.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Enhanced Task Commands for StackMemory CLI\n * Provides task management directly from command line\n */\n\nimport { Command } from 'commander';\nimport Database from 'better-sqlite3';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\nimport {\n PebblesTaskStore,\n TaskPriority,\n TaskStatus,\n} from '../../features/tasks/pebbles-task-store.js';\nimport { logger } from '../../core/monitoring/logger.js';\n\nfunction getTaskStore(projectRoot: string): PebblesTaskStore | null {\n const dbPath = join(projectRoot, '.stackmemory', 'context.db');\n if (!existsSync(dbPath)) {\n console.log(\n '\u274C StackMemory not initialized. Run \"stackmemory init\" first.'\n );\n return null;\n }\n const db = new Database(dbPath);\n return new PebblesTaskStore(projectRoot, db);\n}\n\nexport function createTaskCommands(): Command {\n const tasks = new Command('tasks')\n .alias('task')\n .description('Manage tasks from command line');\n\n // List tasks\n tasks\n .command('list')\n .alias('ls')\n .description('List tasks')\n .option(\n '-s, --status <status>',\n 'Filter by status (pending, in_progress, completed, blocked)'\n )\n .option(\n '-p, --priority <priority>',\n 'Filter by priority (urgent, high, medium, low)'\n )\n .option('-q, --query <text>', 'Search in title/description')\n .option('-l, --limit <n>', 'Limit results', '20')\n .option('-a, --all', 'Include completed tasks')\n .action(async (options) => {\n const projectRoot = process.cwd();\n const taskStore = getTaskStore(projectRoot);\n if (!taskStore) return;\n\n try {\n // Get all tasks from DB\n const db = new Database(\n join(projectRoot, '.stackmemory', 'context.db')\n );\n let query = 'SELECT * FROM task_cache WHERE 1=1';\n const params: any[] = [];\n\n if (!options.all && !options.status) {\n query += \" AND status NOT IN ('completed', 'cancelled')\";\n }\n\n if (options.status) {\n query += ' AND status = ?';\n params.push(options.status);\n }\n\n if (options.priority) {\n query += ' AND priority = ?';\n params.push(options.priority);\n }\n\n if (options.query) {\n query += ' AND (title LIKE ? OR description LIKE ?)';\n params.push(`%${options.query}%`, `%${options.query}%`);\n }\n\n query += ' ORDER BY priority ASC, created_at DESC LIMIT ?';\n params.push(parseInt(options.limit));\n\n const rows = db.prepare(query).all(...params) as any[];\n db.close();\n\n if (rows.length === 0) {\n console.log('\uD83D\uDCDD No tasks found');\n return;\n }\n\n console.log(`\\n\uD83D\uDCCB Tasks (${rows.length})\\n`);\n\n const priorityIcon: Record<string, string> = {\n urgent: '\uD83D\uDD34',\n high: '\uD83D\uDFE0',\n medium: '\uD83D\uDFE1',\n low: '\uD83D\uDFE2',\n };\n const statusIcon: Record<string, string> = {\n pending: '\u23F3',\n in_progress: '\uD83D\uDD04',\n completed: '\u2705',\n blocked: '\uD83D\uDEAB',\n cancelled: '\u274C',\n };\n\n rows.forEach((row, i) => {\n const pIcon = priorityIcon[row.priority] || '\u26AA';\n const sIcon = statusIcon[row.status] || '\u26AA';\n const id = row.id.slice(0, 10);\n console.log(`${sIcon} ${pIcon} [${id}] ${row.title}`);\n if (row.description) {\n const desc = row.description.split('\\n')[0].slice(0, 60);\n console.log(\n ` ${desc}${row.description.length > 60 ? '...' : ''}`\n );\n }\n });\n console.log('');\n } catch (error) {\n console.error('\u274C Failed to list tasks:', (error as Error).message);\n }\n });\n\n // Add task\n tasks\n .command('add <title>')\n .description('Add a new task')\n .option('-d, --description <text>', 'Task description')\n .option(\n '-p, --priority <priority>',\n 'Priority (urgent, high, medium, low)',\n 'medium'\n )\n .option('-t, --tags <tags>', 'Comma-separated tags')\n .action(async (title, options) => {\n const projectRoot = process.cwd();\n const taskStore = getTaskStore(projectRoot);\n if (!taskStore) return;\n\n try {\n const taskId = taskStore.createTask({\n title,\n description: options.description,\n priority: options.priority as TaskPriority,\n frameId: 'cli',\n tags: options.tags\n ? options.tags.split(',').map((t: string) => t.trim())\n : [],\n });\n\n console.log(`\u2705 Created task: ${taskId.slice(0, 10)}`);\n console.log(` Title: ${title}`);\n console.log(` Priority: ${options.priority}`);\n } catch (error) {\n console.error('\u274C Failed to add task:', (error as Error).message);\n }\n });\n\n // Start task (set to in_progress)\n tasks\n .command('start <taskId>')\n .description('Start working on a task')\n .action(async (taskId) => {\n const projectRoot = process.cwd();\n const taskStore = getTaskStore(projectRoot);\n if (!taskStore) return;\n\n try {\n // Find task by partial ID\n const task = findTaskByPartialId(projectRoot, taskId);\n if (!task) {\n console.log(`\u274C Task not found: ${taskId}`);\n return;\n }\n\n taskStore.updateTaskStatus(task.id, 'in_progress', 'Started from CLI');\n console.log(`\uD83D\uDD04 Started: ${task.title}`);\n } catch (error) {\n console.error('\u274C Failed to start task:', (error as Error).message);\n }\n });\n\n // Complete task\n tasks\n .command('done <taskId>')\n .alias('complete')\n .description('Mark task as completed')\n .action(async (taskId) => {\n const projectRoot = process.cwd();\n const taskStore = getTaskStore(projectRoot);\n if (!taskStore) return;\n\n try {\n const task = findTaskByPartialId(projectRoot, taskId);\n if (!task) {\n console.log(`\u274C Task not found: ${taskId}`);\n return;\n }\n\n taskStore.updateTaskStatus(task.id, 'completed', 'Completed from CLI');\n console.log(`\u2705 Completed: ${task.title}`);\n } catch (error) {\n console.error('\u274C Failed to complete task:', (error as Error).message);\n }\n });\n\n // Show task details\n tasks\n .command('show <taskId>')\n .description('Show task details')\n .action(async (taskId) => {\n const projectRoot = process.cwd();\n\n try {\n const task = findTaskByPartialId(projectRoot, taskId);\n if (!task) {\n console.log(`\u274C Task not found: ${taskId}`);\n return;\n }\n\n console.log(`\\n\uD83D\uDCCB Task Details\\n`);\n console.log(`ID: ${task.id}`);\n console.log(`Title: ${task.title}`);\n console.log(`Status: ${task.status}`);\n console.log(`Priority: ${task.priority}`);\n console.log(\n `Created: ${new Date(task.created_at * 1000).toLocaleString()}`\n );\n if (task.completed_at) {\n console.log(\n `Completed: ${new Date(task.completed_at * 1000).toLocaleString()}`\n );\n }\n if (task.description) {\n console.log(`\\nDescription:\\n${task.description}`);\n }\n const tags = JSON.parse(task.tags || '[]');\n if (tags.length > 0) {\n console.log(`\\nTags: ${tags.join(', ')}`);\n }\n console.log('');\n } catch (error) {\n console.error('\u274C Failed to show task:', (error as Error).message);\n }\n });\n\n return tasks;\n}\n\nfunction findTaskByPartialId(\n projectRoot: string,\n partialId: string\n): any | null {\n const dbPath = join(projectRoot, '.stackmemory', 'context.db');\n if (!existsSync(dbPath)) return null;\n\n const db = new Database(dbPath);\n\n // Try exact match first, then partial\n let row = db.prepare('SELECT * FROM task_cache WHERE id = ?').get(partialId);\n\n if (!row) {\n row = db\n .prepare('SELECT * FROM task_cache WHERE id LIKE ?')\n .get(`${partialId}%`);\n }\n\n // Also try matching Linear identifier in title\n if (!row && partialId.match(/^ENG-\\d+$/i)) {\n row = db\n .prepare('SELECT * FROM task_cache WHERE title LIKE ?')\n .get(`%[${partialId.toUpperCase()}]%`);\n }\n\n db.close();\n return row || null;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|