@snapcommit/cli 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.
Files changed (40) hide show
  1. package/README.md +162 -0
  2. package/dist/ai/anthropic-client.js +92 -0
  3. package/dist/ai/commit-generator.js +200 -0
  4. package/dist/ai/gemini-client.js +201 -0
  5. package/dist/ai/git-interpreter.js +209 -0
  6. package/dist/ai/smart-solver.js +260 -0
  7. package/dist/auth/supabase-client.js +288 -0
  8. package/dist/commands/activate.js +108 -0
  9. package/dist/commands/commit.js +255 -0
  10. package/dist/commands/conflict.js +233 -0
  11. package/dist/commands/doctor.js +113 -0
  12. package/dist/commands/git-advanced.js +311 -0
  13. package/dist/commands/github-auth.js +193 -0
  14. package/dist/commands/login.js +11 -0
  15. package/dist/commands/natural.js +305 -0
  16. package/dist/commands/onboard.js +111 -0
  17. package/dist/commands/quick.js +173 -0
  18. package/dist/commands/setup.js +163 -0
  19. package/dist/commands/stats.js +128 -0
  20. package/dist/commands/uninstall.js +131 -0
  21. package/dist/db/database.js +99 -0
  22. package/dist/index.js +144 -0
  23. package/dist/lib/auth.js +171 -0
  24. package/dist/lib/github.js +280 -0
  25. package/dist/lib/multi-repo.js +276 -0
  26. package/dist/lib/supabase.js +153 -0
  27. package/dist/license/manager.js +203 -0
  28. package/dist/repl/index.js +185 -0
  29. package/dist/repl/interpreter.js +524 -0
  30. package/dist/utils/analytics.js +36 -0
  31. package/dist/utils/auth-storage.js +65 -0
  32. package/dist/utils/dopamine.js +211 -0
  33. package/dist/utils/errors.js +56 -0
  34. package/dist/utils/git.js +105 -0
  35. package/dist/utils/heatmap.js +265 -0
  36. package/dist/utils/rate-limit.js +68 -0
  37. package/dist/utils/retry.js +46 -0
  38. package/dist/utils/ui.js +189 -0
  39. package/dist/utils/version.js +81 -0
  40. package/package.json +69 -0
