@stackmemoryai/stackmemory 0.2.4 → 0.2.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.
Files changed (179) hide show
  1. package/README.md +108 -0
  2. package/dist/index.js +382 -0
  3. package/dist/src/analytics/api/analytics-api.d.ts +24 -0
  4. package/dist/src/analytics/api/analytics-api.d.ts.map +1 -0
  5. package/dist/src/analytics/api/analytics-api.js +279 -0
  6. package/dist/src/analytics/api/analytics-api.js.map +1 -0
  7. package/dist/src/analytics/core/analytics-service.d.ts +23 -0
  8. package/dist/src/analytics/core/analytics-service.d.ts.map +1 -0
  9. package/dist/src/analytics/core/analytics-service.js +160 -0
  10. package/dist/src/analytics/core/analytics-service.js.map +1 -0
  11. package/dist/src/analytics/index.d.ts +12 -0
  12. package/dist/src/analytics/index.d.ts.map +1 -0
  13. package/dist/src/analytics/index.js +11 -0
  14. package/dist/src/analytics/index.js.map +1 -0
  15. package/dist/src/analytics/queries/metrics-queries.d.ts +11 -0
  16. package/dist/src/analytics/queries/metrics-queries.d.ts.map +1 -0
  17. package/dist/src/analytics/queries/metrics-queries.js +179 -0
  18. package/dist/src/analytics/queries/metrics-queries.js.map +1 -0
  19. package/dist/src/analytics/types/metrics.d.ts +60 -0
  20. package/dist/src/analytics/types/metrics.d.ts.map +1 -0
  21. package/dist/src/analytics/types/metrics.js +2 -0
  22. package/dist/src/analytics/types/metrics.js.map +1 -0
  23. package/dist/src/cli/analytics-viewer.d.ts +3 -0
  24. package/dist/src/cli/analytics-viewer.d.ts.map +1 -0
  25. package/dist/src/cli/analytics-viewer.js +89 -0
  26. package/dist/src/cli/analytics-viewer.js.map +1 -0
  27. package/dist/src/cli/browser-test.d.ts +6 -0
  28. package/dist/src/cli/browser-test.d.ts.map +1 -0
  29. package/dist/src/cli/browser-test.js +32 -0
  30. package/dist/src/cli/browser-test.js.map +1 -0
  31. package/dist/src/cli/cli.js +157 -0
  32. package/dist/src/cli/cli.js.map +1 -1
  33. package/dist/src/cli/commands/projects.d.ts +8 -0
  34. package/dist/src/cli/commands/projects.d.ts.map +1 -0
  35. package/dist/src/cli/commands/projects.js +220 -0
  36. package/dist/src/cli/commands/projects.js.map +1 -0
  37. package/dist/src/cli/index.d.ts +7 -0
  38. package/dist/src/cli/index.d.ts.map +1 -0
  39. package/dist/src/cli/index.js +704 -0
  40. package/dist/src/cli/index.js.map +1 -0
  41. package/dist/src/cli/project-commands.d.ts +8 -0
  42. package/dist/src/cli/project-commands.d.ts.map +1 -0
  43. package/dist/src/cli/project-commands.js +212 -0
  44. package/dist/src/cli/project-commands.js.map +1 -0
  45. package/dist/src/cli/utils/viewer.d.ts +3 -0
  46. package/dist/src/cli/utils/viewer.d.ts.map +1 -0
  47. package/dist/src/cli/utils/viewer.js +89 -0
  48. package/dist/src/cli/utils/viewer.js.map +1 -0
  49. package/dist/src/core/context/frame-manager.d.ts +106 -0
  50. package/dist/src/core/context/frame-manager.d.ts.map +1 -0
  51. package/dist/src/core/context/frame-manager.js +387 -0
  52. package/dist/src/core/context/frame-manager.js.map +1 -0
  53. package/dist/src/core/logger.test.js +1 -1
  54. package/dist/src/core/logger.test.js.map +1 -1
  55. package/dist/src/core/monitoring/error-handler.d.ts +46 -0
  56. package/dist/src/core/monitoring/error-handler.d.ts.map +1 -0
  57. package/dist/src/core/monitoring/error-handler.js +212 -0
  58. package/dist/src/core/monitoring/error-handler.js.map +1 -0
  59. package/dist/src/core/monitoring/logger.d.ts +24 -0
  60. package/dist/src/core/monitoring/logger.d.ts.map +1 -0
  61. package/dist/src/core/monitoring/logger.js +121 -0
  62. package/dist/src/core/monitoring/logger.js.map +1 -0
  63. package/dist/src/core/monitoring/metrics.d.ts +7 -0
  64. package/dist/src/core/monitoring/metrics.d.ts.map +1 -0
  65. package/dist/src/core/monitoring/metrics.js +13 -0
  66. package/dist/src/core/monitoring/metrics.js.map +1 -0
  67. package/dist/src/core/monitoring/progress-tracker.d.ts +95 -0
  68. package/dist/src/core/monitoring/progress-tracker.d.ts.map +1 -0
  69. package/dist/src/core/monitoring/progress-tracker.js +178 -0
  70. package/dist/src/core/monitoring/progress-tracker.js.map +1 -0
  71. package/dist/src/core/project-manager.d.ts +130 -0
  72. package/dist/src/core/project-manager.d.ts.map +1 -0
  73. package/dist/src/core/project-manager.js +582 -0
  74. package/dist/src/core/project-manager.js.map +1 -0
  75. package/dist/src/core/projects/project-manager.d.ts +130 -0
  76. package/dist/src/core/projects/project-manager.d.ts.map +1 -0
  77. package/dist/src/core/projects/project-manager.js +591 -0
  78. package/dist/src/core/projects/project-manager.js.map +1 -0
  79. package/dist/src/core/utils/update-checker.d.ts +38 -0
  80. package/dist/src/core/utils/update-checker.d.ts.map +1 -0
  81. package/dist/src/core/utils/update-checker.js +156 -0
  82. package/dist/src/core/utils/update-checker.js.map +1 -0
  83. package/dist/src/features/analytics/api/analytics-api.d.ts +24 -0
  84. package/dist/src/features/analytics/api/analytics-api.d.ts.map +1 -0
  85. package/dist/src/features/analytics/api/analytics-api.js +289 -0
  86. package/dist/src/features/analytics/api/analytics-api.js.map +1 -0
  87. package/dist/src/features/analytics/core/analytics-service.d.ts +23 -0
  88. package/dist/src/features/analytics/core/analytics-service.d.ts.map +1 -0
  89. package/dist/src/features/analytics/core/analytics-service.js +160 -0
  90. package/dist/src/features/analytics/core/analytics-service.js.map +1 -0
  91. package/dist/src/features/analytics/index.d.ts +12 -0
  92. package/dist/src/features/analytics/index.d.ts.map +1 -0
  93. package/dist/src/features/analytics/index.js +11 -0
  94. package/dist/src/features/analytics/index.js.map +1 -0
  95. package/dist/src/features/analytics/queries/metrics-queries.d.ts +11 -0
  96. package/dist/src/features/analytics/queries/metrics-queries.d.ts.map +1 -0
  97. package/dist/src/features/analytics/queries/metrics-queries.js +183 -0
  98. package/dist/src/features/analytics/queries/metrics-queries.js.map +1 -0
  99. package/dist/src/features/analytics/types/metrics.d.ts +60 -0
  100. package/dist/src/features/analytics/types/metrics.d.ts.map +1 -0
  101. package/dist/src/features/analytics/types/metrics.js +2 -0
  102. package/dist/src/features/analytics/types/metrics.js.map +1 -0
  103. package/dist/src/features/browser/browser-mcp.d.ts +94 -0
  104. package/dist/src/features/browser/browser-mcp.d.ts.map +1 -0
  105. package/dist/src/features/browser/browser-mcp.js +456 -0
  106. package/dist/src/features/browser/browser-mcp.js.map +1 -0
  107. package/dist/src/features/tasks/pebbles-task-store.d.ts +117 -0
  108. package/dist/src/features/tasks/pebbles-task-store.d.ts.map +1 -0
  109. package/dist/src/features/tasks/pebbles-task-store.js +335 -0
  110. package/dist/src/features/tasks/pebbles-task-store.js.map +1 -0
  111. package/dist/src/features/tasks/task-aware-context.d.ts +103 -0
  112. package/dist/src/features/tasks/task-aware-context.d.ts.map +1 -0
  113. package/dist/src/features/tasks/task-aware-context.js +412 -0
  114. package/dist/src/features/tasks/task-aware-context.js.map +1 -0
  115. package/dist/src/index.d.ts +4 -4
  116. package/dist/src/index.d.ts.map +1 -1
  117. package/dist/src/index.js +4 -4
  118. package/dist/src/index.js.map +1 -1
  119. package/dist/src/integrations/browser-mcp.d.ts +94 -0
  120. package/dist/src/integrations/browser-mcp.d.ts.map +1 -0
  121. package/dist/src/integrations/browser-mcp.js +431 -0
  122. package/dist/src/integrations/browser-mcp.js.map +1 -0
  123. package/dist/src/integrations/linear/auth.d.ts +99 -0
  124. package/dist/src/integrations/linear/auth.d.ts.map +1 -0
  125. package/dist/src/integrations/linear/auth.js +319 -0
  126. package/dist/src/integrations/linear/auth.js.map +1 -0
  127. package/dist/src/integrations/linear/auto-sync.d.ts +77 -0
  128. package/dist/src/integrations/linear/auto-sync.d.ts.map +1 -0
  129. package/dist/src/integrations/linear/auto-sync.js +268 -0
  130. package/dist/src/integrations/linear/auto-sync.js.map +1 -0
  131. package/dist/src/integrations/linear/client.d.ts +86 -0
  132. package/dist/src/integrations/linear/client.d.ts.map +1 -0
  133. package/dist/src/integrations/linear/client.js +277 -0
  134. package/dist/src/integrations/linear/client.js.map +1 -0
  135. package/dist/src/integrations/linear/config.d.ts +51 -0
  136. package/dist/src/integrations/linear/config.d.ts.map +1 -0
  137. package/dist/src/integrations/linear/config.js +103 -0
  138. package/dist/src/integrations/linear/config.js.map +1 -0
  139. package/dist/src/integrations/linear/sync.d.ts +97 -0
  140. package/dist/src/integrations/linear/sync.d.ts.map +1 -0
  141. package/dist/src/integrations/linear/sync.js +391 -0
  142. package/dist/src/integrations/linear/sync.js.map +1 -0
  143. package/dist/src/integrations/mcp/server.d.ts +40 -0
  144. package/dist/src/integrations/mcp/server.d.ts.map +1 -0
  145. package/dist/src/integrations/mcp/server.js +828 -0
  146. package/dist/src/integrations/mcp/server.js.map +1 -0
  147. package/dist/src/mcp/mcp-server.d.ts +1 -0
  148. package/dist/src/mcp/mcp-server.d.ts.map +1 -1
  149. package/dist/src/mcp/mcp-server.js +11 -0
  150. package/dist/src/mcp/mcp-server.js.map +1 -1
  151. package/dist/src/railway/index.d.ts +7 -0
  152. package/dist/src/railway/index.d.ts.map +1 -0
  153. package/dist/src/railway/index.js +401 -0
  154. package/dist/src/railway/index.js.map +1 -0
  155. package/dist/src/runway/auth/auth-middleware.d.ts +66 -0
  156. package/dist/src/runway/auth/auth-middleware.d.ts.map +1 -0
  157. package/dist/src/runway/auth/auth-middleware.js +337 -0
  158. package/dist/src/runway/auth/auth-middleware.js.map +1 -0
  159. package/dist/src/runway/server/runway-mcp-server.d.ts +46 -0
  160. package/dist/src/runway/server/runway-mcp-server.d.ts.map +1 -0
  161. package/dist/src/runway/server/runway-mcp-server.js +601 -0
  162. package/dist/src/runway/server/runway-mcp-server.js.map +1 -0
  163. package/dist/src/runway.bak/auth/auth-middleware.d.ts +66 -0
  164. package/dist/src/runway.bak/auth/auth-middleware.d.ts.map +1 -0
  165. package/dist/src/runway.bak/auth/auth-middleware.js +337 -0
  166. package/dist/src/runway.bak/auth/auth-middleware.js.map +1 -0
  167. package/dist/src/runway.bak/server/runway-mcp-server.d.ts +46 -0
  168. package/dist/src/runway.bak/server/runway-mcp-server.d.ts.map +1 -0
  169. package/dist/src/runway.bak/server/runway-mcp-server.js +601 -0
  170. package/dist/src/runway.bak/server/runway-mcp-server.js.map +1 -0
  171. package/dist/src/servers/production/auth-middleware.d.ts +66 -0
  172. package/dist/src/servers/production/auth-middleware.d.ts.map +1 -0
  173. package/dist/src/servers/production/auth-middleware.js +346 -0
  174. package/dist/src/servers/production/auth-middleware.js.map +1 -0
  175. package/dist/src/servers/railway/index.d.ts +7 -0
  176. package/dist/src/servers/railway/index.d.ts.map +1 -0
  177. package/dist/src/servers/railway/index.js +401 -0
  178. package/dist/src/servers/railway/index.js.map +1 -0
  179. package/package.json +27 -5
