@tekdi/coding-analytics 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/batcher.d.ts +15 -0
- package/dist/batcher.d.ts.map +1 -0
- package/dist/batcher.js +90 -0
- package/dist/batcher.js.map +1 -0
- package/dist/claude-hooks-receiver.d.ts +16 -0
- package/dist/claude-hooks-receiver.d.ts.map +1 -0
- package/dist/claude-hooks-receiver.js +145 -0
- package/dist/claude-hooks-receiver.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +314 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +50 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +119 -0
- package/dist/config.js.map +1 -0
- package/dist/enricher.d.ts +28 -0
- package/dist/enricher.d.ts.map +1 -0
- package/dist/enricher.js +258 -0
- package/dist/enricher.js.map +1 -0
- package/dist/flusher.d.ts +10 -0
- package/dist/flusher.d.ts.map +1 -0
- package/dist/flusher.js +89 -0
- package/dist/flusher.js.map +1 -0
- package/dist/health-monitor.d.ts +35 -0
- package/dist/health-monitor.d.ts.map +1 -0
- package/dist/health-monitor.js +187 -0
- package/dist/health-monitor.js.map +1 -0
- package/dist/hooks-listener.d.ts +23 -0
- package/dist/hooks-listener.d.ts.map +1 -0
- package/dist/hooks-listener.js +168 -0
- package/dist/hooks-listener.js.map +1 -0
- package/dist/install-service.d.ts +15 -0
- package/dist/install-service.d.ts.map +1 -0
- package/dist/install-service.js +218 -0
- package/dist/install-service.js.map +1 -0
- package/dist/local-storage.d.ts +19 -0
- package/dist/local-storage.d.ts.map +1 -0
- package/dist/local-storage.js +152 -0
- package/dist/local-storage.js.map +1 -0
- package/dist/logger.d.ts +3 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +59 -0
- package/dist/logger.js.map +1 -0
- package/dist/queue.d.ts +22 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +102 -0
- package/dist/queue.js.map +1 -0
- package/package.json +49 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface PostHogConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
host: string;
|
|
4
|
+
batchSize: number;
|
|
5
|
+
flushInterval: number;
|
|
6
|
+
}
|
|
7
|
+
export interface CaptureConfig {
|
|
8
|
+
prompts: boolean;
|
|
9
|
+
responses: boolean;
|
|
10
|
+
fileContent: boolean;
|
|
11
|
+
filePaths: boolean;
|
|
12
|
+
agentThinking: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface PrivacyConfig {
|
|
15
|
+
hashUserIds: boolean;
|
|
16
|
+
redactSecrets: boolean;
|
|
17
|
+
allowedRepos: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface StorageConfig {
|
|
20
|
+
fallbackToLocal: boolean;
|
|
21
|
+
localDbPath: string;
|
|
22
|
+
retryFailedEvents: boolean;
|
|
23
|
+
maxRetries: number;
|
|
24
|
+
}
|
|
25
|
+
export interface SystemConfig {
|
|
26
|
+
logLevel: string;
|
|
27
|
+
logPath: string;
|
|
28
|
+
}
|
|
29
|
+
export interface ConfigData {
|
|
30
|
+
posthog: PostHogConfig;
|
|
31
|
+
capture: CaptureConfig;
|
|
32
|
+
privacy: PrivacyConfig;
|
|
33
|
+
storage: StorageConfig;
|
|
34
|
+
system: SystemConfig;
|
|
35
|
+
}
|
|
36
|
+
export declare class Config {
|
|
37
|
+
posthog: PostHogConfig;
|
|
38
|
+
capture: CaptureConfig;
|
|
39
|
+
privacy: PrivacyConfig;
|
|
40
|
+
storage: StorageConfig;
|
|
41
|
+
system: SystemConfig;
|
|
42
|
+
constructor(data?: Partial<ConfigData>);
|
|
43
|
+
static getDataDir(): string;
|
|
44
|
+
static getConfigPath(): string;
|
|
45
|
+
static load(): Config;
|
|
46
|
+
save(): void;
|
|
47
|
+
toJSON(): ConfigData;
|
|
48
|
+
isConfigured(): boolean;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,qBAAa,MAAM;IACV,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;gBAEhB,IAAI,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC;IAoCtC,MAAM,CAAC,UAAU,IAAI,MAAM;IAK3B,MAAM,CAAC,aAAa,IAAI,MAAM;IAI9B,MAAM,CAAC,IAAI,IAAI,MAAM;IAmBrB,IAAI,IAAI,IAAI;IAYZ,MAAM,IAAI,UAAU;IAUpB,YAAY,IAAI,OAAO;CAGxB"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Config = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const os = __importStar(require("os"));
|
|
40
|
+
class Config {
|
|
41
|
+
constructor(data) {
|
|
42
|
+
// Defaults
|
|
43
|
+
this.posthog = {
|
|
44
|
+
apiKey: data?.posthog?.apiKey || '',
|
|
45
|
+
host: data?.posthog?.host || 'https://eu.i.posthog.com',
|
|
46
|
+
batchSize: data?.posthog?.batchSize || 100,
|
|
47
|
+
flushInterval: data?.posthog?.flushInterval || 5000,
|
|
48
|
+
};
|
|
49
|
+
this.capture = {
|
|
50
|
+
prompts: data?.capture?.prompts ?? true,
|
|
51
|
+
responses: data?.capture?.responses ?? false,
|
|
52
|
+
fileContent: data?.capture?.fileContent ?? false,
|
|
53
|
+
filePaths: data?.capture?.filePaths ?? true,
|
|
54
|
+
agentThinking: data?.capture?.agentThinking ?? true,
|
|
55
|
+
};
|
|
56
|
+
this.privacy = {
|
|
57
|
+
hashUserIds: data?.privacy?.hashUserIds ?? true,
|
|
58
|
+
redactSecrets: data?.privacy?.redactSecrets ?? true,
|
|
59
|
+
allowedRepos: data?.privacy?.allowedRepos || [],
|
|
60
|
+
};
|
|
61
|
+
this.storage = {
|
|
62
|
+
fallbackToLocal: data?.storage?.fallbackToLocal ?? true,
|
|
63
|
+
localDbPath: data?.storage?.localDbPath || path.join(Config.getDataDir(), 'events.json'),
|
|
64
|
+
retryFailedEvents: data?.storage?.retryFailedEvents ?? true,
|
|
65
|
+
maxRetries: data?.storage?.maxRetries || 3,
|
|
66
|
+
};
|
|
67
|
+
this.system = {
|
|
68
|
+
logLevel: data?.system?.logLevel || 'info',
|
|
69
|
+
logPath: data?.system?.logPath || path.join(Config.getDataDir(), 'logs'),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
static getDataDir() {
|
|
73
|
+
const homeDir = os.homedir();
|
|
74
|
+
return path.join(homeDir, '.coding-analytics');
|
|
75
|
+
}
|
|
76
|
+
static getConfigPath() {
|
|
77
|
+
return path.join(Config.getDataDir(), 'config.json');
|
|
78
|
+
}
|
|
79
|
+
static load() {
|
|
80
|
+
const configPath = Config.getConfigPath();
|
|
81
|
+
if (!fs.existsSync(configPath)) {
|
|
82
|
+
// Create default config
|
|
83
|
+
const config = new Config();
|
|
84
|
+
config.save();
|
|
85
|
+
return config;
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const data = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
89
|
+
return new Config(data);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
console.warn('Failed to load config, using defaults:', error);
|
|
93
|
+
return new Config();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
save() {
|
|
97
|
+
const configPath = Config.getConfigPath();
|
|
98
|
+
const dataDir = Config.getDataDir();
|
|
99
|
+
// Ensure directory exists
|
|
100
|
+
if (!fs.existsSync(dataDir)) {
|
|
101
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
102
|
+
}
|
|
103
|
+
fs.writeFileSync(configPath, JSON.stringify(this.toJSON(), null, 2));
|
|
104
|
+
}
|
|
105
|
+
toJSON() {
|
|
106
|
+
return {
|
|
107
|
+
posthog: this.posthog,
|
|
108
|
+
capture: this.capture,
|
|
109
|
+
privacy: this.privacy,
|
|
110
|
+
storage: this.storage,
|
|
111
|
+
system: this.system,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
isConfigured() {
|
|
115
|
+
return !!this.posthog.apiKey;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.Config = Config;
|
|
119
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Config } from './config';
|
|
2
|
+
import { HookEvent } from './hooks-listener';
|
|
3
|
+
export interface EnrichedEvent {
|
|
4
|
+
event: string;
|
|
5
|
+
distinct_id: string;
|
|
6
|
+
properties: Record<string, any>;
|
|
7
|
+
timestamp: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class Enricher {
|
|
10
|
+
private config;
|
|
11
|
+
private cachedUserId;
|
|
12
|
+
private cachedMachineId;
|
|
13
|
+
private gitContextCache;
|
|
14
|
+
constructor(config: Config);
|
|
15
|
+
enrich(hookEvent: HookEvent): Promise<EnrichedEvent>;
|
|
16
|
+
private getGitContext;
|
|
17
|
+
private fetchGitContext;
|
|
18
|
+
private extractRepoName;
|
|
19
|
+
private getSystemContext;
|
|
20
|
+
private getCursorVersion;
|
|
21
|
+
private getUserId;
|
|
22
|
+
private getClaudeAccountUuid;
|
|
23
|
+
private getCursorEmail;
|
|
24
|
+
private getCursorDbPath;
|
|
25
|
+
private getMachineId;
|
|
26
|
+
private hash;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=enricher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enricher.d.ts","sourceRoot":"","sources":["../enricher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAQ7C,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,eAAe,CAAuB;IAE9C,OAAO,CAAC,eAAe,CAA0C;gBAErD,MAAM,EAAE,MAAM;IAIpB,MAAM,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC;YA+B5C,aAAa;YASb,eAAe;IA2D7B,OAAO,CAAC,eAAe;YAQT,gBAAgB;YAUhB,gBAAgB;YAqBhB,SAAS;IA+BvB,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,eAAe;YA0BT,YAAY;IAc1B,OAAO,CAAC,IAAI;CAGb"}
|
package/dist/enricher.js
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.Enricher = void 0;
|
|
40
|
+
const simple_git_1 = __importDefault(require("simple-git"));
|
|
41
|
+
const os = __importStar(require("os"));
|
|
42
|
+
const crypto = __importStar(require("crypto"));
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const child_process_1 = require("child_process");
|
|
46
|
+
class Enricher {
|
|
47
|
+
constructor(config) {
|
|
48
|
+
this.cachedUserId = null;
|
|
49
|
+
this.cachedMachineId = null;
|
|
50
|
+
// Keyed by workspace path — avoids re-running 5 git subprocesses per event in a flush batch
|
|
51
|
+
this.gitContextCache = new Map();
|
|
52
|
+
this.config = config;
|
|
53
|
+
}
|
|
54
|
+
async enrich(hookEvent) {
|
|
55
|
+
const properties = {
|
|
56
|
+
...hookEvent.data,
|
|
57
|
+
};
|
|
58
|
+
// Add git context — Claude hooks don't supply workspace_path so fall back to cwd
|
|
59
|
+
const workspacePath = hookEvent.data.workspace_path ||
|
|
60
|
+
(hookEvent.provider === 'claude' ? process.cwd() : undefined);
|
|
61
|
+
if (workspacePath) {
|
|
62
|
+
const gitContext = await this.getGitContext(workspacePath);
|
|
63
|
+
Object.assign(properties, gitContext);
|
|
64
|
+
}
|
|
65
|
+
// Add system context
|
|
66
|
+
const systemContext = await this.getSystemContext();
|
|
67
|
+
Object.assign(properties, systemContext);
|
|
68
|
+
// Get user ID
|
|
69
|
+
const userId = await this.getUserId();
|
|
70
|
+
return {
|
|
71
|
+
event: hookEvent.type,
|
|
72
|
+
distinct_id: userId,
|
|
73
|
+
properties: {
|
|
74
|
+
...properties,
|
|
75
|
+
provider: hookEvent.provider ?? 'cursor',
|
|
76
|
+
},
|
|
77
|
+
timestamp: hookEvent.timestamp,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
async getGitContext(workspacePath) {
|
|
81
|
+
if (this.gitContextCache.has(workspacePath)) {
|
|
82
|
+
return this.gitContextCache.get(workspacePath);
|
|
83
|
+
}
|
|
84
|
+
const context = await this.fetchGitContext(workspacePath);
|
|
85
|
+
this.gitContextCache.set(workspacePath, context);
|
|
86
|
+
return context;
|
|
87
|
+
}
|
|
88
|
+
async fetchGitContext(workspacePath) {
|
|
89
|
+
try {
|
|
90
|
+
const git = (0, simple_git_1.default)(workspacePath);
|
|
91
|
+
// Check if it's a git repo
|
|
92
|
+
const isRepo = await git.checkIsRepo();
|
|
93
|
+
if (!isRepo) {
|
|
94
|
+
return { git_enabled: false };
|
|
95
|
+
}
|
|
96
|
+
// Get current branch
|
|
97
|
+
const branch = await git.branchLocal();
|
|
98
|
+
// Get remote URL
|
|
99
|
+
const remotes = await git.getRemotes(true);
|
|
100
|
+
const origin = remotes.find(r => r.name === 'origin');
|
|
101
|
+
// Get last commit
|
|
102
|
+
const log = await git.log({ n: 1 });
|
|
103
|
+
const lastCommit = log.latest;
|
|
104
|
+
// Check if working directory is dirty
|
|
105
|
+
const status = await git.status();
|
|
106
|
+
// Extract repo name from remote
|
|
107
|
+
const repository = origin?.refs?.fetch
|
|
108
|
+
? this.extractRepoName(origin.refs.fetch)
|
|
109
|
+
: 'unknown';
|
|
110
|
+
// Privacy: Check if repo is allowed
|
|
111
|
+
if (this.config.privacy.allowedRepos.length > 0) {
|
|
112
|
+
const allowed = this.config.privacy.allowedRepos.some(pattern => {
|
|
113
|
+
const regex = new RegExp(pattern.replace('*', '.*'));
|
|
114
|
+
return regex.test(repository);
|
|
115
|
+
});
|
|
116
|
+
if (!allowed) {
|
|
117
|
+
return {
|
|
118
|
+
git_enabled: true,
|
|
119
|
+
repository: '[filtered]',
|
|
120
|
+
branch: '[filtered]',
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
git_enabled: true,
|
|
126
|
+
repository,
|
|
127
|
+
branch: branch.current,
|
|
128
|
+
last_commit: lastCommit?.hash?.substring(0, 7) || null,
|
|
129
|
+
is_dirty: !status.isClean(),
|
|
130
|
+
modified_files: status.modified.length,
|
|
131
|
+
staged_files: status.staged.length,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
return { git_enabled: false, git_error: error.message };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
extractRepoName(remoteUrl) {
|
|
139
|
+
// Extract from URLs like:
|
|
140
|
+
// git@github.com:org/repo.git
|
|
141
|
+
// https://github.com/org/repo.git
|
|
142
|
+
const match = remoteUrl.match(/([^/:]+\/[^/.]+)(\.git)?$/);
|
|
143
|
+
return match ? match[1] : remoteUrl;
|
|
144
|
+
}
|
|
145
|
+
async getSystemContext() {
|
|
146
|
+
return {
|
|
147
|
+
os: os.platform(),
|
|
148
|
+
os_version: os.release(),
|
|
149
|
+
cursor_version: await this.getCursorVersion(),
|
|
150
|
+
node_version: process.version,
|
|
151
|
+
machine_id: await this.getMachineId(),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
async getCursorVersion() {
|
|
155
|
+
try {
|
|
156
|
+
// Try to read Cursor version from common locations
|
|
157
|
+
const cursorPaths = [
|
|
158
|
+
path.join(os.homedir(), '.cursor', 'version'),
|
|
159
|
+
path.join(os.homedir(), 'AppData', 'Local', 'Programs', 'Cursor', 'version'), // Windows
|
|
160
|
+
'/Applications/Cursor.app/Contents/Resources/app/version', // Mac
|
|
161
|
+
];
|
|
162
|
+
for (const versionPath of cursorPaths) {
|
|
163
|
+
if (fs.existsSync(versionPath)) {
|
|
164
|
+
return fs.readFileSync(versionPath, 'utf-8').trim();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return 'unknown';
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return 'unknown';
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async getUserId() {
|
|
174
|
+
if (this.cachedUserId) {
|
|
175
|
+
return this.cachedUserId;
|
|
176
|
+
}
|
|
177
|
+
// 1. Claude account UUID — stable, already opaque, no hashing needed
|
|
178
|
+
const claudeUuid = this.getClaudeAccountUuid();
|
|
179
|
+
if (claudeUuid) {
|
|
180
|
+
this.cachedUserId = claudeUuid;
|
|
181
|
+
return this.cachedUserId;
|
|
182
|
+
}
|
|
183
|
+
// 2. Cursor cached email from state.vscdb
|
|
184
|
+
const cursorEmail = this.getCursorEmail();
|
|
185
|
+
if (cursorEmail) {
|
|
186
|
+
this.cachedUserId = this.config.privacy.hashUserIds ? this.hash(cursorEmail) : cursorEmail;
|
|
187
|
+
return this.cachedUserId;
|
|
188
|
+
}
|
|
189
|
+
// 3. Git global email
|
|
190
|
+
try {
|
|
191
|
+
const git = (0, simple_git_1.default)();
|
|
192
|
+
const email = (await git.raw(['config', '--global', 'user.email'])).trim();
|
|
193
|
+
this.cachedUserId = this.config.privacy.hashUserIds ? this.hash(email) : email;
|
|
194
|
+
return this.cachedUserId;
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
// 4. Last resort: machine ID
|
|
198
|
+
return await this.getMachineId();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
getClaudeAccountUuid() {
|
|
202
|
+
try {
|
|
203
|
+
const claudeJsonPath = path.join(os.homedir(), '.claude.json');
|
|
204
|
+
if (!fs.existsSync(claudeJsonPath))
|
|
205
|
+
return null;
|
|
206
|
+
const data = JSON.parse(fs.readFileSync(claudeJsonPath, 'utf-8'));
|
|
207
|
+
return data?.oauthAccount?.accountUuid ?? null;
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
getCursorEmail() {
|
|
214
|
+
try {
|
|
215
|
+
const dbPath = this.getCursorDbPath();
|
|
216
|
+
if (!dbPath || !fs.existsSync(dbPath))
|
|
217
|
+
return null;
|
|
218
|
+
// sqlite3 CLI ships with macOS and is standard on Linux — no npm dependency needed
|
|
219
|
+
const result = (0, child_process_1.execSync)(`sqlite3 "${dbPath}" "SELECT value FROM ItemTable WHERE key='cursorAuth/cachedEmail';"`, { timeout: 3000, stdio: ['ignore', 'pipe', 'ignore'] }).toString().trim();
|
|
220
|
+
return result || null;
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
getCursorDbPath() {
|
|
227
|
+
const home = os.homedir();
|
|
228
|
+
const candidates = [];
|
|
229
|
+
switch (os.platform()) {
|
|
230
|
+
case 'darwin':
|
|
231
|
+
candidates.push(path.join(home, 'Library', 'Application Support', 'Cursor', 'User', 'globalStorage', 'state.vscdb'), path.join(home, '.config', 'Cursor', 'User', 'globalStorage', 'state.vscdb'));
|
|
232
|
+
break;
|
|
233
|
+
case 'linux':
|
|
234
|
+
candidates.push(path.join(home, '.config', 'Cursor', 'User', 'globalStorage', 'state.vscdb'));
|
|
235
|
+
break;
|
|
236
|
+
case 'win32':
|
|
237
|
+
candidates.push(path.join(process.env.APPDATA ?? '', 'Cursor', 'User', 'globalStorage', 'state.vscdb'));
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
return candidates.find(p => fs.existsSync(p)) ?? null;
|
|
241
|
+
}
|
|
242
|
+
async getMachineId() {
|
|
243
|
+
if (this.cachedMachineId) {
|
|
244
|
+
return this.cachedMachineId;
|
|
245
|
+
}
|
|
246
|
+
// Use machine-specific identifier
|
|
247
|
+
const hostname = os.hostname();
|
|
248
|
+
const username = os.userInfo().username;
|
|
249
|
+
const machineKey = `${hostname}-${username}`;
|
|
250
|
+
this.cachedMachineId = this.hash(machineKey);
|
|
251
|
+
return this.cachedMachineId;
|
|
252
|
+
}
|
|
253
|
+
hash(input) {
|
|
254
|
+
return crypto.createHash('sha256').update(input).digest('hex').substring(0, 16);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
exports.Enricher = Enricher;
|
|
258
|
+
//# sourceMappingURL=enricher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enricher.js","sourceRoot":"","sources":["../enricher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flusher.d.ts","sourceRoot":"","sources":["../flusher.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAS;;IAMjB,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;CAoDpC"}
|
package/dist/flusher.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Flusher = void 0;
|
|
37
|
+
const config_1 = require("./config");
|
|
38
|
+
const enricher_1 = require("./enricher");
|
|
39
|
+
const batcher_1 = require("./batcher");
|
|
40
|
+
const queue_1 = require("./queue");
|
|
41
|
+
const logger_1 = require("./logger");
|
|
42
|
+
class Flusher {
|
|
43
|
+
constructor() {
|
|
44
|
+
this.config = config_1.Config.load();
|
|
45
|
+
}
|
|
46
|
+
async flush() {
|
|
47
|
+
const queue = new queue_1.Queue();
|
|
48
|
+
const events = queue.drain();
|
|
49
|
+
if (events.length === 0) {
|
|
50
|
+
return { processed: 0, failed: 0 };
|
|
51
|
+
}
|
|
52
|
+
logger_1.logger.info('Flusher: processing queued events', { count: events.length });
|
|
53
|
+
// One Enricher for the whole batch:
|
|
54
|
+
// - userId, machineId cached after first resolution
|
|
55
|
+
// - git context cached per workspace path (see Enricher)
|
|
56
|
+
const enricher = new enricher_1.Enricher(this.config);
|
|
57
|
+
const batcher = new batcher_1.EventBatcher(this.config);
|
|
58
|
+
const failedLines = [];
|
|
59
|
+
let processed = 0;
|
|
60
|
+
let failed = 0;
|
|
61
|
+
for (const { hookEvent, queuedAt } of events) {
|
|
62
|
+
try {
|
|
63
|
+
// Preserve the original queued timestamp rather than the flush time
|
|
64
|
+
hookEvent.timestamp = hookEvent.timestamp || queuedAt;
|
|
65
|
+
const enriched = await enricher.enrich(hookEvent);
|
|
66
|
+
await batcher.add(enriched);
|
|
67
|
+
processed++;
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
logger_1.logger.error('Flusher: failed to process event', { error, hookType: hookEvent.type });
|
|
71
|
+
// Re-queue so it retries next flush cycle
|
|
72
|
+
failedLines.push(JSON.stringify({ hookEvent, queuedAt }));
|
|
73
|
+
failed++;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Flush to PostHog (falls back to local-storage on network failure)
|
|
77
|
+
await batcher.shutdown();
|
|
78
|
+
// Re-append failed events so they are retried next cycle
|
|
79
|
+
if (failedLines.length > 0) {
|
|
80
|
+
const { appendFileSync } = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
81
|
+
const { join } = await Promise.resolve().then(() => __importStar(require('path')));
|
|
82
|
+
appendFileSync(join(config_1.Config.getDataDir(), 'queue.jsonl'), failedLines.join('\n') + '\n', 'utf-8');
|
|
83
|
+
}
|
|
84
|
+
logger_1.logger.info('Flusher: complete', { processed, failed });
|
|
85
|
+
return { processed, failed };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.Flusher = Flusher;
|
|
89
|
+
//# sourceMappingURL=flusher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flusher.js","sourceRoot":"","sources":["../flusher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAAkC;AAClC,yCAAsC;AACtC,uCAAyC;AACzC,mCAAgC;AAChC,qCAAkC;AAOlC,MAAa,OAAO;IAGlB;QACE,IAAI,CAAC,MAAM,GAAG,eAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,KAAK,GAAG,IAAI,aAAK,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;QAE7B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QACrC,CAAC;QAED,eAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAE3E,oCAAoC;QACpC,oDAAoD;QACpD,yDAAyD;QACzD,MAAM,QAAQ,GAAG,IAAI,mBAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,sBAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,WAAW,GAAa,EAAE,CAAC;QAEjC,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,KAAK,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,MAAM,EAAE,CAAC;YAC7C,IAAI,CAAC;gBACH,oEAAoE;gBACpE,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,SAAS,IAAI,QAAQ,CAAC;gBACtD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBAClD,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAC5B,SAAS,EAAE,CAAC;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,eAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;gBACtF,0CAA0C;gBAC1C,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;gBAC1D,MAAM,EAAE,CAAC;YACX,CAAC;QACH,CAAC;QAED,oEAAoE;QACpE,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;QAEzB,yDAAyD;QACzD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,EAAE,cAAc,EAAE,GAAG,wDAAa,IAAI,GAAC,CAAC;YAC9C,MAAM,EAAE,IAAI,EAAE,GAAG,wDAAa,MAAM,GAAC,CAAC;YACtC,cAAc,CACZ,IAAI,CAAC,eAAM,CAAC,UAAU,EAAE,EAAE,aAAa,CAAC,EACxC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAC7B,OAAO,CACR,CAAC;QACJ,CAAC;QAED,eAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;QACxD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAC/B,CAAC;CACF;AA3DD,0BA2DC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
interface AuthIds {
|
|
2
|
+
claude: string | null;
|
|
3
|
+
cursor: string | null;
|
|
4
|
+
}
|
|
5
|
+
interface HealthStatus {
|
|
6
|
+
status: 'healthy' | 'degraded' | 'unhealthy';
|
|
7
|
+
checks: {
|
|
8
|
+
posthog: boolean;
|
|
9
|
+
localStorage: boolean;
|
|
10
|
+
cursorHooks: boolean;
|
|
11
|
+
claudeHooks: boolean;
|
|
12
|
+
cron: boolean;
|
|
13
|
+
queueSize: number;
|
|
14
|
+
lastEvent: string | null;
|
|
15
|
+
authIds: AuthIds;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export declare class HealthMonitor {
|
|
19
|
+
private config;
|
|
20
|
+
constructor();
|
|
21
|
+
check(): Promise<HealthStatus>;
|
|
22
|
+
testPostHog(): Promise<boolean>;
|
|
23
|
+
private checkLocalStorage;
|
|
24
|
+
private checkCursorHooksInstalled;
|
|
25
|
+
private checkClaudeHooksInstalled;
|
|
26
|
+
private getLastEventTime;
|
|
27
|
+
private resolveAuthIds;
|
|
28
|
+
private readClaudeId;
|
|
29
|
+
private readCursorId;
|
|
30
|
+
private getCursorDbPath;
|
|
31
|
+
private maskUuid;
|
|
32
|
+
private maskEmail;
|
|
33
|
+
}
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=health-monitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-monitor.d.ts","sourceRoot":"","sources":["../health-monitor.ts"],"names":[],"mappings":"AAUA,UAAU,OAAO;IACf,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;IAC7C,MAAM,EAAE;QACN,OAAO,EAAE,OAAO,CAAC;QACjB,YAAY,EAAE,OAAO,CAAC;QACtB,WAAW,EAAE,OAAO,CAAC;QACrB,WAAW,EAAE,OAAO,CAAC;QACrB,IAAI,EAAE,OAAO,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;;IAMjB,KAAK,IAAI,OAAO,CAAC,YAAY,CAAC;IAuB9B,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;YAavB,iBAAiB;IAU/B,OAAO,CAAC,yBAAyB;IAWjC,OAAO,CAAC,yBAAyB;YAWnB,gBAAgB;IAY9B,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,SAAS;CAOlB"}
|