@@ -0,0 +1,524 @@
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.executeNaturalLanguageCommand = executeNaturalLanguageCommand;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const child_process_1 = require("child_process");
42
+ const git_interpreter_1 = require("../ai/git-interpreter");
43
+ const gemini_client_1 = require("../ai/gemini-client");
44
+ const quick_1 = require("../commands/quick");
45
+ const stats_1 = require("../commands/stats");
46
+ const readline_1 = __importDefault(require("readline"));
47
+ const github = __importStar(require("../lib/github"));
48
+ const gitAdvanced = __importStar(require("../commands/git-advanced"));
49
+ /**
50
+ * Execute a natural language command in the REPL
51
+ */
52
+ async function executeNaturalLanguageCommand(input, context) {
53
+ // Normalize input (handle references like "that", "it", etc.)
54
+ const normalizedInput = normalizeInput(input, context);
55
+ // Check for clarification needs
56
+ const clarification = await (0, gemini_client_1.needsClarificationGemini)(normalizedInput);
57
+ if (clarification.needsClarification && clarification.options) {
58
+ const choice = await askForClarification(clarification.options);
59
+ if (!choice) {
60
+ console.log(chalk_1.default.gray('\n🚫 Cancelled\n'));
61
+ return;
62
+ }
63
+ // Re-execute with clarified intent
64
+ await executeNaturalLanguageCommand(choice, context);
65
+ return;
66
+ }
67
+ // Get Git context
68
+ const gitContext = getGitContext();
69
+ // Pattern matching for common commands (fast path)
70
+ const handled = await tryQuickCommands(normalizedInput, context);
71
+ if (handled) {
72
+ return;
73
+ }
74
+ // AI interpretation
75
+ console.log(chalk_1.default.gray('\n🤖 Understanding your request...\n'));
76
+ try {
77
+ const intent = await (0, git_interpreter_1.interpretGitCommand)(normalizedInput, gitContext);
78
+ // Show what we'll do
79
+ console.log(chalk_1.default.bold(intent.action));
80
+ console.log(chalk_1.default.gray(intent.explanation));
81
+ // Safety warning for high-risk operations
82
+ if (intent.riskLevel === 'high' && intent.safetyWarning) {
83
+ console.log(chalk_1.default.yellow(`\n⚠️ ${intent.safetyWarning}`));
84
+ }
85
+ // Show commands (learning mode)
86
+ if (intent.gitCommands.length > 0) {
87
+ console.log(chalk_1.default.gray(`\n💡 Commands: ${intent.gitCommands.join(' && ')}`));
88
+ }
89
+ // Ask for confirmation for medium/high risk operations
90
+ if (intent.riskLevel === 'medium' || intent.riskLevel === 'high') {
91
+ const confirmed = await askForConfirmation();
92
+ if (!confirmed) {
93
+ console.log(chalk_1.default.gray('\n🚫 Cancelled\n'));
94
+ return;
95
+ }
96
+ }
97
+ // Execute commands
98
+ if (intent.gitCommands.length > 0) {
99
+ console.log('');
100
+ for (const cmd of intent.gitCommands) {
101
+ try {
102
+ console.log(chalk_1.default.gray(` Running: ${cmd}`));
103
+ (0, child_process_1.execSync)(cmd, { stdio: 'inherit' });
104
+ }
105
+ catch (error) {
106
+ console.log(chalk_1.default.red(`\n❌ Command failed: ${cmd}`));
107
+ // Try smart problem solving
108
+ console.log(chalk_1.default.gray('\n🤔 Let me try to fix this...\n'));
109
+ const solution = await (0, gemini_client_1.solveGitProblemGemini)(normalizedInput, {
110
+ currentBranch: gitContext.currentBranch,
111
+ gitStatus: gitContext.gitStatus || '',
112
+ recentError: String(error),
113
+ });
114
+ if (solution.success && solution.gitCommands) {
115
+ console.log(chalk_1.default.cyan(`💡 ${solution.message}\n`));
116
+ for (const fixCmd of solution.gitCommands) {
117
+ console.log(chalk_1.default.gray(` Running: ${fixCmd}`));
118
+ (0, child_process_1.execSync)(fixCmd, { stdio: 'inherit' });
119
+ }
120
+ }
121
+ else {
122
+ console.log(chalk_1.default.red(`\n❌ ${solution.message}\n`));
123
+ return;
124
+ }
125
+ }
126
+ }
127
+ console.log(chalk_1.default.green('\n✅ Done!\n'));
128
+ // Update context
129
+ updateContext(context, intent, normalizedInput);
130
+ }
131
+ else {
132
+ console.log(chalk_1.default.yellow('\n⚠️ No commands to execute\n'));
133
+ }
134
+ }
135
+ catch (error) {
136
+ console.log(chalk_1.default.red(`\n❌ Error: ${error.message}\n`));
137
+ }
138
+ }
139
+ /**
140
+ * Normalize user input (handle "that", "it", etc.)
141
+ */
142
+ function normalizeInput(input, context) {
143
+ let normalized = input;
144
+ // Replace "that" with last context
145
+ if (normalized.includes('that') && context.lastBranch) {
146
+ normalized = normalized.replace(/\bthat\b/gi, context.lastBranch);
147
+ }
148
+ // Replace "it" with last action
149
+ if (normalized.includes('it') && context.lastBranch) {
150
+ normalized = normalized.replace(/\bit\b/gi, context.lastBranch);
151
+ }
152
+ return normalized;
153
+ }
154
+ /**
155
+ * Try to handle common commands quickly (pattern matching)
156
+ */
157
+ async function tryQuickCommands(input, context) {
158
+ const lower = input.toLowerCase();
159
+ // Commit commands
160
+ if (lower === 'commit' ||
161
+ lower === 'commit my changes' ||
162
+ lower === 'commit my work' ||
163
+ lower.startsWith('commit ')) {
164
+ await (0, quick_1.quickCommand)();
165
+ context.lastAction = 'commit';
166
+ return true;
167
+ }
168
+ // Stats commands
169
+ if (lower === 'stats' ||
170
+ lower === 'show me my stats' ||
171
+ lower === 'show stats' ||
172
+ lower === 'show me my progress' ||
173
+ lower === 'show progress') {
174
+ (0, stats_1.statsCommand)();
175
+ return true;
176
+ }
177
+ // Push commands
178
+ if (lower === 'push' || lower === 'push it' || lower === 'push that') {
179
+ try {
180
+ console.log(chalk_1.default.gray('\n📤 Pushing to remote...\n'));
181
+ (0, child_process_1.execSync)('git push', { stdio: 'inherit' });
182
+ console.log(chalk_1.default.green('\n✅ Pushed!\n'));
183
+ context.lastAction = 'push';
184
+ return true;
185
+ }
186
+ catch (error) {
187
+ console.log(chalk_1.default.red('\n❌ Push failed\n'));
188
+ return true;
189
+ }
190
+ }
191
+ // Pull commands
192
+ if (lower === 'pull' || lower === 'pull latest' || lower === 'pull changes') {
193
+ try {
194
+ console.log(chalk_1.default.gray('\n📥 Pulling from remote...\n'));
195
+ (0, child_process_1.execSync)('git pull', { stdio: 'inherit' });
196
+ console.log(chalk_1.default.green('\n✅ Pulled!\n'));
197
+ context.lastAction = 'pull';
198
+ return true;
199
+ }
200
+ catch (error) {
201
+ console.log(chalk_1.default.red('\n❌ Pull failed\n'));
202
+ return true;
203
+ }
204
+ }
205
+ // Status commands
206
+ if (lower === 'status' || lower === 'show status' || lower === 'what changed') {
207
+ try {
208
+ console.log('');
209
+ (0, child_process_1.execSync)('git status', { stdio: 'inherit' });
210
+ console.log('');
211
+ return true;
212
+ }
213
+ catch (error) {
214
+ console.log(chalk_1.default.red('\n❌ Failed to get status\n'));
215
+ return true;
216
+ }
217
+ }
218
+ // GitHub: Create PR
219
+ if (lower === 'create pr' ||
220
+ lower === 'create a pr' ||
221
+ lower === 'make a pr' ||
222
+ lower === 'open pr' ||
223
+ lower === 'create pull request' ||
224
+ lower.includes('create pr')) {
225
+ await handleCreatePR(context);
226
+ return true;
227
+ }
228
+ // GitHub: Check CI
229
+ if (lower === 'check ci' ||
230
+ lower === 'ci status' ||
231
+ lower === 'check status' ||
232
+ lower === 'did ci pass' ||
233
+ lower === 'check if ci passed') {
234
+ await handleCheckCI();
235
+ return true;
236
+ }
237
+ // GitHub: List PRs
238
+ if (lower === 'list prs' ||
239
+ lower === 'show prs' ||
240
+ lower === 'my prs' ||
241
+ lower === 'pull requests') {
242
+ await handleListPRs();
243
+ return true;
244
+ }
245
+ // GitHub: Merge PR
246
+ const mergePRMatch = lower.match(/merge pr (\d+)/);
247
+ if (mergePRMatch) {
248
+ await handleMergePR(parseInt(mergePRMatch[1], 10));
249
+ return true;
250
+ }
251
+ // Git Advanced: Stash
252
+ if (lower === 'stash' ||
253
+ lower === 'stash my changes' ||
254
+ lower === 'stash changes' ||
255
+ lower === 'save my work' ||
256
+ lower.startsWith('stash ')) {
257
+ const messageMatch = input.match(/stash (?:my changes |changes )?(.+)/i);
258
+ await gitAdvanced.stashChanges(messageMatch ? messageMatch[1] : undefined);
259
+ context.lastAction = 'stash';
260
+ return true;
261
+ }
262
+ // Git Advanced: List stash
263
+ if (lower === 'list stash' || lower === 'show stash' || lower === 'stash list') {
264
+ gitAdvanced.listStash();
265
+ return true;
266
+ }
267
+ // Git Advanced: Apply stash
268
+ if (lower === 'apply stash' || lower === 'pop stash' || lower.includes('unstash')) {
269
+ if (lower.includes('pop')) {
270
+ await gitAdvanced.popStash();
271
+ }
272
+ else {
273
+ await gitAdvanced.applyStash();
274
+ }
275
+ context.lastAction = 'apply_stash';
276
+ return true;
277
+ }
278
+ // Git Advanced: Create branch
279
+ const createBranchMatch = input.match(/(?:create|make|new) (?:a )?branch (?:called )?(.+)/i);
280
+ if (createBranchMatch) {
281
+ const branchName = createBranchMatch[1].trim();
282
+ await gitAdvanced.createBranch(branchName);
283
+ context.lastBranch = branchName;
284
+ context.lastAction = 'create_branch';
285
+ return true;
286
+ }
287
+ // Git Advanced: Switch branch
288
+ const switchBranchMatch = input.match(/(?:switch to|checkout|go to) (?:branch )?(.+)/i);
289
+ if (switchBranchMatch && !lower.includes('main') && !lower.includes('master')) {
290
+ const branchName = switchBranchMatch[1].trim();
291
+ await gitAdvanced.switchBranch(branchName);
292
+ context.lastBranch = branchName;
293
+ context.lastAction = 'switch_branch';
294
+ return true;
295
+ }
296
+ // Git Advanced: Merge branch
297
+ const mergeBranchMatch = input.match(/merge (?:branch )?(.+?)(?: into| to)?/i);
298
+ if (mergeBranchMatch && !lower.includes('pr')) {
299
+ const branchName = mergeBranchMatch[1].trim();
300
+ await gitAdvanced.mergeBranch(branchName);
301
+ context.lastAction = 'merge';
302
+ return true;
303
+ }
304
+ // Git Advanced: Delete branch
305
+ const deleteBranchMatch = input.match(/delete (?:branch )?(.+)/i);
306
+ if (deleteBranchMatch) {
307
+ const branchName = deleteBranchMatch[1].trim();
308
+ await gitAdvanced.deleteBranch(branchName);
309
+ context.lastAction = 'delete_branch';
310
+ return true;
311
+ }
312
+ // Git Advanced: Rebase
313
+ const rebaseMatch = input.match(/rebase (?:onto )?(.+)/i);
314
+ if (rebaseMatch) {
315
+ const targetBranch = rebaseMatch[1].trim();
316
+ await gitAdvanced.rebaseOnto(targetBranch);
317
+ context.lastAction = 'rebase';
318
+ return true;
319
+ }
320
+ // Git Advanced: Cherry-pick
321
+ const cherryPickMatch = input.match(/cherry[- ]?pick (.+)/i);
322
+ if (cherryPickMatch) {
323
+ const commitHash = cherryPickMatch[1].trim();
324
+ await gitAdvanced.cherryPick(commitHash);
325
+ context.lastAction = 'cherry_pick';
326
+ return true;
327
+ }
328
+ // Git Advanced: Amend
329
+ if (lower === 'amend' || lower === 'amend commit' || lower === 'fix commit') {
330
+ await gitAdvanced.amendCommit();
331
+ context.lastAction = 'amend';
332
+ return true;
333
+ }
334
+ // Git Advanced: Show log
335
+ if (lower === 'log' ||
336
+ lower === 'show log' ||
337
+ lower === 'history' ||
338
+ lower === 'show history' ||
339
+ lower.includes('last commits')) {
340
+ gitAdvanced.showLog();
341
+ return true;
342
+ }
343
+ // Git Advanced: Show diff
344
+ if (lower === 'diff' || lower === 'show diff' || lower === 'what changed' || lower === 'changes') {
345
+ gitAdvanced.showDiff();
346
+ return true;
347
+ }
348
+ return false;
349
+ }
350
+ /**
351
+ * Handle creating a PR
352
+ */
353
+ async function handleCreatePR(context) {
354
+ try {
355
+ console.log(chalk_1.default.gray('\n🔄 Creating pull request...\n'));
356
+ const pr = await github.createPullRequest({});
357
+ console.log(chalk_1.default.green(`✅ PR #${pr.number} created: ${pr.title}`));
358
+ console.log(chalk_1.default.gray(` URL: ${pr.html_url}\n`));
359
+ context.lastAction = 'create_pr';
360
+ }
361
+ catch (error) {
362
+ console.log(chalk_1.default.red(`\n❌ Failed to create PR: ${error.message}\n`));
363
+ }
364
+ }
365
+ /**
366
+ * Handle checking CI status
367
+ */
368
+ async function handleCheckCI() {
369
+ try {
370
+ console.log(chalk_1.default.gray('\n🔍 Checking CI/CD status...\n'));
371
+ const { status, checks } = await github.getCommitStatus();
372
+ console.log(chalk_1.default.bold('⏳ CI Status:\n'));
373
+ // Show overall status
374
+ if (status.state === 'success') {
375
+ console.log(chalk_1.default.green(` ✅ All checks passed`));
376
+ }
377
+ else if (status.state === 'pending') {
378
+ console.log(chalk_1.default.yellow(` ⏳ Checks running...`));
379
+ }
380
+ else if (status.state === 'failure') {
381
+ console.log(chalk_1.default.red(` ❌ Some checks failed`));
382
+ }
383
+ // Show individual checks
384
+ if (checks.length > 0) {
385
+ console.log('');
386
+ checks.forEach((check) => {
387
+ const icon = check.status === 'completed' && check.conclusion === 'success'
388
+ ? chalk_1.default.green('✅')
389
+ : check.status === 'in_progress'
390
+ ? chalk_1.default.yellow('⏳')
391
+ : chalk_1.default.red('❌');
392
+ console.log(` ${icon} ${check.name}`);
393
+ });
394
+ }
395
+ console.log('');
396
+ }
397
+ catch (error) {
398
+ console.log(chalk_1.default.red(`\n❌ Failed to check CI: ${error.message}\n`));
399
+ }
400
+ }
401
+ /**
402
+ * Handle listing PRs
403
+ */
404
+ async function handleListPRs() {
405
+ try {
406
+ console.log(chalk_1.default.gray('\n🔍 Fetching pull requests...\n'));
407
+ const prs = await github.listPullRequests({ limit: 5 });
408
+ if (prs.length === 0) {
409
+ console.log(chalk_1.default.gray(' No open pull requests\n'));
410
+ return;
411
+ }
412
+ console.log(chalk_1.default.bold('📋 Open Pull Requests:\n'));
413
+ prs.forEach((pr) => {
414
+ console.log(chalk_1.default.cyan(` #${pr.number}`) + ` ${pr.title}`);
415
+ console.log(chalk_1.default.gray(` ${pr.user.login} → ${pr.base.ref}`));
416
+ });
417
+ console.log('');
418
+ }
419
+ catch (error) {
420
+ console.log(chalk_1.default.red(`\n❌ Failed to list PRs: ${error.message}\n`));
421
+ }
422
+ }
423
+ /**
424
+ * Handle merging a PR
425
+ */
426
+ async function handleMergePR(prNumber) {
427
+ try {
428
+ console.log(chalk_1.default.gray(`\n🔄 Merging PR #${prNumber}...\n`));
429
+ const result = await github.mergePullRequest(prNumber);
430
+ console.log(chalk_1.default.green(`✅ PR #${prNumber} merged!`));
431
+ console.log(chalk_1.default.gray(` SHA: ${result.sha}\n`));
432
+ }
433
+ catch (error) {
434
+ console.log(chalk_1.default.red(`\n❌ Failed to merge PR: ${error.message}\n`));
435
+ }
436
+ }
437
+ /**
438
+ * Get current Git context
439
+ */
440
+ function getGitContext() {
441
+ try {
442
+ const currentBranch = (0, child_process_1.execSync)('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8' }).trim();
443
+ const gitStatus = (0, child_process_1.execSync)('git status', { encoding: 'utf-8' }).trim();
444
+ const hasUncommittedChanges = gitStatus.includes('Changes not staged') || gitStatus.includes('Changes to be committed');
445
+ let lastCommitHash;
446
+ try {
447
+ lastCommitHash = (0, child_process_1.execSync)('git rev-parse HEAD', { encoding: 'utf-8' }).trim();
448
+ }
449
+ catch {
450
+ lastCommitHash = undefined;
451
+ }
452
+ return {
453
+ currentBranch,
454
+ hasUncommittedChanges,
455
+ lastCommitHash,
456
+ gitStatus,
457
+ };
458
+ }
459
+ catch (error) {
460
+ return {
461
+ currentBranch: 'unknown',
462
+ hasUncommittedChanges: false,
463
+ gitStatus: '',
464
+ };
465
+ }
466
+ }
467
+ /**
468
+ * Ask user for confirmation
469
+ */
470
+ async function askForConfirmation() {
471
+ return new Promise((resolve) => {
472
+ const rl = readline_1.default.createInterface({
473
+ input: process.stdin,
474
+ output: process.stdout,
475
+ });
476
+ rl.question(chalk_1.default.cyan('\nContinue? (y/N): '), (answer) => {
477
+ rl.close();
478
+ resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
479
+ });
480
+ });
481
+ }
482
+ /**
483
+ * Ask user for clarification
484
+ */
485
+ async function askForClarification(options) {
486
+ return new Promise((resolve) => {
487
+ console.log(chalk_1.default.yellow('\n🤔 I need clarification:\n'));
488
+ options.forEach((opt, i) => {
489
+ console.log(chalk_1.default.cyan(` ${i + 1}) ${opt.label}`));
490
+ });
491
+ console.log('');
492
+ const rl = readline_1.default.createInterface({
493
+ input: process.stdin,
494
+ output: process.stdout,
495
+ });
496
+ rl.question(chalk_1.default.cyan('Choose (1-' + options.length + ') or (c)ancel: '), (answer) => {
497
+ rl.close();
498
+ if (answer.toLowerCase() === 'c' || answer.toLowerCase() === 'cancel') {
499
+ resolve(null);
500
+ return;
501
+ }
502
+ const choice = parseInt(answer, 10);
503
+ if (choice >= 1 && choice <= options.length) {
504
+ resolve(options[choice - 1].value);
505
+ }
506
+ else {
507
+ console.log(chalk_1.default.red('\n❌ Invalid choice\n'));
508
+ resolve(null);
509
+ }
510
+ });
511
+ });
512
+ }
513
+ /**
514
+ * Update context after successful command
515
+ */
516
+ function updateContext(context, intent, input) {
517
+ // Extract branch names from commands
518
+ const branchMatch = intent.gitCommands.join(' ').match(/(?:checkout|branch|switch) (\S+)/);
519
+ if (branchMatch) {
520
+ context.lastBranch = branchMatch[1];
521
+ }
522
+ // Store last action
523
+ context.lastAction = intent.action;
524
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ /**
3
+ * Privacy-focused analytics tracking
4
+ * Stores locally for insights, no external tracking
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.EVENTS = void 0;
8
+ exports.trackEvent = trackEvent;
9
+ const database_1 = require("../db/database");
10
+ /**
11
+ * Track an event (privacy-friendly, local only)
12
+ */
13
+ function trackEvent(eventData) {
14
+ try {
15
+ (0, database_1.logAnalyticsEvent)(eventData.event, eventData.data || {});
16
+ }
17
+ catch (error) {
18
+ // Silent fail - don't break user experience for analytics
19
+ }
20
+ }
21
+ /**
22
+ * Get common event types (for consistency)
23
+ */
24
+ exports.EVENTS = {
25
+ COMMIT_SUCCESS: 'commit_success',
26
+ COMMIT_ERROR: 'commit_error',
27
+ COMMIT_BLOCKED: 'commit_blocked',
28
+ RATE_LIMITED: 'rate_limited',
29
+ TRIAL_STARTED: 'trial_started',
30
+ PRO_ACTIVATED: 'pro_activated',
31
+ NATURAL_COMMAND_SUCCESS: 'natural_command_success',
32
+ NATURAL_COMMAND_ERROR: 'natural_command_error',
33
+ CONFLICT_RESOLVED: 'conflict_resolved',
34
+ ONBOARDING_COMPLETED: 'onboarding_completed',
35
+ SETUP_COMPLETED: 'setup_completed',
36
+ };
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ /**
3
+ * Auth token storage utilities
4
+ * Stores Supabase auth tokens securely in local database
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.saveAuthToken = saveAuthToken;
11
+ exports.getAuthToken = getAuthToken;
12
+ exports.clearAuthToken = clearAuthToken;
13
+ const database_1 = require("../db/database");
14
+ const chalk_1 = __importDefault(require("chalk"));
15
+ /**
16
+ * Save auth tokens to local database
17
+ */
18
+ async function saveAuthToken(accessToken, refreshToken) {
19
+ try {
20
+ const db = (0, database_1.getDB)();
21
+ db.prepare(`
22
+ INSERT OR REPLACE INTO auth_tokens (id, access_token, refresh_token, updated_at)
23
+ VALUES (1, ?, ?, ?)
24
+ `).run(accessToken, refreshToken || null, Date.now());
25
+ return true;
26
+ }
27
+ catch (error) {
28
+ console.error(chalk_1.default.red('Failed to save auth token:'), error.message);
29
+ return false;
30
+ }
31
+ }
32
+ /**
33
+ * Get auth tokens from local database
34
+ */
35
+ function getAuthToken() {
36
+ try {
37
+ const db = (0, database_1.getDB)();
38
+ const row = db.prepare(`
39
+ SELECT access_token, refresh_token FROM auth_tokens WHERE id = 1
40
+ `).get();
41
+ if (!row)
42
+ return null;
43
+ return {
44
+ accessToken: row.access_token,
45
+ refreshToken: row.refresh_token || undefined,
46
+ };
47
+ }
48
+ catch (error) {
49
+ return null;
50
+ }
51
+ }
52
+ /**
53
+ * Clear auth tokens from local database
54
+ */
55
+ async function clearAuthToken() {
56
+ try {
57
+ const db = (0, database_1.getDB)();
58
+ db.prepare('DELETE FROM auth_tokens').run();
59
+ return true;
60
+ }
61
+ catch (error) {
62
+ console.error(chalk_1.default.red('Failed to clear auth token:'), error.message);
63
+ return false;
64
+ }
65
+ }