@@ -0,0 +1,160 @@
1
+ import { MetricsQueries } from '../queries/metrics-queries.js';
2
+ import { LinearClient } from '../../../integrations/linear/client.js';
3
+ import path from 'path';
4
+ import fs from 'fs';
5
+ import os from 'os';
6
+ export class AnalyticsService {
7
+ metricsQueries;
8
+ linearClient;
9
+ dbPath;
10
+ updateCallbacks = new Set();
11
+ constructor(projectPath) {
12
+ const basePath = projectPath || process.cwd();
13
+ this.dbPath = path.join(basePath, '.stackmemory', 'analytics.db');
14
+ this.ensureDirectoryExists();
15
+ this.metricsQueries = new MetricsQueries(this.dbPath);
16
+ if (process.env.LINEAR_API_KEY) {
17
+ this.initializeLinearIntegration();
18
+ }
19
+ }
20
+ ensureDirectoryExists() {
21
+ const dir = path.dirname(this.dbPath);
22
+ if (!fs.existsSync(dir)) {
23
+ fs.mkdirSync(dir, { recursive: true });
24
+ }
25
+ }
26
+ async initializeLinearIntegration() {
27
+ try {
28
+ const configPath = path.join(os.homedir(), '.stackmemory', 'linear-config.json');
29
+ if (fs.existsSync(configPath)) {
30
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
31
+ this.linearClient = new LinearClient(config);
32
+ await this.syncLinearTasks();
33
+ }
34
+ }
35
+ catch (error) {
36
+ console.error('Failed to initialize Linear integration:', error);
37
+ }
38
+ }
39
+ async syncLinearTasks() {
40
+ if (!this.linearClient)
41
+ return;
42
+ try {
43
+ // For now, we'll stub this as LinearClient doesn't expose a public query method
44
+ // In a real implementation, we'd need to add a public method to LinearClient
45
+ // or use LinearSyncEngine from linear-sync.ts
46
+ console.log('Linear sync not fully implemented - LinearClient needs public query method');
47
+ await this.notifyUpdate();
48
+ }
49
+ catch (error) {
50
+ console.error('Failed to sync Linear tasks:', error);
51
+ }
52
+ }
53
+ mapLinearState(linearState) {
54
+ const stateMap = {
55
+ backlog: 'todo',
56
+ unstarted: 'todo',
57
+ started: 'in_progress',
58
+ completed: 'completed',
59
+ done: 'completed',
60
+ canceled: 'blocked',
61
+ };
62
+ return stateMap[linearState.toLowerCase()] || 'todo';
63
+ }
64
+ mapLinearPriority(priority) {
65
+ if (priority === 1)
66
+ return 'urgent';
67
+ if (priority === 2)
68
+ return 'high';
69
+ if (priority === 3)
70
+ return 'medium';
71
+ return 'low';
72
+ }
73
+ async getDashboardState(query = {}) {
74
+ const timeRange = query.timeRange || this.getDefaultTimeRange();
75
+ const metrics = this.metricsQueries.getTaskMetrics({
76
+ ...query,
77
+ timeRange,
78
+ });
79
+ const recentTasks = this.metricsQueries.getRecentTasks({
80
+ ...query,
81
+ limit: 20,
82
+ });
83
+ const teamMetrics = await this.getTeamMetrics(query);
84
+ return {
85
+ metrics,
86
+ teamMetrics,
87
+ recentTasks,
88
+ timeRange,
89
+ teamFilter: query.userIds || [],
90
+ isLive: this.updateCallbacks.size > 0,
91
+ lastUpdated: new Date(),
92
+ };
93
+ }
94
+ async getTeamMetrics(query) {
95
+ const uniqueUserIds = new Set();
96
+ const tasks = this.metricsQueries.getRecentTasks({ limit: 1000 });
97
+ tasks.forEach((task) => {
98
+ if (task.assigneeId) {
99
+ uniqueUserIds.add(task.assigneeId);
100
+ }
101
+ });
102
+ const teamMetrics = [];
103
+ const totalCompleted = tasks.filter((t) => t.state === 'completed').length;
104
+ for (const userId of uniqueUserIds) {
105
+ const userQuery = { ...query, userIds: [userId] };
106
+ const individualMetrics = this.metricsQueries.getTaskMetrics(userQuery);
107
+ teamMetrics.push({
108
+ userId,
109
+ userName: await this.getUserName(userId),
110
+ individualMetrics,
111
+ contributionPercentage: totalCompleted > 0
112
+ ? (individualMetrics.completedTasks / totalCompleted) * 100
113
+ : 0,
114
+ lastActive: new Date(),
115
+ });
116
+ }
117
+ return teamMetrics.sort((a, b) => b.contributionPercentage - a.contributionPercentage);
118
+ }
119
+ async getUserName(userId) {
120
+ // Stub for now - would need LinearClient to expose user query method
121
+ return userId;
122
+ }
123
+ getDefaultTimeRange() {
124
+ const end = new Date();
125
+ const start = new Date();
126
+ start.setDate(start.getDate() - 7);
127
+ return {
128
+ start,
129
+ end,
130
+ preset: '7d',
131
+ };
132
+ }
133
+ subscribeToUpdates(callback) {
134
+ this.updateCallbacks.add(callback);
135
+ return () => {
136
+ this.updateCallbacks.delete(callback);
137
+ };
138
+ }
139
+ async notifyUpdate() {
140
+ const state = await this.getDashboardState();
141
+ this.updateCallbacks.forEach((callback) => callback(state));
142
+ }
143
+ async addTask(task) {
144
+ this.metricsQueries.upsertTask(task);
145
+ await this.notifyUpdate();
146
+ }
147
+ async updateTask(taskId, updates) {
148
+ const tasks = this.metricsQueries.getRecentTasks({ limit: 1 });
149
+ const existingTask = tasks.find((t) => t.id === taskId);
150
+ if (existingTask) {
151
+ const updatedTask = { ...existingTask, ...updates };
152
+ this.metricsQueries.upsertTask(updatedTask);
153
+ await this.notifyUpdate();
154
+ }
155
+ }
156
+ close() {
157
+ this.metricsQueries.close();
158
+ }
159
+ }
160
+ //# sourceMappingURL=analytics-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics-service.js","sourceRoot":"","sources":["../../../../../src/features/analytics/core/analytics-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export * from './types/metrics.js';
2
+ export * from './core/analytics-service.js';
3
+ export * from './api/analytics-api.js';
4
+ export * from './queries/metrics-queries.js';
5
+ import { AnalyticsService } from './core/analytics-service.js';
6
+ import { AnalyticsAPI } from './api/analytics-api.js';
7
+ declare const _default: {
8
+ AnalyticsService: typeof AnalyticsService;
9
+ AnalyticsAPI: typeof AnalyticsAPI;
10
+ };
11
+ export default _default;
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/features/analytics/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;;;;;AAEtD,wBAGE"}
@@ -0,0 +1,11 @@
1
+ export * from './types/metrics.js';
2
+ export * from './core/analytics-service.js';
3
+ export * from './api/analytics-api.js';
4
+ export * from './queries/metrics-queries.js';
5
+ import { AnalyticsService } from './core/analytics-service.js';
6
+ import { AnalyticsAPI } from './api/analytics-api.js';
7
+ export default {
8
+ AnalyticsService,
9
+ AnalyticsAPI,
10
+ };
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/features/analytics/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,eAAe;IACb,gBAAgB;IAChB,YAAY;CACb,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { TaskAnalytics, TaskMetrics, AnalyticsQuery } from '../types/metrics.js';
2
+ export declare class MetricsQueries {
3
+ private db;
4
+ constructor(dbPath: string);
5
+ private initializeTables;
6
+ getTaskMetrics(query?: AnalyticsQuery): TaskMetrics;
7
+ getRecentTasks(query?: AnalyticsQuery): TaskAnalytics[];
8
+ upsertTask(task: TaskAnalytics): void;
9
+ close(): void;
10
+ }
11
+ //# sourceMappingURL=metrics-queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-queries.d.ts","sourceRoot":"","sources":["../../../../../src/features/analytics/queries/metrics-queries.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,WAAW,EAEX,cAAc,EACf,MAAM,qBAAqB,CAAC;AAE7B,qBAAa,cAAc;IACzB,OAAO,CAAC,EAAE,CAAoB;gBAElB,MAAM,EAAE,MAAM;IAK1B,OAAO,CAAC,gBAAgB;IAuBxB,cAAc,CAAC,KAAK,GAAE,cAAmB,GAAG,WAAW;IA+FvD,cAAc,CAAC,KAAK,GAAE,cAAmB,GAAG,aAAa,EAAE;IAwC3D,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAyCrC,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,183 @@
1
+ import Database from 'better-sqlite3';
2
+ export class MetricsQueries {
3
+ db;
4
+ constructor(dbPath) {
5
+ this.db = new Database(dbPath, { readonly: false });
6
+ this.initializeTables();
7
+ }
8
+ initializeTables() {
9
+ this.db.exec(`
10
+ CREATE TABLE IF NOT EXISTS task_analytics (
11
+ id TEXT PRIMARY KEY,
12
+ title TEXT NOT NULL,
13
+ state TEXT NOT NULL,
14
+ created_at INTEGER NOT NULL,
15
+ completed_at INTEGER,
16
+ estimated_effort INTEGER,
17
+ actual_effort INTEGER,
18
+ assignee_id TEXT,
19
+ priority TEXT DEFAULT 'medium',
20
+ labels TEXT DEFAULT '[]',
21
+ blocking_issues TEXT DEFAULT '[]',
22
+ updated_at INTEGER DEFAULT (strftime('%s', 'now'))
23
+ );
24
+
25
+ CREATE INDEX IF NOT EXISTS idx_task_state ON task_analytics(state);
26
+ CREATE INDEX IF NOT EXISTS idx_task_created ON task_analytics(created_at);
27
+ CREATE INDEX IF NOT EXISTS idx_task_assignee ON task_analytics(assignee_id);
28
+ `);
29
+ }
30
+ getTaskMetrics(query = {}) {
31
+ const { timeRange, userIds, states, priorities } = query;
32
+ let whereConditions = ['1=1'];
33
+ const params = {};
34
+ if (timeRange) {
35
+ whereConditions.push('created_at >= @startTime AND created_at <= @endTime');
36
+ params.startTime = Math.floor(timeRange.start.getTime() / 1000);
37
+ params.endTime = Math.floor(timeRange.end.getTime() / 1000);
38
+ }
39
+ if (userIds && userIds.length > 0) {
40
+ whereConditions.push(`assignee_id IN (${userIds.map((_, i) => `@user${i}`).join(',')})`);
41
+ userIds.forEach((id, i) => (params[`user${i}`] = id));
42
+ }
43
+ if (states && states.length > 0) {
44
+ whereConditions.push(`state IN (${states.map((_, i) => `@state${i}`).join(',')})`);
45
+ states.forEach((s, i) => (params[`state${i}`] = s));
46
+ }
47
+ if (priorities && priorities.length > 0) {
48
+ whereConditions.push(`priority IN (${priorities.map((_, i) => `@priority${i}`).join(',')})`);
49
+ priorities.forEach((p, i) => (params[`priority${i}`] = p));
50
+ }
51
+ const whereClause = whereConditions.join(' AND ');
52
+ const metricsQuery = this.db.prepare(`
53
+ SELECT
54
+ COUNT(*) as total_tasks,
55
+ SUM(CASE WHEN state = 'completed' THEN 1 ELSE 0 END) as completed_tasks,
56
+ SUM(CASE WHEN state = 'in_progress' THEN 1 ELSE 0 END) as in_progress_tasks,
57
+ SUM(CASE WHEN state = 'blocked' THEN 1 ELSE 0 END) as blocked_tasks,
58
+ AVG(CASE
59
+ WHEN state = 'completed' AND completed_at IS NOT NULL
60
+ THEN (completed_at - created_at) * 1000
61
+ ELSE NULL
62
+ END) as avg_time_to_complete,
63
+ AVG(CASE
64
+ WHEN actual_effort IS NOT NULL AND estimated_effort IS NOT NULL AND estimated_effort > 0
65
+ THEN (CAST(actual_effort AS REAL) / estimated_effort) * 100
66
+ ELSE NULL
67
+ END) as effort_accuracy,
68
+ SUM(CASE
69
+ WHEN json_array_length(blocking_issues) > 0
70
+ THEN json_array_length(blocking_issues)
71
+ ELSE 0
72
+ END) as blocking_issues_count
73
+ FROM task_analytics
74
+ WHERE ${whereClause}
75
+ `);
76
+ const result = metricsQuery.get(params);
77
+ const velocityQuery = this.db.prepare(`
78
+ SELECT
79
+ DATE(created_at, 'unixepoch') as day,
80
+ COUNT(*) as completed_count
81
+ FROM task_analytics
82
+ WHERE state = 'completed'
83
+ AND ${whereClause}
84
+ GROUP BY day
85
+ ORDER BY day DESC
86
+ LIMIT 30
87
+ `);
88
+ const velocityData = velocityQuery.all(params);
89
+ const velocityTrend = velocityData.map((v) => v.completed_count).reverse();
90
+ return {
91
+ totalTasks: result.total_tasks || 0,
92
+ completedTasks: result.completed_tasks || 0,
93
+ inProgressTasks: result.in_progress_tasks || 0,
94
+ blockedTasks: result.blocked_tasks || 0,
95
+ completionRate: result.total_tasks > 0
96
+ ? (result.completed_tasks / result.total_tasks) * 100
97
+ : 0,
98
+ averageTimeToComplete: result.avg_time_to_complete || 0,
99
+ effortAccuracy: result.effort_accuracy || 100,
100
+ blockingIssuesCount: result.blocking_issues_count || 0,
101
+ velocityTrend,
102
+ };
103
+ }
104
+ getRecentTasks(query = {}) {
105
+ const { limit = 100, offset = 0 } = query;
106
+ const tasksQuery = this.db.prepare(`
107
+ SELECT
108
+ id,
109
+ title,
110
+ state,
111
+ created_at,
112
+ completed_at,
113
+ estimated_effort,
114
+ actual_effort,
115
+ assignee_id,
116
+ priority,
117
+ labels,
118
+ blocking_issues
119
+ FROM task_analytics
120
+ ORDER BY updated_at DESC
121
+ LIMIT ? OFFSET ?
122
+ `);
123
+ const rows = tasksQuery.all(limit, offset);
124
+ return rows.map((row) => ({
125
+ id: row.id,
126
+ title: row.title,
127
+ state: row.state,
128
+ createdAt: new Date(row.created_at * 1000),
129
+ completedAt: row.completed_at
130
+ ? new Date(row.completed_at * 1000)
131
+ : undefined,
132
+ estimatedEffort: row.estimated_effort,
133
+ actualEffort: row.actual_effort,
134
+ assigneeId: row.assignee_id,
135
+ priority: row.priority,
136
+ labels: JSON.parse(row.labels),
137
+ blockingIssues: JSON.parse(row.blocking_issues),
138
+ }));
139
+ }
140
+ upsertTask(task) {
141
+ const stmt = this.db.prepare(`
142
+ INSERT INTO task_analytics (
143
+ id, title, state, created_at, completed_at,
144
+ estimated_effort, actual_effort, assignee_id,
145
+ priority, labels, blocking_issues
146
+ ) VALUES (
147
+ @id, @title, @state, @created_at, @completed_at,
148
+ @estimated_effort, @actual_effort, @assignee_id,
149
+ @priority, @labels, @blocking_issues
150
+ )
151
+ ON CONFLICT(id) DO UPDATE SET
152
+ title = @title,
153
+ state = @state,
154
+ completed_at = @completed_at,
155
+ estimated_effort = @estimated_effort,
156
+ actual_effort = @actual_effort,
157
+ assignee_id = @assignee_id,
158
+ priority = @priority,
159
+ labels = @labels,
160
+ blocking_issues = @blocking_issues,
161
+ updated_at = strftime('%s', 'now')
162
+ `);
163
+ stmt.run({
164
+ id: task.id,
165
+ title: task.title,
166
+ state: task.state,
167
+ created_at: Math.floor(task.createdAt.getTime() / 1000),
168
+ completed_at: task.completedAt
169
+ ? Math.floor(task.completedAt.getTime() / 1000)
170
+ : null,
171
+ estimated_effort: task.estimatedEffort || null,
172
+ actual_effort: task.actualEffort || null,
173
+ assignee_id: task.assigneeId || null,
174
+ priority: task.priority,
175
+ labels: JSON.stringify(task.labels),
176
+ blocking_issues: JSON.stringify(task.blockingIssues),
177
+ });
178
+ }
179
+ close() {
180
+ this.db.close();
181
+ }
182
+ }
183
+ //# sourceMappingURL=metrics-queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-queries.js","sourceRoot":"","sources":["../../../../../src/features/analytics/queries/metrics-queries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ export interface TimeRange {
2
+ start: Date;
3
+ end: Date;
4
+ preset?: 'today' | '7d' | '30d' | '90d' | 'custom';
5
+ }
6
+ export interface TaskMetrics {
7
+ completionRate: number;
8
+ averageTimeToComplete: number;
9
+ effortAccuracy: number;
10
+ blockingIssuesCount: number;
11
+ velocityTrend: number[];
12
+ totalTasks: number;
13
+ completedTasks: number;
14
+ inProgressTasks: number;
15
+ blockedTasks: number;
16
+ }
17
+ export interface TeamMetrics {
18
+ userId: string;
19
+ userName: string;
20
+ individualMetrics: TaskMetrics;
21
+ contributionPercentage: number;
22
+ lastActive: Date;
23
+ }
24
+ export interface TaskAnalytics {
25
+ id: string;
26
+ title: string;
27
+ state: 'todo' | 'in_progress' | 'completed' | 'blocked';
28
+ createdAt: Date;
29
+ completedAt?: Date;
30
+ estimatedEffort?: number;
31
+ actualEffort?: number;
32
+ assigneeId?: string;
33
+ priority: 'urgent' | 'high' | 'medium' | 'low';
34
+ labels: string[];
35
+ blockingIssues: string[];
36
+ }
37
+ export interface DashboardState {
38
+ metrics: TaskMetrics;
39
+ teamMetrics: TeamMetrics[];
40
+ recentTasks: TaskAnalytics[];
41
+ timeRange: TimeRange;
42
+ teamFilter: string[];
43
+ isLive: boolean;
44
+ lastUpdated: Date;
45
+ }
46
+ export interface MetricAggregation {
47
+ period: 'hour' | 'day' | 'week' | 'month';
48
+ timestamp: Date;
49
+ metrics: Partial<TaskMetrics>;
50
+ }
51
+ export interface AnalyticsQuery {
52
+ timeRange?: TimeRange;
53
+ userIds?: string[];
54
+ states?: TaskAnalytics['state'][];
55
+ priorities?: TaskAnalytics['priority'][];
56
+ labels?: string[];
57
+ limit?: number;
58
+ offset?: number;
59
+ }
60
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../../../src/features/analytics/types/metrics.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,IAAI,CAAC;IACZ,GAAG,EAAE,IAAI,CAAC;IACV,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAC;CACpD;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,WAAW,CAAC;IAC/B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,WAAW,GAAG,SAAS,CAAC;IACxD,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC/C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,CAAC;IACrB,WAAW,EAAE,WAAW,EAAE,CAAC;IAC3B,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;IAC1C,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;IAClC,UAAU,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../../../src/features/analytics/types/metrics.ts"],"names":[],"mappings":""}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Browser MCP Integration for StackMemory
3
+ * Provides browser automation capabilities through MCP
4
+ */
5
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
6
+ import { Browser, Page } from 'puppeteer';
7
+ export interface BrowserAction {
8
+ type: 'navigate' | 'click' | 'type' | 'screenshot' | 'evaluate' | 'wait';
9
+ selector?: string;
10
+ value?: string;
11
+ script?: string;
12
+ timeout?: number;
13
+ }
14
+ export interface BrowserSession {
15
+ id: string;
16
+ browser: Browser;
17
+ page: Page;
18
+ createdAt: Date;
19
+ lastActivity: Date;
20
+ url?: string;
21
+ }
22
+ export declare class BrowserMCPIntegration {
23
+ private config;
24
+ private sessions;
25
+ private server?;
26
+ private maxSessions;
27
+ private sessionTimeout;
28
+ constructor(config?: {
29
+ headless?: boolean;
30
+ defaultViewport?: {
31
+ width: number;
32
+ height: number;
33
+ };
34
+ userDataDir?: string;
35
+ executablePath?: string;
36
+ });
37
+ /**
38
+ * Initialize the Browser MCP server
39
+ */
40
+ initialize(mcpServer?: Server): Promise<void>;
41
+ /**
42
+ * Set up MCP request handlers
43
+ */
44
+ private setupHandlers;
45
+ /**
46
+ * Navigate to a URL
47
+ */
48
+ private navigate;
49
+ /**
50
+ * Take a screenshot
51
+ */
52
+ private screenshot;
53
+ /**
54
+ * Click an element
55
+ */
56
+ private click;
57
+ /**
58
+ * Type text into an input
59
+ */
60
+ private type;
61
+ /**
62
+ * Execute JavaScript in page context
63
+ */
64
+ private evaluate;
65
+ /**
66
+ * Wait for element or timeout
67
+ */
68
+ private waitFor;
69
+ /**
70
+ * Get page content
71
+ */
72
+ private getContent;
73
+ /**
74
+ * Get or create a browser session
75
+ */
76
+ private getOrCreateSession;
77
+ /**
78
+ * Get existing session
79
+ */
80
+ private getSession;
81
+ /**
82
+ * Close a browser session
83
+ */
84
+ private closeSession;
85
+ /**
86
+ * Clean up inactive sessions
87
+ */
88
+ private startCleanupInterval;
89
+ /**
90
+ * Close all sessions
91
+ */
92
+ cleanup(): Promise<void>;
93
+ }
94
+ //# sourceMappingURL=browser-mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-mcp.d.ts","sourceRoot":"","sources":["../../../../src/features/browser/browser-mcp.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAQnE,OAAkB,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGrD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,YAAY,GAAG,UAAU,GAAG,MAAM,CAAC;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,IAAI,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,qBAAqB;IAO9B,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,QAAQ,CAA0C;IAC1D,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,cAAc,CAAkB;gBAG9B,MAAM,GAAE;QACd,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,eAAe,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;QACpD,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACpB;IAKR;;OAEG;IACG,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBnD;;OAEG;IACH,OAAO,CAAC,aAAa;IAmMrB;;OAEG;YACW,QAAQ;IAqBtB;;OAEG;YACW,UAAU;IAmCxB;;OAEG;YACW,KAAK;IAoBnB;;OAEG;YACW,IAAI;IAwBlB;;OAEG;YACW,QAAQ;IAqBtB;;OAEG;YACW,OAAO;IA6BrB;;OAEG;YACW,UAAU;IA8BxB;;OAEG;YACW,kBAAkB;IAgDhC;;OAEG;IACH,OAAO,CAAC,UAAU;IAIlB;;OAEG;YACW,YAAY;IA4B1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAe5B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAK/B"}