@hasna/cloud 0.1.35 → 0.1.36

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 (78) hide show
  1. package/LICENSE +2 -1
  2. package/README.md +30 -27
  3. package/dist/adapter.d.ts +65 -0
  4. package/dist/adapter.d.ts.map +1 -0
  5. package/dist/adapter.test.d.ts +2 -0
  6. package/dist/adapter.test.d.ts.map +1 -0
  7. package/dist/auto-sync.d.ts +28 -0
  8. package/dist/auto-sync.d.ts.map +1 -0
  9. package/dist/cli/cmd-doctor.d.ts +3 -0
  10. package/dist/cli/cmd-doctor.d.ts.map +1 -0
  11. package/dist/cli/cmd-feedback.d.ts +3 -0
  12. package/dist/cli/cmd-feedback.d.ts.map +1 -0
  13. package/dist/cli/cmd-migrate.d.ts +3 -0
  14. package/dist/cli/cmd-migrate.d.ts.map +1 -0
  15. package/dist/cli/cmd-setup.d.ts +3 -0
  16. package/dist/cli/cmd-setup.d.ts.map +1 -0
  17. package/dist/cli/cmd-sync.d.ts +4 -0
  18. package/dist/cli/cmd-sync.d.ts.map +1 -0
  19. package/dist/cli/index.d.ts +3 -0
  20. package/dist/cli/index.d.ts.map +1 -0
  21. package/dist/cli/index.js +15346 -0
  22. package/dist/cli-helpers.d.ts +17 -0
  23. package/dist/cli-helpers.d.ts.map +1 -0
  24. package/dist/config.d.ts +220 -0
  25. package/dist/config.d.ts.map +1 -0
  26. package/dist/daemon-sync.d.ts +108 -0
  27. package/dist/daemon-sync.d.ts.map +1 -0
  28. package/dist/dialect.d.ts +17 -0
  29. package/dist/dialect.d.ts.map +1 -0
  30. package/dist/dialect.test.d.ts +2 -0
  31. package/dist/dialect.test.d.ts.map +1 -0
  32. package/dist/discover.d.ts +35 -0
  33. package/dist/discover.d.ts.map +1 -0
  34. package/dist/discover.test.d.ts +2 -0
  35. package/dist/discover.test.d.ts.map +1 -0
  36. package/dist/dotfile.d.ts +27 -0
  37. package/dist/dotfile.d.ts.map +1 -0
  38. package/dist/feedback.d.ts +32 -0
  39. package/dist/feedback.d.ts.map +1 -0
  40. package/dist/index.d.ts +19 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +12223 -0
  43. package/dist/machines.d.ts +63 -0
  44. package/dist/machines.d.ts.map +1 -0
  45. package/dist/mcp/bin.js +2 -0
  46. package/dist/mcp/http.d.ts +28 -0
  47. package/dist/mcp/http.d.ts.map +1 -0
  48. package/dist/mcp/index.d.ts +4 -0
  49. package/dist/mcp/index.d.ts.map +1 -0
  50. package/dist/mcp/index.js +27795 -0
  51. package/dist/mcp-helpers.d.ts +22 -0
  52. package/dist/mcp-helpers.d.ts.map +1 -0
  53. package/dist/pg-migrate.d.ts +58 -0
  54. package/dist/pg-migrate.d.ts.map +1 -0
  55. package/dist/scheduled-sync.d.ts +24 -0
  56. package/dist/scheduled-sync.d.ts.map +1 -0
  57. package/dist/scheduled-sync.js +9517 -0
  58. package/dist/sync-conflicts.d.ts +76 -0
  59. package/dist/sync-conflicts.d.ts.map +1 -0
  60. package/dist/sync-conflicts.test.d.ts +2 -0
  61. package/dist/sync-conflicts.test.d.ts.map +1 -0
  62. package/dist/sync-incremental.d.ts +67 -0
  63. package/dist/sync-incremental.d.ts.map +1 -0
  64. package/dist/sync-progress.d.ts +68 -0
  65. package/dist/sync-progress.d.ts.map +1 -0
  66. package/dist/sync-schedule.d.ts +36 -0
  67. package/dist/sync-schedule.d.ts.map +1 -0
  68. package/dist/sync-schedule.test.d.ts +2 -0
  69. package/dist/sync-schedule.test.d.ts.map +1 -0
  70. package/dist/sync.d.ts +53 -0
  71. package/dist/sync.d.ts.map +1 -0
  72. package/dist/sync.test.d.ts +2 -0
  73. package/dist/sync.test.d.ts.map +1 -0
  74. package/package.json +26 -15
  75. package/archive/cli.js +0 -4
  76. package/archive/index.d.ts +0 -9
  77. package/archive/index.js +0 -15
  78. package/archive/mcp.js +0 -4
