@code-insights/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 (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +287 -0
  3. package/dist/commands/connect.d.ts +8 -0
  4. package/dist/commands/connect.d.ts.map +1 -0
  5. package/dist/commands/connect.js +33 -0
  6. package/dist/commands/connect.js.map +1 -0
  7. package/dist/commands/init.d.ts +9 -0
  8. package/dist/commands/init.d.ts.map +1 -0
  9. package/dist/commands/init.js +176 -0
  10. package/dist/commands/init.js.map +1 -0
  11. package/dist/commands/insights.d.ts +13 -0
  12. package/dist/commands/insights.d.ts.map +1 -0
  13. package/dist/commands/insights.js +87 -0
  14. package/dist/commands/insights.js.map +1 -0
  15. package/dist/commands/install-hook.d.ts +9 -0
  16. package/dist/commands/install-hook.d.ts.map +1 -0
  17. package/dist/commands/install-hook.js +98 -0
  18. package/dist/commands/install-hook.js.map +1 -0
  19. package/dist/commands/link.d.ts +8 -0
  20. package/dist/commands/link.d.ts.map +1 -0
  21. package/dist/commands/link.js +39 -0
  22. package/dist/commands/link.js.map +1 -0
  23. package/dist/commands/reset.d.ts +3 -0
  24. package/dist/commands/reset.d.ts.map +1 -0
  25. package/dist/commands/reset.js +95 -0
  26. package/dist/commands/reset.js.map +1 -0
  27. package/dist/commands/status.d.ts +5 -0
  28. package/dist/commands/status.d.ts.map +1 -0
  29. package/dist/commands/status.js +107 -0
  30. package/dist/commands/status.js.map +1 -0
  31. package/dist/commands/sync.d.ts +13 -0
  32. package/dist/commands/sync.d.ts.map +1 -0
  33. package/dist/commands/sync.js +205 -0
  34. package/dist/commands/sync.js.map +1 -0
  35. package/dist/firebase/client.d.ts +35 -0
  36. package/dist/firebase/client.d.ts.map +1 -0
  37. package/dist/firebase/client.js +317 -0
  38. package/dist/firebase/client.js.map +1 -0
  39. package/dist/index.d.ts +3 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +48 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/parser/insights.d.ts +7 -0
  44. package/dist/parser/insights.d.ts.map +1 -0
  45. package/dist/parser/insights.js +271 -0
  46. package/dist/parser/insights.js.map +1 -0
  47. package/dist/parser/jsonl.d.ts +6 -0
  48. package/dist/parser/jsonl.d.ts.map +1 -0
  49. package/dist/parser/jsonl.js +305 -0
  50. package/dist/parser/jsonl.js.map +1 -0
  51. package/dist/parser/titles.d.ts +14 -0
  52. package/dist/parser/titles.d.ts.map +1 -0
  53. package/dist/parser/titles.js +258 -0
  54. package/dist/parser/titles.js.map +1 -0
  55. package/dist/types.d.ts +216 -0
  56. package/dist/types.d.ts.map +1 -0
  57. package/dist/types.js +3 -0
  58. package/dist/types.js.map +1 -0
  59. package/dist/utils/config.d.ts +46 -0
  60. package/dist/utils/config.d.ts.map +1 -0
  61. package/dist/utils/config.js +106 -0
  62. package/dist/utils/config.js.map +1 -0
  63. package/dist/utils/device.d.ts +32 -0
  64. package/dist/utils/device.d.ts.map +1 -0
  65. package/dist/utils/device.js +132 -0
  66. package/dist/utils/device.js.map +1 -0
  67. package/dist/utils/firebase-json.d.ts +87 -0
  68. package/dist/utils/firebase-json.d.ts.map +1 -0
  69. package/dist/utils/firebase-json.js +206 -0
  70. package/dist/utils/firebase-json.js.map +1 -0
  71. package/dist/utils/pricing.d.ts +29 -0
  72. package/dist/utils/pricing.d.ts.map +1 -0
  73. package/dist/utils/pricing.js +66 -0
  74. package/dist/utils/pricing.js.map +1 -0
  75. package/package.json +56 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insights.js","sourceRoot":"","sources":["../../src/commands/insights.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Install Claude Code hook for auto-sync
3
+ */
4
+ export declare function installHookCommand(): Promise<void>;
5
+ /**
6
+ * Uninstall Claude Code hook
7
+ */
8
+ export declare function uninstallHookCommand(): Promise<void>;
9
+ //# sourceMappingURL=install-hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-hook.d.ts","sourceRoot":"","sources":["../../src/commands/install-hook.ts"],"names":[],"mappings":"AA4BA;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CA6DxD;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAqC1D"}
@@ -0,0 +1,98 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ import chalk from 'chalk';
5
+ import { isConfigured } from '../utils/config.js';
6
+ const CLAUDE_SETTINGS_DIR = path.join(os.homedir(), '.claude');
7
+ const HOOKS_FILE = path.join(CLAUDE_SETTINGS_DIR, 'settings.json');
8
+ /** Extract command string from both old (string) and new ({type, command}) hook formats */
9
+ function getHookCommand(hook) {
10
+ return typeof hook === 'string' ? hook : hook.command;
11
+ }
12
+ /**
13
+ * Install Claude Code hook for auto-sync
14
+ */
15
+ export async function installHookCommand() {
16
+ console.log(chalk.cyan('\nšŸ”— Install Code Insights Hook\n'));
17
+ // Check if configured
18
+ if (!isConfigured()) {
19
+ console.log(chalk.red('Not configured. Run `code-insights init` first.'));
20
+ process.exit(1);
21
+ }
22
+ // Get CLI path
23
+ const cliPath = process.argv[1];
24
+ const syncCommand = `node ${cliPath} sync -q`;
25
+ console.log(chalk.gray('This will add a Claude Code hook that syncs sessions automatically.'));
26
+ console.log(chalk.gray(`Hook command: ${syncCommand}\n`));
27
+ // Load existing settings
28
+ let settings = {};
29
+ if (fs.existsSync(HOOKS_FILE)) {
30
+ try {
31
+ const content = fs.readFileSync(HOOKS_FILE, 'utf-8');
32
+ settings = JSON.parse(content);
33
+ }
34
+ catch {
35
+ console.log(chalk.yellow('Could not parse existing settings.json, creating new one.'));
36
+ }
37
+ }
38
+ // Initialize hooks structure
39
+ if (!settings.hooks) {
40
+ settings.hooks = {};
41
+ }
42
+ // Add Stop hook (runs when Claude finishes responding)
43
+ const stopHook = {
44
+ hooks: [{ type: 'command', command: syncCommand }],
45
+ };
46
+ // Check if hook already exists
47
+ const existingStopHooks = settings.hooks.Stop || [];
48
+ const hookExists = existingStopHooks.some((h) => h.hooks.some((hook) => getHookCommand(hook).includes('code-insights')));
49
+ if (hookExists) {
50
+ console.log(chalk.yellow('Code Insights hook already installed.'));
51
+ console.log(chalk.gray('To reinstall, first run `code-insights uninstall-hook`'));
52
+ return;
53
+ }
54
+ settings.hooks.Stop = [...existingStopHooks, stopHook];
55
+ // Write settings
56
+ fs.mkdirSync(CLAUDE_SETTINGS_DIR, { recursive: true });
57
+ fs.writeFileSync(HOOKS_FILE, JSON.stringify(settings, null, 2));
58
+ console.log(chalk.green('āœ… Hook installed successfully!'));
59
+ console.log(chalk.gray(`\nConfiguration saved to: ${HOOKS_FILE}`));
60
+ console.log(chalk.cyan('\nHow it works:'));
61
+ console.log(chalk.white(' • When a Claude Code session ends, the hook runs'));
62
+ console.log(chalk.white(' • Sessions are automatically synced to your Firestore'));
63
+ console.log(chalk.white(' • Check your dashboard for new insights'));
64
+ }
65
+ /**
66
+ * Uninstall Claude Code hook
67
+ */
68
+ export async function uninstallHookCommand() {
69
+ console.log(chalk.cyan('\nšŸ”— Uninstall Code Insights Hook\n'));
70
+ if (!fs.existsSync(HOOKS_FILE)) {
71
+ console.log(chalk.yellow('No hooks file found. Nothing to uninstall.'));
72
+ return;
73
+ }
74
+ try {
75
+ const content = fs.readFileSync(HOOKS_FILE, 'utf-8');
76
+ const settings = JSON.parse(content);
77
+ if (!settings.hooks?.Stop) {
78
+ console.log(chalk.yellow('No Stop hooks found. Nothing to uninstall.'));
79
+ return;
80
+ }
81
+ // Filter out Code Insights hooks
82
+ settings.hooks.Stop = settings.hooks.Stop.filter((h) => !h.hooks.some((hook) => getHookCommand(hook).includes('code-insights')));
83
+ // Clean up empty arrays
84
+ if (settings.hooks.Stop.length === 0) {
85
+ delete settings.hooks.Stop;
86
+ }
87
+ if (Object.keys(settings.hooks).length === 0) {
88
+ delete settings.hooks;
89
+ }
90
+ fs.writeFileSync(HOOKS_FILE, JSON.stringify(settings, null, 2));
91
+ console.log(chalk.green('āœ… Hook uninstalled successfully!'));
92
+ }
93
+ catch (error) {
94
+ console.log(chalk.red('Failed to uninstall hook:'));
95
+ console.error(error instanceof Error ? error.message : 'Unknown error');
96
+ }
97
+ }
98
+ //# sourceMappingURL=install-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-hook.js","sourceRoot":"","sources":["../../src/commands/install-hook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export interface LinkOptions {
2
+ qr?: boolean;
3
+ }
4
+ /**
5
+ * Generate and display dashboard link
6
+ */
7
+ export declare function linkCommand(options: LinkOptions): Promise<void>;
8
+ //# sourceMappingURL=link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCrE"}
@@ -0,0 +1,39 @@
1
+ import chalk from 'chalk';
2
+ import qrcode from 'qrcode-terminal';
3
+ import { isConfigured, loadWebConfig, hasWebConfig } from '../utils/config.js';
4
+ import { generateDashboardUrl, validateWebConfig } from '../utils/firebase-json.js';
5
+ /**
6
+ * Generate and display dashboard link
7
+ */
8
+ export async function linkCommand(options) {
9
+ if (!isConfigured()) {
10
+ console.log(chalk.red('\nāŒ Code Insights is not configured.'));
11
+ console.log(chalk.gray('Run "code-insights init" first.\n'));
12
+ return;
13
+ }
14
+ if (!hasWebConfig()) {
15
+ console.log(chalk.yellow('\n⚠ No web config found.'));
16
+ console.log(chalk.gray('\nTo generate a dashboard link, add web config:'));
17
+ console.log(chalk.white(' code-insights init --web-config <path-to-config.json>\n'));
18
+ console.log(chalk.gray('Or visit the dashboard and configure Firebase manually:'));
19
+ console.log(chalk.white(' https://code-insights.app\n'));
20
+ return;
21
+ }
22
+ const webConfigData = loadWebConfig();
23
+ if (!webConfigData || !validateWebConfig(webConfigData)) {
24
+ console.log(chalk.red('\nāŒ Invalid web config stored.'));
25
+ console.log(chalk.gray('Run "code-insights init --web-config <path>" to reconfigure.\n'));
26
+ return;
27
+ }
28
+ const webConfig = webConfigData;
29
+ const url = generateDashboardUrl(webConfig);
30
+ console.log(chalk.cyan('\nšŸ”— Dashboard Link\n'));
31
+ console.log(chalk.white('Open this URL to connect the dashboard:'));
32
+ console.log(chalk.bold.underline(url));
33
+ if (options.qr !== false) {
34
+ console.log(chalk.gray('\nšŸ“± QR Code:\n'));
35
+ qrcode.generate(url, { small: true });
36
+ }
37
+ console.log('');
38
+ }
39
+ //# sourceMappingURL=link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link.js","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAOpF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAoB;IACpD,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IAED,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC,CAAC;QAC3E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC,CAAC;QACtF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC,CAAC;QACnF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;QAC1D,OAAO;IACT,CAAC;IAED,MAAM,aAAa,GAAG,aAAa,EAAE,CAAC;IACtC,IAAI,CAAC,aAAa,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,EAAE,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC,CAAC;QAC1F,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,aAAkC,CAAC;IACrD,MAAM,GAAG,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAE5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAEvC,IAAI,OAAO,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const resetCommand: Command;
3
+ //# sourceMappingURL=reset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../../src/commands/reset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,eAAO,MAAM,YAAY,SA2ErB,CAAC"}
@@ -0,0 +1,95 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import ora from 'ora';
4
+ import admin from 'firebase-admin';
5
+ import { existsSync, unlinkSync } from 'fs';
6
+ import { join } from 'path';
7
+ import { loadConfig } from '../utils/config.js';
8
+ const SYNC_STATE_FILE = join(process.env.HOME || '~', '.code-insights', 'sync-state.json');
9
+ export const resetCommand = new Command('reset')
10
+ .description('Delete all data from Firestore and reset local sync state')
11
+ .option('--confirm', 'Skip confirmation prompt')
12
+ .action(async (options) => {
13
+ console.log(chalk.red.bold('\nāš ļø WARNING: This will permanently delete ALL data from your Firestore database!'));
14
+ console.log(chalk.yellow('Collections to be deleted: projects, sessions, insights, messages\n'));
15
+ if (!options.confirm) {
16
+ // Simple confirmation using stdin
17
+ const readline = await import('readline');
18
+ const rl = readline.createInterface({
19
+ input: process.stdin,
20
+ output: process.stdout,
21
+ });
22
+ const answer = await new Promise((resolve) => {
23
+ rl.question(chalk.cyan('Type "DELETE" to confirm: '), resolve);
24
+ });
25
+ rl.close();
26
+ if (answer !== 'DELETE') {
27
+ console.log(chalk.gray('\nAborted. No data was deleted.'));
28
+ process.exit(0);
29
+ }
30
+ }
31
+ // Load config
32
+ const config = loadConfig();
33
+ if (!config) {
34
+ console.error(chalk.red('Error: Not configured. Run `code-insights init` first.'));
35
+ process.exit(1);
36
+ }
37
+ // Initialize Firebase
38
+ if (admin.apps.length === 0) {
39
+ admin.initializeApp({
40
+ credential: admin.credential.cert({
41
+ projectId: config.firebase.projectId,
42
+ clientEmail: config.firebase.clientEmail,
43
+ privateKey: config.firebase.privateKey.replace(/\\n/g, '\n'),
44
+ }),
45
+ });
46
+ }
47
+ const db = admin.firestore();
48
+ const collections = ['projects', 'sessions', 'insights', 'messages'];
49
+ console.log('');
50
+ for (const collectionName of collections) {
51
+ const spinner = ora(`Deleting ${collectionName}...`).start();
52
+ try {
53
+ const deleted = await deleteCollection(db, collectionName);
54
+ spinner.succeed(`Deleted ${deleted} documents from ${collectionName}`);
55
+ }
56
+ catch (error) {
57
+ spinner.fail(`Failed to delete ${collectionName}: ${error}`);
58
+ }
59
+ }
60
+ // Delete local sync state
61
+ const syncSpinner = ora('Removing local sync state...').start();
62
+ try {
63
+ if (existsSync(SYNC_STATE_FILE)) {
64
+ unlinkSync(SYNC_STATE_FILE);
65
+ syncSpinner.succeed('Removed local sync state');
66
+ }
67
+ else {
68
+ syncSpinner.info('No local sync state file found');
69
+ }
70
+ }
71
+ catch (error) {
72
+ syncSpinner.fail(`Failed to remove sync state: ${error}`);
73
+ }
74
+ console.log(chalk.green('\nāœ“ Reset complete. Run `code-insights sync` to re-sync all sessions.\n'));
75
+ process.exit(0);
76
+ });
77
+ async function deleteCollection(db, collectionName) {
78
+ const collectionRef = db.collection(collectionName);
79
+ const batchSize = 500;
80
+ let totalDeleted = 0;
81
+ while (true) {
82
+ const snapshot = await collectionRef.limit(batchSize).get();
83
+ if (snapshot.empty) {
84
+ break;
85
+ }
86
+ const batch = db.batch();
87
+ snapshot.docs.forEach((doc) => {
88
+ batch.delete(doc.ref);
89
+ });
90
+ await batch.commit();
91
+ totalDeleted += snapshot.size;
92
+ }
93
+ return totalDeleted;
94
+ }
95
+ //# sourceMappingURL=reset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.js","sourceRoot":"","sources":["../../src/commands/reset.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Show Code Insights status
3
+ */
4
+ export declare function statusCommand(): Promise<void>;
5
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAkFnD"}
@@ -0,0 +1,107 @@
1
+ import chalk from 'chalk';
2
+ import { loadConfig, loadSyncState, isConfigured, getConfigDir, getClaudeDir, hasWebConfig, loadWebConfig } from '../utils/config.js';
3
+ import { initializeFirebase, getProjects } from '../firebase/client.js';
4
+ import * as fs from 'fs';
5
+ /**
6
+ * Show Code Insights status
7
+ */
8
+ export async function statusCommand() {
9
+ console.log(chalk.cyan('\nšŸ“Š Code Insights Status\n'));
10
+ // Check configuration
11
+ console.log(chalk.white('Configuration:'));
12
+ if (isConfigured()) {
13
+ console.log(chalk.green(` āœ“ Configured at ${getConfigDir()}`));
14
+ const config = loadConfig();
15
+ if (config) {
16
+ console.log(chalk.gray(` Project: ${config.firebase.projectId}`));
17
+ }
18
+ }
19
+ else {
20
+ console.log(chalk.red(' āœ— Not configured'));
21
+ console.log(chalk.gray(' Run `code-insights init` to set up'));
22
+ return;
23
+ }
24
+ // Check Claude directory
25
+ console.log(chalk.white('\nClaude Code:'));
26
+ const claudeDir = getClaudeDir();
27
+ if (fs.existsSync(claudeDir)) {
28
+ const projectDirs = fs.readdirSync(claudeDir).filter((d) => !d.startsWith('.'));
29
+ const sessionCount = countJsonlFiles(claudeDir);
30
+ console.log(chalk.green(` āœ“ Found at ${claudeDir}`));
31
+ console.log(chalk.gray(` ${projectDirs.length} projects, ${sessionCount} sessions`));
32
+ }
33
+ else {
34
+ console.log(chalk.yellow(` ⚠ Not found at ${claudeDir}`));
35
+ }
36
+ // Check sync state
37
+ console.log(chalk.white('\nSync State:'));
38
+ const syncState = loadSyncState();
39
+ if (syncState.lastSync) {
40
+ const lastSync = new Date(syncState.lastSync);
41
+ const syncedFiles = Object.keys(syncState.files).length;
42
+ console.log(chalk.green(` āœ“ Last sync: ${lastSync.toLocaleString()}`));
43
+ console.log(chalk.gray(` ${syncedFiles} files tracked`));
44
+ }
45
+ else {
46
+ console.log(chalk.yellow(' ⚠ Never synced'));
47
+ console.log(chalk.gray(' Run `code-insights sync` to sync'));
48
+ }
49
+ // Check Firebase connection
50
+ console.log(chalk.white('\nFirebase:'));
51
+ const config = loadConfig();
52
+ if (config) {
53
+ try {
54
+ initializeFirebase(config);
55
+ const projects = await getProjects();
56
+ console.log(chalk.green(' āœ“ Connected'));
57
+ console.log(chalk.gray(` ${projects.length} projects in Firestore`));
58
+ if (projects.length > 0) {
59
+ console.log(chalk.white('\nSynced Projects:'));
60
+ for (const project of projects.slice(0, 5)) {
61
+ console.log(chalk.gray(` ${project.name} (${project.sessionCount} sessions)`));
62
+ }
63
+ if (projects.length > 5) {
64
+ console.log(chalk.gray(` ... and ${projects.length - 5} more`));
65
+ }
66
+ }
67
+ }
68
+ catch (error) {
69
+ console.log(chalk.red(' āœ— Connection failed'));
70
+ console.log(chalk.gray(` ${error instanceof Error ? error.message : 'Unknown error'}`));
71
+ }
72
+ }
73
+ // Check web dashboard config
74
+ console.log(chalk.white('\nWeb Dashboard:'));
75
+ if (hasWebConfig()) {
76
+ const webConfig = loadWebConfig();
77
+ console.log(chalk.green(' āœ“ Configured'));
78
+ if (webConfig && typeof webConfig.projectId === 'string') {
79
+ console.log(chalk.gray(` Project: ${webConfig.projectId}`));
80
+ }
81
+ console.log(chalk.gray(' Run "code-insights connect" to get dashboard URL'));
82
+ }
83
+ else {
84
+ console.log(chalk.yellow(' ā—‹ Not configured'));
85
+ console.log(chalk.gray(' Run "code-insights init" to configure'));
86
+ }
87
+ console.log('');
88
+ }
89
+ /**
90
+ * Count JSONL files in Claude directory
91
+ */
92
+ function countJsonlFiles(baseDir) {
93
+ let count = 0;
94
+ const dirs = fs.readdirSync(baseDir);
95
+ for (const dir of dirs) {
96
+ if (dir.startsWith('.'))
97
+ continue;
98
+ const projectPath = `${baseDir}/${dir}`;
99
+ const stat = fs.statSync(projectPath);
100
+ if (!stat.isDirectory())
101
+ continue;
102
+ const files = fs.readdirSync(projectPath);
103
+ count += files.filter((f) => f.endsWith('.jsonl')).length;
104
+ }
105
+ return count;
106
+ }
107
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ interface SyncOptions {
2
+ force?: boolean;
3
+ project?: string;
4
+ dryRun?: boolean;
5
+ quiet?: boolean;
6
+ regenerateTitles?: boolean;
7
+ }
8
+ /**
9
+ * Sync Claude Code sessions to Firestore
10
+ */
11
+ export declare function syncCommand(options?: SyncOptions): Promise<void>;
12
+ export {};
13
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAUA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmJ1E"}
@@ -0,0 +1,205 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import chalk from 'chalk';
4
+ import ora from 'ora';
5
+ import { loadConfig, loadSyncState, saveSyncState, getClaudeDir } from '../utils/config.js';
6
+ import { parseJsonlFile } from '../parser/jsonl.js';
7
+ import { initializeFirebase, uploadSession, uploadMessages, sessionExists, recalculateUsageStats } from '../firebase/client.js';
8
+ /**
9
+ * Sync Claude Code sessions to Firestore
10
+ */
11
+ export async function syncCommand(options = {}) {
12
+ const log = options.quiet ? () => { } : console.log.bind(console);
13
+ const noopSpinner = {
14
+ start: function () { return this; },
15
+ succeed: function () { return this; },
16
+ fail: function () { return this; },
17
+ warn: function () { return this; },
18
+ info: function () { return this; },
19
+ };
20
+ const createSpinner = options.quiet
21
+ ? () => noopSpinner
22
+ : ora;
23
+ log(chalk.cyan('\nšŸ“¤ Code Insights Sync\n'));
24
+ // Load config
25
+ const config = loadConfig();
26
+ if (!config) {
27
+ log(chalk.red('Not configured. Run `code-insights init` first.'));
28
+ process.exit(1);
29
+ }
30
+ // Initialize Firebase
31
+ const spinner = createSpinner('Connecting to Firebase...').start();
32
+ try {
33
+ initializeFirebase(config);
34
+ spinner.succeed('Connected to Firebase');
35
+ }
36
+ catch (error) {
37
+ spinner.fail('Failed to connect to Firebase');
38
+ if (!options.quiet) {
39
+ console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));
40
+ }
41
+ process.exit(1);
42
+ }
43
+ // Find JSONL files
44
+ const claudeDir = getClaudeDir();
45
+ if (!fs.existsSync(claudeDir)) {
46
+ log(chalk.yellow(`Claude directory not found: ${claudeDir}`));
47
+ log(chalk.gray('Make sure you have Claude Code installed and have run at least one session.'));
48
+ process.exit(1);
49
+ }
50
+ spinner.start('Discovering sessions...');
51
+ const jsonlFiles = discoverJsonlFiles(claudeDir, options.project);
52
+ spinner.succeed(`Found ${jsonlFiles.length} session files`);
53
+ if (jsonlFiles.length === 0) {
54
+ log(chalk.yellow('No sessions to sync.'));
55
+ return;
56
+ }
57
+ // Load sync state
58
+ const syncState = options.force ? { lastSync: '', files: {} } : loadSyncState();
59
+ // Filter to only new/modified files
60
+ const filesToSync = filterFilesToSync(jsonlFiles, syncState, options.force);
61
+ log(chalk.gray(` ${filesToSync.length} files need syncing (${jsonlFiles.length - filesToSync.length} already synced)`));
62
+ if (filesToSync.length === 0) {
63
+ log(chalk.green('\nāœ… Already up to date!'));
64
+ return;
65
+ }
66
+ if (options.dryRun) {
67
+ log(chalk.yellow('\nšŸ” Dry run - no changes will be made'));
68
+ for (const file of filesToSync) {
69
+ log(chalk.gray(` Would sync: ${path.basename(file)}`));
70
+ }
71
+ return;
72
+ }
73
+ // Process files
74
+ let syncedCount = 0;
75
+ let messageCount = 0;
76
+ let errorCount = 0;
77
+ for (const filePath of filesToSync) {
78
+ const fileName = path.basename(filePath);
79
+ spinner.start(`Processing ${fileName}...`);
80
+ try {
81
+ // Parse session
82
+ const session = await parseJsonlFile(filePath);
83
+ if (!session) {
84
+ spinner.warn(`Skipped ${fileName} (no valid data)`);
85
+ continue;
86
+ }
87
+ // Check if already exists (unless force)
88
+ if (!options.force) {
89
+ const exists = await sessionExists(session.id);
90
+ if (exists) {
91
+ spinner.info(`Skipped ${fileName} (already synced)`);
92
+ updateSyncState(syncState, filePath, session.id);
93
+ saveSyncState(syncState);
94
+ continue;
95
+ }
96
+ }
97
+ // Upload session and messages to Firestore
98
+ await uploadSession(session, !!options.force);
99
+ await uploadMessages(session);
100
+ // Update and persist sync state after each file
101
+ // so progress survives crashes (e.g., Firebase quota exceeded)
102
+ updateSyncState(syncState, filePath, session.id);
103
+ saveSyncState(syncState);
104
+ syncedCount++;
105
+ messageCount += session.messages.length;
106
+ spinner.succeed(`Synced ${fileName} (${session.messages.length} messages)`);
107
+ }
108
+ catch (error) {
109
+ errorCount++;
110
+ spinner.fail(`Failed to sync ${fileName}`);
111
+ if (!options.quiet) {
112
+ console.error(chalk.red(` ${error instanceof Error ? error.message : 'Unknown error'}`));
113
+ }
114
+ }
115
+ }
116
+ // Reconcile usage stats after force sync
117
+ if (options.force) {
118
+ spinner.start('Recalculating usage stats...');
119
+ try {
120
+ const result = await recalculateUsageStats();
121
+ spinner.succeed(`Usage stats reconciled (${result.sessionsWithUsage} sessions with usage data)`);
122
+ }
123
+ catch (error) {
124
+ spinner.warn('Could not reconcile usage stats');
125
+ if (!options.quiet) {
126
+ console.error(chalk.red(` ${error instanceof Error ? error.message : 'Unknown error'}`));
127
+ }
128
+ }
129
+ }
130
+ // Save sync state
131
+ syncState.lastSync = new Date().toISOString();
132
+ saveSyncState(syncState);
133
+ // Summary
134
+ log(chalk.cyan('\nšŸ“Š Sync Summary'));
135
+ log(chalk.white(` Sessions synced: ${syncedCount}`));
136
+ log(chalk.white(` Messages uploaded: ${messageCount}`));
137
+ if (errorCount > 0) {
138
+ log(chalk.red(` Errors: ${errorCount}`));
139
+ }
140
+ log(chalk.green('\nāœ… Sync complete!'));
141
+ }
142
+ /**
143
+ * Discover all JSONL files in Claude directory
144
+ */
145
+ function discoverJsonlFiles(baseDir, projectFilter) {
146
+ const files = [];
147
+ const projectDirs = fs.readdirSync(baseDir);
148
+ for (const projectDir of projectDirs) {
149
+ // Skip hidden files and non-directories
150
+ if (projectDir.startsWith('.'))
151
+ continue;
152
+ const projectPath = path.join(baseDir, projectDir);
153
+ const stat = fs.statSync(projectPath);
154
+ if (!stat.isDirectory())
155
+ continue;
156
+ // Apply project filter if specified
157
+ if (projectFilter && !projectDir.toLowerCase().includes(projectFilter.toLowerCase())) {
158
+ continue;
159
+ }
160
+ // Find JSONL files in project directory
161
+ const projectFiles = fs.readdirSync(projectPath);
162
+ for (const file of projectFiles) {
163
+ if (file.endsWith('.jsonl')) {
164
+ files.push(path.join(projectPath, file));
165
+ }
166
+ }
167
+ // Also check subagents directory
168
+ const subagentsDir = path.join(projectPath, 'subagents');
169
+ if (fs.existsSync(subagentsDir)) {
170
+ const subagentFiles = fs.readdirSync(subagentsDir);
171
+ for (const file of subagentFiles) {
172
+ if (file.endsWith('.jsonl')) {
173
+ files.push(path.join(subagentsDir, file));
174
+ }
175
+ }
176
+ }
177
+ }
178
+ return files;
179
+ }
180
+ /**
181
+ * Filter files to only those that need syncing
182
+ */
183
+ function filterFilesToSync(files, syncState, force) {
184
+ if (force)
185
+ return files;
186
+ return files.filter((filePath) => {
187
+ const stat = fs.statSync(filePath);
188
+ const lastModified = stat.mtime.toISOString();
189
+ const fileState = syncState.files[filePath];
190
+ // Sync if never synced or modified since last sync
191
+ return !fileState || fileState.lastModified !== lastModified;
192
+ });
193
+ }
194
+ /**
195
+ * Update sync state for a file
196
+ */
197
+ function updateSyncState(state, filePath, sessionId) {
198
+ const stat = fs.statSync(filePath);
199
+ state.files[filePath] = {
200
+ lastModified: stat.mtime.toISOString(),
201
+ lastSyncedLine: 0, // Not tracking lines for now
202
+ sessionId,
203
+ };
204
+ }
205
+ //# sourceMappingURL=sync.js.map