progga 1.0.6 → 1.0.7

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 (3) hide show
  1. package/index.js +65 -0
  2. package/package.json +4 -2
  3. package/telemetry.js +122 -0
package/index.js CHANGED
@@ -11,6 +11,49 @@ const ProfileRegistry = require('./profiles/ProfileRegistry');
11
11
  const ProjectTypeDetector = require('./core/ProjectTypeDetector');
12
12
  const PresetSelector = require('./core/PresetSelector');
13
13
  const Spinner = require('./core/Spinner');
14
+ const { capture, maybeShowTelemetryNotice } = require('./telemetry');
15
+ const os = require('os');
16
+
17
+ function handleTelemetryCommand(args) {
18
+ if (args[0] !== 'telemetry') return false;
19
+
20
+ const action = args[1];
21
+ const configPath = path.join(os.homedir(), '.progga', 'config.json');
22
+
23
+ let config = {};
24
+ try {
25
+ if (fs.existsSync(configPath)) {
26
+ config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
27
+ }
28
+ } catch { }
29
+
30
+ if (action === 'on') {
31
+ config.telemetry = true;
32
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
33
+ console.log('āœ… Telemetry enabled');
34
+ return true;
35
+ }
36
+
37
+ if (action === 'off') {
38
+ config.telemetry = false;
39
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
40
+ console.log('🚫 Telemetry disabled');
41
+ return true;
42
+ }
43
+
44
+ if (action === 'status') {
45
+ const enabled = config.telemetry !== false;
46
+ console.log(
47
+ enabled
48
+ ? 'šŸ“Š Telemetry is enabled'
49
+ : '🚫 Telemetry is disabled'
50
+ );
51
+ return true;
52
+ }
53
+
54
+ console.log('Usage: progga telemetry [on|off|status]');
55
+ return true;
56
+ }
14
57
 
15
58
 
16
59
  const CLI_IGNORE_PATHS = new Set();
@@ -305,6 +348,10 @@ function generateDocumentation(projectPath, outputFile, profile) {
305
348
  // Write to file
306
349
  fs.writeFileSync(outputFile, output, 'utf-8');
307
350
 
351
+ capture('generation_completed', {
352
+ files_processed: files.length,
353
+ });
354
+
308
355
  console.log(`\nāœ… Documentation generated successfully: ${outputFile}`);
309
356
  console.log(`šŸ“Š Total files processed: ${files.length}`);
310
357
  }
