kaimon-cli 0.1.2 → 0.1.3

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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +71 -32
  3. package/bin/index.js +1 -1
  4. package/dist/commands/config.d.ts.map +1 -1
  5. package/dist/commands/config.js +13 -4
  6. package/dist/commands/config.js.map +1 -1
  7. package/dist/commands/pull.d.ts +4 -0
  8. package/dist/commands/pull.d.ts.map +1 -0
  9. package/dist/commands/pull.js +20 -0
  10. package/dist/commands/pull.js.map +1 -0
  11. package/dist/commands/push.d.ts +4 -0
  12. package/dist/commands/push.d.ts.map +1 -0
  13. package/dist/commands/push.js +19 -0
  14. package/dist/commands/push.js.map +1 -0
  15. package/dist/commands/sync.d.ts.map +1 -1
  16. package/dist/commands/sync.js +3 -14
  17. package/dist/commands/sync.js.map +1 -1
  18. package/dist/config/constants.d.ts +1 -1
  19. package/dist/config/constants.d.ts.map +1 -1
  20. package/dist/config/constants.js +7 -3
  21. package/dist/config/constants.js.map +1 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +4 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/utils/markdown.d.ts +21 -0
  26. package/dist/utils/markdown.d.ts.map +1 -0
  27. package/dist/utils/markdown.js +180 -0
  28. package/dist/utils/markdown.js.map +1 -0
  29. package/dist/utils/projectConfig.d.ts +25 -0
  30. package/dist/utils/projectConfig.d.ts.map +1 -0
  31. package/dist/utils/projectConfig.js +160 -0
  32. package/dist/utils/projectConfig.js.map +1 -0
  33. package/dist/utils/supabaseClient.d.ts +11 -0
  34. package/dist/utils/supabaseClient.d.ts.map +1 -0
  35. package/dist/utils/supabaseClient.js +43 -0
  36. package/dist/utils/supabaseClient.js.map +1 -0
  37. package/dist/utils/syncOperations.d.ts +16 -0
  38. package/dist/utils/syncOperations.d.ts.map +1 -0
  39. package/dist/utils/syncOperations.js +168 -0
  40. package/dist/utils/syncOperations.js.map +1 -0
  41. package/package.json +15 -8
  42. package/src/commands/auth.ts +0 -170
  43. package/src/commands/config.ts +0 -72
  44. package/src/commands/sync.ts +0 -30
  45. package/src/config/constants.ts +0 -27
  46. package/src/index.ts +0 -20
  47. package/src/utils/config.ts +0 -81
  48. package/src/utils/requireAuth.ts +0 -65
  49. package/tsconfig.json +0 -21
