@meechi-ai/core 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 (116) hide show
  1. package/LICENSE +624 -0
  2. package/README.md +59 -0
  3. package/dist/components/CalendarView.d.ts +3 -0
  4. package/dist/components/CalendarView.js +72 -0
  5. package/dist/components/ChatInterface.d.ts +6 -0
  6. package/dist/components/ChatInterface.js +105 -0
  7. package/dist/components/FileExplorer.d.ts +9 -0
  8. package/dist/components/FileExplorer.js +757 -0
  9. package/dist/components/Icon.d.ts +9 -0
  10. package/dist/components/Icon.js +44 -0
  11. package/dist/components/SourceEditor.d.ts +13 -0
  12. package/dist/components/SourceEditor.js +50 -0
  13. package/dist/components/ThemeProvider.d.ts +5 -0
  14. package/dist/components/ThemeProvider.js +105 -0
  15. package/dist/components/ThemeSwitcher.d.ts +1 -0
  16. package/dist/components/ThemeSwitcher.js +16 -0
  17. package/dist/components/voice/VoiceInputArea.d.ts +14 -0
  18. package/dist/components/voice/VoiceInputArea.js +190 -0
  19. package/dist/components/voice/VoiceOverlay.d.ts +7 -0
  20. package/dist/components/voice/VoiceOverlay.js +71 -0
  21. package/dist/hooks/useMeechi.d.ts +16 -0
  22. package/dist/hooks/useMeechi.js +461 -0
  23. package/dist/hooks/useSync.d.ts +8 -0
  24. package/dist/hooks/useSync.js +87 -0
  25. package/dist/index.d.ts +14 -0
  26. package/dist/index.js +22 -0
  27. package/dist/lib/ai/embeddings.d.ts +15 -0
  28. package/dist/lib/ai/embeddings.js +128 -0
  29. package/dist/lib/ai/gpu-lock.d.ts +19 -0
  30. package/dist/lib/ai/gpu-lock.js +43 -0
  31. package/dist/lib/ai/llm.worker.d.ts +1 -0
  32. package/dist/lib/ai/llm.worker.js +7 -0
  33. package/dist/lib/ai/local-llm.d.ts +30 -0
  34. package/dist/lib/ai/local-llm.js +211 -0
  35. package/dist/lib/ai/manager.d.ts +20 -0
  36. package/dist/lib/ai/manager.js +51 -0
  37. package/dist/lib/ai/parsing.d.ts +12 -0
  38. package/dist/lib/ai/parsing.js +56 -0
  39. package/dist/lib/ai/prompts.d.ts +2 -0
  40. package/dist/lib/ai/prompts.js +2 -0
  41. package/dist/lib/ai/providers/gemini.d.ts +6 -0
  42. package/dist/lib/ai/providers/gemini.js +88 -0
  43. package/dist/lib/ai/providers/groq.d.ts +6 -0
  44. package/dist/lib/ai/providers/groq.js +42 -0
  45. package/dist/lib/ai/registry.d.ts +29 -0
  46. package/dist/lib/ai/registry.js +52 -0
  47. package/dist/lib/ai/tools.d.ts +2 -0
  48. package/dist/lib/ai/tools.js +106 -0
  49. package/dist/lib/ai/types.d.ts +22 -0
  50. package/dist/lib/ai/types.js +1 -0
  51. package/dist/lib/ai/worker.d.ts +1 -0
  52. package/dist/lib/ai/worker.js +60 -0
  53. package/dist/lib/audio/input.d.ts +13 -0
  54. package/dist/lib/audio/input.js +121 -0
  55. package/dist/lib/audio/stt.d.ts +13 -0
  56. package/dist/lib/audio/stt.js +119 -0
  57. package/dist/lib/audio/tts.d.ts +12 -0
  58. package/dist/lib/audio/tts.js +128 -0
  59. package/dist/lib/audio/vad.d.ts +18 -0
  60. package/dist/lib/audio/vad.js +117 -0
  61. package/dist/lib/colors.d.ts +16 -0
  62. package/dist/lib/colors.js +67 -0
  63. package/dist/lib/extensions.d.ts +35 -0
  64. package/dist/lib/extensions.js +24 -0
  65. package/dist/lib/hooks/use-voice-loop.d.ts +13 -0
  66. package/dist/lib/hooks/use-voice-loop.js +313 -0
  67. package/dist/lib/mcp/McpClient.d.ts +19 -0
  68. package/dist/lib/mcp/McpClient.js +42 -0
  69. package/dist/lib/mcp/McpRegistry.d.ts +47 -0
  70. package/dist/lib/mcp/McpRegistry.js +117 -0
  71. package/dist/lib/mcp/native/GroqVoiceNative.d.ts +21 -0
  72. package/dist/lib/mcp/native/GroqVoiceNative.js +29 -0
  73. package/dist/lib/mcp/native/LocalSyncNative.d.ts +19 -0
  74. package/dist/lib/mcp/native/LocalSyncNative.js +26 -0
  75. package/dist/lib/mcp/native/LocalVoiceNative.d.ts +19 -0
  76. package/dist/lib/mcp/native/LocalVoiceNative.js +27 -0
  77. package/dist/lib/mcp/native/MeechiNativeCore.d.ts +25 -0
  78. package/dist/lib/mcp/native/MeechiNativeCore.js +209 -0
  79. package/dist/lib/mcp/native/index.d.ts +10 -0
  80. package/dist/lib/mcp/native/index.js +10 -0
  81. package/dist/lib/mcp/types.d.ts +35 -0
  82. package/dist/lib/mcp/types.js +1 -0
  83. package/dist/lib/pdf.d.ts +10 -0
  84. package/dist/lib/pdf.js +142 -0
  85. package/dist/lib/settings.d.ts +48 -0
  86. package/dist/lib/settings.js +87 -0
  87. package/dist/lib/storage/db.d.ts +57 -0
  88. package/dist/lib/storage/db.js +45 -0
  89. package/dist/lib/storage/local.d.ts +28 -0
  90. package/dist/lib/storage/local.js +534 -0
  91. package/dist/lib/storage/migrate.d.ts +3 -0
  92. package/dist/lib/storage/migrate.js +122 -0
  93. package/dist/lib/storage/types.d.ts +66 -0
  94. package/dist/lib/storage/types.js +1 -0
  95. package/dist/lib/sync/client-drive.d.ts +9 -0
  96. package/dist/lib/sync/client-drive.js +69 -0
  97. package/dist/lib/sync/engine.d.ts +18 -0
  98. package/dist/lib/sync/engine.js +517 -0
  99. package/dist/lib/sync/google-drive.d.ts +52 -0
  100. package/dist/lib/sync/google-drive.js +183 -0
  101. package/dist/lib/sync/merge.d.ts +1 -0
  102. package/dist/lib/sync/merge.js +68 -0
  103. package/dist/lib/yjs/YjsProvider.d.ts +11 -0
  104. package/dist/lib/yjs/YjsProvider.js +33 -0
  105. package/dist/lib/yjs/graph.d.ts +11 -0
  106. package/dist/lib/yjs/graph.js +7 -0
  107. package/dist/lib/yjs/hooks.d.ts +7 -0
  108. package/dist/lib/yjs/hooks.js +37 -0
  109. package/dist/lib/yjs/store.d.ts +4 -0
  110. package/dist/lib/yjs/store.js +19 -0
  111. package/dist/lib/yjs/syncGraph.d.ts +1 -0
  112. package/dist/lib/yjs/syncGraph.js +38 -0
  113. package/dist/providers/theme-provider.d.ts +3 -0
  114. package/dist/providers/theme-provider.js +18 -0
  115. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  116. package/package.json +69 -0
