@stackmemoryai/stackmemory 0.5.4 → 0.5.6
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/bin/claude-sm +6 -0
- package/bin/claude-smd +6 -0
- package/dist/agents/core/agent-task-manager.js +4 -0
- package/dist/agents/core/agent-task-manager.js.map +1 -1
- package/dist/agents/testing-agent.js +4 -0
- package/dist/agents/testing-agent.js.map +1 -1
- package/dist/agents/verifiers/base-verifier.js +4 -0
- package/dist/agents/verifiers/base-verifier.js.map +1 -1
- package/dist/agents/verifiers/formatter-verifier.js +4 -0
- package/dist/agents/verifiers/formatter-verifier.js.map +1 -1
- package/dist/agents/verifiers/llm-judge.js +4 -0
- package/dist/agents/verifiers/llm-judge.js.map +1 -1
- package/dist/cli/auto-detect.js +4 -0
- package/dist/cli/auto-detect.js.map +1 -1
- package/dist/cli/browser-test.js +4 -0
- package/dist/cli/browser-test.js.map +1 -1
- package/dist/cli/claude-sm-danger.js +21 -0
- package/dist/cli/claude-sm-danger.js.map +7 -0
- package/dist/cli/claude-sm.js +4 -0
- package/dist/cli/claude-sm.js.map +2 -2
- package/dist/cli/codex-sm.js +4 -0
- package/dist/cli/codex-sm.js.map +1 -1
- package/dist/cli/commands/api.js +232 -0
- package/dist/cli/commands/api.js.map +7 -0
- package/dist/cli/commands/cleanup-processes.js +68 -0
- package/dist/cli/commands/cleanup-processes.js.map +7 -0
- package/dist/cli/commands/clear.js +4 -0
- package/dist/cli/commands/clear.js.map +1 -1
- package/dist/cli/commands/config.js +4 -0
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/context-rehydrate.js +4 -0
- package/dist/cli/commands/context-rehydrate.js.map +1 -1
- package/dist/cli/commands/context.js +4 -0
- package/dist/cli/commands/context.js.map +1 -1
- package/dist/cli/commands/dashboard.js +4 -0
- package/dist/cli/commands/dashboard.js.map +1 -1
- package/dist/cli/commands/db.js +4 -0
- package/dist/cli/commands/db.js.map +1 -1
- package/dist/cli/commands/decision.js +4 -0
- package/dist/cli/commands/decision.js.map +1 -1
- package/dist/cli/commands/handoff.js +4 -0
- package/dist/cli/commands/handoff.js.map +1 -1
- package/dist/cli/commands/hooks.js +298 -0
- package/dist/cli/commands/hooks.js.map +7 -0
- package/dist/cli/commands/linear-unified.js +4 -0
- package/dist/cli/commands/linear-unified.js.map +1 -1
- package/dist/cli/commands/linear.js +4 -0
- package/dist/cli/commands/linear.js.map +1 -1
- package/dist/cli/commands/log.js +4 -0
- package/dist/cli/commands/log.js.map +1 -1
- package/dist/cli/commands/login.js +4 -0
- package/dist/cli/commands/login.js.map +1 -1
- package/dist/cli/commands/migrate.js +4 -0
- package/dist/cli/commands/migrate.js.map +1 -1
- package/dist/cli/commands/monitor.js +4 -0
- package/dist/cli/commands/monitor.js.map +1 -1
- package/dist/cli/commands/onboard.js +4 -0
- package/dist/cli/commands/onboard.js.map +1 -1
- package/dist/cli/commands/projects.js +4 -0
- package/dist/cli/commands/projects.js.map +1 -1
- package/dist/cli/commands/quality.js +4 -0
- package/dist/cli/commands/quality.js.map +1 -1
- package/dist/cli/commands/ralph.js +4 -0
- package/dist/cli/commands/ralph.js.map +1 -1
- package/dist/cli/commands/search.js +4 -0
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/service.js +4 -0
- package/dist/cli/commands/service.js.map +1 -1
- package/dist/cli/commands/session.js +4 -0
- package/dist/cli/commands/session.js.map +1 -1
- package/dist/cli/commands/shell.js +249 -0
- package/dist/cli/commands/shell.js.map +7 -0
- package/dist/cli/commands/signup.js +4 -0
- package/dist/cli/commands/signup.js.map +1 -1
- package/dist/cli/commands/skills.js +4 -0
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/commands/storage-tier.js +4 -0
- package/dist/cli/commands/storage-tier.js.map +1 -1
- package/dist/cli/commands/storage.js +4 -0
- package/dist/cli/commands/storage.js.map +1 -1
- package/dist/cli/commands/sweep.js +5 -4
- package/dist/cli/commands/sweep.js.map +2 -2
- package/dist/cli/commands/tasks.js +4 -0
- package/dist/cli/commands/tasks.js.map +1 -1
- package/dist/cli/commands/test.js +4 -0
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/commands/workflow.js +4 -0
- package/dist/cli/commands/workflow.js.map +1 -1
- package/dist/cli/commands/worktree.js +4 -0
- package/dist/cli/commands/worktree.js.map +1 -1
- package/dist/cli/index.js +13 -1
- package/dist/cli/index.js.map +2 -2
- package/dist/cli/utils/viewer.js +4 -0
- package/dist/cli/utils/viewer.js.map +1 -1
- package/dist/core/analytics/team-analytics.js +4 -0
- package/dist/core/analytics/team-analytics.js.map +1 -1
- package/dist/core/config/config-manager.js +4 -0
- package/dist/core/config/config-manager.js.map +1 -1
- package/dist/core/config/storage-config.js +4 -0
- package/dist/core/config/storage-config.js.map +1 -1
- package/dist/core/config/types.js +4 -0
- package/dist/core/config/types.js.map +1 -1
- package/dist/core/context/auto-context.js +4 -0
- package/dist/core/context/auto-context.js.map +1 -1
- package/dist/core/context/compaction-handler.js +4 -0
- package/dist/core/context/compaction-handler.js.map +1 -1
- package/dist/core/context/context-bridge.js +4 -0
- package/dist/core/context/context-bridge.js.map +1 -1
- package/dist/core/context/dual-stack-manager.js +4 -0
- package/dist/core/context/dual-stack-manager.js.map +1 -1
- package/dist/core/context/enhanced-rehydration.js +4 -0
- package/dist/core/context/enhanced-rehydration.js.map +1 -1
- package/dist/core/context/frame-database.js +4 -0
- package/dist/core/context/frame-database.js.map +1 -1
- package/dist/core/context/frame-digest.js +4 -0
- package/dist/core/context/frame-digest.js.map +1 -1
- package/dist/core/context/frame-handoff-manager.js +4 -0
- package/dist/core/context/frame-handoff-manager.js.map +1 -1
- package/dist/core/context/frame-manager.js +4 -0
- package/dist/core/context/frame-manager.js.map +1 -1
- package/dist/core/context/frame-stack.js +4 -0
- package/dist/core/context/frame-stack.js.map +1 -1
- package/dist/core/context/frame-types.js +4 -0
- package/dist/core/context/incremental-gc.js +4 -0
- package/dist/core/context/incremental-gc.js.map +1 -1
- package/dist/core/context/index.js +4 -0
- package/dist/core/context/index.js.map +1 -1
- package/dist/core/context/model-aware-compaction.js +4 -0
- package/dist/core/context/model-aware-compaction.js.map +1 -1
- package/dist/core/context/permission-manager.js +4 -0
- package/dist/core/context/permission-manager.js.map +1 -1
- package/dist/core/context/recursive-context-manager.js +4 -0
- package/dist/core/context/recursive-context-manager.js.map +1 -1
- package/dist/core/context/refactored-frame-manager.js +4 -0
- package/dist/core/context/refactored-frame-manager.js.map +1 -1
- package/dist/core/context/shared-context-layer.js +4 -0
- package/dist/core/context/shared-context-layer.js.map +1 -1
- package/dist/core/context/stack-merge-resolver.js +4 -0
- package/dist/core/context/stack-merge-resolver.js.map +1 -1
- package/dist/core/context/validation.js +4 -0
- package/dist/core/context/validation.js.map +1 -1
- package/dist/core/database/batch-operations.js +4 -0
- package/dist/core/database/batch-operations.js.map +1 -1
- package/dist/core/database/connection-pool.js +4 -0
- package/dist/core/database/connection-pool.js.map +1 -1
- package/dist/core/database/database-adapter.js +4 -0
- package/dist/core/database/database-adapter.js.map +1 -1
- package/dist/core/database/migration-manager.js +4 -0
- package/dist/core/database/migration-manager.js.map +1 -1
- package/dist/core/database/paradedb-adapter.js +4 -0
- package/dist/core/database/paradedb-adapter.js.map +1 -1
- package/dist/core/database/query-cache.js +4 -0
- package/dist/core/database/query-cache.js.map +1 -1
- package/dist/core/database/query-router.js +4 -0
- package/dist/core/database/query-router.js.map +1 -1
- package/dist/core/database/sqlite-adapter.js +4 -0
- package/dist/core/database/sqlite-adapter.js.map +1 -1
- package/dist/core/digest/enhanced-hybrid-digest.js +4 -0
- package/dist/core/digest/enhanced-hybrid-digest.js.map +1 -1
- package/dist/core/digest/frame-digest-integration.js +4 -0
- package/dist/core/digest/frame-digest-integration.js.map +1 -1
- package/dist/core/digest/hybrid-digest-generator.js +4 -0
- package/dist/core/digest/hybrid-digest-generator.js.map +1 -1
- package/dist/core/digest/index.js +4 -0
- package/dist/core/digest/index.js.map +1 -1
- package/dist/core/digest/types.js +4 -0
- package/dist/core/digest/types.js.map +1 -1
- package/dist/core/errors/index.js +4 -0
- package/dist/core/errors/index.js.map +1 -1
- package/dist/core/errors/recovery.js +4 -0
- package/dist/core/errors/recovery.js.map +1 -1
- package/dist/core/execution/parallel-executor.js +4 -0
- package/dist/core/execution/parallel-executor.js.map +1 -1
- package/dist/core/frame/workflow-templates.js +4 -0
- package/dist/core/frame/workflow-templates.js.map +1 -1
- package/dist/core/merge/conflict-detector.js +4 -0
- package/dist/core/merge/conflict-detector.js.map +1 -1
- package/dist/core/merge/index.js +4 -0
- package/dist/core/merge/index.js.map +1 -1
- package/dist/core/merge/resolution-engine.js +4 -0
- package/dist/core/merge/resolution-engine.js.map +1 -1
- package/dist/core/merge/stack-diff.js +4 -0
- package/dist/core/merge/stack-diff.js.map +1 -1
- package/dist/core/merge/types.js +4 -0
- package/dist/core/monitoring/error-handler.js +4 -0
- package/dist/core/monitoring/error-handler.js.map +1 -1
- package/dist/core/monitoring/logger.js +4 -0
- package/dist/core/monitoring/logger.js.map +1 -1
- package/dist/core/monitoring/metrics.js +4 -0
- package/dist/core/monitoring/metrics.js.map +1 -1
- package/dist/core/monitoring/progress-tracker.js +4 -0
- package/dist/core/monitoring/progress-tracker.js.map +1 -1
- package/dist/core/monitoring/session-monitor.js +4 -0
- package/dist/core/monitoring/session-monitor.js.map +1 -1
- package/dist/core/performance/context-cache.js +4 -0
- package/dist/core/performance/context-cache.js.map +1 -1
- package/dist/core/performance/index.js +4 -0
- package/dist/core/performance/index.js.map +1 -1
- package/dist/core/performance/lazy-context-loader.js +4 -0
- package/dist/core/performance/lazy-context-loader.js.map +1 -1
- package/dist/core/performance/monitor.js +4 -0
- package/dist/core/performance/monitor.js.map +1 -1
- package/dist/core/performance/optimized-frame-context.js +4 -0
- package/dist/core/performance/optimized-frame-context.js.map +1 -1
- package/dist/core/performance/performance-benchmark.js +4 -0
- package/dist/core/performance/performance-benchmark.js.map +1 -1
- package/dist/core/performance/performance-profiler.js +4 -0
- package/dist/core/performance/performance-profiler.js.map +1 -1
- package/dist/core/performance/streaming-jsonl-parser.js +4 -0
- package/dist/core/performance/streaming-jsonl-parser.js.map +1 -1
- package/dist/core/persistence/postgres-adapter.js +4 -0
- package/dist/core/persistence/postgres-adapter.js.map +1 -1
- package/dist/core/projects/project-isolation.js +4 -0
- package/dist/core/projects/project-isolation.js.map +1 -1
- package/dist/core/projects/project-manager.js +4 -0
- package/dist/core/projects/project-manager.js.map +1 -1
- package/dist/core/query/query-parser.js +4 -0
- package/dist/core/query/query-parser.js.map +1 -1
- package/dist/core/query/query-templates.js +4 -0
- package/dist/core/query/query-templates.js.map +1 -1
- package/dist/core/retrieval/context-retriever.js +4 -0
- package/dist/core/retrieval/context-retriever.js.map +1 -1
- package/dist/core/retrieval/graph-retrieval.js +4 -0
- package/dist/core/retrieval/graph-retrieval.js.map +1 -1
- package/dist/core/retrieval/hierarchical-retrieval.js +4 -0
- package/dist/core/retrieval/hierarchical-retrieval.js.map +1 -1
- package/dist/core/retrieval/index.js +4 -0
- package/dist/core/retrieval/index.js.map +1 -1
- package/dist/core/retrieval/llm-context-retrieval.js +4 -0
- package/dist/core/retrieval/llm-context-retrieval.js.map +1 -1
- package/dist/core/retrieval/retrieval-benchmarks.js +4 -0
- package/dist/core/retrieval/retrieval-benchmarks.js.map +1 -1
- package/dist/core/retrieval/summary-generator.js +4 -0
- package/dist/core/retrieval/summary-generator.js.map +1 -1
- package/dist/core/retrieval/types.js +4 -0
- package/dist/core/retrieval/types.js.map +1 -1
- package/dist/core/session/clear-survival.js +4 -0
- package/dist/core/session/clear-survival.js.map +1 -1
- package/dist/core/session/enhanced-handoff.js +4 -0
- package/dist/core/session/enhanced-handoff.js.map +1 -1
- package/dist/core/session/handoff-generator.js +4 -0
- package/dist/core/session/handoff-generator.js.map +1 -1
- package/dist/core/session/index.js +4 -0
- package/dist/core/session/index.js.map +1 -1
- package/dist/core/session/session-manager.js +4 -0
- package/dist/core/session/session-manager.js.map +1 -1
- package/dist/core/skills/index.js +4 -0
- package/dist/core/skills/index.js.map +1 -1
- package/dist/core/skills/skill-storage.js +4 -0
- package/dist/core/skills/skill-storage.js.map +1 -1
- package/dist/core/skills/types.js +4 -0
- package/dist/core/skills/types.js.map +1 -1
- package/dist/core/storage/chromadb-adapter.js +4 -0
- package/dist/core/storage/chromadb-adapter.js.map +1 -1
- package/dist/core/storage/infinite-storage.js +4 -0
- package/dist/core/storage/infinite-storage.js.map +1 -1
- package/dist/core/storage/railway-optimized-storage.js +4 -0
- package/dist/core/storage/railway-optimized-storage.js.map +1 -1
- package/dist/core/storage/remote-storage.js +4 -0
- package/dist/core/storage/remote-storage.js.map +1 -1
- package/dist/core/storage/two-tier-storage.js +4 -0
- package/dist/core/storage/two-tier-storage.js.map +1 -1
- package/dist/core/trace/cli-trace-wrapper.js +4 -0
- package/dist/core/trace/cli-trace-wrapper.js.map +1 -1
- package/dist/core/trace/db-trace-wrapper.js +4 -0
- package/dist/core/trace/db-trace-wrapper.js.map +1 -1
- package/dist/core/trace/debug-trace.js +4 -0
- package/dist/core/trace/debug-trace.js.map +1 -1
- package/dist/core/trace/index.js +4 -0
- package/dist/core/trace/index.js.map +1 -1
- package/dist/core/trace/linear-api-wrapper.js +4 -0
- package/dist/core/trace/linear-api-wrapper.js.map +1 -1
- package/dist/core/trace/trace-demo.js +4 -0
- package/dist/core/trace/trace-demo.js.map +1 -1
- package/dist/core/trace/trace-detector.demo.js +4 -0
- package/dist/core/trace/trace-detector.demo.js.map +1 -1
- package/dist/core/trace/trace-detector.js +4 -0
- package/dist/core/trace/trace-detector.js.map +1 -1
- package/dist/core/trace/trace-store.js +4 -0
- package/dist/core/trace/trace-store.js.map +1 -1
- package/dist/core/trace/types.js +4 -0
- package/dist/core/trace/types.js.map +1 -1
- package/dist/core/types.js +4 -0
- package/dist/core/utils/compression.js +4 -0
- package/dist/core/utils/compression.js.map +1 -1
- package/dist/core/utils/update-checker.js +4 -0
- package/dist/core/utils/update-checker.js.map +1 -1
- package/dist/core/worktree/worktree-manager.js +4 -0
- package/dist/core/worktree/worktree-manager.js.map +1 -1
- package/dist/daemon/session-daemon.js +4 -0
- package/dist/daemon/session-daemon.js.map +1 -1
- package/dist/features/analytics/api/analytics-api.js +4 -0
- package/dist/features/analytics/api/analytics-api.js.map +1 -1
- package/dist/features/analytics/core/analytics-service.js +4 -0
- package/dist/features/analytics/core/analytics-service.js.map +1 -1
- package/dist/features/analytics/index.js +4 -0
- package/dist/features/analytics/index.js.map +1 -1
- package/dist/features/analytics/queries/metrics-queries.js +4 -0
- package/dist/features/analytics/queries/metrics-queries.js.map +1 -1
- package/dist/features/analytics/types/metrics.js +4 -0
- package/dist/features/browser/browser-mcp.js +4 -0
- package/dist/features/browser/browser-mcp.js.map +1 -1
- package/dist/features/tasks/linear-task-manager.js +4 -0
- package/dist/features/tasks/linear-task-manager.js.map +1 -1
- package/dist/features/tasks/task-aware-context.js +4 -0
- package/dist/features/tasks/task-aware-context.js.map +1 -1
- package/dist/features/tui/simple-monitor.js +4 -0
- package/dist/features/tui/simple-monitor.js.map +1 -1
- package/dist/features/tui/swarm-monitor.js +4 -0
- package/dist/features/tui/swarm-monitor.js.map +1 -1
- package/dist/features/web/client/stores/task-store.js +4 -0
- package/dist/features/web/client/stores/task-store.js.map +1 -1
- package/dist/features/web/server/index.js +4 -0
- package/dist/features/web/server/index.js.map +1 -1
- package/dist/hooks/config.js +150 -0
- package/dist/hooks/config.js.map +7 -0
- package/dist/hooks/daemon.js +364 -0
- package/dist/hooks/daemon.js.map +7 -0
- package/dist/hooks/events.js +55 -0
- package/dist/hooks/events.js.map +7 -0
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/index.js.map +7 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/integrations/anthropic/client.js +4 -0
- package/dist/integrations/anthropic/client.js.map +1 -1
- package/dist/integrations/claude-code/agent-bridge.js +4 -0
- package/dist/integrations/claude-code/agent-bridge.js.map +1 -1
- package/dist/integrations/claude-code/enhanced-pre-clear-hooks.js +4 -0
- package/dist/integrations/claude-code/enhanced-pre-clear-hooks.js.map +1 -1
- package/dist/integrations/claude-code/lifecycle-hooks.js +4 -0
- package/dist/integrations/claude-code/lifecycle-hooks.js.map +1 -1
- package/dist/integrations/claude-code/post-task-hooks.js +4 -0
- package/dist/integrations/claude-code/post-task-hooks.js.map +1 -1
- package/dist/integrations/claude-code/subagent-client-stub.js +4 -0
- package/dist/integrations/claude-code/subagent-client-stub.js.map +1 -1
- package/dist/integrations/claude-code/subagent-client.js +4 -0
- package/dist/integrations/claude-code/subagent-client.js.map +1 -1
- package/dist/integrations/claude-code/task-coordinator.js +4 -0
- package/dist/integrations/claude-code/task-coordinator.js.map +1 -1
- package/dist/integrations/linear/auth.js +4 -0
- package/dist/integrations/linear/auth.js.map +1 -1
- package/dist/integrations/linear/auto-sync.js +4 -0
- package/dist/integrations/linear/auto-sync.js.map +1 -1
- package/dist/integrations/linear/client.js +4 -0
- package/dist/integrations/linear/client.js.map +1 -1
- package/dist/integrations/linear/config.js +4 -0
- package/dist/integrations/linear/config.js.map +1 -1
- package/dist/integrations/linear/migration.js +4 -0
- package/dist/integrations/linear/migration.js.map +1 -1
- package/dist/integrations/linear/oauth-server.js +4 -0
- package/dist/integrations/linear/oauth-server.js.map +1 -1
- package/dist/integrations/linear/rest-client.js +4 -0
- package/dist/integrations/linear/rest-client.js.map +1 -1
- package/dist/integrations/linear/sync-manager.js +4 -0
- package/dist/integrations/linear/sync-manager.js.map +1 -1
- package/dist/integrations/linear/sync-service.js +4 -0
- package/dist/integrations/linear/sync-service.js.map +1 -1
- package/dist/integrations/linear/sync.js +4 -0
- package/dist/integrations/linear/sync.js.map +1 -1
- package/dist/integrations/linear/types.js +4 -0
- package/dist/integrations/linear/unified-sync.js +4 -0
- package/dist/integrations/linear/unified-sync.js.map +1 -1
- package/dist/integrations/linear/webhook-handler.js +4 -0
- package/dist/integrations/linear/webhook-handler.js.map +1 -1
- package/dist/integrations/linear/webhook-server.js +4 -0
- package/dist/integrations/linear/webhook-server.js.map +1 -1
- package/dist/integrations/linear/webhook.js +4 -0
- package/dist/integrations/linear/webhook.js.map +1 -1
- package/dist/integrations/mcp/handlers/code-execution-handlers.js +4 -0
- package/dist/integrations/mcp/handlers/code-execution-handlers.js.map +1 -1
- package/dist/integrations/mcp/handlers/context-handlers.js +4 -0
- package/dist/integrations/mcp/handlers/context-handlers.js.map +1 -1
- package/dist/integrations/mcp/handlers/index.js +4 -0
- package/dist/integrations/mcp/handlers/index.js.map +1 -1
- package/dist/integrations/mcp/handlers/linear-handlers.js +4 -0
- package/dist/integrations/mcp/handlers/linear-handlers.js.map +1 -1
- package/dist/integrations/mcp/handlers/skill-handlers.js +4 -0
- package/dist/integrations/mcp/handlers/skill-handlers.js.map +1 -1
- package/dist/integrations/mcp/handlers/task-handlers.js +4 -0
- package/dist/integrations/mcp/handlers/task-handlers.js.map +1 -1
- package/dist/integrations/mcp/handlers/trace-handlers.js +4 -0
- package/dist/integrations/mcp/handlers/trace-handlers.js.map +1 -1
- package/dist/integrations/mcp/index.js +4 -0
- package/dist/integrations/mcp/index.js.map +1 -1
- package/dist/integrations/mcp/middleware/tool-scoring.js +4 -0
- package/dist/integrations/mcp/middleware/tool-scoring.js.map +1 -1
- package/dist/integrations/mcp/refactored-server.js +4 -0
- package/dist/integrations/mcp/refactored-server.js.map +1 -1
- package/dist/integrations/mcp/server.js +4 -0
- package/dist/integrations/mcp/server.js.map +1 -1
- package/dist/integrations/mcp/tool-definitions-code.js +4 -0
- package/dist/integrations/mcp/tool-definitions-code.js.map +1 -1
- package/dist/integrations/mcp/tool-definitions.js +4 -0
- package/dist/integrations/mcp/tool-definitions.js.map +1 -1
- package/dist/integrations/mcp/trace-test.js +4 -0
- package/dist/integrations/mcp/trace-test.js.map +1 -1
- package/dist/integrations/pg-aiguide/embedding-provider.js +4 -0
- package/dist/integrations/pg-aiguide/embedding-provider.js.map +1 -1
- package/dist/integrations/pg-aiguide/semantic-search.js +4 -0
- package/dist/integrations/pg-aiguide/semantic-search.js.map +1 -1
- package/dist/integrations/pg-aiguide/timescale-analytics.js +4 -0
- package/dist/integrations/pg-aiguide/timescale-analytics.js.map +1 -1
- package/dist/integrations/ralph/bridge/ralph-stackmemory-bridge.js +4 -0
- package/dist/integrations/ralph/bridge/ralph-stackmemory-bridge.js.map +1 -1
- package/dist/integrations/ralph/context/context-budget-manager.js +4 -0
- package/dist/integrations/ralph/context/context-budget-manager.js.map +1 -1
- package/dist/integrations/ralph/context/stackmemory-context-loader.js +4 -0
- package/dist/integrations/ralph/context/stackmemory-context-loader.js.map +1 -1
- package/dist/integrations/ralph/coordination/enhanced-coordination.js +4 -0
- package/dist/integrations/ralph/coordination/enhanced-coordination.js.map +1 -1
- package/dist/integrations/ralph/index.js +4 -0
- package/dist/integrations/ralph/index.js.map +1 -1
- package/dist/integrations/ralph/learning/pattern-learner.js +4 -0
- package/dist/integrations/ralph/learning/pattern-learner.js.map +1 -1
- package/dist/integrations/ralph/lifecycle/iteration-lifecycle.js +4 -0
- package/dist/integrations/ralph/lifecycle/iteration-lifecycle.js.map +1 -1
- package/dist/integrations/ralph/monitoring/swarm-dashboard.js +4 -0
- package/dist/integrations/ralph/monitoring/swarm-dashboard.js.map +1 -1
- package/dist/integrations/ralph/monitoring/swarm-registry.js +4 -0
- package/dist/integrations/ralph/monitoring/swarm-registry.js.map +1 -1
- package/dist/integrations/ralph/orchestration/multi-loop-orchestrator.js +4 -0
- package/dist/integrations/ralph/orchestration/multi-loop-orchestrator.js.map +1 -1
- package/dist/integrations/ralph/patterns/compounding-engineering-pattern.js +4 -0
- package/dist/integrations/ralph/patterns/compounding-engineering-pattern.js.map +1 -1
- package/dist/integrations/ralph/patterns/extended-coherence-sessions.js +4 -0
- package/dist/integrations/ralph/patterns/extended-coherence-sessions.js.map +1 -1
- package/dist/integrations/ralph/patterns/oracle-worker-pattern.js +4 -0
- package/dist/integrations/ralph/patterns/oracle-worker-pattern.js.map +1 -1
- package/dist/integrations/ralph/performance/performance-optimizer.js +4 -0
- package/dist/integrations/ralph/performance/performance-optimizer.js.map +1 -1
- package/dist/integrations/ralph/ralph-integration-demo.js +4 -0
- package/dist/integrations/ralph/ralph-integration-demo.js.map +1 -1
- package/dist/integrations/ralph/recovery/crash-recovery.js +4 -0
- package/dist/integrations/ralph/recovery/crash-recovery.js.map +1 -1
- package/dist/integrations/ralph/state/state-reconciler.js +4 -0
- package/dist/integrations/ralph/state/state-reconciler.js.map +1 -1
- package/dist/integrations/ralph/swarm/git-workflow-manager.js +4 -0
- package/dist/integrations/ralph/swarm/git-workflow-manager.js.map +1 -1
- package/dist/integrations/ralph/swarm/swarm-coordinator.js +4 -0
- package/dist/integrations/ralph/swarm/swarm-coordinator.js.map +1 -1
- package/dist/integrations/ralph/types.js +4 -0
- package/dist/integrations/ralph/visualization/ralph-debugger.js +4 -0
- package/dist/integrations/ralph/visualization/ralph-debugger.js.map +1 -1
- package/dist/mcp/stackmemory-mcp-server.js +4 -0
- package/dist/mcp/stackmemory-mcp-server.js.map +1 -1
- package/dist/middleware/exponential-rate-limiter.js +4 -0
- package/dist/middleware/exponential-rate-limiter.js.map +1 -1
- package/dist/models/user.model.js +4 -0
- package/dist/models/user.model.js.map +1 -1
- package/dist/servers/production/auth-middleware.js +4 -0
- package/dist/servers/production/auth-middleware.js.map +1 -1
- package/dist/servers/railway/config.js +4 -0
- package/dist/servers/railway/config.js.map +1 -1
- package/dist/servers/railway/index-enhanced.js +4 -0
- package/dist/servers/railway/index-enhanced.js.map +1 -1
- package/dist/servers/railway/index.js +4 -0
- package/dist/servers/railway/index.js.map +1 -1
- package/dist/servers/railway/simple.js +4 -0
- package/dist/servers/railway/simple.js.map +1 -1
- package/dist/servers/railway/storage-test.js +4 -0
- package/dist/servers/railway/storage-test.js.map +1 -1
- package/dist/services/config-service.js +4 -0
- package/dist/services/config-service.js.map +1 -1
- package/dist/services/context-service.js +4 -0
- package/dist/services/context-service.js.map +1 -1
- package/dist/skills/api-discovery.js +353 -0
- package/dist/skills/api-discovery.js.map +7 -0
- package/dist/skills/api-skill.js +475 -0
- package/dist/skills/api-skill.js.map +7 -0
- package/dist/skills/claude-skills.js +53 -1
- package/dist/skills/claude-skills.js.map +2 -2
- package/dist/skills/dashboard-launcher.js +4 -0
- package/dist/skills/dashboard-launcher.js.map +1 -1
- package/dist/skills/recursive-agent-orchestrator.js +4 -0
- package/dist/skills/recursive-agent-orchestrator.js.map +1 -1
- package/dist/skills/repo-ingestion-skill.js +4 -0
- package/dist/skills/repo-ingestion-skill.js.map +1 -1
- package/dist/skills/security-secrets-scanner.js +4 -0
- package/dist/skills/security-secrets-scanner.js.map +1 -1
- package/dist/skills/unified-rlm-orchestrator.js +4 -0
- package/dist/skills/unified-rlm-orchestrator.js.map +1 -1
- package/dist/types/task.js +4 -0
- package/dist/utils/env.js +4 -0
- package/dist/utils/env.js.map +1 -1
- package/dist/utils/formatting.js +4 -0
- package/dist/utils/formatting.js.map +1 -1
- package/dist/utils/process-cleanup.js +136 -0
- package/dist/utils/process-cleanup.js.map +7 -0
- package/dist/validation/schemas.js +4 -0
- package/dist/validation/schemas.js.map +1 -1
- package/package.json +4 -2
- package/templates/shell/sweep-complete.zsh +116 -0
- package/templates/shell/sweep-suggest.js +161 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
2
|
+
import { dirname as __pathDirname } from 'path';
|
|
3
|
+
const __filename = __fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = __pathDirname(__filename);
|
|
5
|
+
import {
|
|
6
|
+
existsSync,
|
|
7
|
+
readFileSync,
|
|
8
|
+
writeFileSync,
|
|
9
|
+
unlinkSync,
|
|
10
|
+
watch,
|
|
11
|
+
appendFileSync
|
|
12
|
+
} from "fs";
|
|
13
|
+
import { join, extname, relative } from "path";
|
|
14
|
+
import { spawn } from "child_process";
|
|
15
|
+
import { loadConfig } from "./config.js";
|
|
16
|
+
import {
|
|
17
|
+
hookEmitter
|
|
18
|
+
} from "./events.js";
|
|
19
|
+
const state = {
|
|
20
|
+
running: false,
|
|
21
|
+
startTime: 0,
|
|
22
|
+
eventsProcessed: 0,
|
|
23
|
+
watchers: /* @__PURE__ */ new Map(),
|
|
24
|
+
pendingPrediction: false
|
|
25
|
+
};
|
|
26
|
+
let config;
|
|
27
|
+
let logStream = null;
|
|
28
|
+
function log(level, message, data) {
|
|
29
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
30
|
+
const line = `[${timestamp}] [${level.toUpperCase()}] ${message}${data ? " " + JSON.stringify(data) : ""}`;
|
|
31
|
+
if (logStream) {
|
|
32
|
+
logStream(line);
|
|
33
|
+
}
|
|
34
|
+
const logLevels = ["debug", "info", "warn", "error"];
|
|
35
|
+
const configLevel = logLevels.indexOf(config?.daemon?.log_level || "info");
|
|
36
|
+
const msgLevel = logLevels.indexOf(level);
|
|
37
|
+
if (msgLevel >= configLevel) {
|
|
38
|
+
if (level === "error") {
|
|
39
|
+
console.error(line);
|
|
40
|
+
} else {
|
|
41
|
+
console.log(line);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function startDaemon(options = {}) {
|
|
46
|
+
config = loadConfig();
|
|
47
|
+
if (!config.daemon.enabled) {
|
|
48
|
+
log("warn", "Daemon is disabled in config");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const pidFile = config.daemon.pid_file;
|
|
52
|
+
if (existsSync(pidFile)) {
|
|
53
|
+
const pid = parseInt(readFileSync(pidFile, "utf-8").trim(), 10);
|
|
54
|
+
try {
|
|
55
|
+
process.kill(pid, 0);
|
|
56
|
+
log("warn", "Daemon already running", { pid });
|
|
57
|
+
return;
|
|
58
|
+
} catch {
|
|
59
|
+
unlinkSync(pidFile);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (!options.foreground) {
|
|
63
|
+
const child = spawn(
|
|
64
|
+
process.argv[0],
|
|
65
|
+
[...process.argv.slice(1), "--foreground"],
|
|
66
|
+
{
|
|
67
|
+
detached: true,
|
|
68
|
+
stdio: "ignore"
|
|
69
|
+
}
|
|
70
|
+
);
|
|
71
|
+
child.unref();
|
|
72
|
+
log("info", "Daemon started in background", { pid: child.pid });
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
writeFileSync(pidFile, process.pid.toString());
|
|
76
|
+
state.running = true;
|
|
77
|
+
state.startTime = Date.now();
|
|
78
|
+
log("info", "Hook daemon starting", { pid: process.pid });
|
|
79
|
+
setupLogStream();
|
|
80
|
+
registerBuiltinHandlers();
|
|
81
|
+
startFileWatchers();
|
|
82
|
+
setupSignalHandlers();
|
|
83
|
+
hookEmitter.emitHook({
|
|
84
|
+
type: "session_start",
|
|
85
|
+
timestamp: Date.now(),
|
|
86
|
+
data: { pid: process.pid }
|
|
87
|
+
});
|
|
88
|
+
log("info", "Hook daemon ready", {
|
|
89
|
+
events: hookEmitter.getRegisteredEvents(),
|
|
90
|
+
watching: Array.from(state.watchers.keys())
|
|
91
|
+
});
|
|
92
|
+
await new Promise(() => {
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function stopDaemon() {
|
|
96
|
+
const pidFile = config?.daemon?.pid_file || join(process.env.HOME || "/tmp", ".stackmemory", "hooks.pid");
|
|
97
|
+
if (!existsSync(pidFile)) {
|
|
98
|
+
log("info", "Daemon not running");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const pid = parseInt(readFileSync(pidFile, "utf-8").trim(), 10);
|
|
102
|
+
try {
|
|
103
|
+
process.kill(pid, "SIGTERM");
|
|
104
|
+
log("info", "Daemon stopped", { pid });
|
|
105
|
+
} catch {
|
|
106
|
+
log("warn", "Could not stop daemon", { pid });
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
unlinkSync(pidFile);
|
|
110
|
+
} catch {
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function getDaemonStatus() {
|
|
114
|
+
config = loadConfig();
|
|
115
|
+
const pidFile = config.daemon.pid_file;
|
|
116
|
+
if (!existsSync(pidFile)) {
|
|
117
|
+
return { running: false };
|
|
118
|
+
}
|
|
119
|
+
const pid = parseInt(readFileSync(pidFile, "utf-8").trim(), 10);
|
|
120
|
+
try {
|
|
121
|
+
process.kill(pid, 0);
|
|
122
|
+
return {
|
|
123
|
+
running: true,
|
|
124
|
+
pid,
|
|
125
|
+
uptime: state.running ? Date.now() - state.startTime : void 0,
|
|
126
|
+
eventsProcessed: state.eventsProcessed
|
|
127
|
+
};
|
|
128
|
+
} catch {
|
|
129
|
+
return { running: false };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function setupLogStream() {
|
|
133
|
+
const logFile = config.daemon.log_file;
|
|
134
|
+
logStream = (msg) => {
|
|
135
|
+
try {
|
|
136
|
+
appendFileSync(logFile, msg + "\n");
|
|
137
|
+
} catch {
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function registerBuiltinHandlers() {
|
|
142
|
+
hookEmitter.registerHandler("file_change", handleFileChange);
|
|
143
|
+
hookEmitter.registerHandler("suggestion_ready", handleSuggestionReady);
|
|
144
|
+
hookEmitter.registerHandler("error", handleError);
|
|
145
|
+
hookEmitter.on("*", () => {
|
|
146
|
+
state.eventsProcessed++;
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
async function handleFileChange(event) {
|
|
150
|
+
const fileEvent = event;
|
|
151
|
+
const hookConfig = config.hooks.file_change;
|
|
152
|
+
if (!hookConfig?.enabled) return;
|
|
153
|
+
log("debug", "File change detected", { path: fileEvent.data.path });
|
|
154
|
+
if (hookConfig.handler === "sweep-predict") {
|
|
155
|
+
await runSweepPrediction(fileEvent);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
async function runSweepPrediction(event) {
|
|
159
|
+
const hookConfig = config.hooks.file_change;
|
|
160
|
+
if (!hookConfig) return;
|
|
161
|
+
if (state.pendingPrediction) {
|
|
162
|
+
log("debug", "Prediction already pending, skipping");
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (state.lastPrediction) {
|
|
166
|
+
const cooldown = hookConfig.cooldown_ms || 1e4;
|
|
167
|
+
if (Date.now() - state.lastPrediction < cooldown) {
|
|
168
|
+
log("debug", "In cooldown period, skipping");
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
state.pendingPrediction = true;
|
|
173
|
+
const debounce = hookConfig.debounce_ms || 2e3;
|
|
174
|
+
await new Promise((r) => setTimeout(r, debounce));
|
|
175
|
+
try {
|
|
176
|
+
const sweepScript = findSweepScript();
|
|
177
|
+
if (!sweepScript) {
|
|
178
|
+
log("warn", "Sweep script not found");
|
|
179
|
+
state.pendingPrediction = false;
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const filePath = event.data.path;
|
|
183
|
+
const content = event.data.content || (existsSync(filePath) ? readFileSync(filePath, "utf-8") : "");
|
|
184
|
+
const input = {
|
|
185
|
+
file_path: filePath,
|
|
186
|
+
current_content: content
|
|
187
|
+
};
|
|
188
|
+
const result = await runPythonScript(sweepScript, input);
|
|
189
|
+
if (result && result.success && result.predicted_content) {
|
|
190
|
+
state.lastPrediction = Date.now();
|
|
191
|
+
const suggestionEvent = {
|
|
192
|
+
type: "suggestion_ready",
|
|
193
|
+
timestamp: Date.now(),
|
|
194
|
+
data: {
|
|
195
|
+
suggestion: result.predicted_content,
|
|
196
|
+
source: "sweep",
|
|
197
|
+
confidence: result.confidence,
|
|
198
|
+
preview: result.predicted_content.split("\n").slice(0, 3).join("\n")
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
await hookEmitter.emitHook(suggestionEvent);
|
|
202
|
+
}
|
|
203
|
+
} catch (error) {
|
|
204
|
+
log("error", "Sweep prediction failed", {
|
|
205
|
+
error: error.message
|
|
206
|
+
});
|
|
207
|
+
} finally {
|
|
208
|
+
state.pendingPrediction = false;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function findSweepScript() {
|
|
212
|
+
const locations = [
|
|
213
|
+
join(process.env.HOME || "", ".stackmemory", "sweep", "sweep_predict.py"),
|
|
214
|
+
join(
|
|
215
|
+
process.cwd(),
|
|
216
|
+
"packages",
|
|
217
|
+
"sweep-addon",
|
|
218
|
+
"python",
|
|
219
|
+
"sweep_predict.py"
|
|
220
|
+
)
|
|
221
|
+
];
|
|
222
|
+
for (const loc of locations) {
|
|
223
|
+
if (existsSync(loc)) {
|
|
224
|
+
return loc;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
async function runPythonScript(scriptPath, input) {
|
|
230
|
+
return new Promise((resolve) => {
|
|
231
|
+
const proc = spawn("python3", [scriptPath], {
|
|
232
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
233
|
+
});
|
|
234
|
+
let stdout = "";
|
|
235
|
+
proc.stdout.on("data", (data) => stdout += data);
|
|
236
|
+
proc.stderr.on("data", () => {
|
|
237
|
+
});
|
|
238
|
+
proc.on("close", () => {
|
|
239
|
+
try {
|
|
240
|
+
resolve(JSON.parse(stdout.trim()));
|
|
241
|
+
} catch {
|
|
242
|
+
resolve({ success: false });
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
proc.on("error", () => resolve({ success: false }));
|
|
246
|
+
proc.stdin.write(JSON.stringify(input));
|
|
247
|
+
proc.stdin.end();
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
function handleSuggestionReady(event) {
|
|
251
|
+
const suggestionEvent = event;
|
|
252
|
+
const hookConfig = config.hooks.suggestion_ready;
|
|
253
|
+
if (!hookConfig?.enabled) return;
|
|
254
|
+
const output = hookConfig.output || "overlay";
|
|
255
|
+
switch (output) {
|
|
256
|
+
case "overlay":
|
|
257
|
+
displayOverlay(suggestionEvent.data);
|
|
258
|
+
break;
|
|
259
|
+
case "notification":
|
|
260
|
+
displayNotification(suggestionEvent.data);
|
|
261
|
+
break;
|
|
262
|
+
case "log":
|
|
263
|
+
log("info", "Suggestion ready", suggestionEvent.data);
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function displayOverlay(data) {
|
|
268
|
+
const preview = data.preview || data.suggestion.slice(0, 200);
|
|
269
|
+
console.log("\n" + "\u2500".repeat(50));
|
|
270
|
+
console.log(`[${data.source}] Suggestion:`);
|
|
271
|
+
console.log(preview);
|
|
272
|
+
if (data.suggestion.length > 200) console.log("...");
|
|
273
|
+
console.log("\u2500".repeat(50) + "\n");
|
|
274
|
+
}
|
|
275
|
+
function displayNotification(data) {
|
|
276
|
+
const title = `StackMemory - ${data.source}`;
|
|
277
|
+
const message = data.preview || data.suggestion.slice(0, 100);
|
|
278
|
+
if (process.platform === "darwin") {
|
|
279
|
+
spawn("osascript", [
|
|
280
|
+
"-e",
|
|
281
|
+
`display notification "${message}" with title "${title}"`
|
|
282
|
+
]);
|
|
283
|
+
} else if (process.platform === "linux") {
|
|
284
|
+
spawn("notify-send", [title, message]);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function handleError(event) {
|
|
288
|
+
log("error", "Hook error", event.data);
|
|
289
|
+
}
|
|
290
|
+
function startFileWatchers() {
|
|
291
|
+
if (!config.file_watch.enabled) return;
|
|
292
|
+
const paths = config.file_watch.paths;
|
|
293
|
+
const ignore = new Set(config.file_watch.ignore);
|
|
294
|
+
const extensions = new Set(config.file_watch.extensions);
|
|
295
|
+
for (const watchPath of paths) {
|
|
296
|
+
const absPath = join(process.cwd(), watchPath);
|
|
297
|
+
if (!existsSync(absPath)) continue;
|
|
298
|
+
try {
|
|
299
|
+
const watcher = watch(
|
|
300
|
+
absPath,
|
|
301
|
+
{ recursive: true },
|
|
302
|
+
(eventType, filename) => {
|
|
303
|
+
if (!filename) return;
|
|
304
|
+
const relPath = relative(absPath, join(absPath, filename));
|
|
305
|
+
const parts = relPath.split("/");
|
|
306
|
+
if (parts.some((p) => ignore.has(p))) return;
|
|
307
|
+
const ext = extname(filename);
|
|
308
|
+
if (!extensions.has(ext)) return;
|
|
309
|
+
const fullPath = join(absPath, filename);
|
|
310
|
+
const changeType = eventType === "rename" ? existsSync(fullPath) ? "create" : "delete" : "modify";
|
|
311
|
+
const fileEvent = {
|
|
312
|
+
type: "file_change",
|
|
313
|
+
timestamp: Date.now(),
|
|
314
|
+
data: {
|
|
315
|
+
path: fullPath,
|
|
316
|
+
changeType,
|
|
317
|
+
content: changeType !== "delete" && existsSync(fullPath) ? readFileSync(fullPath, "utf-8") : void 0
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
hookEmitter.emitHook(fileEvent);
|
|
321
|
+
}
|
|
322
|
+
);
|
|
323
|
+
state.watchers.set(absPath, watcher);
|
|
324
|
+
log("debug", "Watching directory", { path: absPath });
|
|
325
|
+
} catch (error) {
|
|
326
|
+
log("warn", "Failed to watch directory", {
|
|
327
|
+
path: absPath,
|
|
328
|
+
error: error.message
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
function setupSignalHandlers() {
|
|
334
|
+
const cleanup = () => {
|
|
335
|
+
log("info", "Daemon shutting down");
|
|
336
|
+
state.running = false;
|
|
337
|
+
for (const [path, watcher] of state.watchers) {
|
|
338
|
+
watcher.close();
|
|
339
|
+
log("debug", "Stopped watching", { path });
|
|
340
|
+
}
|
|
341
|
+
hookEmitter.emitHook({
|
|
342
|
+
type: "session_end",
|
|
343
|
+
timestamp: Date.now(),
|
|
344
|
+
data: { uptime: Date.now() - state.startTime }
|
|
345
|
+
});
|
|
346
|
+
try {
|
|
347
|
+
unlinkSync(config.daemon.pid_file);
|
|
348
|
+
} catch {
|
|
349
|
+
}
|
|
350
|
+
process.exit(0);
|
|
351
|
+
};
|
|
352
|
+
process.on("SIGTERM", cleanup);
|
|
353
|
+
process.on("SIGINT", cleanup);
|
|
354
|
+
process.on("SIGHUP", cleanup);
|
|
355
|
+
}
|
|
356
|
+
export {
|
|
357
|
+
config,
|
|
358
|
+
getDaemonStatus,
|
|
359
|
+
log,
|
|
360
|
+
startDaemon,
|
|
361
|
+
state,
|
|
362
|
+
stopDaemon
|
|
363
|
+
};
|
|
364
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hooks/daemon.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * StackMemory Hook Daemon\n * Background process that manages hooks and events\n */\n\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n unlinkSync,\n watch,\n appendFileSync,\n} from 'fs';\nimport { join, extname, relative } from 'path';\nimport { spawn } from 'child_process';\nimport { loadConfig, HooksConfig } from './config.js';\nimport {\n hookEmitter,\n HookEventData,\n FileChangeEvent,\n SuggestionReadyEvent,\n} from './events.js';\n\ninterface DaemonState {\n running: boolean;\n startTime: number;\n eventsProcessed: number;\n lastEvent?: HookEventData;\n watchers: Map<string, ReturnType<typeof watch>>;\n pendingPrediction: boolean;\n lastPrediction?: number;\n}\n\nconst state: DaemonState = {\n running: false,\n startTime: 0,\n eventsProcessed: 0,\n watchers: new Map(),\n pendingPrediction: false,\n};\n\nlet config: HooksConfig;\nlet logStream: ((msg: string) => void) | null = null;\n\nexport function log(level: string, message: string, data?: unknown): void {\n const timestamp = new Date().toISOString();\n const line = `[${timestamp}] [${level.toUpperCase()}] ${message}${data ? ' ' + JSON.stringify(data) : ''}`;\n\n if (logStream) {\n logStream(line);\n }\n\n const logLevels = ['debug', 'info', 'warn', 'error'];\n const configLevel = logLevels.indexOf(config?.daemon?.log_level || 'info');\n const msgLevel = logLevels.indexOf(level);\n\n if (msgLevel >= configLevel) {\n if (level === 'error') {\n console.error(line);\n } else {\n console.log(line);\n }\n }\n}\n\nexport async function startDaemon(\n options: { foreground?: boolean } = {}\n): Promise<void> {\n config = loadConfig();\n\n if (!config.daemon.enabled) {\n log('warn', 'Daemon is disabled in config');\n return;\n }\n\n const pidFile = config.daemon.pid_file;\n\n if (existsSync(pidFile)) {\n const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);\n try {\n process.kill(pid, 0);\n log('warn', 'Daemon already running', { pid });\n return;\n } catch {\n unlinkSync(pidFile);\n }\n }\n\n if (!options.foreground) {\n const child = spawn(\n process.argv[0],\n [...process.argv.slice(1), '--foreground'],\n {\n detached: true,\n stdio: 'ignore',\n }\n );\n child.unref();\n log('info', 'Daemon started in background', { pid: child.pid });\n return;\n }\n\n writeFileSync(pidFile, process.pid.toString());\n state.running = true;\n state.startTime = Date.now();\n\n log('info', 'Hook daemon starting', { pid: process.pid });\n\n setupLogStream();\n registerBuiltinHandlers();\n startFileWatchers();\n setupSignalHandlers();\n\n hookEmitter.emitHook({\n type: 'session_start',\n timestamp: Date.now(),\n data: { pid: process.pid },\n });\n\n log('info', 'Hook daemon ready', {\n events: hookEmitter.getRegisteredEvents(),\n watching: Array.from(state.watchers.keys()),\n });\n\n await new Promise(() => {});\n}\n\nexport function stopDaemon(): void {\n const pidFile =\n config?.daemon?.pid_file ||\n join(process.env.HOME || '/tmp', '.stackmemory', 'hooks.pid');\n\n if (!existsSync(pidFile)) {\n log('info', 'Daemon not running');\n return;\n }\n\n const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);\n\n try {\n process.kill(pid, 'SIGTERM');\n log('info', 'Daemon stopped', { pid });\n } catch {\n log('warn', 'Could not stop daemon', { pid });\n }\n\n try {\n unlinkSync(pidFile);\n } catch {\n // Ignore\n }\n}\n\nexport function getDaemonStatus(): {\n running: boolean;\n pid?: number;\n uptime?: number;\n eventsProcessed?: number;\n} {\n config = loadConfig();\n const pidFile = config.daemon.pid_file;\n\n if (!existsSync(pidFile)) {\n return { running: false };\n }\n\n const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);\n\n try {\n process.kill(pid, 0);\n return {\n running: true,\n pid,\n uptime: state.running ? Date.now() - state.startTime : undefined,\n eventsProcessed: state.eventsProcessed,\n };\n } catch {\n return { running: false };\n }\n}\n\nfunction setupLogStream(): void {\n const logFile = config.daemon.log_file;\n\n logStream = (msg: string) => {\n try {\n appendFileSync(logFile, msg + '\\n');\n } catch {\n // Ignore\n }\n };\n}\n\nfunction registerBuiltinHandlers(): void {\n hookEmitter.registerHandler('file_change', handleFileChange);\n hookEmitter.registerHandler('suggestion_ready', handleSuggestionReady);\n hookEmitter.registerHandler('error', handleError);\n\n hookEmitter.on('*', () => {\n state.eventsProcessed++;\n });\n}\n\nasync function handleFileChange(event: HookEventData): Promise<void> {\n const fileEvent = event as FileChangeEvent;\n const hookConfig = config.hooks.file_change;\n\n if (!hookConfig?.enabled) return;\n\n log('debug', 'File change detected', { path: fileEvent.data.path });\n\n if (hookConfig.handler === 'sweep-predict') {\n await runSweepPrediction(fileEvent);\n }\n}\n\nasync function runSweepPrediction(event: FileChangeEvent): Promise<void> {\n const hookConfig = config.hooks.file_change;\n if (!hookConfig) return;\n\n if (state.pendingPrediction) {\n log('debug', 'Prediction already pending, skipping');\n return;\n }\n\n if (state.lastPrediction) {\n const cooldown = hookConfig.cooldown_ms || 10000;\n if (Date.now() - state.lastPrediction < cooldown) {\n log('debug', 'In cooldown period, skipping');\n return;\n }\n }\n\n state.pendingPrediction = true;\n\n const debounce = hookConfig.debounce_ms || 2000;\n await new Promise((r) => setTimeout(r, debounce));\n\n try {\n const sweepScript = findSweepScript();\n if (!sweepScript) {\n log('warn', 'Sweep script not found');\n state.pendingPrediction = false;\n return;\n }\n\n const filePath = event.data.path;\n const content =\n event.data.content ||\n (existsSync(filePath) ? readFileSync(filePath, 'utf-8') : '');\n\n const input = {\n file_path: filePath,\n current_content: content,\n };\n\n const result = await runPythonScript(sweepScript, input);\n\n if (result && result.success && result.predicted_content) {\n state.lastPrediction = Date.now();\n\n const suggestionEvent: SuggestionReadyEvent = {\n type: 'suggestion_ready',\n timestamp: Date.now(),\n data: {\n suggestion: result.predicted_content,\n source: 'sweep',\n confidence: result.confidence,\n preview: result.predicted_content.split('\\n').slice(0, 3).join('\\n'),\n },\n };\n\n await hookEmitter.emitHook(suggestionEvent);\n }\n } catch (error) {\n log('error', 'Sweep prediction failed', {\n error: (error as Error).message,\n });\n } finally {\n state.pendingPrediction = false;\n }\n}\n\nfunction findSweepScript(): string | null {\n const locations = [\n join(process.env.HOME || '', '.stackmemory', 'sweep', 'sweep_predict.py'),\n join(\n process.cwd(),\n 'packages',\n 'sweep-addon',\n 'python',\n 'sweep_predict.py'\n ),\n ];\n\n for (const loc of locations) {\n if (existsSync(loc)) {\n return loc;\n }\n }\n return null;\n}\n\nasync function runPythonScript(\n scriptPath: string,\n input: Record<string, unknown>\n): Promise<{\n success: boolean;\n predicted_content?: string;\n confidence?: number;\n}> {\n return new Promise((resolve) => {\n const proc = spawn('python3', [scriptPath], {\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n proc.stdout.on('data', (data) => (stdout += data));\n proc.stderr.on('data', () => {});\n\n proc.on('close', () => {\n try {\n resolve(JSON.parse(stdout.trim()));\n } catch {\n resolve({ success: false });\n }\n });\n\n proc.on('error', () => resolve({ success: false }));\n\n proc.stdin.write(JSON.stringify(input));\n proc.stdin.end();\n });\n}\n\nfunction handleSuggestionReady(event: HookEventData): void {\n const suggestionEvent = event as SuggestionReadyEvent;\n const hookConfig = config.hooks.suggestion_ready;\n\n if (!hookConfig?.enabled) return;\n\n const output = hookConfig.output || 'overlay';\n\n switch (output) {\n case 'overlay':\n displayOverlay(suggestionEvent.data);\n break;\n case 'notification':\n displayNotification(suggestionEvent.data);\n break;\n case 'log':\n log('info', 'Suggestion ready', suggestionEvent.data);\n break;\n }\n}\n\nfunction displayOverlay(data: SuggestionReadyEvent['data']): void {\n const preview = data.preview || data.suggestion.slice(0, 200);\n console.log('\\n' + '\u2500'.repeat(50));\n console.log(`[${data.source}] Suggestion:`);\n console.log(preview);\n if (data.suggestion.length > 200) console.log('...');\n console.log('\u2500'.repeat(50) + '\\n');\n}\n\nfunction displayNotification(data: SuggestionReadyEvent['data']): void {\n const title = `StackMemory - ${data.source}`;\n const message = data.preview || data.suggestion.slice(0, 100);\n\n if (process.platform === 'darwin') {\n spawn('osascript', [\n '-e',\n `display notification \"${message}\" with title \"${title}\"`,\n ]);\n } else if (process.platform === 'linux') {\n spawn('notify-send', [title, message]);\n }\n}\n\nfunction handleError(event: HookEventData): void {\n log('error', 'Hook error', event.data);\n}\n\nfunction startFileWatchers(): void {\n if (!config.file_watch.enabled) return;\n\n const paths = config.file_watch.paths;\n const ignore = new Set(config.file_watch.ignore);\n const extensions = new Set(config.file_watch.extensions);\n\n for (const watchPath of paths) {\n const absPath = join(process.cwd(), watchPath);\n if (!existsSync(absPath)) continue;\n\n try {\n const watcher = watch(\n absPath,\n { recursive: true },\n (eventType, filename) => {\n if (!filename) return;\n\n const relPath = relative(absPath, join(absPath, filename));\n const parts = relPath.split('/');\n\n if (parts.some((p) => ignore.has(p))) return;\n\n const ext = extname(filename);\n if (!extensions.has(ext)) return;\n\n const fullPath = join(absPath, filename);\n const changeType =\n eventType === 'rename'\n ? existsSync(fullPath)\n ? 'create'\n : 'delete'\n : 'modify';\n\n const fileEvent: FileChangeEvent = {\n type: 'file_change',\n timestamp: Date.now(),\n data: {\n path: fullPath,\n changeType,\n content:\n changeType !== 'delete' && existsSync(fullPath)\n ? readFileSync(fullPath, 'utf-8')\n : undefined,\n },\n };\n\n hookEmitter.emitHook(fileEvent);\n }\n );\n\n state.watchers.set(absPath, watcher);\n log('debug', 'Watching directory', { path: absPath });\n } catch (error) {\n log('warn', 'Failed to watch directory', {\n path: absPath,\n error: (error as Error).message,\n });\n }\n }\n}\n\nfunction setupSignalHandlers(): void {\n const cleanup = () => {\n log('info', 'Daemon shutting down');\n state.running = false;\n\n for (const [path, watcher] of state.watchers) {\n watcher.close();\n log('debug', 'Stopped watching', { path });\n }\n\n hookEmitter.emitHook({\n type: 'session_end',\n timestamp: Date.now(),\n data: { uptime: Date.now() - state.startTime },\n });\n\n try {\n unlinkSync(config.daemon.pid_file);\n } catch {\n // Ignore\n }\n\n process.exit(0);\n };\n\n process.on('SIGTERM', cleanup);\n process.on('SIGINT', cleanup);\n process.on('SIGHUP', cleanup);\n}\n\nexport { config, state };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
2
|
+
import { dirname as __pathDirname } from 'path';
|
|
3
|
+
const __filename = __fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = __pathDirname(__filename);
|
|
5
|
+
import { EventEmitter } from "events";
|
|
6
|
+
class HookEventEmitter extends EventEmitter {
|
|
7
|
+
handlers = /* @__PURE__ */ new Map();
|
|
8
|
+
registerHandler(eventType, handler) {
|
|
9
|
+
if (!this.handlers.has(eventType)) {
|
|
10
|
+
this.handlers.set(eventType, /* @__PURE__ */ new Set());
|
|
11
|
+
}
|
|
12
|
+
this.handlers.get(eventType).add(handler);
|
|
13
|
+
this.on(eventType, handler);
|
|
14
|
+
}
|
|
15
|
+
unregisterHandler(eventType, handler) {
|
|
16
|
+
const handlers = this.handlers.get(eventType);
|
|
17
|
+
if (handlers) {
|
|
18
|
+
handlers.delete(handler);
|
|
19
|
+
this.off(eventType, handler);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async emitHook(event) {
|
|
23
|
+
const handlers = this.handlers.get(event.type);
|
|
24
|
+
if (!handlers || handlers.size === 0) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const promises = [];
|
|
28
|
+
for (const handler of handlers) {
|
|
29
|
+
try {
|
|
30
|
+
const result = handler(event);
|
|
31
|
+
if (result instanceof Promise) {
|
|
32
|
+
promises.push(result);
|
|
33
|
+
}
|
|
34
|
+
} catch (error) {
|
|
35
|
+
this.emit("error", {
|
|
36
|
+
type: "error",
|
|
37
|
+
timestamp: Date.now(),
|
|
38
|
+
data: { error, originalEvent: event }
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
await Promise.allSettled(promises);
|
|
43
|
+
}
|
|
44
|
+
getRegisteredEvents() {
|
|
45
|
+
return Array.from(this.handlers.keys()).filter(
|
|
46
|
+
(type) => (this.handlers.get(type)?.size ?? 0) > 0
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const hookEmitter = new HookEventEmitter();
|
|
51
|
+
export {
|
|
52
|
+
HookEventEmitter,
|
|
53
|
+
hookEmitter
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hooks/events.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * StackMemory Hook Events\n * Event types and emitter for the hook system\n */\n\nimport { EventEmitter } from 'events';\n\nexport type HookEventType =\n | 'input_idle'\n | 'file_change'\n | 'context_switch'\n | 'session_start'\n | 'session_end'\n | 'prompt_submit'\n | 'tool_use'\n | 'suggestion_ready'\n | 'error';\n\nexport interface HookEvent {\n type: HookEventType;\n timestamp: number;\n data: Record<string, unknown>;\n}\n\nexport interface FileChangeEvent extends HookEvent {\n type: 'file_change';\n data: {\n path: string;\n changeType: 'create' | 'modify' | 'delete';\n content?: string;\n };\n}\n\nexport interface InputIdleEvent extends HookEvent {\n type: 'input_idle';\n data: {\n idleDuration: number;\n lastInput?: string;\n };\n}\n\nexport interface ContextSwitchEvent extends HookEvent {\n type: 'context_switch';\n data: {\n fromBranch?: string;\n toBranch?: string;\n fromProject?: string;\n toProject?: string;\n };\n}\n\nexport interface SuggestionReadyEvent extends HookEvent {\n type: 'suggestion_ready';\n data: {\n suggestion: string;\n source: string;\n confidence?: number;\n preview?: string;\n };\n}\n\nexport type HookEventData =\n | FileChangeEvent\n | InputIdleEvent\n | ContextSwitchEvent\n | SuggestionReadyEvent\n | HookEvent;\n\nexport type HookHandler = (event: HookEventData) => Promise<void> | void;\n\nexport class HookEventEmitter extends EventEmitter {\n private handlers: Map<HookEventType, Set<HookHandler>> = new Map();\n\n registerHandler(eventType: HookEventType, handler: HookHandler): void {\n if (!this.handlers.has(eventType)) {\n this.handlers.set(eventType, new Set());\n }\n this.handlers.get(eventType)!.add(handler);\n this.on(eventType, handler);\n }\n\n unregisterHandler(eventType: HookEventType, handler: HookHandler): void {\n const handlers = this.handlers.get(eventType);\n if (handlers) {\n handlers.delete(handler);\n this.off(eventType, handler);\n }\n }\n\n async emitHook(event: HookEventData): Promise<void> {\n const handlers = this.handlers.get(event.type);\n if (!handlers || handlers.size === 0) {\n return;\n }\n\n const promises: Promise<void>[] = [];\n for (const handler of handlers) {\n try {\n const result = handler(event);\n if (result instanceof Promise) {\n promises.push(result);\n }\n } catch (error) {\n this.emit('error', {\n type: 'error',\n timestamp: Date.now(),\n data: { error, originalEvent: event },\n });\n }\n }\n\n await Promise.allSettled(promises);\n }\n\n getRegisteredEvents(): HookEventType[] {\n return Array.from(this.handlers.keys()).filter(\n (type) => (this.handlers.get(type)?.size ?? 0) > 0\n );\n }\n}\n\nexport const hookEmitter = new HookEventEmitter();\n"],
|
|
5
|
+
"mappings": ";;;;AAKA,SAAS,oBAAoB;AAiEtB,MAAM,yBAAyB,aAAa;AAAA,EACzC,WAAiD,oBAAI,IAAI;AAAA,EAEjE,gBAAgB,WAA0B,SAA4B;AACpE,QAAI,CAAC,KAAK,SAAS,IAAI,SAAS,GAAG;AACjC,WAAK,SAAS,IAAI,WAAW,oBAAI,IAAI,CAAC;AAAA,IACxC;AACA,SAAK,SAAS,IAAI,SAAS,EAAG,IAAI,OAAO;AACzC,SAAK,GAAG,WAAW,OAAO;AAAA,EAC5B;AAAA,EAEA,kBAAkB,WAA0B,SAA4B;AACtE,UAAM,WAAW,KAAK,SAAS,IAAI,SAAS;AAC5C,QAAI,UAAU;AACZ,eAAS,OAAO,OAAO;AACvB,WAAK,IAAI,WAAW,OAAO;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,OAAqC;AAClD,UAAM,WAAW,KAAK,SAAS,IAAI,MAAM,IAAI;AAC7C,QAAI,CAAC,YAAY,SAAS,SAAS,GAAG;AACpC;AAAA,IACF;AAEA,UAAM,WAA4B,CAAC;AACnC,eAAW,WAAW,UAAU;AAC9B,UAAI;AACF,cAAM,SAAS,QAAQ,KAAK;AAC5B,YAAI,kBAAkB,SAAS;AAC7B,mBAAS,KAAK,MAAM;AAAA,QACtB;AAAA,MACF,SAAS,OAAO;AACd,aAAK,KAAK,SAAS;AAAA,UACjB,MAAM;AAAA,UACN,WAAW,KAAK,IAAI;AAAA,UACpB,MAAM,EAAE,OAAO,eAAe,MAAM;AAAA,QACtC,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,QAAQ,WAAW,QAAQ;AAAA,EACnC;AAAA,EAEA,sBAAuC;AACrC,WAAO,MAAM,KAAK,KAAK,SAAS,KAAK,CAAC,EAAE;AAAA,MACtC,CAAC,UAAU,KAAK,SAAS,IAAI,IAAI,GAAG,QAAQ,KAAK;AAAA,IACnD;AAAA,EACF;AACF;AAEO,MAAM,cAAc,IAAI,iBAAiB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
2
|
+
import { dirname as __pathDirname } from 'path';
|
|
3
|
+
const __filename = __fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = __pathDirname(__filename);
|
|
5
|
+
export * from "./events.js";
|
|
6
|
+
export * from "./config.js";
|
|
7
|
+
export * from "./daemon.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hooks/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * StackMemory Hooks Module\n * User-configurable hook system for automation and suggestions\n */\n\nexport * from './events.js';\nexport * from './config.js';\nexport * from './daemon.js';\n"],
|
|
5
|
+
"mappings": ";;;;AAKA,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
2
|
+
import { dirname as __pathDirname } from 'path';
|
|
3
|
+
const __filename = __fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = __pathDirname(__filename);
|
|
1
5
|
import {
|
|
2
6
|
FrameManager
|
|
3
7
|
} from "./core/context/frame-manager.js";
|
package/dist/index.js.map
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
4
|
"sourcesContent": ["/**\n * StackMemory - Lossless memory runtime for AI coding tools\n * Main entry point for the StackMemory package\n */\n\nexport {\n FrameManager,\n type FrameType,\n type FrameState,\n} from './core/context/frame-manager.js';\nexport { logger, Logger, LogLevel } from './core/monitoring/logger.js';\nexport {\n StackMemoryError,\n ErrorCode,\n ErrorHandler,\n} from './core/monitoring/error-handler.js';\nexport { default as LocalStackMemoryMCP } from './integrations/mcp/server.js';\n\n// Re-export key types\nexport interface StackMemoryConfig {\n projectRoot?: string;\n dbPath?: string;\n logLevel?: 'ERROR' | 'WARN' | 'INFO' | 'DEBUG';\n}\n\nexport interface ContextItem {\n id: string;\n type: string;\n content: string;\n importance: number;\n timestamp: number;\n}\n"],
|
|
5
|
-
"mappings": "AAKA;AAAA,EACE;AAAA,OAGK;AACP,SAAS,QAAQ,QAAQ,gBAAgB;AACzC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAoB,WAAXA,gBAAsC;",
|
|
5
|
+
"mappings": ";;;;AAKA;AAAA,EACE;AAAA,OAGK;AACP,SAAS,QAAQ,QAAQ,gBAAgB;AACzC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAoB,WAAXA,gBAAsC;",
|
|
6
6
|
"names": ["default"]
|
|
7
7
|
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
2
|
+
import { dirname as __pathDirname } from 'path';
|
|
3
|
+
const __filename = __fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = __pathDirname(__filename);
|
|
1
5
|
import { logger } from "../../core/monitoring/logger.js";
|
|
2
6
|
class AnthropicClient {
|
|
3
7
|
apiKey;
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/integrations/anthropic/client.ts"],
|
|
4
4
|
"sourcesContent": ["/**\n * Anthropic API Client for Claude Integration\n * \n * Manages API calls to Claude with retry logic, rate limiting,\n * and response streaming\n */\n\nimport { logger } from '../../core/monitoring/logger.js';\n\nexport interface CompletionRequest {\n model: string;\n systemPrompt: string;\n prompt: string;\n maxTokens: number;\n temperature: number;\n stream?: boolean;\n}\n\nexport interface CompletionResponse {\n content: string;\n stopReason: string;\n model: string;\n usage: {\n inputTokens: number;\n outputTokens: number;\n };\n}\n\nexport interface AnthropicClientConfig {\n apiKey?: string;\n baseURL?: string;\n maxRetries?: number;\n timeout?: number;\n}\n\n/**\n * Anthropic API Client\n * \n * NOTE: This is a mock implementation. In production, you would:\n * 1. Install @anthropic-ai/sdk: npm install @anthropic-ai/sdk\n * 2. Use the actual SDK methods\n * 3. Handle real API responses\n */\nexport class AnthropicClient {\n private apiKey: string;\n private baseURL: string;\n private maxRetries: number;\n private timeout: number;\n \n // Rate limiting\n private requestCount: number = 0;\n private lastResetTime: number = Date.now();\n private rateLimitPerMinute: number = 60;\n \n constructor(config?: AnthropicClientConfig) {\n this.apiKey = config?.apiKey || process.env['ANTHROPIC_API_KEY'] || '';\n this.baseURL = config?.baseURL || 'https://api.anthropic.com';\n this.maxRetries = config?.maxRetries || 3;\n this.timeout = config?.timeout || 60000;\n \n if (!this.apiKey) {\n logger.warn('Anthropic API key not configured. Using mock mode.');\n }\n \n logger.info('Anthropic client initialized', {\n baseURL: this.baseURL,\n maxRetries: this.maxRetries,\n timeout: this.timeout,\n mockMode: !this.apiKey,\n });\n }\n \n /**\n * Send completion request to Claude\n */\n async complete(request: CompletionRequest): Promise<string> {\n // Rate limiting check\n await this.checkRateLimit();\n \n logger.debug('Sending completion request', {\n model: request.model,\n promptLength: request.prompt.length,\n maxTokens: request.maxTokens,\n });\n \n // Mock implementation for development\n if (!this.apiKey) {\n return this.mockComplete(request);\n }\n \n // Real implementation would use Anthropic SDK\n try {\n const response = await this.sendRequest(request);\n return response.content;\n } catch (error) {\n logger.error('Anthropic API error', { error });\n throw error;\n }\n }\n \n /**\n * Send request with retry logic\n */\n private async sendRequest(\n request: CompletionRequest,\n attempt: number = 1\n ): Promise<CompletionResponse> {\n try {\n // In production, use actual Anthropic SDK:\n /*\n import Anthropic from '@anthropic-ai/sdk';\n \n const anthropic = new Anthropic({\n apiKey: this.apiKey,\n });\n \n const response = await anthropic.messages.create({\n model: request.model,\n system: request.systemPrompt,\n messages: [{ role: 'user', content: request.prompt }],\n max_tokens: request.maxTokens,\n temperature: request.temperature,\n });\n \n return {\n content: response.content[0].text,\n stopReason: response.stop_reason,\n model: response.model,\n usage: {\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n },\n };\n */\n \n // Mock response for now\n return this.createMockResponse(request);\n \n } catch (error: any) {\n if (attempt < this.maxRetries) {\n const delay = Math.pow(2, attempt) * 1000;\n logger.warn(`Retrying after ${delay}ms (attempt ${attempt}/${this.maxRetries})`);\n await this.delay(delay);\n return this.sendRequest(request, attempt + 1);\n }\n throw error;\n }\n }\n \n /**\n * Mock completion for development/testing\n */\n private async mockComplete(request: CompletionRequest): Promise<string> {\n // Simulate API delay\n await this.delay(500 + Math.random() * 1500);\n \n // Generate mock response based on agent type\n if (request.systemPrompt.includes('Planning Agent')) {\n return this.mockPlanningResponse(request.prompt);\n } else if (request.systemPrompt.includes('Code Agent')) {\n return this.mockCodeResponse(request.prompt);\n } else if (request.systemPrompt.includes('Testing Agent')) {\n return this.mockTestingResponse(request.prompt);\n } else if (request.systemPrompt.includes('Review Agent')) {\n return this.mockReviewResponse(request.prompt);\n } else {\n return `Mock response for: ${request.prompt.slice(0, 100)}...`;\n }\n }\n \n /**\n * Mock response generators\n */\n \n private mockPlanningResponse(prompt: string): string {\n return JSON.stringify({\n plan: {\n type: 'sequential',\n tasks: [\n {\n id: 'task-1',\n description: 'Analyze requirements',\n agent: 'context',\n dependencies: [],\n },\n {\n id: 'task-2',\n type: 'parallel',\n description: 'Implementation phase',\n children: [\n {\n id: 'task-2a',\n description: 'Write core logic',\n agent: 'code',\n dependencies: ['task-1'],\n },\n {\n id: 'task-2b',\n description: 'Write tests',\n agent: 'testing',\n dependencies: ['task-1'],\n },\n ],\n },\n {\n id: 'task-3',\n description: 'Review and improve',\n agent: 'review',\n dependencies: ['task-2'],\n },\n ],\n },\n }, null, 2);\n }\n \n private mockCodeResponse(prompt: string): string {\n return `\n// Mock implementation\nexport function processTask(input: string): string {\n // TODO: Implement actual logic\n console.log('Processing:', input);\n return \\`Processed: \\${input}\\`;\n}\n\nexport function validateInput(input: unknown): boolean {\n return typeof input === 'string' && input.length > 0;\n}\n `.trim();\n }\n \n private mockTestingResponse(prompt: string): string {\n return `\nimport { describe, test, expect } from 'vitest';\nimport { processTask, validateInput } from './implementation';\n\ndescribe('processTask', () => {\n test('should process valid input', () => {\n const result = processTask('test input');\n expect(result).toBe('Processed: test input');\n });\n \n test('should handle empty input', () => {\n const result = processTask('');\n expect(result).toBe('Processed: ');\n });\n});\n\ndescribe('validateInput', () => {\n test('should validate string input', () => {\n expect(validateInput('valid')).toBe(true);\n expect(validateInput('')).toBe(false);\n expect(validateInput(123)).toBe(false);\n expect(validateInput(null)).toBe(false);\n });\n});\n `.trim();\n }\n \n private mockReviewResponse(prompt: string): string {\n return JSON.stringify({\n quality: 0.75,\n issues: [\n 'Missing error handling in processTask function',\n 'No input validation before processing',\n 'Tests could cover more edge cases',\n ],\n suggestions: [\n 'Add try-catch block in processTask',\n 'Validate input length and type',\n 'Add tests for special characters and long inputs',\n 'Consider adding performance tests',\n ],\n improvements: [\n {\n file: 'implementation.ts',\n line: 3,\n suggestion: 'Add input validation',\n priority: 'high',\n },\n {\n file: 'tests.ts',\n line: 15,\n suggestion: 'Add edge case tests',\n priority: 'medium',\n },\n ],\n }, null, 2);\n }\n \n /**\n * Create mock response object\n */\n private createMockResponse(request: CompletionRequest): CompletionResponse {\n const content = this.mockComplete(request).toString();\n \n return {\n content,\n stopReason: 'stop_sequence',\n model: request.model,\n usage: {\n inputTokens: Math.ceil(request.prompt.length / 4),\n outputTokens: Math.ceil(content.length / 4),\n },\n };\n }\n \n /**\n * Check rate limiting\n */\n private async checkRateLimit(): Promise<void> {\n const now = Date.now();\n const timeSinceReset = now - this.lastResetTime;\n \n if (timeSinceReset >= 60000) {\n this.requestCount = 0;\n this.lastResetTime = now;\n }\n \n if (this.requestCount >= this.rateLimitPerMinute) {\n const waitTime = 60000 - timeSinceReset;\n logger.warn(`Rate limit reached, waiting ${waitTime}ms`);\n await this.delay(waitTime);\n this.requestCount = 0;\n this.lastResetTime = Date.now();\n }\n \n this.requestCount++;\n }\n \n /**\n * Stream completion response\n */\n async *streamComplete(request: CompletionRequest): AsyncGenerator<string> {\n // Mock streaming implementation\n const response = await this.complete(request);\n const words = response.split(' ');\n \n for (const word of words) {\n yield word + ' ';\n await this.delay(50); // Simulate streaming delay\n }\n }\n \n /**\n * Utility delay function\n */\n private delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n \n /**\n * Get API usage statistics\n */\n getUsageStats() {\n return {\n requestCount: this.requestCount,\n rateLimitRemaining: this.rateLimitPerMinute - this.requestCount,\n resetTime: new Date(this.lastResetTime + 60000).toISOString(),\n };\n }\n}"],
|
|
5
|
-
"mappings": "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",
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
2
|
+
import { dirname as __pathDirname } from 'path';
|
|
3
|
+
const __filename = __fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = __pathDirname(__filename);
|
|
1
5
|
import { v4 as uuidv4 } from "uuid";
|
|
2
6
|
import { logger } from "../../core/monitoring/logger.js";
|
|
3
7
|
import {
|