kaimon-cli 0.1.41 → 0.1.44

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 (74) hide show
  1. package/README.md +56 -0
  2. package/dist/__tests__/commands/pull.test.d.ts +2 -0
  3. package/dist/__tests__/commands/pull.test.d.ts.map +1 -0
  4. package/dist/__tests__/commands/pull.test.js +182 -0
  5. package/dist/__tests__/commands/pull.test.js.map +1 -0
  6. package/dist/__tests__/commands/push.test.d.ts +2 -0
  7. package/dist/__tests__/commands/push.test.d.ts.map +1 -0
  8. package/dist/__tests__/commands/push.test.js +255 -0
  9. package/dist/__tests__/commands/push.test.js.map +1 -0
  10. package/dist/__tests__/helpers.d.ts +49 -0
  11. package/dist/__tests__/helpers.d.ts.map +1 -0
  12. package/dist/__tests__/helpers.js +151 -0
  13. package/dist/__tests__/helpers.js.map +1 -0
  14. package/dist/__tests__/integration/full-workflow.test.d.ts +2 -0
  15. package/dist/__tests__/integration/full-workflow.test.d.ts.map +1 -0
  16. package/dist/__tests__/integration/full-workflow.test.js +213 -0
  17. package/dist/__tests__/integration/full-workflow.test.js.map +1 -0
  18. package/dist/__tests__/setup.d.ts +2 -0
  19. package/dist/__tests__/setup.d.ts.map +1 -0
  20. package/dist/__tests__/setup.js +24 -0
  21. package/dist/__tests__/setup.js.map +1 -0
  22. package/dist/__tests__/unit/utils/config.test.d.ts +2 -0
  23. package/dist/__tests__/unit/utils/config.test.d.ts.map +1 -0
  24. package/dist/__tests__/unit/utils/config.test.js +171 -0
  25. package/dist/__tests__/unit/utils/config.test.js.map +1 -0
  26. package/dist/__tests__/unit/utils/frontmatter.test.d.ts +2 -0
  27. package/dist/__tests__/unit/utils/frontmatter.test.d.ts.map +1 -0
  28. package/dist/__tests__/unit/utils/frontmatter.test.js +231 -0
  29. package/dist/__tests__/unit/utils/frontmatter.test.js.map +1 -0
  30. package/dist/__tests__/unit/utils/markdown.test.d.ts +2 -0
  31. package/dist/__tests__/unit/utils/markdown.test.d.ts.map +1 -0
  32. package/dist/__tests__/unit/utils/markdown.test.js +296 -0
  33. package/dist/__tests__/unit/utils/markdown.test.js.map +1 -0
  34. package/dist/__tests__/unit/utils/projectConfig.test.d.ts +2 -0
  35. package/dist/__tests__/unit/utils/projectConfig.test.d.ts.map +1 -0
  36. package/dist/__tests__/unit/utils/projectConfig.test.js +160 -0
  37. package/dist/__tests__/unit/utils/projectConfig.test.js.map +1 -0
  38. package/dist/__tests__/unit/utils/requireAuth.test.d.ts +2 -0
  39. package/dist/__tests__/unit/utils/requireAuth.test.d.ts.map +1 -0
  40. package/dist/__tests__/unit/utils/requireAuth.test.js +96 -0
  41. package/dist/__tests__/unit/utils/requireAuth.test.js.map +1 -0
  42. package/dist/__tests__/unit/utils/tokenRefresh.test.d.ts +2 -0
  43. package/dist/__tests__/unit/utils/tokenRefresh.test.d.ts.map +1 -0
  44. package/dist/__tests__/unit/utils/tokenRefresh.test.js +170 -0
  45. package/dist/__tests__/unit/utils/tokenRefresh.test.js.map +1 -0
  46. package/dist/__tests__/unit/utils/versionCheck.test.d.ts +2 -0
  47. package/dist/__tests__/unit/utils/versionCheck.test.d.ts.map +1 -0
  48. package/dist/__tests__/unit/utils/versionCheck.test.js +105 -0
  49. package/dist/__tests__/unit/utils/versionCheck.test.js.map +1 -0
  50. package/dist/commands/pull.d.ts.map +1 -1
  51. package/dist/commands/pull.js +2 -1
  52. package/dist/commands/pull.js.map +1 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +9 -0
  55. package/dist/index.js.map +1 -1
  56. package/dist/utils/frontmatter.d.ts +28 -0
  57. package/dist/utils/frontmatter.d.ts.map +1 -0
  58. package/dist/utils/frontmatter.js +79 -0
  59. package/dist/utils/frontmatter.js.map +1 -0
  60. package/dist/utils/projectConfig.d.ts.map +1 -1
  61. package/dist/utils/projectConfig.js +9 -1
  62. package/dist/utils/projectConfig.js.map +1 -1
  63. package/dist/utils/pushOperations.d.ts.map +1 -1
  64. package/dist/utils/pushOperations.js +242 -19
  65. package/dist/utils/pushOperations.js.map +1 -1
  66. package/dist/utils/syncOperations.d.ts +2 -1
  67. package/dist/utils/syncOperations.d.ts.map +1 -1
  68. package/dist/utils/syncOperations.js +153 -43
  69. package/dist/utils/syncOperations.js.map +1 -1
  70. package/dist/utils/versionCheck.d.ts +6 -0
  71. package/dist/utils/versionCheck.d.ts.map +1 -0
  72. package/dist/utils/versionCheck.js +61 -0
  73. package/dist/utils/versionCheck.js.map +1 -0
  74. package/package.json +2 -1