@@ -0,0 +1,76 @@
1
+ import type { DbAdapter } from "./adapter.js";
2
+ export interface SyncConflict {
3
+ table: string;
4
+ row_id: string;
5
+ local_updated_at: string;
6
+ remote_updated_at: string;
7
+ local_data: Record<string, any>;
8
+ remote_data: Record<string, any>;
9
+ resolved: boolean;
10
+ resolution?: "local-wins" | "remote-wins" | "newest-wins" | "manual";
11
+ }
12
+ export type ConflictStrategy = "local-wins" | "remote-wins" | "newest-wins";
13
+ export interface StoredConflict {
14
+ id: string;
15
+ table_name: string;
16
+ row_id: string;
17
+ local_data: string;
18
+ remote_data: string;
19
+ local_updated_at: string;
20
+ remote_updated_at: string;
21
+ resolution: string | null;
22
+ resolved_at: string | null;
23
+ created_at: string;
24
+ }
25
+ /**
26
+ * Find rows that exist in BOTH local and remote datasets with DIFFERENT
27
+ * `updated_at` values. Returns a list of SyncConflict objects.
28
+ *
29
+ * @param local - Array of rows from the local database
30
+ * @param remote - Array of rows from the remote database
31
+ * @param table - The table name these rows belong to
32
+ * @param primaryKey - Column used as primary key (default: "id")
33
+ * @param conflictColumn - Column used for timestamp comparison (default: "updated_at")
34
+ */
35
+ export declare function detectConflicts(local: Record<string, any>[], remote: Record<string, any>[], table: string, primaryKey?: string, conflictColumn?: string): SyncConflict[];
36
+ /**
37
+ * Resolve a list of conflicts using the given strategy.
38
+ * Returns the winning row data for each conflict.
39
+ *
40
+ * @param conflicts - The conflicts to resolve
41
+ * @param strategy - Resolution strategy (default: "newest-wins")
42
+ * @returns Array of resolved conflicts with `resolved: true` and `resolution` set
43
+ */
44
+ export declare function resolveConflicts(conflicts: SyncConflict[], strategy?: ConflictStrategy): SyncConflict[];
45
+ /**
46
+ * Get the winning data for a resolved conflict.
47
+ */
48
+ export declare function getWinningData(conflict: SyncConflict): Record<string, any>;
49
+ /**
50
+ * Ensure the _sync_conflicts table exists.
51
+ */
52
+ export declare function ensureConflictsTable(db: DbAdapter): void;
53
+ /**
54
+ * Store unresolved conflicts in the database for later review.
55
+ */
56
+ export declare function storeConflicts(db: DbAdapter, conflicts: SyncConflict[]): void;
57
+ /**
58
+ * List all stored conflicts, optionally filtered by resolved status.
59
+ */
60
+ export declare function listConflicts(db: DbAdapter, opts?: {
61
+ resolved?: boolean;
62
+ table?: string;
63
+ }): StoredConflict[];
64
+ /**
65
+ * Resolve a stored conflict by ID using the given strategy.
66
+ */
67
+ export declare function resolveConflict(db: DbAdapter, conflictId: string, strategy: ConflictStrategy | "manual"): StoredConflict | null;
68
+ /**
69
+ * Get a single stored conflict by ID.
70
+ */
71
+ export declare function getConflict(db: DbAdapter, conflictId: string): StoredConflict | null;
72
+ /**
73
+ * Delete all resolved conflicts (cleanup).
74
+ */
75
+ export declare function purgeResolvedConflicts(db: DbAdapter): number;
76
+ //# sourceMappingURL=sync-conflicts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-conflicts.d.ts","sourceRoot":"","sources":["../src/sync-conflicts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAM9C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,YAAY,GAAG,aAAa,GAAG,aAAa,GAAG,QAAQ,CAAC;CACtE;AAED,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,aAAa,GAAG,aAAa,CAAC;AAE5E,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAC7B,KAAK,EAAE,MAAM,EACb,UAAU,SAAO,EACjB,cAAc,SAAe,GAC5B,YAAY,EAAE,CAkChB;AAMD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,YAAY,EAAE,EACzB,QAAQ,GAAE,gBAAgC,GACzC,YAAY,EAAE,CA4BhB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAyB1E;AAMD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI,CAexD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,IAAI,CAmB7E;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,SAAS,EACb,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,cAAc,EAAE,CAsBlB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,SAAS,EACb,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,gBAAgB,GAAG,QAAQ,GACpC,cAAc,GAAG,IAAI,CAoBvB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAMpF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,CAM5D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sync-conflicts.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-conflicts.test.d.ts","sourceRoot":"","sources":["../src/sync-conflicts.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ import type { DbAdapter } from "./adapter.js";
2
+ import type { ConflictStrategy } from "./sync-conflicts.js";
3
+ export interface IncrementalSyncStats {
4
+ table: string;
5
+ total_rows: number;
6
+ synced_rows: number;
7
+ skipped_rows: number;
8
+ errors: string[];
9
+ first_sync: boolean;
10
+ }
11
+ export interface SyncMeta {
12
+ table_name: string;
13
+ last_synced_at: string;
14
+ last_synced_row_count: number;
15
+ direction: "push" | "pull";
16
+ }
17
+ export interface IncrementalSyncOptions {
18
+ /** Primary key column name (default: "id"). */
19
+ primaryKey?: string;
20
+ /** Conflict resolution column (default: "updated_at"). */
21
+ conflictColumn?: string;
22
+ /** Batch size for writes (default: 500). */
23
+ batchSize?: number;
24
+ /** Conflict resolution strategy for rows present on both sides. */
25
+ conflictStrategy?: ConflictStrategy;
26
+ /** Which side is being transferred into the target. */
27
+ sourceRole?: "local" | "remote";
28
+ }
29
+ /**
30
+ * Ensure the `_sync_meta` table exists in the given database.
31
+ */
32
+ export declare function ensureSyncMetaTable(db: DbAdapter): void;
33
+ /**
34
+ * Push only changed rows (since last sync) from local to remote.
35
+ *
36
+ * - Checks `_sync_meta` in the local DB for `last_synced_at`.
37
+ * - If found: only selects rows where `updated_at > last_synced_at`.
38
+ * - If not found: full push (first-time sync).
39
+ * - After push, updates `_sync_meta` with current timestamp and row count.
40
+ */
41
+ export declare function incrementalSyncPush(local: DbAdapter, remote: DbAdapter, tables: string[], options?: IncrementalSyncOptions): IncrementalSyncStats[];
42
+ /**
43
+ * Pull only changed rows (since last sync) from remote to local.
44
+ *
45
+ * - Checks `_sync_meta` in the local DB for `last_synced_at`.
46
+ * - If found: only selects rows where `updated_at > last_synced_at`.
47
+ * - If not found: full pull (first-time sync).
48
+ * - After pull, updates `_sync_meta` with current timestamp and row count.
49
+ */
50
+ export declare function incrementalSyncPull(remote: DbAdapter, local: DbAdapter, tables: string[], options?: IncrementalSyncOptions): IncrementalSyncStats[];
51
+ /**
52
+ * Get the sync metadata for all tables or a specific table.
53
+ */
54
+ export declare function getSyncMetaAll(db: DbAdapter): SyncMeta[];
55
+ /**
56
+ * Get sync metadata for a specific table.
57
+ */
58
+ export declare function getSyncMetaForTable(db: DbAdapter, table: string): SyncMeta | null;
59
+ /**
60
+ * Reset sync metadata for a table (forces full re-sync on next run).
61
+ */
62
+ export declare function resetSyncMeta(db: DbAdapter, table: string): void;
63
+ /**
64
+ * Reset all sync metadata (forces full re-sync for all tables).
65
+ */
66
+ export declare function resetAllSyncMeta(db: DbAdapter): void;
67
+ //# sourceMappingURL=sync-incremental.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-incremental.d.ts","sourceRoot":"","sources":["../src/sync-incremental.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAM5D,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,uDAAuD;IACvD,UAAU,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CACjC;AAcD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI,CAEvD;AAmJD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,GAAE,sBAA2B,GACnC,oBAAoB,EAAE,CA4ExB;AAMD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,GAAE,sBAA2B,GACnC,oBAAoB,EAAE,CA4ExB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,SAAS,GAAG,QAAQ,EAAE,CAKxD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,SAAS,EACb,KAAK,EAAE,MAAM,GACZ,QAAQ,GAAG,IAAI,CAEjB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAGhE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI,CAGpD"}
@@ -0,0 +1,68 @@
1
+ import type { DbAdapter } from "./adapter.js";
2
+ export interface SyncProgressInfo {
3
+ table: string;
4
+ total: number;
5
+ done: number;
6
+ percent: number;
7
+ elapsed_ms: number;
8
+ eta_ms: number;
9
+ status: "pending" | "in_progress" | "completed" | "failed" | "resumed";
10
+ }
11
+ export type ProgressCallback = (progress: SyncProgressInfo) => void;
12
+ export interface ResumePoint {
13
+ table_name: string;
14
+ last_row_id: string;
15
+ direction: string;
16
+ started_at: string;
17
+ status: string;
18
+ }
19
+ export declare class SyncProgressTracker {
20
+ private db;
21
+ private progress;
22
+ private startTimes;
23
+ private callback?;
24
+ constructor(db: DbAdapter, callback?: ProgressCallback);
25
+ private ensureResumeTable;
26
+ /**
27
+ * Start tracking a table sync. Sets status to in_progress or resumed.
28
+ */
29
+ start(table: string, total: number, direction: string): void;
30
+ /**
31
+ * Update progress for a table after processing rows.
32
+ */
33
+ update(table: string, done: number, lastRowId: string): void;
34
+ /**
35
+ * Mark a table sync as completed.
36
+ */
37
+ markComplete(table: string): void;
38
+ /**
39
+ * Mark a table sync as failed.
40
+ */
41
+ markFailed(table: string, _error: string): void;
42
+ /**
43
+ * Check if a previous sync was interrupted (status is 'in_progress' or 'resumed').
44
+ */
45
+ canResume(table: string): boolean;
46
+ /**
47
+ * Returns the last successfully synced row ID for a table, or null.
48
+ */
49
+ getResumePoint(table: string): ResumePoint | null;
50
+ /**
51
+ * Clear resume state for a table (e.g., after a fresh sync starts).
52
+ */
53
+ clearResume(table: string): void;
54
+ /**
55
+ * Get current progress info for a table.
56
+ */
57
+ getProgress(table: string): SyncProgressInfo | null;
58
+ /**
59
+ * Get progress info for all tracked tables.
60
+ */
61
+ getAllProgress(): SyncProgressInfo[];
62
+ /**
63
+ * List all resume records from the database (including historical).
64
+ */
65
+ listResumeRecords(): ResumePoint[];
66
+ private notify;
67
+ }
68
+ //# sourceMappingURL=sync-progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-progress.d.ts","sourceRoot":"","sources":["../src/sync-progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAM9C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;CACxE;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAEpE,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAMD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,EAAE,CAAY;IACtB,OAAO,CAAC,QAAQ,CAA4C;IAC5D,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,QAAQ,CAAC,CAAmB;gBAExB,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,gBAAgB;IAUtD,OAAO,CAAC,iBAAiB;IAgBzB;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAmC5D;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IA0B5D;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAkBjC;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAmB/C;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IASjC;;OAEG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAUjD;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAahC;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAInD;;OAEG;IACH,cAAc,IAAI,gBAAgB,EAAE;IAIpC;;OAEG;IACH,iBAAiB,IAAI,WAAW,EAAE;IAUlC,OAAO,CAAC,MAAM;CAMf"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Parse a human-friendly interval string into minutes.
3
+ *
4
+ * Supported formats:
5
+ * - `5m`, `10m`, `30m` - minutes
6
+ * - `1h`, `2h` - hours (converted to minutes)
7
+ * - `5` - plain number treated as minutes
8
+ */
9
+ export declare function parseInterval(input: string): number;
10
+ /**
11
+ * Convert minutes to a cron expression.
12
+ */
13
+ export declare function minutesToCron(minutes: number): string;
14
+ export interface SyncScheduleStatus {
15
+ registered: boolean;
16
+ schedule_minutes: number;
17
+ cron_expression: string | null;
18
+ mechanism: "launchd" | "systemd" | "none";
19
+ }
20
+ /**
21
+ * Register a system-level scheduled sync.
22
+ *
23
+ * - macOS: creates a launchd plist in ~/Library/LaunchAgents/
24
+ * - Linux: creates a systemd user timer in ~/.config/systemd/user/
25
+ * - Persists interval in ~/.hasna/cloud/config.json
26
+ */
27
+ export declare function registerSyncSchedule(intervalMinutes: number): Promise<void>;
28
+ /**
29
+ * Remove the registered sync schedule.
30
+ */
31
+ export declare function removeSyncSchedule(): Promise<void>;
32
+ /**
33
+ * Get the current sync schedule status.
34
+ */
35
+ export declare function getSyncScheduleStatus(): SyncScheduleStatus;
36
+ //# sourceMappingURL=sync-schedule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-schedule.d.ts","sourceRoot":"","sources":["../src/sync-schedule.ts"],"names":[],"mappings":"AAgBA;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAiCnD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAiBrD;AAsKD,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;CAC3C;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAUxD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,kBAAkB,CAoB1D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sync-schedule.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-schedule.test.d.ts","sourceRoot":"","sources":["../src/sync-schedule.test.ts"],"names":[],"mappings":""}
package/dist/sync.d.ts ADDED
@@ -0,0 +1,53 @@
1
+ import type { DbAdapter } from "./adapter.js";
2
+ import type { PgAdapterAsync } from "./adapter.js";
3
+ export interface SyncProgress {
4
+ table: string;
5
+ phase: "reading" | "writing" | "done";
6
+ rowsRead: number;
7
+ rowsWritten: number;
8
+ totalTables: number;
9
+ currentTableIndex: number;
10
+ }
11
+ export type SyncProgressCallback = (progress: SyncProgress) => void;
12
+ export interface SyncOptions {
13
+ /** Tables to sync. */
14
+ tables: string[];
15
+ /** Optional progress callback. */
16
+ onProgress?: SyncProgressCallback;
17
+ /** Batch size for UPSERT operations. Default: 100 */
18
+ batchSize?: number;
19
+ /** Conflict resolution column (default: "updated_at"). Newest wins. */
20
+ conflictColumn?: string;
21
+ /**
22
+ * Primary key column name(s). Can be a single column string or an array
23
+ * for composite primary keys (default: auto-detected from the database).
24
+ * If not provided and auto-detection fails, falls back to "id".
25
+ */
26
+ primaryKey?: string | string[];
27
+ }
28
+ export interface SyncResult {
29
+ table: string;
30
+ rowsRead: number;
31
+ rowsWritten: number;
32
+ rowsSkipped: number;
33
+ errors: string[];
34
+ }
35
+ /**
36
+ * Push data from a local SQLite database to the cloud PostgreSQL database.
37
+ * Uses batch UPSERT for performance and FK-aware table ordering.
38
+ */
39
+ export declare function syncPush(local: DbAdapter, remote: PgAdapterAsync, options: SyncOptions): Promise<SyncResult[]>;
40
+ /**
41
+ * Pull data from the cloud PostgreSQL database into a local SQLite database.
42
+ * Uses FK-aware table ordering.
43
+ */
44
+ export declare function syncPull(remote: PgAdapterAsync, local: DbAdapter, options: SyncOptions): Promise<SyncResult[]>;
45
+ /**
46
+ * List all user tables in a SQLite database.
47
+ */
48
+ export declare function listSqliteTables(db: DbAdapter): string[];
49
+ /**
50
+ * List all user tables in a PostgreSQL database (async).
51
+ */
52
+ export declare function listPgTables(db: PgAdapterAsync): Promise<string[]>;
53
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAMnD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;AAEpE,MAAM,WAAW,WAAW;IAC1B,sBAAsB;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,kCAAkC;IAClC,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAClC,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAMD;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,EAAE,CAAC,CAGvB;AAMD;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,EAAE,CAAC,CAGvB;AAmxBD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,EAAE,CAKxD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAKxE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sync.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.test.d.ts","sourceRoot":"","sources":["../src/sync.test.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,35 +1,46 @@
1
1
  {
2
2
  "name": "@hasna/cloud",
3
- "version": "0.1.35",
4
- "description": "Deprecated archive stub for legacy Hasna cloud sync adapters; do not depend on this package",
3
+ "version": "0.1.36",
4
+ "description": "Shared cloud infrastructure database adapter (SQLite + PostgreSQL), sync engine, feedback system, unified dotfile config",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
- "main": "archive/index.js",
8
- "types": "archive/index.d.ts",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
9
  "bin": {
10
- "cloud": "archive/cli.js",
11
- "cloud-mcp": "archive/mcp.js"
10
+ "cloud": "dist/cli/index.js",
11
+ "cloud-mcp": "dist/mcp/bin.js"
12
12
  },
13
13
  "exports": {
14
14
  ".": {
15
- "import": "./archive/index.js",
16
- "types": "./archive/index.d.ts"
15
+ "import": "./dist/index.js",
16
+ "types": "./dist/index.d.ts"
17
17
  }
18
18
  },
19
19
  "files": [
20
- "archive",
21
- "README.md",
20
+ "dist",
22
21
  "LICENSE"
23
22
  ],
24
23
  "scripts": {
25
- "build": "bun -e 'await import(\"./archive/index.js\")'",
26
- "test": "bun -e 'const mod = await import(\"./archive/index.js\"); if (!mod.archivedCloudPackageNotice().includes(\"deprecated\")) process.exit(1)'"
27
- },
28
- "devDependencies": {
29
- "@types/bun": "^1.2.6"
24
+ "build": "bun build src/index.ts --outdir dist --target node && bun build src/cli/index.ts --outdir dist/cli --target node && bun build src/mcp/index.ts --outdir dist/mcp --target node && printf '#!/usr/bin/env bun\\nimport \"./index.js\";\\n' > dist/mcp/bin.js && chmod +x dist/mcp/bin.js && bun build src/scheduled-sync.ts --outdir dist --target node && bun run build:types",
25
+ "build:types": "tsc --emitDeclarationOnly --declaration --outDir dist",
26
+ "test": "bun test",
27
+ "prepublishOnly": "bun run build",
28
+ "postinstall": "mkdir -p $HOME/.hasna/cloud 2>/dev/null || true; test -f $HOME/.hasna/cloud/config.json || printf '{\"rds\":{\"host\":\"hasnaxyz-prod-opensource.c4limg0qgqvk.us-east-1.rds.amazonaws.com\",\"port\":5432,\"username\":\"\",\"password_env\":\"HASNA_RDS_PASSWORD\",\"ssl\":true},\"mode\":\"local\",\"feedback_endpoint\":\"https://feedback.hasna.com/api/v1/feedback\",\"auto_sync_interval_minutes\":0,\"sync\":{\"schedule_minutes\":0}}\\n' > $HOME/.hasna/cloud/config.json 2>/dev/null || true"
30
29
  },
31
30
  "publishConfig": {
32
31
  "registry": "https://registry.npmjs.org",
33
32
  "access": "public"
33
+ },
34
+ "dependencies": {
35
+ "@modelcontextprotocol/sdk": "^1.12.1",
36
+ "commander": "^13.1.0",
37
+ "pg": "^8.13.3",
38
+ "zod": "^3.24.2",
39
+ "@hasna/events": "^0.1.6"
40
+ },
41
+ "devDependencies": {
42
+ "@types/bun": "^1.2.6",
43
+ "@types/pg": "^8.11.11",
44
+ "typescript": "^5.7.3"
34
45
  }
35
46
  }
package/archive/cli.js DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- console.error("@hasna/cloud is deprecated. Use repo-native storage/sync in each open package instead.");
4
- process.exitCode = 1;
@@ -1,9 +0,0 @@
1
- export declare function archivedCloudPackageNotice(): string;
2
-
3
- declare const archiveNotice: {
4
- archived: true;
5
- deprecated: true;
6
- message: string;
7
- };
8
-
9
- export default archiveNotice;
package/archive/index.js DELETED
@@ -1,15 +0,0 @@
1
- const message = [
2
- "@hasna/cloud is deprecated.",
3
- "Do not use it as a runtime dependency for open packages.",
4
- "Use repo-native local SQLite/file storage and explicit remote adapters instead.",
5
- ].join(" ");
6
-
7
- export function archivedCloudPackageNotice() {
8
- return message;
9
- }
10
-
11
- export default {
12
- archived: true,
13
- deprecated: true,
14
- message,
15
- };
package/archive/mcp.js DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- console.error("@hasna/cloud MCP is deprecated. Use the target open package MCP server instead.");
4
- process.exitCode = 1;