@@ -0,0 +1,160 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+ import readline from 'readline/promises';
5
+ const CONFIG_DIR = '.kaimon';
6
+ const CONFIG_FILE = 'config.json';
7
+ const CONFIG_VERSION = '1.0.0';
8
+ // Get project config directory path
9
+ export function getProjectConfigDir(baseDir = process.cwd()) {
10
+ return path.join(baseDir, CONFIG_DIR);
11
+ }
12
+ // Get project config file path
13
+ export function getProjectConfigPath(baseDir = process.cwd()) {
14
+ return path.join(getProjectConfigDir(baseDir), CONFIG_FILE);
15
+ }
16
+ // Check if project is initialized
17
+ export function isProjectInitialized(baseDir = process.cwd()) {
18
+ return fs.existsSync(getProjectConfigPath(baseDir));
19
+ }
20
+ // Load project config
21
+ export function loadProjectConfig(baseDir = process.cwd()) {
22
+ const configPath = getProjectConfigPath(baseDir);
23
+ if (!fs.existsSync(configPath)) {
24
+ return null;
25
+ }
26
+ try {
27
+ const content = fs.readFileSync(configPath, 'utf-8');
28
+ return JSON.parse(content);
29
+ }
30
+ catch (error) {
31
+ throw new Error(`Failed to load project config: ${error}`);
32
+ }
33
+ }
34
+ // Save project config
35
+ export function saveProjectConfig(config, baseDir = process.cwd()) {
36
+ const configDir = getProjectConfigDir(baseDir);
37
+ const configPath = getProjectConfigPath(baseDir);
38
+ // Ensure directory exists
39
+ if (!fs.existsSync(configDir)) {
40
+ fs.mkdirSync(configDir, { recursive: true, mode: 0o755 });
41
+ }
42
+ try {
43
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), {
44
+ mode: 0o644
45
+ });
46
+ }
47
+ catch (error) {
48
+ throw new Error(`Failed to save project config: ${error}`);
49
+ }
50
+ }
51
+ // Validate project config
52
+ export function validateProjectConfig(config) {
53
+ const errors = [];
54
+ if (!config.version) {
55
+ errors.push('Missing version field');
56
+ }
57
+ if (!config.user_id) {
58
+ errors.push('Missing user_id field');
59
+ }
60
+ return {
61
+ valid: errors.length === 0,
62
+ errors
63
+ };
64
+ }
65
+ // Find project config by walking up directory tree
66
+ export function findProjectConfig(startDir = process.cwd()) {
67
+ let currentDir = startDir;
68
+ const root = path.parse(currentDir).root;
69
+ while (currentDir !== root) {
70
+ const configPath = getProjectConfigPath(currentDir);
71
+ if (fs.existsSync(configPath)) {
72
+ const config = loadProjectConfig(currentDir);
73
+ if (config) {
74
+ return { path: currentDir, config };
75
+ }
76
+ }
77
+ // Move up one directory
78
+ const parentDir = path.dirname(currentDir);
79
+ if (parentDir === currentDir)
80
+ break; // Reached root
81
+ currentDir = parentDir;
82
+ }
83
+ return null;
84
+ }
85
+ // Initialize project config with user interaction
86
+ export async function initProjectConfig(baseDir = process.cwd()) {
87
+ // Check if already initialized
88
+ if (isProjectInitialized(baseDir)) {
89
+ console.log(chalk.yellow('āš ļø This directory is already initialized'));
90
+ console.log(chalk.gray(`Config: ${getProjectConfigPath(baseDir)}\n`));
91
+ // Ask if they want to reconfigure
92
+ const rl = readline.createInterface({
93
+ input: process.stdin,
94
+ output: process.stdout
95
+ });
96
+ const answer = await rl.question(chalk.cyan('Do you want to reinitialize? (y/N): '));
97
+ rl.close();
98
+ if (answer.toLowerCase() !== 'y' && answer.toLowerCase() !== 'yes') {
99
+ console.log(chalk.gray('Initialization cancelled\n'));
100
+ return;
101
+ }
102
+ }
103
+ // Get user ID from global config
104
+ const { loadConfig } = await import('./config.js');
105
+ const globalConfig = loadConfig();
106
+ if (!globalConfig.access_token) {
107
+ throw new Error('Not authenticated. Run "kaimon auth login" first.');
108
+ }
109
+ // For now, we'll store just the user ID
110
+ // In the future, we can add workspace/folder selection
111
+ const config = {
112
+ version: CONFIG_VERSION,
113
+ user_id: globalConfig.user_email || 'default',
114
+ sync_patterns: {
115
+ include: ['**/*.md'],
116
+ exclude: ['node_modules/**', '.git/**', 'dist/**', 'build/**']
117
+ }
118
+ };
119
+ // Save config
120
+ saveProjectConfig(config, baseDir);
121
+ console.log(chalk.green('āœ… Initialized Kaimon sync!'));
122
+ console.log(chalk.gray(`Config saved to: ${getProjectConfigPath(baseDir)}`));
123
+ console.log(chalk.gray('\nYou can now use:'));
124
+ console.log(chalk.cyan(' kaimon sync --pull') + chalk.gray(' # Download docs from Kaimon'));
125
+ console.log(chalk.cyan(' kaimon sync --push') + chalk.gray(' # Upload docs to Kaimon'));
126
+ console.log(chalk.cyan(' kaimon sync --diff') + chalk.gray(' # Preview changes\n'));
127
+ // Show what will be synced
128
+ console.log(chalk.blue('šŸ“ Sync Configuration:'));
129
+ if (config.sync_patterns) {
130
+ console.log(chalk.gray(' Include patterns:'));
131
+ config.sync_patterns.include.forEach(pattern => {
132
+ console.log(chalk.dim(` - ${pattern}`));
133
+ });
134
+ console.log(chalk.gray(' Exclude patterns:'));
135
+ config.sync_patterns.exclude.forEach(pattern => {
136
+ console.log(chalk.dim(` - ${pattern}`));
137
+ });
138
+ }
139
+ console.log();
140
+ }
141
+ // Require project config (throws if not found)
142
+ export async function requireProjectConfig(baseDir = process.cwd()) {
143
+ const found = findProjectConfig(baseDir);
144
+ if (!found) {
145
+ console.log(chalk.red('\nāŒ Not in a Kaimon project'));
146
+ console.log(chalk.yellow('Please initialize first:'));
147
+ console.log(chalk.cyan(' kaimon config init\n'));
148
+ process.exit(1);
149
+ }
150
+ const { valid, errors } = validateProjectConfig(found.config);
151
+ if (!valid) {
152
+ console.log(chalk.red('\nāŒ Invalid project configuration'));
153
+ errors.forEach(error => console.log(chalk.yellow(` - ${error}`)));
154
+ console.log(chalk.gray('\nPlease reinitialize:'));
155
+ console.log(chalk.cyan(' kaimon config init\n'));
156
+ process.exit(1);
157
+ }
158
+ return found.config;
159
+ }
160
+ //# sourceMappingURL=projectConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectConfig.js","sourceRoot":"","sources":["../../src/utils/projectConfig.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { SupabaseClient } from '@supabase/supabase-js';
2
+ /**
3
+ * Get authenticated Supabase client
4
+ * Uses the access token from the CLI config
5
+ */
6
+ export declare function getSupabaseClient(): SupabaseClient;
7
+ /**
8
+ * Reset the Supabase client (useful after logout/login)
9
+ */
10
+ export declare function resetSupabaseClient(): void;
11
+ //# sourceMappingURL=supabaseClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabaseClient.d.ts","sourceRoot":"","sources":["../../src/utils/supabaseClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAqBrE;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,CAsBlD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
@@ -0,0 +1,43 @@
1
+ import { createClient } from '@supabase/supabase-js';
2
+ import { loadConfig } from './config.js';
3
+ import { SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY } from '../config/constants.js';
4
+ let supabaseInstance = null;
5
+ // Validate that constants are configured
6
+ if (!SUPABASE_URL || SUPABASE_URL.includes('YOUR_PROJECT_ID')) {
7
+ throw new Error('Supabase URL not configured in constants.ts\n' +
8
+ 'Please update SUPABASE_URL in cli/src/config/constants.ts with your actual Supabase project URL.');
9
+ }
10
+ if (!SUPABASE_PUBLISHABLE_KEY || SUPABASE_PUBLISHABLE_KEY.includes('...')) {
11
+ throw new Error('Supabase publishable key not configured in constants.ts\n' +
12
+ 'Please update SUPABASE_PUBLISHABLE_KEY in cli/src/config/constants.ts with your actual publishable key.');
13
+ }
14
+ /**
15
+ * Get authenticated Supabase client
16
+ * Uses the access token from the CLI config
17
+ */
18
+ export function getSupabaseClient() {
19
+ if (supabaseInstance) {
20
+ return supabaseInstance;
21
+ }
22
+ // Load config to get access token
23
+ const config = loadConfig();
24
+ if (!config.access_token) {
25
+ throw new Error('Not authenticated. Please run "kaimon auth login" first.');
26
+ }
27
+ // Create Supabase client with user's access token
28
+ supabaseInstance = createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, {
29
+ global: {
30
+ headers: {
31
+ Authorization: `Bearer ${config.access_token}`
32
+ }
33
+ }
34
+ });
35
+ return supabaseInstance;
36
+ }
37
+ /**
38
+ * Reset the Supabase client (useful after logout/login)
39
+ */
40
+ export function resetSupabaseClient() {
41
+ supabaseInstance = null;
42
+ }
43
+ //# sourceMappingURL=supabaseClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabaseClient.js","sourceRoot":"","sources":["../../src/utils/supabaseClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAkB,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAEhF,IAAI,gBAAgB,GAA0B,IAAI,CAAC;AAEnD,yCAAyC;AACzC,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;IAC9D,MAAM,IAAI,KAAK,CACb,+CAA+C;QAC/C,kGAAkG,CACnG,CAAC;AACJ,CAAC;AAED,IAAI,CAAC,wBAAwB,IAAI,wBAAwB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;IAC1E,MAAM,IAAI,KAAK,CACb,2DAA2D;QAC3D,yGAAyG,CAC1G,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,kCAAkC;IAClC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IAED,kDAAkD;IAClD,gBAAgB,GAAG,YAAY,CAAC,YAAY,EAAE,wBAAwB,EAAE;QACtE,MAAM,EAAE;YACN,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,MAAM,CAAC,YAAY,EAAE;aAC/C;SACF;KACF,CAAC,CAAC;IAEH,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,gBAAgB,GAAG,IAAI,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Pull all documents from Kaimon and save as markdown files
3
+ * @param flat - If true, save directly to current folder; if false, create KaimonDocs/ subfolder
4
+ */
5
+ export declare function pullDocuments(flat?: boolean): Promise<void>;
6
+ /**
7
+ * Push local markdown files to Kaimon
8
+ * TODO: Implement in Phase 3
9
+ */
10
+ export declare function pushDocuments(): Promise<void>;
11
+ /**
12
+ * Show diff between local and remote
13
+ * TODO: Implement in Phase 3
14
+ */
15
+ export declare function showDiff(): Promise<void>;
16
+ //# sourceMappingURL=syncOperations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syncOperations.d.ts","sourceRoot":"","sources":["../../src/utils/syncOperations.ts"],"names":[],"mappings":"AA6CA;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAoJxE;AAED;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnD;AAED;;;GAGG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAE9C"}
@@ -0,0 +1,168 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+ import ora from 'ora';
5
+ import { getSupabaseClient } from './supabaseClient.js';
6
+ import { loadConfig } from './config.js';
7
+ import { blocknoteToMarkdown } from './markdown.js';
8
+ const BUCKET_NAME = 'user-documents';
9
+ /**
10
+ * Get document path in Supabase Storage
11
+ */
12
+ function getDocumentPath(userId, documentId) {
13
+ return `users/${userId}/documents/${documentId}/latest.json`;
14
+ }
15
+ /**
16
+ * Sanitize filename (remove invalid characters)
17
+ */
18
+ function sanitizeFilename(filename) {
19
+ return filename
20
+ .replace(/[<>:"/\\|?*]/g, '-') // Replace invalid chars
21
+ .replace(/\s+/g, '-') // Replace spaces with hyphens
22
+ .replace(/-+/g, '-') // Collapse multiple hyphens
23
+ .trim();
24
+ }
25
+ /**
26
+ * Pull all documents from Kaimon and save as markdown files
27
+ * @param flat - If true, save directly to current folder; if false, create KaimonDocs/ subfolder
28
+ */
29
+ export async function pullDocuments(flat = false) {
30
+ const spinner = ora('Fetching documents from Kaimon...').start();
31
+ try {
32
+ // Get user ID from global config (no project config needed)
33
+ const globalConfig = loadConfig();
34
+ if (!globalConfig.access_token) {
35
+ throw new Error('Not authenticated');
36
+ }
37
+ spinner.stop();
38
+ // Show confirmation before syncing
39
+ const readline = await import('readline');
40
+ const rl = readline.createInterface({
41
+ input: process.stdin,
42
+ output: process.stdout
43
+ });
44
+ const currentFolder = process.cwd();
45
+ const docsDir = flat
46
+ ? currentFolder
47
+ : path.join(currentFolder, 'KaimonDocs');
48
+ console.log(chalk.blue('\nšŸ“ Sync Location'));
49
+ console.log(chalk.gray(` Current folder: ${currentFolder}`));
50
+ console.log(chalk.gray(` Will sync to: ${docsDir}\n`));
51
+ const answer = await new Promise((resolve) => {
52
+ rl.question(chalk.cyan('Continue? (y/N): '), (ans) => {
53
+ rl.close();
54
+ resolve(ans);
55
+ });
56
+ });
57
+ if (answer.toLowerCase() !== 'y' && answer.toLowerCase() !== 'yes') {
58
+ console.log(chalk.yellow('\nāš ļø Sync cancelled.\n'));
59
+ return;
60
+ }
61
+ spinner.start();
62
+ // Get Supabase client
63
+ const supabase = getSupabaseClient();
64
+ // Fetch all user documents from database
65
+ spinner.text = 'Querying database...';
66
+ const { data: documents, error: dbError } = await supabase
67
+ .from('user_documents')
68
+ .select('*')
69
+ .order('updated_at', { ascending: false });
70
+ if (dbError) {
71
+ throw new Error(`Database error: ${dbError.message}`);
72
+ }
73
+ if (!documents || documents.length === 0) {
74
+ spinner.succeed(chalk.yellow('No documents found in your Kaimon account'));
75
+ console.log(chalk.dim('Create some documents first at kaimon.ai\n'));
76
+ return;
77
+ }
78
+ spinner.text = `Found ${documents.length} document(s), downloading...`;
79
+ // Create docs directory if it doesn't exist
80
+ if (!fs.existsSync(docsDir)) {
81
+ fs.mkdirSync(docsDir, { recursive: true });
82
+ }
83
+ let successCount = 0;
84
+ let errorCount = 0;
85
+ const errors = [];
86
+ // Download each document
87
+ for (const doc of documents) {
88
+ try {
89
+ const documentPath = getDocumentPath(doc.user_id, doc.id);
90
+ // Download from Supabase Storage
91
+ const { data: fileData, error: downloadError } = await supabase.storage
92
+ .from(BUCKET_NAME)
93
+ .download(documentPath);
94
+ if (downloadError) {
95
+ // Handle missing file gracefully
96
+ if (downloadError.message.includes('not found')) {
97
+ spinner.warn(chalk.yellow(`āš ļø Skipping "${doc.title}" - file not found in storage`));
98
+ continue;
99
+ }
100
+ throw downloadError;
101
+ }
102
+ // Parse JSON content
103
+ const text = await fileData.text();
104
+ const content = JSON.parse(text);
105
+ // Convert to markdown
106
+ let markdown = '';
107
+ if (content.type === 'blocknote' && Array.isArray(content.content)) {
108
+ markdown = blocknoteToMarkdown(content.content);
109
+ }
110
+ else if (typeof content.content === 'string') {
111
+ markdown = content.content;
112
+ }
113
+ else {
114
+ spinner.warn(chalk.yellow(`āš ļø Skipping "${doc.title}" - unsupported format`));
115
+ continue;
116
+ }
117
+ // Generate filename
118
+ const filename = sanitizeFilename(doc.title) + '.md';
119
+ const filepath = path.join(docsDir, filename);
120
+ // Add frontmatter with metadata
121
+ const frontmatter = [
122
+ '---',
123
+ `title: "${doc.title}"`,
124
+ `kaimon_id: "${doc.id}"`,
125
+ `created_at: "${doc.created_at}"`,
126
+ `updated_at: "${doc.updated_at}"`,
127
+ '---',
128
+ '',
129
+ markdown
130
+ ].join('\n');
131
+ // Write to file
132
+ fs.writeFileSync(filepath, frontmatter, 'utf-8');
133
+ successCount++;
134
+ }
135
+ catch (error) {
136
+ errorCount++;
137
+ errors.push(`${doc.title}: ${error.message}`);
138
+ }
139
+ }
140
+ // Show results
141
+ const relativeDocsDir = flat ? '.' : './KaimonDocs';
142
+ spinner.succeed(chalk.green(`āœ… Downloaded ${successCount} document(s) to ${relativeDocsDir}/`));
143
+ if (errorCount > 0) {
144
+ console.log(chalk.yellow(`\nāš ļø ${errorCount} error(s) occurred:`));
145
+ errors.forEach(err => console.log(chalk.dim(` - ${err}`)));
146
+ }
147
+ console.log(chalk.gray(`\nLast synced: ${new Date().toLocaleString()}\n`));
148
+ }
149
+ catch (error) {
150
+ spinner.fail(chalk.red('Failed to pull documents'));
151
+ throw error;
152
+ }
153
+ }
154
+ /**
155
+ * Push local markdown files to Kaimon
156
+ * TODO: Implement in Phase 3
157
+ */
158
+ export async function pushDocuments() {
159
+ throw new Error('Push functionality not yet implemented');
160
+ }
161
+ /**
162
+ * Show diff between local and remote
163
+ * TODO: Implement in Phase 3
164
+ */
165
+ export async function showDiff() {
166
+ throw new Error('Diff functionality not yet implemented');
167
+ }
168
+ //# sourceMappingURL=syncOperations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syncOperations.js","sourceRoot":"","sources":["../../src/utils/syncOperations.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kaimon-cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "CLI tool to sync Kaimon documentation with your codebase",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,23 +23,30 @@
23
23
  ],
24
24
  "author": "Kaimon",
25
25
  "license": "MIT",
26
+ "files": [
27
+ "bin",
28
+ "dist",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
26
32
  "dependencies": {
27
- "commander": "^14.0.0",
33
+ "@supabase/supabase-js": "^2.97.0",
28
34
  "axios": "^1.7.0",
29
35
  "chalk": "^5.3.0",
30
- "ora": "^9.0.0",
31
- "dotenv": "^17.0.0",
36
+ "commander": "^14.0.0",
32
37
  "conf": "^15.0.0",
33
- "open": "^10.0.0"
38
+ "dotenv": "^17.0.0",
39
+ "open": "^10.0.0",
40
+ "ora": "^9.0.0"
34
41
  },
35
42
  "devDependencies": {
36
43
  "@types/node": "^25.0.0",
37
- "typescript": "^5.4.0",
38
- "ts-node": "^10.9.2",
39
- "eslint": "^10.0.0",
40
44
  "@typescript-eslint/eslint-plugin": "^8.0.0",
41
45
  "@typescript-eslint/parser": "^8.0.0",
46
+ "eslint": "^10.0.0",
42
47
  "prettier": "^3.2.0",
48
+ "ts-node": "^10.9.2",
49
+ "typescript": "^5.4.0",
43
50
  "vitest": "^4.0.0"
44
51
  },
45
52
  "engines": {
@@ -1,170 +0,0 @@
1
- import { Command } from 'commander';
2
- import chalk from 'chalk';
3
- import open from 'open';
4
- import { getAuthUrl, CLI_AUTH_PATH } from '../config/constants.js';
5
- import { loadConfig, saveConfig, clearConfig, isAuthenticated } from '../utils/config.js';
6
-
7
- // Mask token for display (show first 8 and last 8 characters)
8
- function maskToken(token: string): string {
9
- if (!token) return '';
10
- if (token.length <= 20) return token; // Don't mask if too short
11
- const start = token.substring(0, 8);
12
- const end = token.substring(token.length - 8);
13
- const maskLength = Math.min(token.length - 16, 40); // Max 40 dots
14
- return `${start}${'•'.repeat(maskLength)}${end}`;
15
- }
16
-
17
- const auth = new Command('auth')
18
- .description('Authenticate with Kaimon');
19
-
20
- // Login command
21
- auth
22
- .command('login')
23
- .description('Login to your Kaimon account')
24
- .option('--dev', 'Use development URL (localhost)')
25
- .action(async (options) => {
26
- try {
27
- console.log(chalk.blue('šŸ” Opening browser for authentication...\n'));
28
-
29
- // Construct auth URL
30
- const baseUrl = options.dev ? 'http://localhost:5173' : getAuthUrl();
31
- const authUrl = `${baseUrl}${CLI_AUTH_PATH}`;
32
-
33
- console.log(chalk.gray(`URL: ${authUrl}\n`));
34
-
35
- // Open browser
36
- await open(authUrl);
37
-
38
- console.log(chalk.yellow('Please complete authentication in your browser.'));
39
- console.log(chalk.gray('After logging in, copy the access token and paste it here.\n'));
40
-
41
- // Wait for user to paste token with hidden input
42
- const readline = await import('readline');
43
- const rl = readline.createInterface({
44
- input: process.stdin,
45
- output: process.stdout
46
- });
47
-
48
- // Mute output to hide token input
49
- const mutableStdout = process.stdout as any;
50
- console.log(chalk.cyan('Paste your access token below:'));
51
- console.log(chalk.dim('(Your paste will be invisible for security - press Enter when done)'));
52
- mutableStdout.write(chalk.cyan('> '));
53
-
54
- let token = '';
55
- rl.on('line', (input) => {
56
- token = input;
57
- rl.close();
58
- });
59
-
60
- // Mute the output while typing
61
- const oldWrite = mutableStdout.write;
62
- mutableStdout.write = (chunk: string) => {
63
- // Only show the prompt, hide everything else
64
- return true;
65
- };
66
-
67
- rl.on('close', () => {
68
- // Restore normal output
69
- mutableStdout.write = oldWrite;
70
-
71
- if (!token || token.trim() === '') {
72
- console.log(chalk.red('\nāŒ No token provided. Authentication cancelled.'));
73
- process.exit(1);
74
- }
75
-
76
- // Show confirmation that token was received
77
- console.log(chalk.green(`\nāœ“ Token received (${token.trim().length} characters)`));
78
- console.log(chalk.gray('Verifying and saving...\n'));
79
-
80
- // Save token to config
81
- saveConfig({
82
- access_token: token.trim(),
83
- expires_at: new Date(Date.now() + 60 * 60 * 1000).toISOString() // 1 hour from now
84
- });
85
-
86
- console.log(chalk.green('āœ… Authentication successful!'));
87
- console.log(chalk.gray(`Token: ${maskToken(token.trim())}`));
88
- console.log(chalk.gray('Saved to ~/.kaimon/config.json\n'));
89
- console.log(chalk.blue('You can now use other CLI commands like:'));
90
- console.log(chalk.gray(' kaimon sync --pull'));
91
- console.log(chalk.gray(' kaimon sync --push\n'));
92
- });
93
-
94
- } catch (error: any) {
95
- console.error(chalk.red('āŒ Login failed:'), error.message);
96
- process.exit(1);
97
- }
98
- });
99
-
100
- // Logout command
101
- auth
102
- .command('logout')
103
- .description('Logout from Kaimon')
104
- .action(async () => {
105
- try {
106
- if (!isAuthenticated()) {
107
- console.log(chalk.yellow('āš ļø You are not logged in.'));
108
- return;
109
- }
110
-
111
- clearConfig();
112
- console.log(chalk.green('āœ… Logged out successfully!'));
113
- console.log(chalk.gray('Token removed from ~/.kaimon/config.json\n'));
114
- } catch (error: any) {
115
- console.error(chalk.red('āŒ Logout failed:'), error.message);
116
- process.exit(1);
117
- }
118
- });
119
-
120
- // Status command
121
- auth
122
- .command('status')
123
- .description('Check authentication status')
124
- .option('--show-token', 'Show full access token (security risk)')
125
- .action(async (options) => {
126
- try {
127
- const config = loadConfig();
128
-
129
- if (!config.access_token) {
130
- console.log(chalk.yellow('āŒ Not authenticated'));
131
- console.log(chalk.gray('Run "kaimon auth login" to authenticate\n'));
132
- return;
133
- }
134
-
135
- console.log(chalk.green('āœ… Authenticated'));
136
-
137
- if (config.user_email) {
138
- console.log(chalk.gray(`Email: ${config.user_email}`));
139
- }
140
-
141
- // Show token (masked by default)
142
- if (options.showToken) {
143
- console.log(chalk.gray(`Token: ${config.access_token}`));
144
- console.log(chalk.yellow('āš ļø Full token shown above - keep it secure!'));
145
- } else {
146
- console.log(chalk.gray(`Token: ${maskToken(config.access_token)}`));
147
- console.log(chalk.dim('Use --show-token to reveal full token'));
148
- }
149
-
150
- if (config.expires_at) {
151
- const expiresAt = new Date(config.expires_at);
152
- const now = new Date();
153
- const isExpired = expiresAt < now;
154
-
155
- if (isExpired) {
156
- console.log(chalk.red('Status: Expired'));
157
- console.log(chalk.yellow('Please login again: kaimon auth login\n'));
158
- } else {
159
- console.log(chalk.gray(`Expires: ${expiresAt.toLocaleString()}`));
160
- }
161
- }
162
-
163
- console.log(chalk.gray(`Config: ~/.kaimon/config.json\n`));
164
- } catch (error: any) {
165
- console.error(chalk.red('āŒ Status check failed:'), error.message);
166
- process.exit(1);
167
- }
168
- });
169
-
170
- export { auth };