package/README.md CHANGED
@@ -68,6 +68,9 @@ kaimon pull
68
68
  # Download documents to current folder (no KaimonDocs subfolder)
69
69
  kaimon pull --flat
70
70
 
71
+ # Pull without confirmation
72
+ kaimon pull -y
73
+
71
74
  # Upload local markdown files to Kaimon
72
75
  kaimon push
73
76
 
@@ -82,13 +85,22 @@ kaimon sync
82
85
  ```
83
86
 
84
87
  **Pull behavior:**
88
+ - **Smart sync**: Only pulls new or updated documents (compares timestamps)
89
+ - If local file is newer than remote → skips (no overwrite)
85
90
  - Default: Creates `./KaimonDocs/` subfolder and downloads documents there
86
91
  - `--flat`: Downloads documents directly to current folder (no subfolder)
92
+ - `-y, --yes`: Skip confirmation and pull all documents
93
+ - Shows preview with file counts and timestamps before pulling
87
94
 
88
95
  **Push behavior:**
96
+ - **Smart sync**: Only pushes new or modified files (compares timestamps)
97
+ - If remote is newer than local → skips (no overwrite)
98
+ - Reads frontmatter `kaimon_id` to match existing documents
89
99
  - Default: Finds all `.md` files in current folder + subfolders, lists them, asks for confirmation
90
100
  - `[files...]`: Push only specific files (e.g., `kaimon push doc1.md readme.md`)
91
101
  - `-y, --yes`: Skip confirmation and push all files found
102
+ - Shows preview with actions and timestamps before pushing
103
+ - Automatically updates frontmatter with `kaimon_id` for new documents
92
104
 
93
105
  ## Document Format
94
106
 
@@ -107,6 +119,50 @@ updated_at: "2024-02-21T15:00:00Z"
107
119
  Content here...
108
120
  ```
109
121
 
122
+ **Important**: The `kaimon_id` field links local files to remote documents. Don't remove it!
123
+ - When pushing: Files with `kaimon_id` update existing documents
124
+ - When pushing: Files without `kaimon_id` create new documents
125
+ - The CLI automatically adds `kaimon_id` to new files after first push
126
+
127
+ ## Smart Sync
128
+
129
+ Both `pull` and `push` use **timestamp-based smart sync** to avoid unnecessary transfers:
130
+
131
+ ### Pull Logic
132
+ - **New documents**: Not in local folder → pull
133
+ - **Updated documents**: Remote newer than local → pull
134
+ - **Up-to-date**: Remote same age or older → skip
135
+
136
+ ### Push Logic
137
+ - **New files**: No `kaimon_id` in frontmatter → create new document
138
+ - **Modified files**: Local newer than remote → push update
139
+ - **Up-to-date**: Remote same age or newer → skip
140
+
141
+ ### Example Output
142
+
143
+ ```bash
144
+ $ kaimon pull
145
+
146
+ Checking authentication... ✓
147
+ Analyzing documents...
148
+
149
+ 📄 Found 3 document(s) to pull:
150
+
151
+ New documents:
152
+ 1. Project Roadmap.md (created 2 hours ago)
153
+
154
+ Updated documents:
155
+ 2. README.md (Local: 2 hours ago, Remote: 30 mins ago)
156
+ 3. Architecture.md (Local: 5 days ago, Remote: 1 day ago)
157
+
158
+ ⏭️ 12 document(s) already up to date
159
+
160
+ 📁 Sync Location
161
+ Will sync to: ./KaimonDocs/
162
+
163
+ Continue? (y/N):
164
+ ```
165
+
110
166
  ## Troubleshooting
