kaimon-cli 0.1.2 → 0.1.4

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 (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +79 -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 +24 -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/pushOperations.d.ts +10 -0
  34. package/dist/utils/pushOperations.d.ts.map +1 -0
  35. package/dist/utils/pushOperations.js +119 -0
  36. package/dist/utils/pushOperations.js.map +1 -0
  37. package/dist/utils/supabaseClient.d.ts +11 -0
  38. package/dist/utils/supabaseClient.d.ts.map +1 -0
  39. package/dist/utils/supabaseClient.js +43 -0
  40. package/dist/utils/supabaseClient.js.map +1 -0
  41. package/dist/utils/syncOperations.d.ts +16 -0
  42. package/dist/utils/syncOperations.d.ts.map +1 -0
  43. package/dist/utils/syncOperations.js +179 -0
  44. package/dist/utils/syncOperations.js.map +1 -0
  45. package/dist/utils/tokenRefresh.d.ts +17 -0
  46. package/dist/utils/tokenRefresh.d.ts.map +1 -0
  47. package/dist/utils/tokenRefresh.js +80 -0
  48. package/dist/utils/tokenRefresh.js.map +1 -0
  49. package/package.json +15 -8
  50. package/src/commands/auth.ts +0 -170
  51. package/src/commands/config.ts +0 -72
  52. package/src/commands/sync.ts +0 -30
  53. package/src/config/constants.ts +0 -27
  54. package/src/index.ts +0 -20
  55. package/src/utils/config.ts +0 -81
  56. package/src/utils/requireAuth.ts +0 -65
  57. package/tsconfig.json +0 -21
@@ -0,0 +1,25 @@
1
+ export interface ProjectConfig {
2
+ version: string;
3
+ user_id?: string;
4
+ sync_patterns?: {
5
+ include: string[];
6
+ exclude: string[];
7
+ };
8
+ last_sync?: string;
9
+ }
10
+ export declare function getProjectConfigDir(baseDir?: string): string;
11
+ export declare function getProjectConfigPath(baseDir?: string): string;
12
+ export declare function isProjectInitialized(baseDir?: string): boolean;
13
+ export declare function loadProjectConfig(baseDir?: string): ProjectConfig | null;
14
+ export declare function saveProjectConfig(config: ProjectConfig, baseDir?: string): void;
15
+ export declare function validateProjectConfig(config: ProjectConfig): {
16
+ valid: boolean;
17
+ errors: string[];
18
+ };
19
+ export declare function findProjectConfig(startDir?: string): {
20
+ path: string;
21
+ config: ProjectConfig;
22
+ } | null;
23
+ export declare function initProjectConfig(baseDir?: string): Promise<void>;
24
+ export declare function requireProjectConfig(baseDir?: string): Promise<ProjectConfig>;
25
+ //# sourceMappingURL=projectConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectConfig.d.ts","sourceRoot":"","sources":["../../src/utils/projectConfig.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE;QACd,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAOD,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,MAAsB,GAAG,MAAM,CAE3E;AAGD,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,MAAsB,GAAG,MAAM,CAE5E;AAGD,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,MAAsB,GAAG,OAAO,CAE7E;AAGD,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,MAAsB,GAAG,aAAa,GAAG,IAAI,CAavF;AAGD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,GAAE,MAAsB,GAAG,IAAI,CAgB9F;AAGD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAejG;AAGD,wBAAgB,iBAAiB,CAAC,QAAQ,GAAE,MAAsB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GAAG,IAAI,CAqBlH;AAGD,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,MAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+DtF;AAGD,wBAAsB,oBAAoB,CAAC,OAAO,GAAE,MAAsB,GAAG,OAAO,CAAC,aAAa,CAAC,CAqBlG"}
@@ -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,10 @@
1
+ interface PushOptions {
2
+ files?: string[];
3
+ skipConfirmation?: boolean;
4
+ }
5
+ /**
6
+ * Push markdown files to Kaimon
7
+ */
8
+ export declare function pushDocuments(options?: PushOptions): Promise<void>;
9
+ export {};
10
+ //# sourceMappingURL=pushOperations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pushOperations.d.ts","sourceRoot":"","sources":["../../src/utils/pushOperations.ts"],"names":[],"mappings":"AAUA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AA+CD;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgF5E"}
@@ -0,0 +1,119 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+ import ora from 'ora';
5
+ import { loadConfig } from './config.js';
6
+ import { ensureValidToken } from './tokenRefresh.js';
7
+ const BUCKET_NAME = 'user-documents';
8
+ /**
9
+ * Find all markdown files in current directory
10
+ */
11
+ function findMarkdownFiles(dir = process.cwd()) {
12
+ const mdFiles = [];
13
+ function walkDir(currentPath, relativeBase = '') {
14
+ try {
15
+ const entries = fs.readdirSync(currentPath, { withFileTypes: true });
16
+ for (const entry of entries) {
17
+ // Skip hidden files/folders and common exclusions
18
+ if (entry.name.startsWith('.') ||
19
+ entry.name === 'node_modules' ||
20
+ entry.name === 'dist' ||
21
+ entry.name === 'build' ||
22
+ entry.name === '.git') {
23
+ continue;
24
+ }
25
+ const fullPath = path.join(currentPath, entry.name);
26
+ const relativePath = relativeBase ? path.join(relativeBase, entry.name) : entry.name;
27
+ if (entry.isDirectory()) {
28
+ walkDir(fullPath, relativePath);
29
+ }
30
+ else if (entry.name.endsWith('.md')) {
31
+ mdFiles.push(relativePath);
32
+ }
33
+ }
34
+ }
35
+ catch (error) {
36
+ // Skip inaccessible directories
37
+ }
38
+ }
39
+ walkDir(dir);
40
+ return mdFiles.sort();
41
+ }
42
+ /**
43
+ * Get document path in Supabase Storage
44
+ */
45
+ function getDocumentPath(userId, documentId) {
46
+ return `users/${userId}/documents/${documentId}/latest.json`;
47
+ }
48
+ /**
49
+ * Push markdown files to Kaimon
50
+ */
51
+ export async function pushDocuments(options = {}) {
52
+ const spinner = ora('Preparing to push documents...').start();
53
+ try {
54
+ // Ensure token is valid (refresh if needed)
55
+ spinner.text = 'Checking authentication...';
56
+ const hasValidToken = await ensureValidToken();
57
+ if (!hasValidToken) {
58
+ spinner.fail(chalk.red('Authentication failed'));
59
+ console.log(chalk.yellow('\nYour session has expired or is invalid.'));
60
+ console.log(chalk.cyan('Please login again:\n'));
61
+ console.log(chalk.dim(' kaimon auth login\n'));
62
+ throw new Error('Not authenticated');
63
+ }
64
+ // Get authentication
65
+ const globalConfig = loadConfig();
66
+ if (!globalConfig.access_token) {
67
+ throw new Error('Not authenticated');
68
+ }
69
+ // Find markdown files
70
+ let filesToPush = options.files || [];
71
+ if (filesToPush.length === 0) {
72
+ // Auto-find all markdown files in current directory
73
+ filesToPush = findMarkdownFiles();
74
+ if (filesToPush.length === 0) {
75
+ spinner.warn(chalk.yellow('No markdown files found in current directory'));
76
+ console.log(chalk.dim('Create some .md files first\n'));
77
+ return;
78
+ }
79
+ }
80
+ spinner.stop();
81
+ // Show files and ask for confirmation (unless -y flag)
82
+ if (!options.skipConfirmation) {
83
+ console.log(chalk.blue('\n📄 Files to push:'));
84
+ filesToPush.forEach((file, idx) => {
85
+ console.log(chalk.gray(` ${idx + 1}. ${file}`));
86
+ });
87
+ const readline = await import('readline');
88
+ const rl = readline.createInterface({
89
+ input: process.stdin,
90
+ output: process.stdout
91
+ });
92
+ const answer = await new Promise((resolve) => {
93
+ rl.question(chalk.cyan(`\nPush ${filesToPush.length} file(s)? (y/N): `), (ans) => {
94
+ rl.close();
95
+ resolve(ans);
96
+ });
97
+ });
98
+ if (answer.toLowerCase() !== 'y' && answer.toLowerCase() !== 'yes') {
99
+ console.log(chalk.yellow('\n⚠️ Push cancelled.\n'));
100
+ return;
101
+ }
102
+ }
103
+ spinner.start();
104
+ spinner.text = `Pushing ${filesToPush.length} file(s) to Kaimon...`;
105
+ // TODO: Implement actual push logic
106
+ // This would involve:
107
+ // 1. Reading each .md file
108
+ // 2. Creating document records in database
109
+ // 3. Uploading content to Supabase Storage
110
+ // 4. Handling conflicts (existing docs)
111
+ spinner.succeed(chalk.green(`✅ Push functionality coming soon!`));
112
+ console.log(chalk.dim(`Ready to push ${filesToPush.length} file(s) when implemented\n`));
113
+ }
114
+ catch (error) {
115
+ spinner.fail(chalk.red('Failed to push documents'));
116
+ throw error;
117
+ }
118
+ }
119
+ //# sourceMappingURL=pushOperations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pushOperations.js","sourceRoot":"","sources":["../../src/utils/pushOperations.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":"AA8CA;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA+JxE;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,179 @@
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
+ import { ensureValidToken } from './tokenRefresh.js';
9
+ const BUCKET_NAME = 'user-documents';
10
+ /**
11
+ * Get document path in Supabase Storage
12
+ */
13
+ function getDocumentPath(userId, documentId) {
14
+ return `users/${userId}/documents/${documentId}/latest.json`;
15
+ }
16
+ /**
17
+ * Sanitize filename (remove invalid characters)
18
+ */
19
+ function sanitizeFilename(filename) {
20
+ return filename
21
+ .replace(/[<>:"/\\|?*]/g, '-') // Replace invalid chars
22
+ .replace(/\s+/g, '-') // Replace spaces with hyphens
23
+ .replace(/-+/g, '-') // Collapse multiple hyphens
24
+ .trim();
25
+ }
26
+ /**
27
+ * Pull all documents from Kaimon and save as markdown files
28
+ * @param flat - If true, save directly to current folder; if false, create KaimonDocs/ subfolder
29
+ */
30
+ export async function pullDocuments(flat = false) {
31
+ const spinner = ora('Fetching documents from Kaimon...').start();
32
+ try {
33
+ // Ensure token is valid (refresh if needed)
34
+ spinner.text = 'Checking authentication...';
35
+ const hasValidToken = await ensureValidToken();
36
+ if (!hasValidToken) {
37
+ spinner.fail(chalk.red('Authentication failed'));
38
+ console.log(chalk.yellow('\nYour session has expired or is invalid.'));
39
+ console.log(chalk.cyan('Please login again:\n'));
40
+ console.log(chalk.dim(' kaimon auth login\n'));
41
+ throw new Error('Not authenticated');
42
+ }
43
+ // Get user ID from global config (no project config needed)
44
+ const globalConfig = loadConfig();
45
+ if (!globalConfig.access_token) {
46
+ throw new Error('Not authenticated');
47
+ }
48
+ spinner.stop();
49
+ // Show confirmation before syncing
50
+ const readline = await import('readline');
51
+ const rl = readline.createInterface({
52
+ input: process.stdin,
53
+ output: process.stdout
54
+ });
55
+ const currentFolder = process.cwd();
56
+ const docsDir = flat
57
+ ? currentFolder
58
+ : path.join(currentFolder, 'KaimonDocs');
59
+ console.log(chalk.blue('\n📁 Sync Location'));
60
+ console.log(chalk.gray(` Current folder: ${currentFolder}`));
61
+ console.log(chalk.gray(` Will sync to: ${docsDir}\n`));
62
+ const answer = await new Promise((resolve) => {
63
+ rl.question(chalk.cyan('Continue? (y/N): '), (ans) => {
64
+ rl.close();
65
+ resolve(ans);
66
+ });
67
+ });
68
+ if (answer.toLowerCase() !== 'y' && answer.toLowerCase() !== 'yes') {
69
+ console.log(chalk.yellow('\n⚠️ Sync cancelled.\n'));
70
+ return;
71
+ }
72
+ spinner.start();
73
+ // Get Supabase client
74
+ const supabase = getSupabaseClient();
75
+ // Fetch all user documents from database
76
+ spinner.text = 'Querying database...';
77
+ const { data: documents, error: dbError } = await supabase
78
+ .from('user_documents')
79
+ .select('*')
80
+ .order('updated_at', { ascending: false });
81
+ if (dbError) {
82
+ throw new Error(`Database error: ${dbError.message}`);
83
+ }
84
+ if (!documents || documents.length === 0) {
85
+ spinner.succeed(chalk.yellow('No documents found in your Kaimon account'));
86
+ console.log(chalk.dim('Create some documents first at kaimon.ai\n'));
87
+ return;
88
+ }
89
+ spinner.text = `Found ${documents.length} document(s), downloading...`;
90
+ // Create docs directory if it doesn't exist
91
+ if (!fs.existsSync(docsDir)) {
92
+ fs.mkdirSync(docsDir, { recursive: true });
93
+ }
94
+ let successCount = 0;
95
+ let errorCount = 0;
96
+ const errors = [];
97
+ // Download each document
98
+ for (const doc of documents) {
99
+ try {
100
+ const documentPath = getDocumentPath(doc.user_id, doc.id);
101
+ // Download from Supabase Storage
102
+ const { data: fileData, error: downloadError } = await supabase.storage
103
+ .from(BUCKET_NAME)
104
+ .download(documentPath);
105
+ if (downloadError) {
106
+ // Handle missing file gracefully
107
+ if (downloadError.message.includes('not found')) {
108
+ spinner.warn(chalk.yellow(`⚠️ Skipping "${doc.title}" - file not found in storage`));
109
+ continue;
110
+ }
111
+ throw downloadError;
112
+ }
113
+ // Parse JSON content
114
+ const text = await fileData.text();
115
+ const content = JSON.parse(text);
116
+ // Convert to markdown
117
+ let markdown = '';
118
+ if (content.type === 'blocknote' && Array.isArray(content.content)) {
119
+ markdown = blocknoteToMarkdown(content.content);
120
+ }
121
+ else if (typeof content.content === 'string') {
122
+ markdown = content.content;
123
+ }
124
+ else {
125
+ spinner.warn(chalk.yellow(`⚠️ Skipping "${doc.title}" - unsupported format`));
126
+ continue;
127
+ }
128
+ // Generate filename
129
+ const filename = sanitizeFilename(doc.title) + '.md';
130
+ const filepath = path.join(docsDir, filename);
131
+ // Add frontmatter with metadata
132
+ const frontmatter = [
133
+ '---',
134
+ `title: "${doc.title}"`,
135
+ `kaimon_id: "${doc.id}"`,
136
+ `created_at: "${doc.created_at}"`,
137
+ `updated_at: "${doc.updated_at}"`,
138
+ '---',
139
+ '',
140
+ markdown
141
+ ].join('\n');
142
+ // Write to file
143
+ fs.writeFileSync(filepath, frontmatter, 'utf-8');
144
+ successCount++;
145
+ }
146
+ catch (error) {
147
+ errorCount++;
148
+ errors.push(`${doc.title}: ${error.message}`);
149
+ }
150
+ }
151
+ // Show results
152
+ const relativeDocsDir = flat ? '.' : './KaimonDocs';
153
+ spinner.succeed(chalk.green(`✅ Downloaded ${successCount} document(s) to ${relativeDocsDir}/`));
154
+ if (errorCount > 0) {
155
+ console.log(chalk.yellow(`\n⚠️ ${errorCount} error(s) occurred:`));
156
+ errors.forEach(err => console.log(chalk.dim(` - ${err}`)));
157
+ }
158
+ console.log(chalk.gray(`\nLast synced: ${new Date().toLocaleString()}\n`));
159
+ }
160
+ catch (error) {
161
+ spinner.fail(chalk.red('Failed to pull documents'));
162
+ throw error;
163
+ }
164
+ }
165
+ /**
166
+ * Push local markdown files to Kaimon
167
+ * TODO: Implement in Phase 3
168
+ */
169
+ export async function pushDocuments() {
170
+ throw new Error('Push functionality not yet implemented');
171
+ }
172
+ /**
173
+ * Show diff between local and remote
174
+ * TODO: Implement in Phase 3
175
+ */
176
+ export async function showDiff() {
177
+ throw new Error('Diff functionality not yet implemented');
178
+ }
179
+ //# 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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"}
@@ -0,0 +1,17 @@
1
+ export interface CLIConfig {
2
+ access_token?: string;
3
+ refresh_token?: string;
4
+ expires_at?: string;
5
+ user_email?: string;
6
+ }
7
+ /**
8
+ * Refresh the user's access token using the refresh token
9
+ * Returns true if refresh was successful, false if it failed or wasn't needed
10
+ */
11
+ export declare function refreshAccessToken(): Promise<boolean>;
12
+ /**
13
+ * Ensure user has a valid token before executing commands
14
+ * Will attempt to refresh if expired
15
+ */
16
+ export declare function ensureValidToken(): Promise<boolean>;
17
+ //# sourceMappingURL=tokenRefresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenRefresh.d.ts","sourceRoot":"","sources":["../../src/utils/tokenRefresh.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,SAAS;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAaD;;;GAGG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAoD3D;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CAgBzD"}