@@ -313,6 +360,19 @@ function generateDocumentation(projectPath, outputFile, profile) {
313
360
  async function main() {
314
361
  let cliIgnores = [];
315
362
  const args = process.argv.slice(2);
363
+ if (handleTelemetryCommand(args)) {
364
+ return; // šŸ”„ EXIT EARLY
365
+ }
366
+
367
+ maybeShowTelemetryNotice();
368
+
369
+ capture('cli_run', {
370
+ args_count: args.length,
371
+ used_ignore_flag: args.includes('--ignore') || args.includes('-i'),
372
+ used_preset: args.includes('--preset'),
373
+ is_tty: process.stdin.isTTY,
374
+ });
375
+
316
376
 
317
377
  let projectPath = '.';
318
378
  let outputFile = 'PROJECT_DOCUMENTATION.md';
@@ -367,7 +427,12 @@ async function main() {
367
427
  console.log(`🚫 CLI ignores applied: ${cliIgnores.join(', ')}`);
368
428
  }
369
429
 
430
+ capture('profile_selected', {
431
+ profile: profile.name,
432
+ });
433
+
370
434
  console.log(`Using profile: ${profile.name}`);
435
+
371
436
  generateDocumentation(projectPath, outputFile, profile);
372
437
 
373
438
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "progga",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Generate comprehensive project documentation for AI assistants - Share your entire codebase context in one markdown file",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -40,7 +40,9 @@
40
40
  "homepage": "https://github.com/Yousuf-Basir/progga#readme",
41
41
  "dependencies": {
42
42
  "@inquirer/select": "^5.0.4",
43
+ "dotenv": "^17.2.3",
43
44
  "inquirer": "^13.2.0",
44
- "ora": "^9.0.0"
45
+ "ora": "^9.0.0",
46
+ "posthog-node": "^5.20.0"
45
47
  }
46
48
  }
package/telemetry.js ADDED
@@ -0,0 +1,122 @@
1
+ require('dotenv').config();
2
+ const os = require('os')
3
+ const fs = require('fs')
4
+ const path = require('path')
5
+ const { PostHog } = require('posthog-node')
6
+ const pkg = require('./package.json')
7
+
8
+ const POSTHOG_KEY = process.env.POSTHOG_KEY;
9
+ const POSTHOG_HOST = process.env.POSTHOG_HOST || 'https://us.i.posthog.com';
10
+
11
+ const CONFIG_DIR = path.join(os.homedir(), '.progga')
12
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json')
13
+
14
+ let client = null;
15
+
16
+ if (POSTHOG_KEY) {
17
+ client = new PostHog(POSTHOG_KEY, {
18
+ host: POSTHOG_HOST,
19
+ flushAt: 1,
20
+ flushInterval: 0
21
+ });
22
+ }
23
+
24
+ function getConfig() {
25
+ try {
26
+ if (!fs.existsSync(CONFIG_DIR)) {
27
+ fs.mkdirSync(CONFIG_DIR);
28
+ }
29
+
30
+ if (fs.existsSync(CONFIG_FILE)) {
31
+ return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
32
+ }
33
+ } catch { }
34
+
35
+ return {};
36
+ }
37
+
38
+ function saveConfig(config) {
39
+ try {
40
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
41
+ } catch { }
42
+ }
43
+
44
+
45
+ function getOrCreateUserId() {
46
+ try {
47
+ if (!fs.existsSync(CONFIG_DIR)) {
48
+ fs.mkdirSync(CONFIG_DIR)
49
+ }
50
+
51
+ if (fs.existsSync(CONFIG_FILE)) {
52
+ const data = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'))
53
+ if (data.userId) return data.userId
54
+ }
55
+
56
+ const userId = cryptoRandomId()
57
+ saveConfig({ userId });
58
+
59
+ return userId
60
+ } catch {
61
+ return null
62
+ }
63
+ }
64
+
65
+ function isTelemetryEnabled() {
66
+ const config = getConfig();
67
+ return config.telemetry !== false; // default ON
68
+ }
69
+
70
+ function cryptoRandomId() {
71
+ return require('crypto').randomUUID()
72
+ }
73
+
74
+ function capture(event, properties = {}) {
75
+ if (!client) return;
76
+ if (!isTelemetryEnabled()) return;
77
+
78
+ const distinctId = getOrCreateUserId();
79
+ if (!distinctId) return;
80
+
81
+ client.capture({
82
+ distinctId,
83
+ event,
84
+ properties: {
85
+ tool: 'progga',
86
+ version: pkg.version,
87
+ os: os.platform(),
88
+ node: process.version,
89
+ ...properties,
90
+ },
91
+ });
92
+
93
+ client.flush().catch(() => { });
94
+ }
95
+
96
+ function maybeShowTelemetryNotice() {
97
+ if (!process.stdin.isTTY) return;
98
+
99
+ const config = getConfig();
100
+
101
+ if (config.telemetry_notice_shown) return;
102
+
103
+ console.log('');
104
+ console.log('ℹ Progga collects anonymous usage data to improve the tool.');
105
+ console.log(' No project files, paths, or code are ever collected.');
106
+ console.log('');
107
+ console.log(' You can disable telemetry anytime with:');
108
+ console.log(' progga telemetry off');
109
+ console.log('');
110
+
111
+ saveConfig({
112
+ ...config,
113
+ telemetry_notice_shown: true,
114
+ });
115
+ }
116
+
117
+
118
+ process.on('exit', () => {
119
+ client.shutdown()
120
+ })
121
+
122
+ module.exports = { capture, maybeShowTelemetryNotice }