111
167
 
112
168
  ### "Not authenticated"
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pull.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/commands/pull.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,182 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import { pullDocuments } from '../../utils/syncOperations.js';
6
+ import * as config from '../../utils/config.js';
7
+ import * as supabaseClient from '../../utils/supabaseClient.js';
8
+ import * as tokenRefresh from '../../utils/tokenRefresh.js';
9
+ import { createTempDir, cleanupTempDir, mockConfig, mockDocumentRecord, mockBlockNoteContent, createMockSupabaseClient } from '../helpers.js';
10
+ describe('pull command', () => {
11
+ let tempDir;
12
+ let docsDir;
13
+ beforeEach(() => {
14
+ tempDir = createTempDir();
15
+ docsDir = path.join(tempDir, 'KaimonDocs');
16
+ vi.spyOn(os, 'homedir').mockReturnValue(tempDir);
17
+ vi.spyOn(process, 'cwd').mockReturnValue(tempDir);
18
+ });
19
+ afterEach(() => {
20
+ cleanupTempDir(tempDir);
21
+ vi.restoreAllMocks();
22
+ });
23
+ describe('pullDocuments', () => {
24
+ it('should pull new documents', async () => {
25
+ // Setup auth
26
+ config.saveConfig(mockConfig());
27
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
28
+ // Mock Supabase
29
+ const mockSupabase = createMockSupabaseClient();
30
+ const mockDocs = [mockDocumentRecord({ title: 'Test Document' })];
31
+ mockSupabase.from.mockReturnValue({
32
+ select: vi.fn().mockReturnThis(),
33
+ order: vi.fn().mockResolvedValue({ data: mockDocs, error: null })
34
+ });
35
+ const mockContent = mockBlockNoteContent('Test Document');
36
+ const blob = new Blob([JSON.stringify(mockContent)], { type: 'application/json' });
37
+ mockSupabase.storage.from.mockReturnValue({
38
+ download: vi.fn().mockResolvedValue({ data: blob, error: null })
39
+ });
40
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
41
+ // Pull with -y flag to skip confirmation
42
+ await pullDocuments(false, true);
43
+ // Verify file was created
44
+ const files = fs.readdirSync(docsDir);
45
+ expect(files).toHaveLength(1);
46
+ expect(files[0]).toContain('.md');
47
+ // Verify content
48
+ const content = fs.readFileSync(path.join(docsDir, files[0]), 'utf-8');
49
+ expect(content).toContain('kaimon_id:');
50
+ expect(content).toContain('Test Document');
51
+ });
52
+ it('should skip up-to-date documents', async () => {
53
+ config.saveConfig(mockConfig());
54
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
55
+ // Create existing file with newer mtime
56
+ const mockDoc = mockDocumentRecord({
57
+ id: 'doc-123',
58
+ title: 'Existing Document',
59
+ updated_at: new Date(Date.now() - 86400000).toISOString() // 1 day ago
60
+ });
61
+ fs.mkdirSync(docsDir, { recursive: true });
62
+ const existingFile = path.join(docsDir, 'Existing-Document.md');
63
+ fs.writeFileSync(existingFile, `---
64
+ kaimon_id: "doc-123"
65
+ ---
66
+
67
+ Content`, 'utf-8');
68
+ // Set file mtime to now (newer than remote)
69
+ fs.utimesSync(existingFile, new Date(), new Date());
70
+ const mockSupabase = createMockSupabaseClient();
71
+ mockSupabase.from.mockReturnValue({
72
+ select: vi.fn().mockReturnThis(),
73
+ order: vi.fn().mockResolvedValue({ data: [mockDoc], error: null })
74
+ });
75
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
76
+ await pullDocuments(false, true);
77
+ // File should not be modified
78
+ const content = fs.readFileSync(existingFile, 'utf-8');
79
+ expect(content).toBe(`---
80
+ kaimon_id: "doc-123"
81
+ ---
82
+
83
+ Content`);
84
+ });
85
+ it('should use flat directory structure with --flat', async () => {
86
+ config.saveConfig(mockConfig());
87
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
88
+ const mockSupabase = createMockSupabaseClient();
89
+ const mockDocs = [mockDocumentRecord()];
90
+ mockSupabase.from.mockReturnValue({
91
+ select: vi.fn().mockReturnThis(),
92
+ order: vi.fn().mockResolvedValue({ data: mockDocs, error: null })
93
+ });
94
+ const mockContent = mockBlockNoteContent();
95
+ const blob = new Blob([JSON.stringify(mockContent)], { type: 'application/json' });
96
+ mockSupabase.storage.from.mockReturnValue({
97
+ download: vi.fn().mockResolvedValue({ data: blob, error: null })
98
+ });
99
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
100
+ // Pull with --flat
101
+ await pullDocuments(true, true);
102
+ // Files should be in current directory, not KaimonDocs/
103
+ const files = fs.readdirSync(tempDir);
104
+ const mdFiles = files.filter(f => f.endsWith('.md'));
105
+ expect(mdFiles.length).toBeGreaterThan(0);
106
+ expect(fs.existsSync(docsDir)).toBe(false);
107
+ });
108
+ it('should handle no documents gracefully', async () => {
109
+ config.saveConfig(mockConfig());
110
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
111
+ const mockSupabase = createMockSupabaseClient();
112
+ mockSupabase.from.mockReturnValue({
113
+ select: vi.fn().mockReturnThis(),
114
+ order: vi.fn().mockResolvedValue({ data: [], error: null })
115
+ });
116
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
117
+ await pullDocuments(false, true);
118
+ // Should not create directory if no docs
119
+ expect(fs.existsSync(docsDir)).toBe(false);
120
+ });
121
+ it('should handle authentication failure', async () => {
122
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(false);
123
+ await expect(pullDocuments(false, true)).rejects.toThrow('Not authenticated');
124
+ });
125
+ it('should handle database errors', async () => {
126
+ config.saveConfig(mockConfig());
127
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
128
+ const mockSupabase = createMockSupabaseClient();
129
+ mockSupabase.from.mockReturnValue({
130
+ select: vi.fn().mockReturnThis(),
131
+ order: vi.fn().mockResolvedValue({
132
+ data: null,
133
+ error: { message: 'Database error' }
134
+ })
135
+ });
136
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
137
+ await expect(pullDocuments(false, true)).rejects.toThrow();
138
+ });
139
+ it('should handle storage download errors gracefully', async () => {
140
+ config.saveConfig(mockConfig());
141
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
142
+ const mockSupabase = createMockSupabaseClient();
143
+ const mockDocs = [mockDocumentRecord()];
144
+ mockSupabase.from.mockReturnValue({
145
+ select: vi.fn().mockReturnThis(),
146
+ order: vi.fn().mockResolvedValue({ data: mockDocs, error: null })
147
+ });
148
+ mockSupabase.storage.from.mockReturnValue({
149
+ download: vi.fn().mockResolvedValue({
150
+ data: null,
151
+ error: { message: 'File not found' }
152
+ })
153
+ });
154
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
155
+ // Should not throw, but handle error gracefully
156
+ await pullDocuments(false, true);
157
+ });
158
+ it('should update file mtime to match remote', async () => {
159
+ config.saveConfig(mockConfig());
160
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
161
+ const remoteTime = new Date('2024-01-15T10:00:00Z');
162
+ const mockDoc = mockDocumentRecord({ updated_at: remoteTime.toISOString() });
163
+ const mockSupabase = createMockSupabaseClient();
164
+ mockSupabase.from.mockReturnValue({
165
+ select: vi.fn().mockReturnThis(),
166
+ order: vi.fn().mockResolvedValue({ data: [mockDoc], error: null })
167
+ });
168
+ const mockContent = mockBlockNoteContent();
169
+ const blob = new Blob([JSON.stringify(mockContent)], { type: 'application/json' });
170
+ mockSupabase.storage.from.mockReturnValue({
171
+ download: vi.fn().mockResolvedValue({ data: blob, error: null })
172
+ });
173
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
174
+ await pullDocuments(false, true);
175
+ const files = fs.readdirSync(docsDir);
176
+ const filePath = path.join(docsDir, files[0]);
177
+ const stats = fs.statSync(filePath);
178
+ expect(stats.mtime.toISOString()).toBe(remoteTime.toISOString());
179
+ });
180
+ });
181
+ });
182
+ //# sourceMappingURL=pull.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.test.js","sourceRoot":"","sources":["../../../src/__tests__/commands/pull.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=push.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/commands/push.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,255 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import { pushDocuments } from '../../utils/pushOperations.js';
6
+ import * as config from '../../utils/config.js';
7
+ import * as supabaseClient from '../../utils/supabaseClient.js';
8
+ import * as tokenRefresh from '../../utils/tokenRefresh.js';
9
+ import { createTempDir, cleanupTempDir, mockConfig, mockDocumentRecord, createMockSupabaseClient, createMockMarkdownFile } from '../helpers.js';
10
+ describe('push command', () => {
11
+ let tempDir;
12
+ beforeEach(() => {
13
+ tempDir = createTempDir();
14
+ vi.spyOn(os, 'homedir').mockReturnValue(tempDir);
15
+ vi.spyOn(process, 'cwd').mockReturnValue(tempDir);
16
+ });
17
+ afterEach(() => {
18
+ cleanupTempDir(tempDir);
19
+ vi.restoreAllMocks();
20
+ });
21
+ describe('pushDocuments', () => {
22
+ it('should create new documents without kaimon_id', async () => {
23
+ config.saveConfig(mockConfig());
24
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
25
+ // Create a markdown file without kaimon_id
26
+ const filePath = createMockMarkdownFile(tempDir, 'new-doc.md', '# New Document\n\nContent here.');
27
+ const mockSupabase = createMockSupabaseClient();
28
+ // Mock user
29
+ mockSupabase.auth.getUser.mockResolvedValue({
30
+ data: { user: { id: 'user-123', email: 'test@example.com' } },
31
+ error: null
32
+ });
33
+ // Create a chainable mock query builder
34
+ const mockChain = {
35
+ select: vi.fn().mockReturnThis(),
36
+ in: vi.fn().mockResolvedValue({ data: [], error: null }),
37
+ insert: vi.fn().mockReturnThis(),
38
+ single: vi.fn().mockResolvedValue({
39
+ data: { id: 'new-doc-id', title: 'new-doc', created_at: new Date().toISOString(), updated_at: new Date().toISOString() },
40
+ error: null
41
+ })
42
+ };
43
+ // Make sure each method returns the same chain object
44
+ mockChain.select.mockReturnValue(mockChain);
45
+ mockChain.insert.mockReturnValue(mockChain);
46
+ mockSupabase.from.mockReturnValue(mockChain);
47
+ // Mock storage upload
48
+ mockSupabase.storage.from.mockReturnValue({
49
+ upload: vi.fn().mockResolvedValue({ data: {}, error: null })
50
+ });
51
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
52
+ await pushDocuments({ skipConfirmation: true });
53
+ // Verify insert was called (document created)
54
+ expect(mockChain.insert).toHaveBeenCalled();
55
+ // Verify file was updated with kaimon_id
56
+ const content = fs.readFileSync(filePath, 'utf-8');
57
+ expect(content).toContain('kaimon_id: "new-doc-id"');
58
+ });
59
+ it('should update existing documents with kaimon_id', async () => {
60
+ config.saveConfig(mockConfig());
61
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
62
+ // Create a markdown file with kaimon_id (older than remote)
63
+ const oldTime = new Date(Date.now() - 86400000); // 1 day ago
64
+ const filePath = createMockMarkdownFile(tempDir, 'existing-doc.md', '# Updated Content', { kaimon_id: 'doc-123', updated_at: oldTime.toISOString() });
65
+ // Make file newer by touching it
66
+ const newTime = new Date();
67
+ fs.utimesSync(filePath, newTime, newTime);
68
+ const mockSupabase = createMockSupabaseClient();
69
+ mockSupabase.auth.getUser.mockResolvedValue({
70
+ data: { user: { id: 'user-123', email: 'test@example.com' } },
71
+ error: null
72
+ });
73
+ // Mock finding existing document
74
+ mockSupabase.from.mockReturnValue({
75
+ select: vi.fn().mockReturnThis(),
76
+ in: vi.fn().mockResolvedValue({
77
+ data: [mockDocumentRecord({ id: 'doc-123', updated_at: oldTime.toISOString() })],
78
+ error: null
79
+ }),
80
+ update: vi.fn().mockReturnThis(),
81
+ eq: vi.fn().mockResolvedValue({ error: null })
82
+ });
83
+ mockSupabase.storage.from.mockReturnValue({
84
+ upload: vi.fn().mockResolvedValue({ data: {}, error: null })
85
+ });
86
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
87
+ await pushDocuments({ skipConfirmation: true });
88
+ // Verify upload was called
89
+ expect(mockSupabase.storage.from().upload).toHaveBeenCalled();
90
+ });
91
+ it('should skip up-to-date documents', async () => {
92
+ config.saveConfig(mockConfig());
93
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
94
+ // Create file with older local time
95
+ const oldTime = new Date(Date.now() - 86400000);
96
+ const filePath = createMockMarkdownFile(tempDir, 'old-doc.md', '# Content', { kaimon_id: 'doc-123' });
97
+ fs.utimesSync(filePath, oldTime, oldTime);
98
+ const mockSupabase = createMockSupabaseClient();
99
+ mockSupabase.auth.getUser.mockResolvedValue({
100
+ data: { user: { id: 'user-123' } },
101
+ error: null
102
+ });
103
+ // Remote is newer
104
+ mockSupabase.from.mockReturnValue({
105
+ select: vi.fn().mockReturnThis(),
106
+ in: vi.fn().mockResolvedValue({
107
+ data: [mockDocumentRecord({ id: 'doc-123', updated_at: new Date().toISOString() })],
108
+ error: null
109
+ })
110
+ });
111
+ const uploadSpy = vi.fn().mockResolvedValue({ data: {}, error: null });
112
+ mockSupabase.storage.from.mockReturnValue({
113
+ upload: uploadSpy
114
+ });
115
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
116
+ await pushDocuments({ skipConfirmation: true });
117
+ // Upload should not be called for up-to-date docs
118
+ expect(uploadSpy).not.toHaveBeenCalled();
119
+ });
120
+ it('should push only specified files', async () => {
121
+ config.saveConfig(mockConfig());
122
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
123
+ createMockMarkdownFile(tempDir, 'doc1.md', '# Doc 1');
124
+ createMockMarkdownFile(tempDir, 'doc2.md', '# Doc 2');
125
+ createMockMarkdownFile(tempDir, 'doc3.md', '# Doc 3');
126
+ const mockSupabase = createMockSupabaseClient();
127
+ mockSupabase.auth.getUser.mockResolvedValue({
128
+ data: { user: { id: 'user-123' } },
129
+ error: null
130
+ });
131
+ mockSupabase.from.mockReturnValue({
132
+ select: vi.fn().mockReturnThis(),
133
+ in: vi.fn().mockResolvedValue({ data: [], error: null }),
134
+ insert: vi.fn().mockReturnThis(),
135
+ single: vi.fn().mockResolvedValue({
136
+ data: { id: 'new-id', created_at: new Date().toISOString(), updated_at: new Date().toISOString() },
137
+ error: null
138
+ })
139
+ });
140
+ const uploadSpy = vi.fn().mockResolvedValue({ data: {}, error: null });
141
+ mockSupabase.storage.from.mockReturnValue({
142
+ upload: uploadSpy
143
+ });
144
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
145
+ // Push only doc1.md
146
+ await pushDocuments({ files: ['doc1.md'], skipConfirmation: true });
147
+ // Only one file should be uploaded
148
+ expect(uploadSpy).toHaveBeenCalledTimes(1);
149
+ });
150
+ it('should skip excluded directories', async () => {
151
+ config.saveConfig(mockConfig());
152
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
153
+ // Create files in excluded directories
154
+ fs.mkdirSync(path.join(tempDir, 'node_modules'), { recursive: true });
155
+ fs.mkdirSync(path.join(tempDir, '.git'), { recursive: true });
156
+ createMockMarkdownFile(path.join(tempDir, 'node_modules'), 'should-skip.md', '# Skip');
157
+ createMockMarkdownFile(path.join(tempDir, '.git'), 'also-skip.md', '# Skip');
158
+ createMockMarkdownFile(tempDir, 'should-include.md', '# Include');
159
+ const mockSupabase = createMockSupabaseClient();
160
+ mockSupabase.auth.getUser.mockResolvedValue({
161
+ data: { user: { id: 'user-123' } },
162
+ error: null
163
+ });
164
+ mockSupabase.from.mockReturnValue({
165
+ select: vi.fn().mockReturnThis(),
166
+ in: vi.fn().mockResolvedValue({ data: [], error: null }),
167
+ insert: vi.fn().mockReturnThis(),
168
+ single: vi.fn().mockResolvedValue({
169
+ data: { id: 'new-id', created_at: new Date().toISOString(), updated_at: new Date().toISOString() },
170
+ error: null
171
+ })
172
+ });
173
+ const uploadSpy = vi.fn().mockResolvedValue({ data: {}, error: null });
174
+ mockSupabase.storage.from.mockReturnValue({
175
+ upload: uploadSpy
176
+ });
177
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
178
+ await pushDocuments({ skipConfirmation: true });
179
+ // Only one file should be found (excluded dirs skipped)
180
+ expect(uploadSpy).toHaveBeenCalledTimes(1);
181
+ });
182
+ it('should handle no markdown files gracefully', async () => {
183
+ config.saveConfig(mockConfig());
184
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
185
+ const mockSupabase = createMockSupabaseClient();
186
+ mockSupabase.auth.getUser.mockResolvedValue({
187
+ data: { user: { id: 'user-123' } },
188
+ error: null
189
+ });
190
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
191
+ await pushDocuments({ skipConfirmation: true });
192
+ // Should complete without error
193
+ });
194
+ it('should handle authentication failure', async () => {
195
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(false);
196
+ await expect(pushDocuments({ skipConfirmation: true })).rejects.toThrow('Not authenticated');
197
+ });
198
+ it('should handle upload errors gracefully', async () => {
199
+ config.saveConfig(mockConfig());
200
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
201
+ createMockMarkdownFile(tempDir, 'doc.md', '# Document');
202
+ const mockSupabase = createMockSupabaseClient();
203
+ mockSupabase.auth.getUser.mockResolvedValue({
204
+ data: { user: { id: 'user-123' } },
205
+ error: null
206
+ });
207
+ mockSupabase.from.mockReturnValue({
208
+ select: vi.fn().mockReturnThis(),
209
+ in: vi.fn().mockResolvedValue({ data: [], error: null }),
210
+ insert: vi.fn().mockReturnThis(),
211
+ single: vi.fn().mockResolvedValue({
212
+ data: { id: 'new-id', created_at: new Date().toISOString(), updated_at: new Date().toISOString() },
213
+ error: null
214
+ })
215
+ });
216
+ mockSupabase.storage.from.mockReturnValue({
217
+ upload: vi.fn().mockResolvedValue({
218
+ data: null,
219
+ error: { message: 'Upload failed' }
220
+ })
221
+ });
222
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
223
+ // Should not throw, but handle error gracefully
224
+ await pushDocuments({ skipConfirmation: true });
225
+ });
226
+ it('should extract title from filename if not in frontmatter', async () => {
227
+ config.saveConfig(mockConfig());
228
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
229
+ createMockMarkdownFile(tempDir, 'My-Great-Document.md', '# Content');
230
+ const mockSupabase = createMockSupabaseClient();
231
+ mockSupabase.auth.getUser.mockResolvedValue({
232
+ data: { user: { id: 'user-123' } },
233
+ error: null
234
+ });
235
+ const insertSpy = vi.fn().mockReturnThis();
236
+ mockSupabase.from.mockReturnValue({
237
+ select: vi.fn().mockReturnThis(),
238
+ in: vi.fn().mockResolvedValue({ data: [], error: null }),
239
+ insert: insertSpy,
240
+ single: vi.fn().mockResolvedValue({
241
+ data: { id: 'new-id', title: 'My-Great-Document', created_at: new Date().toISOString(), updated_at: new Date().toISOString() },
242
+ error: null
243
+ })
244
+ });
245
+ mockSupabase.storage.from.mockReturnValue({
246
+ upload: vi.fn().mockResolvedValue({ data: {}, error: null })
247
+ });
248
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
249
+ await pushDocuments({ skipConfirmation: true });
250
+ // Verify title was extracted from filename
251
+ expect(insertSpy).toHaveBeenCalledWith(expect.objectContaining({ title: 'My-Great-Document' }));
252
+ });
253
+ });
254
+ });
255
+ //# sourceMappingURL=push.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.test.js","sourceRoot":"","sources":["../../../src/__tests__/commands/push.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Test helpers for mocking and utilities
3
+ */
4
+ export declare function createMockSupabaseClient(): {
5
+ auth: {
6
+ getUser: import("vitest").Mock<import("@vitest/spy").Procedure>;
7
+ refreshSession: import("vitest").Mock<import("@vitest/spy").Procedure>;
8
+ };
9
+ from: import("vitest").Mock<import("@vitest/spy").Procedure>;
10
+ storage: {
11
+ from: import("vitest").Mock<import("@vitest/spy").Procedure>;
12
+ };
13
+ };
14
+ export declare function mockBlockNoteContent(title?: string): {
15
+ type: string;
16
+ content: ({
17
+ type: string;
18
+ props: {
19
+ level: number;
20
+ };
21
+ content: {
22
+ type: string;
23
+ text: string;
24
+ }[];
25
+ } | {
26
+ type: string;
27
+ content: {
28
+ type: string;
29
+ text: string;
30
+ }[];
31
+ props?: undefined;
32
+ })[];
33
+ };
34
+ export declare function mockDocumentRecord(overrides?: any): any;
35
+ export declare function createTempDir(prefix?: string): string;
36
+ export declare function cleanupTempDir(dirPath: string): void;
37
+ export declare function mockConfig(overrides?: any): any;
38
+ export declare function mockProjectConfig(overrides?: any): any;
39
+ export declare function createMockMarkdownFile(dirPath: string, filename: string, content: string, frontmatter?: any): string;
40
+ export declare function mockReadline(answers: string[]): {
41
+ createInterface: import("vitest").Mock<import("@vitest/spy").Procedure>;
42
+ };
43
+ export declare function mockStdin(input: string): {
44
+ on: import("vitest").Mock<(event: string, handler: (data: string) => void) => void>;
45
+ setRawMode: import("vitest").Mock<import("@vitest/spy").Procedure>;
46
+ resume: import("vitest").Mock<import("@vitest/spy").Procedure>;
47
+ pause: import("vitest").Mock<import("@vitest/spy").Procedure>;
48
+ };
49
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/__tests__/helpers.ts"],"names":[],"mappings":"AAKA;;GAEG;AAGH,wBAAgB,wBAAwB;;;;;;;;;EAkCvC;AAGD,wBAAgB,oBAAoB,CAAC,KAAK,GAAE,MAAwB;;;;;;;;;;;;;;;;;;;EAuBnE;AAGD,wBAAgB,kBAAkB,CAAC,SAAS,GAAE,GAAQ,OASrD;AAGD,wBAAgB,aAAa,CAAC,MAAM,GAAE,MAAuB,GAAG,MAAM,CAErE;AAGD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAIpD;AAGD,wBAAgB,UAAU,CAAC,SAAS,GAAE,GAAQ,OAQ7C;AAGD,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,GAAQ,OAUpD;AAGD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,GAAQ,GACpB,MAAM,CAaR;AAGD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE;;EAY7C;AAGD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM;sCAEjB,MAAM,WAAW,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;;;;EAW5D"}