@@ -0,0 +1,122 @@
1
+ import { openDB } from 'idb';
2
+ import { db } from './db';
3
+ import Dexie from 'dexie';
4
+ const OLD_DB_NAME = 'michio-local-v1';
5
+ const OLD_STORE_NAME = 'files';
6
+ export async function migrateFromIdbToDexie() {
7
+ // 1. Check if we already have data in Dexie
8
+ const count = await db.files.count();
9
+ if (count > 0) {
10
+ // Already migrated
11
+ return;
12
+ }
13
+ try {
14
+ const oldDb = await openDB(OLD_DB_NAME, 1, {
15
+ upgrade(db) {
16
+ if (!db.objectStoreNames.contains(OLD_STORE_NAME)) {
17
+ // No old store
18
+ }
19
+ }
20
+ });
21
+ if (!oldDb.objectStoreNames.contains(OLD_STORE_NAME)) {
22
+ return;
23
+ }
24
+ const allRecords = await oldDb.getAll(OLD_STORE_NAME);
25
+ if (allRecords.length === 0)
26
+ return;
27
+ // 4. Transform & Insert
28
+ const recordsToInsert = allRecords.map((rec) => ({
29
+ path: rec.path,
30
+ content: rec.content,
31
+ updatedAt: rec.updatedAt,
32
+ remoteId: rec.remoteId,
33
+ type: 'file'
34
+ }));
35
+ // Use bulkPut to overwrite/merge
36
+ await db.files.bulkPut(recordsToInsert);
37
+ console.log(`[Meechi] Migrated ${recordsToInsert.length} files to new storage.`);
38
+ }
39
+ catch (e) {
40
+ console.warn("Migration check failed (safe to ignore if new user)", e);
41
+ }
42
+ }
43
+ const OLD_MICHIO_DB = 'michio-db';
44
+ export async function migrateFromMichioToMeechi() {
45
+ // Check if new DB is empty
46
+ const count = await db.files.count();
47
+ if (count > 0)
48
+ return; // Already initialized
49
+ // Check if old DB exists via Dexie
50
+ const oldExists = await Dexie.exists(OLD_MICHIO_DB);
51
+ if (!oldExists)
52
+ return;
53
+ console.log("[Meechi] Migrating from michio-db...");
54
+ try {
55
+ const oldDb = new Dexie(OLD_MICHIO_DB);
56
+ oldDb.version(1).stores({
57
+ files: 'path, remoteId, type, updatedAt'
58
+ });
59
+ // We know up to version 6 existed, let's just try to open dynamic or match the latest structure
60
+ // Since Dexie can open dynamically if we don't specify version, or we can use idb to just dump stores.
61
+ // Using idb is safer for raw dump.
62
+ const oldIdb = await openDB(OLD_MICHIO_DB);
63
+ // Migrate Files
64
+ if (oldIdb.objectStoreNames.contains('files')) {
65
+ const files = await oldIdb.getAll('files');
66
+ if (files.length > 0) {
67
+ // Ensure tags/metadata structure if moving from v6
68
+ // But since our current schema is v6, we can just put them in.
69
+ // We might need to sanitize if schema changed, but it hasn't between michio->meechi rename.
70
+ await db.files.bulkPut(files);
71
+ console.log(`[Meechi] Transferred ${files.length} files from michio-db`);
72
+ }
73
+ }
74
+ // Migrate Settings
75
+ if (oldIdb.objectStoreNames.contains('settings')) {
76
+ const settings = await oldIdb.getAll('settings');
77
+ if (settings.length > 0) {
78
+ await db.settings.bulkPut(settings);
79
+ }
80
+ }
81
+ // Migrate Journal
82
+ if (oldIdb.objectStoreNames.contains('journal')) {
83
+ const journal = await oldIdb.getAll('journal');
84
+ if (journal.length > 0) {
85
+ await db.journal.bulkPut(journal);
86
+ }
87
+ }
88
+ console.log("[Meechi] Migration complete.");
89
+ }
90
+ catch (e) {
91
+ console.error("[Meechi] Migration from michio-db failed", e);
92
+ }
93
+ }
94
+ const GUEST_DB_NAME = 'michio-guest-db';
95
+ export async function migrateJournal() {
96
+ const count = await db.journal.count();
97
+ if (count > 0)
98
+ return;
99
+ try {
100
+ // We just try to open it. If it doesn't exist, openDB might create it empty or fail?
101
+ // Actually IDB openDB will create if not exists. We should check if it has the store.
102
+ const guestDb = await openDB(GUEST_DB_NAME, 1, {
103
+ upgrade(db) {
104
+ // If it doesn't exist, we don't create stores here, we just want to read.
105
+ // But openDB with upgrade triggers creation.
106
+ // If we don't provide upgrade, and version matches, it opens.
107
+ // If we want to check existence safely:
108
+ }
109
+ });
110
+ if (!guestDb.objectStoreNames.contains('journal')) {
111
+ return;
112
+ }
113
+ const allEntries = await guestDb.getAll('journal');
114
+ if (allEntries.length > 0) {
115
+ await db.journal.bulkAdd(allEntries);
116
+ console.log(`[Meechi] Migrated ${allEntries.length} journal entries.`);
117
+ }
118
+ }
119
+ catch (e) {
120
+ // Likely DB doesn't exist or other error
121
+ }
122
+ }
@@ -0,0 +1,66 @@
1
+ export interface FileMetadata {
2
+ isSource?: boolean;
3
+ originalContent?: string;
4
+ summary?: string;
5
+ comments?: Array<{
6
+ id: string;
7
+ text: string;
8
+ range?: any;
9
+ timestamp: number;
10
+ }>;
11
+ [key: string]: any;
12
+ }
13
+ export interface FileMeta {
14
+ id: string;
15
+ name: string;
16
+ path: string;
17
+ updatedAt: number;
18
+ type: 'file' | 'folder' | 'source';
19
+ remoteId?: string;
20
+ deleted?: number;
21
+ tags?: string[];
22
+ metadata?: FileMetadata;
23
+ content?: string | Blob | ArrayBuffer;
24
+ }
25
+ export interface StorageProvider {
26
+ /**
27
+ * Initialize the storage (e.g. open DB, auth check)
28
+ */
29
+ init(): Promise<void>;
30
+ /**
31
+ * Write content to a file. Overwrites if exists.
32
+ */
33
+ saveFile(virtualPath: string, content: string | Blob | ArrayBuffer, remoteId?: string, tags?: string[], metadata?: any): Promise<void>;
34
+ updateMetadata(virtualPath: string, updates: Partial<FileMeta>): Promise<void>;
35
+ getFilesByTag(tag: string): Promise<FileMeta[]>;
36
+ /**
37
+ * Read content of a file. Returns null if not found.
38
+ */
39
+ readFile(virtualPath: string): Promise<string | Blob | ArrayBuffer | null>;
40
+ /**
41
+ * List files in a virtual folder.
42
+ */
43
+ listFiles(virtualFolder: string): Promise<FileMeta[]>;
44
+ /**
45
+ * Append content to a file. Creates if not exists.
46
+ */
47
+ appendFile(virtualPath: string, content: string): Promise<void>;
48
+ renameFile(oldPath: string, newPath: string): Promise<void>;
49
+ deleteFile(virtualPath: string): Promise<void>;
50
+ createFolder(virtualPath: string): Promise<void>;
51
+ getFile(virtualPath: string): Promise<FileMeta | null>;
52
+ resetSyncState(): Promise<void>;
53
+ factoryReset(): Promise<void>;
54
+ /**
55
+ * Trigger a manual sync immediately.
56
+ */
57
+ forceSync?(): Promise<void>;
58
+ /**
59
+ * Collect relevant context for the AI from the local knowledge base.
60
+ */
61
+ getKnowledgeContext(query?: string): Promise<string>;
62
+ /**
63
+ * Re-index a file for semantic search.
64
+ */
65
+ indexFile(path: string, content: string): Promise<void>;
66
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ export declare class ClientDriveService {
2
+ private accessToken;
3
+ constructor();
4
+ setToken(token: string): void;
5
+ private request;
6
+ listFiles(): Promise<any>;
7
+ getFileContent(fileId: string): Promise<string>;
8
+ }
9
+ export declare const clientDrive: ClientDriveService;
@@ -0,0 +1,69 @@
1
+ // Client-Side Google Drive Service for Desktop App
2
+ // This replaces the server-side logic in /api/sync/* when running in static mode.
3
+ const GOOGLE_DRIVE_API_BASE = 'https://www.googleapis.com/drive/v3';
4
+ const DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive.file';
5
+ export class ClientDriveService {
6
+ constructor() {
7
+ this.accessToken = null;
8
+ if (typeof window !== 'undefined') {
9
+ this.accessToken = localStorage.getItem('google_access_token');
10
+ }
11
+ }
12
+ setToken(token) {
13
+ this.accessToken = token;
14
+ localStorage.setItem('google_access_token', token);
15
+ }
16
+ async request(endpoint, options = {}) {
17
+ if (!this.accessToken) {
18
+ throw new Error("No Google Access Token found. Please connect Account.");
19
+ }
20
+ const url = `${GOOGLE_DRIVE_API_BASE}/${endpoint}`;
21
+ const headers = Object.assign({ 'Authorization': `Bearer ${this.accessToken}`, 'Content-Type': 'application/json' }, options.headers);
22
+ const res = await fetch(url, Object.assign(Object.assign({}, options), { headers }));
23
+ if (res.status === 401) {
24
+ // Token expired
25
+ localStorage.removeItem('google_access_token');
26
+ this.accessToken = null;
27
+ throw new Error("Token Expired. Please reconnect.");
28
+ }
29
+ if (!res.ok) {
30
+ throw new Error(`Google Drive API Error: ${res.statusText}`);
31
+ }
32
+ return res.json();
33
+ }
34
+ async listFiles() {
35
+ try {
36
+ // Query for Docs and PDFs, not trashed
37
+ const q = "mimeType != 'application/vnd.google-apps.folder' and trashed = false";
38
+ const res = await this.request(`files?q=${encodeURIComponent(q)}&fields=files(id, name, mimeType, modifiedTime)`);
39
+ return res.files || [];
40
+ }
41
+ catch (e) {
42
+ console.error("Client Drive List Error:", e);
43
+ throw e;
44
+ }
45
+ }
46
+ async getFileContent(fileId) {
47
+ // For Google Docs, we must export them. For PDFs/Text, get media.
48
+ // Simplified: Export everything as text/plain if possible
49
+ try {
50
+ // 1. Check Metadata
51
+ const metadata = await this.request(`files/${fileId}?fields=mimeType`);
52
+ let url = `${GOOGLE_DRIVE_API_BASE}/files/${fileId}?alt=media`;
53
+ if (metadata.mimeType === 'application/vnd.google-apps.document') {
54
+ url = `${GOOGLE_DRIVE_API_BASE}/files/${fileId}/export?mimeType=text/plain`;
55
+ }
56
+ const res = await fetch(url, {
57
+ headers: { 'Authorization': `Bearer ${this.accessToken}` }
58
+ });
59
+ if (!res.ok)
60
+ throw new Error("Failed to download file content");
61
+ return await res.text();
62
+ }
63
+ catch (e) {
64
+ console.error("Download Error:", e);
65
+ throw e;
66
+ }
67
+ }
68
+ }
69
+ export const clientDrive = new ClientDriveService();
@@ -0,0 +1,18 @@
1
+ import { GoogleDriveClient } from './google-drive';
2
+ import { StorageProvider } from '../storage/types';
3
+ export declare class SyncEngine {
4
+ private drive;
5
+ private storage;
6
+ private syncing;
7
+ constructor(drive: GoogleDriveClient, storage: StorageProvider);
8
+ sync(onProgress?: (msg: string) => void): Promise<void>;
9
+ private syncDown;
10
+ private performInitialPull;
11
+ private recursivePull;
12
+ private handleRemoteDelete;
13
+ private handleRemoteChange;
14
+ private syncUp;
15
+ private getName;
16
+ private getRootFolderId;
17
+ private resolveParentId;
18
+ }