@vkenliu/adit-cloud 0.2.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 (98) hide show
  1. package/LICENSE +21 -0
  2. package/dist/auth/credentials.d.ts +62 -0
  3. package/dist/auth/credentials.d.ts.map +1 -0
  4. package/dist/auth/credentials.js +151 -0
  5. package/dist/auth/credentials.js.map +1 -0
  6. package/dist/auth/device-auth.d.ts +40 -0
  7. package/dist/auth/device-auth.d.ts.map +1 -0
  8. package/dist/auth/device-auth.js +84 -0
  9. package/dist/auth/device-auth.js.map +1 -0
  10. package/dist/config.d.ts +48 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +80 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/http/client.d.ts +28 -0
  15. package/dist/http/client.d.ts.map +1 -0
  16. package/dist/http/client.js +229 -0
  17. package/dist/http/client.js.map +1 -0
  18. package/dist/http/errors.d.ts +19 -0
  19. package/dist/http/errors.d.ts.map +1 -0
  20. package/dist/http/errors.js +31 -0
  21. package/dist/http/errors.js.map +1 -0
  22. package/dist/index.d.ts +20 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +25 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/project-link/auto-link.d.ts +30 -0
  27. package/dist/project-link/auto-link.d.ts.map +1 -0
  28. package/dist/project-link/auto-link.js +91 -0
  29. package/dist/project-link/auto-link.js.map +1 -0
  30. package/dist/project-link/bulk-task.d.ts +15 -0
  31. package/dist/project-link/bulk-task.d.ts.map +1 -0
  32. package/dist/project-link/bulk-task.js +107 -0
  33. package/dist/project-link/bulk-task.js.map +1 -0
  34. package/dist/project-link/cache.d.ts +22 -0
  35. package/dist/project-link/cache.d.ts.map +1 -0
  36. package/dist/project-link/cache.js +82 -0
  37. package/dist/project-link/cache.js.map +1 -0
  38. package/dist/project-link/doc-discovery.d.ts +35 -0
  39. package/dist/project-link/doc-discovery.d.ts.map +1 -0
  40. package/dist/project-link/doc-discovery.js +260 -0
  41. package/dist/project-link/doc-discovery.js.map +1 -0
  42. package/dist/project-link/git-collector.d.ts +88 -0
  43. package/dist/project-link/git-collector.d.ts.map +1 -0
  44. package/dist/project-link/git-collector.js +250 -0
  45. package/dist/project-link/git-collector.js.map +1 -0
  46. package/dist/project-link/index.d.ts +15 -0
  47. package/dist/project-link/index.d.ts.map +1 -0
  48. package/dist/project-link/index.js +20 -0
  49. package/dist/project-link/index.js.map +1 -0
  50. package/dist/project-link/intent-command.d.ts +23 -0
  51. package/dist/project-link/intent-command.d.ts.map +1 -0
  52. package/dist/project-link/intent-command.js +104 -0
  53. package/dist/project-link/intent-command.js.map +1 -0
  54. package/dist/project-link/link-command.d.ts +26 -0
  55. package/dist/project-link/link-command.d.ts.map +1 -0
  56. package/dist/project-link/link-command.js +350 -0
  57. package/dist/project-link/link-command.js.map +1 -0
  58. package/dist/project-link/qualify.d.ts +25 -0
  59. package/dist/project-link/qualify.d.ts.map +1 -0
  60. package/dist/project-link/qualify.js +45 -0
  61. package/dist/project-link/qualify.js.map +1 -0
  62. package/dist/project-link/types.d.ts +254 -0
  63. package/dist/project-link/types.d.ts.map +1 -0
  64. package/dist/project-link/types.js +8 -0
  65. package/dist/project-link/types.js.map +1 -0
  66. package/dist/sync/auto-sync.d.ts +42 -0
  67. package/dist/sync/auto-sync.d.ts.map +1 -0
  68. package/dist/sync/auto-sync.js +136 -0
  69. package/dist/sync/auto-sync.js.map +1 -0
  70. package/dist/sync/conflicts.d.ts +27 -0
  71. package/dist/sync/conflicts.d.ts.map +1 -0
  72. package/dist/sync/conflicts.js +28 -0
  73. package/dist/sync/conflicts.js.map +1 -0
  74. package/dist/sync/engine.d.ts +76 -0
  75. package/dist/sync/engine.d.ts.map +1 -0
  76. package/dist/sync/engine.js +152 -0
  77. package/dist/sync/engine.js.map +1 -0
  78. package/dist/sync/serializer.d.ts +123 -0
  79. package/dist/sync/serializer.d.ts.map +1 -0
  80. package/dist/sync/serializer.js +280 -0
  81. package/dist/sync/serializer.js.map +1 -0
  82. package/dist/transcript/auto-upload.d.ts +25 -0
  83. package/dist/transcript/auto-upload.d.ts.map +1 -0
  84. package/dist/transcript/auto-upload.js +75 -0
  85. package/dist/transcript/auto-upload.js.map +1 -0
  86. package/dist/transcript/index.d.ts +4 -0
  87. package/dist/transcript/index.d.ts.map +1 -0
  88. package/dist/transcript/index.js +4 -0
  89. package/dist/transcript/index.js.map +1 -0
  90. package/dist/transcript/manager.d.ts +63 -0
  91. package/dist/transcript/manager.d.ts.map +1 -0
  92. package/dist/transcript/manager.js +143 -0
  93. package/dist/transcript/manager.js.map +1 -0
  94. package/dist/transcript/uploader.d.ts +135 -0
  95. package/dist/transcript/uploader.d.ts.map +1 -0
  96. package/dist/transcript/uploader.js +235 -0
  97. package/dist/transcript/uploader.js.map +1 -0
  98. package/package.json +29 -0
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Type definitions for the Project Link feature.
3
+ *
4
+ * Covers git metadata collection, document discovery, local cache,
5
+ * server API request/response shapes, and command options.
6
+ */
7
+ export interface GitBranch {
8
+ name: string;
9
+ headSha: string;
10
+ isDefault: boolean;
11
+ }
12
+ export interface GitCommit {
13
+ sha: string;
14
+ authorName: string;
15
+ authorEmail: string;
16
+ date: string;
17
+ message: string;
18
+ branch?: string;
19
+ }
20
+ export interface DiscoveredDocument {
21
+ /** File name (e.g. "README.md") */
22
+ fileName: string;
23
+ /** Relative path from project root (e.g. "docs/architecture.md") */
24
+ sourcePath: string;
25
+ /** Full file content */
26
+ content: string;
27
+ /** SHA-256 hex digest of content */
28
+ contentHash: string;
29
+ /** File size in bytes */
30
+ sizeBytes: number;
31
+ /** Status relative to the cached hash */
32
+ status: "new" | "changed" | "unchanged";
33
+ }
34
+ export interface ProjectLinkCache {
35
+ projectId: string;
36
+ serverUrl: string;
37
+ confirmedProjectId: string | null;
38
+ lastCommitSha: string | null;
39
+ lastBranchSyncAt: string | null;
40
+ lastDocSyncAt: string | null;
41
+ docHashes: Record<string, string>;
42
+ qualified: boolean;
43
+ initializedAt: string;
44
+ updatedAt: string;
45
+ }
46
+ export interface NegotiateResponse {
47
+ confirmedProjectId: string;
48
+ projectName: string;
49
+ status: "confirmed" | "id_mismatch";
50
+ message: string;
51
+ }
52
+ export interface LinkInitResponse {
53
+ projectLink: {
54
+ id: string;
55
+ projectId: string;
56
+ remoteUrl: string;
57
+ defaultBranch: string | null;
58
+ branchCount: number;
59
+ qualified: boolean;
60
+ lastGitSyncAt: string | null;
61
+ lastDocSyncAt: string | null;
62
+ createdAt: string;
63
+ };
64
+ status: "created" | "updated";
65
+ }
66
+ export interface CommitUploadResponse {
67
+ accepted: number;
68
+ duplicates: number;
69
+ totalCommits: number;
70
+ latestCommitSha: string;
71
+ }
72
+ export interface DocumentUploadResponse {
73
+ results: Array<{
74
+ fileName: string;
75
+ documentId: string;
76
+ status: "created" | "new_version" | "unchanged";
77
+ versionNumber?: number;
78
+ }>;
79
+ summary: {
80
+ created: number;
81
+ updated: number;
82
+ unchanged: number;
83
+ total: number;
84
+ };
85
+ }
86
+ export interface QualifyResponse {
87
+ qualified: boolean;
88
+ score: number;
89
+ documentCount: number;
90
+ feedback: {
91
+ missing: string[];
92
+ suggestions: string[];
93
+ summaryPrompt: string;
94
+ } | null;
95
+ }
96
+ export interface LinkStatusResponse {
97
+ projectLink: {
98
+ id: string;
99
+ projectId: string;
100
+ remoteUrl: string;
101
+ defaultBranch: string | null;
102
+ qualified: boolean;
103
+ lastGitSyncAt: string | null;
104
+ lastDocSyncAt: string | null;
105
+ createdAt: string;
106
+ };
107
+ branchCount: number;
108
+ commitCount: number;
109
+ latestCommitSha: string | null;
110
+ latestCommitDate: string | null;
111
+ documentCount: number;
112
+ documents: Array<{
113
+ fileName: string;
114
+ contentHash: string;
115
+ updatedAt: string;
116
+ }>;
117
+ }
118
+ export interface IntentSummary {
119
+ id: string;
120
+ title: string;
121
+ businessGoal: string;
122
+ state: string;
123
+ ambiguityScore: number | null;
124
+ linkedBranches: string[];
125
+ taskCount: number;
126
+ completedTaskCount: number;
127
+ createdAt: string;
128
+ updatedAt: string;
129
+ }
130
+ export interface IntentDetail extends IntentSummary {
131
+ acceptanceMd: string | null;
132
+ antiGoals: string | null;
133
+ clarityScores: {
134
+ goal: number;
135
+ constraints: number;
136
+ criteria: number;
137
+ context: number;
138
+ } | null;
139
+ tasks: TaskSlice[];
140
+ latestPlan: {
141
+ version: number;
142
+ versionType: string;
143
+ responsePayload: string;
144
+ gatekeeperVerdict: string | null;
145
+ createdAt: string;
146
+ } | null;
147
+ recentShipNotes: Array<{
148
+ id: string;
149
+ noteBody: string;
150
+ createdBy: string;
151
+ architecturalDecision: boolean;
152
+ createdAt: string;
153
+ }>;
154
+ }
155
+ export interface TaskSlice {
156
+ id: string;
157
+ title: string;
158
+ description: string | null;
159
+ phase: number;
160
+ phaseTitle: string | null;
161
+ sortOrder: number;
162
+ wave: number | null;
163
+ complexityScore: number | null;
164
+ approvalStatus: string;
165
+ featureTag: string | null;
166
+ acceptanceCriteria: string[];
167
+ dependsOn: number[];
168
+ codingPrompt: string | null;
169
+ createdAt: string;
170
+ updatedAt: string;
171
+ }
172
+ export interface LinkOptions {
173
+ force?: boolean;
174
+ skipDocs?: boolean;
175
+ skipCommits?: boolean;
176
+ skipQualify?: boolean;
177
+ dryRun?: boolean;
178
+ json?: boolean;
179
+ }
180
+ export interface IntentOptions {
181
+ id?: string;
182
+ state?: string;
183
+ json?: boolean;
184
+ }
185
+ export interface StepTiming {
186
+ /** Human-readable step name (e.g. "Negotiate project ID") */
187
+ step: string;
188
+ /** Duration in milliseconds */
189
+ durationMs: number;
190
+ }
191
+ export interface LinkResult {
192
+ projectId: string;
193
+ projectName: string;
194
+ serverUrl: string;
195
+ branchCount: number;
196
+ commitCount: number;
197
+ documentCount: number;
198
+ qualified: boolean;
199
+ score: number | null;
200
+ /** Per-step timing breakdown */
201
+ stepTimings: StepTiming[];
202
+ /** Total wall-clock duration in milliseconds */
203
+ totalDurationMs: number;
204
+ }
205
+ export interface IntentResult {
206
+ intents?: IntentSummary[];
207
+ intent?: IntentDetail;
208
+ }
209
+ export interface BulkTaskFilter {
210
+ /** Filter by phase number (1-99) */
211
+ phase?: number;
212
+ /** Filter by task status */
213
+ status?: "pending" | "approved" | "in_progress" | "completed" | "rejected";
214
+ /** Filter by feature tag */
215
+ featureTag?: string;
216
+ /** Filter by wave number */
217
+ wave?: number;
218
+ }
219
+ export interface BulkTaskUpdate {
220
+ /** Task ID to update */
221
+ taskId: string;
222
+ /** New status for the task */
223
+ status: "pending" | "approved" | "in_progress" | "completed" | "rejected";
224
+ /** Optional phase number */
225
+ phase?: number;
226
+ /** Optional title update */
227
+ title?: string;
228
+ /** Optional description update */
229
+ description?: string;
230
+ }
231
+ export interface BulkTaskUpdateOptions {
232
+ /** Intent ID containing the tasks to update */
233
+ intentId: string;
234
+ /** Specific tasks to update (when not provided, all tasks in intent are updated) */
235
+ taskId?: string[];
236
+ /** Target status (default: "completed") */
237
+ status?: "pending" | "approved" | "in_progress" | "completed" | "rejected";
238
+ /** Filters to apply before updating */
239
+ filters?: BulkTaskFilter;
240
+ /** Output as JSON */
241
+ json?: boolean;
242
+ }
243
+ export interface BulkTaskUpdateResult {
244
+ /** Number of tasks successfully updated */
245
+ updated: number;
246
+ /** Array of failed updates with error details */
247
+ failed: Array<{
248
+ taskId: string;
249
+ error: string;
250
+ }>;
251
+ /** Summary message */
252
+ message: string;
253
+ }
254
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/project-link/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Type definitions for the Project Link feature.
3
+ *
4
+ * Covers git metadata collection, document discovery, local cache,
5
+ * server API request/response shapes, and command options.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/project-link/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Auto-sync trigger — fire-and-forget sync after hook events.
3
+ *
4
+ * Called from the hooks system via dynamic import. Fully fail-open:
5
+ * any error is swallowed so it never blocks the AI agent.
6
+ *
7
+ * Sync is triggered when any of the following is true:
8
+ * - `options.force` is true (used on session-end to flush all data), OR
9
+ * - The number of unsynced records meets the configured threshold
10
+ * (ADIT_CLOUD_SYNC_THRESHOLD, default 50), OR
11
+ * - More than syncTimeoutHours (default 12h) have elapsed since
12
+ * the last successful sync (ADIT_CLOUD_SYNC_TIMEOUT_HOURS).
13
+ *
14
+ * The time-based trigger is checked first using the already-loaded
15
+ * sync_state row (single PK lookup), skipping the more expensive
16
+ * multi-table COUNT queries when the timeout has elapsed.
17
+ *
18
+ * Failed syncs are not retried immediately — they will be picked up
19
+ * on the next trigger when conditions are still met.
20
+ */
21
+ import type Database from "better-sqlite3";
22
+ /**
23
+ * Trigger a background sync if credentials exist and the unsynced record
24
+ * count meets the threshold (or the time trigger fires).
25
+ *
26
+ * This function is designed to be called as fire-and-forget:
27
+ * triggerAutoSync(db, projectId).catch(() => {})
28
+ *
29
+ * Precondition checks (in order):
30
+ * 1. Valid credentials present (client is authenticated)
31
+ * 2. Resolve server URL: env var takes priority, falls back to credentials
32
+ * 3. Auto-sync not explicitly disabled (ADIT_CLOUD_AUTO_SYNC !== "false")
33
+ * 4. Time-based trigger: >syncTimeoutHours since last sync (skips count)
34
+ * 5. Count-based trigger: unsynced record count >= syncThreshold
35
+ *
36
+ * If any check fails, the function returns silently. Failed events
37
+ * remain unsynced and will be retried on the next trigger.
38
+ */
39
+ export declare function triggerAutoSync(db: Database.Database, projectId: string, options?: {
40
+ force?: boolean;
41
+ }): Promise<void>;
42
+ //# sourceMappingURL=auto-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-sync.d.ts","sourceRoot":"","sources":["../../src/sync/auto-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAiB3C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5B,OAAO,CAAC,IAAI,CAAC,CA0Gf"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Auto-sync trigger — fire-and-forget sync after hook events.
3
+ *
4
+ * Called from the hooks system via dynamic import. Fully fail-open:
5
+ * any error is swallowed so it never blocks the AI agent.
6
+ *
7
+ * Sync is triggered when any of the following is true:
8
+ * - `options.force` is true (used on session-end to flush all data), OR
9
+ * - The number of unsynced records meets the configured threshold
10
+ * (ADIT_CLOUD_SYNC_THRESHOLD, default 50), OR
11
+ * - More than syncTimeoutHours (default 12h) have elapsed since
12
+ * the last successful sync (ADIT_CLOUD_SYNC_TIMEOUT_HOURS).
13
+ *
14
+ * The time-based trigger is checked first using the already-loaded
15
+ * sync_state row (single PK lookup), skipping the more expensive
16
+ * multi-table COUNT queries when the timeout has elapsed.
17
+ *
18
+ * Failed syncs are not retried immediately — they will be picked up
19
+ * on the next trigger when conditions are still met.
20
+ */
21
+ import { getSyncState } from "@vkenliu/adit-core";
22
+ import { loadCloudConfig, DEFAULT_SERVER_URL } from "../config.js";
23
+ import { loadCredentials, isTokenExpired, credentialsFromEnvToken, incrementSyncErrors, clearSyncErrors, isSyncDisabled, } from "../auth/credentials.js";
24
+ import { CloudClient } from "../http/client.js";
25
+ import { CloudNetworkError, CloudAuthError } from "../http/errors.js";
26
+ import { SyncEngine } from "./engine.js";
27
+ import { countUnsyncedRecords } from "./serializer.js";
28
+ /**
29
+ * Trigger a background sync if credentials exist and the unsynced record
30
+ * count meets the threshold (or the time trigger fires).
31
+ *
32
+ * This function is designed to be called as fire-and-forget:
33
+ * triggerAutoSync(db, projectId).catch(() => {})
34
+ *
35
+ * Precondition checks (in order):
36
+ * 1. Valid credentials present (client is authenticated)
37
+ * 2. Resolve server URL: env var takes priority, falls back to credentials
38
+ * 3. Auto-sync not explicitly disabled (ADIT_CLOUD_AUTO_SYNC !== "false")
39
+ * 4. Time-based trigger: >syncTimeoutHours since last sync (skips count)
40
+ * 5. Count-based trigger: unsynced record count >= syncThreshold
41
+ *
42
+ * If any check fails, the function returns silently. Failed events
43
+ * remain unsynced and will be retried on the next trigger.
44
+ */
45
+ export async function triggerAutoSync(db, projectId, options) {
46
+ const cloudConfig = loadCloudConfig();
47
+ // 0. Circuit breaker — skip if too many consecutive failures
48
+ if (isSyncDisabled())
49
+ return;
50
+ // 1. Check credentials exist — credentials are the implicit opt-in.
51
+ // ADIT_AUTH_TOKEN env var takes priority over stored credentials
52
+ // (enables CI/CD and headless use without writing credentials first).
53
+ let credentials = null;
54
+ if (process.env.ADIT_AUTH_TOKEN) {
55
+ const serverUrl = cloudConfig.serverUrl ?? DEFAULT_SERVER_URL;
56
+ // Prefer stored credentials' clientId (set by `auth-token` verification)
57
+ // over the local config clientId, since the server assigns its own UUID.
58
+ const stored = loadCredentials();
59
+ const clientId = stored?.clientId ?? (await import("@vkenliu/adit-core")).loadConfig().clientId;
60
+ credentials = credentialsFromEnvToken(serverUrl, clientId);
61
+ }
62
+ if (!credentials) {
63
+ credentials = loadCredentials();
64
+ }
65
+ if (!credentials)
66
+ return;
67
+ // 2. Resolve server URL: env var takes priority, fall back to credentials
68
+ const serverUrl = cloudConfig.serverUrl ?? credentials.serverUrl;
69
+ if (!serverUrl)
70
+ return;
71
+ // 2a. If env var specifies a different server than credentials, skip
72
+ // (single-server binding: don't send credentials to wrong server)
73
+ if (cloudConfig.serverUrl && credentials.serverUrl !== cloudConfig.serverUrl) {
74
+ return;
75
+ }
76
+ // 3. Auto-sync is enabled by default when credentials exist.
77
+ // Only skip if explicitly disabled via ADIT_CLOUD_AUTO_SYNC=false
78
+ // or ADIT_CLOUD_ENABLED=false.
79
+ if (process.env.ADIT_CLOUD_AUTO_SYNC === "false")
80
+ return;
81
+ if (process.env.ADIT_CLOUD_ENABLED === "false")
82
+ return;
83
+ // 4. Check sync triggers (skipped when force=true, e.g. session-end)
84
+ if (!options?.force) {
85
+ const syncState = getSyncState(db, serverUrl);
86
+ // 4a. Time-based trigger: if more than syncTimeoutHours since last successful sync,
87
+ // skip the expensive multi-table COUNT and trigger sync directly.
88
+ // Only applies when we have a previous sync timestamp (first sync uses count-based).
89
+ const timeoutMs = cloudConfig.syncTimeoutHours * 60 * 60 * 1000;
90
+ const timeTriggered = syncState?.lastSyncedAt != null &&
91
+ Date.now() - new Date(syncState.lastSyncedAt).getTime() > timeoutMs;
92
+ // 4b. Count-based trigger: only run the expensive count if time didn't trigger
93
+ if (!timeTriggered) {
94
+ const unsyncedCount = countUnsyncedRecords(db, syncState?.lastSyncedEventId ?? null, syncState?.lastSyncedAt ?? null, projectId);
95
+ if (unsyncedCount < cloudConfig.syncThreshold) {
96
+ return;
97
+ }
98
+ }
99
+ }
100
+ // 5. Attempt sync — CloudClient handles token refresh, retries,
101
+ // and reachability internally. Network errors are caught below.
102
+ if (isTokenExpired(credentials)) {
103
+ // Let CloudClient try to refresh — it will throw CloudAuthError if it can't
104
+ }
105
+ try {
106
+ const client = new CloudClient(serverUrl, credentials);
107
+ const engine = new SyncEngine(db, client, {
108
+ projectId,
109
+ batchSize: cloudConfig.batchSize,
110
+ serverUrl,
111
+ cloudClientId: credentials.clientId,
112
+ });
113
+ await engine.sync();
114
+ clearSyncErrors();
115
+ }
116
+ catch (error) {
117
+ // Track consecutive failures — disable sync after threshold
118
+ const disabled = incrementSyncErrors();
119
+ // Fail silently — this is fire-and-forget.
120
+ // CloudNetworkError: server unreachable, will retry next trigger
121
+ // CloudAuthError: credentials invalid, user needs to re-login
122
+ // Any other error: unexpected, but still fail-open
123
+ if (process.env.ADIT_DEBUG) {
124
+ const msg = error instanceof CloudNetworkError
125
+ ? `[adit-cloud] auto-sync skipped: server unreachable — ${error.message}`
126
+ : error instanceof CloudAuthError
127
+ ? `[adit-cloud] auto-sync skipped: auth failed — ${error.message}`
128
+ : `[adit-cloud] auto-sync failed: ${error instanceof Error ? error.message : String(error)}`;
129
+ process.stderr.write(msg + "\n");
130
+ if (disabled) {
131
+ process.stderr.write("[adit-cloud] auto-sync disabled after repeated failures. Run 'adit cloud sync' to re-enable.\n");
132
+ }
133
+ }
134
+ }
135
+ }
136
+ //# sourceMappingURL=auto-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-sync.js","sourceRoot":"","sources":["../../src/sync/auto-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EACL,eAAe,EACf,cAAc,EACd,uBAAuB,EACvB,mBAAmB,EACnB,eAAe,EACf,cAAc,GAEf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,EAAqB,EACrB,SAAiB,EACjB,OAA6B;IAE7B,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;IAEtC,6DAA6D;IAC7D,IAAI,cAAc,EAAE;QAAE,OAAO;IAE7B,oEAAoE;IACpE,oEAAoE;IACpE,yEAAyE;IACzE,IAAI,WAAW,GAA4B,IAAI,CAAC;IAChD,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,WAAW,CAAC,SAAS,IAAI,kBAAkB,CAAC;QAC9D,yEAAyE;QACzE,yEAAyE;QACzE,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,CAAC,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC;QAChG,WAAW,GAAG,uBAAuB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,WAAW,GAAG,eAAe,EAAE,CAAC;IAClC,CAAC;IACD,IAAI,CAAC,WAAW;QAAE,OAAO;IAEzB,0EAA0E;IAC1E,MAAM,SAAS,GAAG,WAAW,CAAC,SAAS,IAAI,WAAW,CAAC,SAAS,CAAC;IACjE,IAAI,CAAC,SAAS;QAAE,OAAO;IAEvB,qEAAqE;IACrE,sEAAsE;IACtE,IAAI,WAAW,CAAC,SAAS,IAAI,WAAW,CAAC,SAAS,KAAK,WAAW,CAAC,SAAS,EAAE,CAAC;QAC7E,OAAO;IACT,CAAC;IAED,6DAA6D;IAC7D,qEAAqE;IACrE,kCAAkC;IAClC,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,OAAO;QAAE,OAAO;IACzD,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,OAAO;QAAE,OAAO;IAEvD,qEAAqE;IACrE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QACpB,MAAM,SAAS,GAAG,YAAY,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QAE9C,oFAAoF;QACpF,sEAAsE;QACtE,yFAAyF;QACzF,MAAM,SAAS,GAAG,WAAW,CAAC,gBAAgB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QAChE,MAAM,aAAa,GACjB,SAAS,EAAE,YAAY,IAAI,IAAI;YAC/B,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC;QAEtE,+EAA+E;QAC/E,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,aAAa,GAAG,oBAAoB,CACxC,EAAE,EACF,SAAS,EAAE,iBAAiB,IAAI,IAAI,EACpC,SAAS,EAAE,YAAY,IAAI,IAAI,EAC/B,SAAS,CACV,CAAC;YAEF,IAAI,aAAa,GAAG,WAAW,CAAC,aAAa,EAAE,CAAC;gBAC9C,OAAO;YACT,CAAC;QACH,CAAC;IACH,CAAC;IAED,gEAAgE;IAChE,mEAAmE;IACnE,IAAI,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,4EAA4E;IAC9E,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE;YACxC,SAAS;YACT,SAAS,EAAE,WAAW,CAAC,SAAS;YAChC,SAAS;YACT,aAAa,EAAE,WAAW,CAAC,QAAQ;SACpC,CAAC,CAAC;QAEH,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,eAAe,EAAE,CAAC;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,4DAA4D;QAC5D,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;QAEvC,2CAA2C;QAC3C,iEAAiE;QACjE,8DAA8D;QAC9D,mDAAmD;QACnD,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,GAAG,GACP,KAAK,YAAY,iBAAiB;gBAChC,CAAC,CAAC,wDAAwD,KAAK,CAAC,OAAO,EAAE;gBACzE,CAAC,CAAC,KAAK,YAAY,cAAc;oBAC/B,CAAC,CAAC,iDAAiD,KAAK,CAAC,OAAO,EAAE;oBAClE,CAAC,CAAC,kCAAkC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACnG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;YACjC,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,gGAAgG,CACjG,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Conflict handler for sync responses.
3
+ *
4
+ * When the server detects concurrent modifications on mutable records
5
+ * (sessions, plans), it returns conflict details with its resolution.
6
+ * This module processes those responses.
7
+ *
8
+ * Design: Local-first. We log conflicts but don't overwrite local data.
9
+ * The server is authoritative for the cloud view; the local DB remains
10
+ * the user's working copy.
11
+ */
12
+ export interface SyncConflict {
13
+ type: "session" | "plan";
14
+ id: string;
15
+ resolution: string;
16
+ reason: string;
17
+ }
18
+ /**
19
+ * Process conflict responses from the server.
20
+ *
21
+ * Currently just logs conflicts. Future versions could:
22
+ * - Fetch the server's version and store it separately
23
+ * - Prompt the user to choose a resolution
24
+ * - Apply server's version to local state
25
+ */
26
+ export declare function handleConflicts(conflicts: SyncConflict[]): void;
27
+ //# sourceMappingURL=conflicts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflicts.d.ts","sourceRoot":"","sources":["../../src/sync/conflicts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,IAAI,CAS/D"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Conflict handler for sync responses.
3
+ *
4
+ * When the server detects concurrent modifications on mutable records
5
+ * (sessions, plans), it returns conflict details with its resolution.
6
+ * This module processes those responses.
7
+ *
8
+ * Design: Local-first. We log conflicts but don't overwrite local data.
9
+ * The server is authoritative for the cloud view; the local DB remains
10
+ * the user's working copy.
11
+ */
12
+ /**
13
+ * Process conflict responses from the server.
14
+ *
15
+ * Currently just logs conflicts. Future versions could:
16
+ * - Fetch the server's version and store it separately
17
+ * - Prompt the user to choose a resolution
18
+ * - Apply server's version to local state
19
+ */
20
+ export function handleConflicts(conflicts) {
21
+ for (const conflict of conflicts) {
22
+ // Structured log for debugging — not user-facing
23
+ if (process.env.ADIT_DEBUG) {
24
+ process.stderr.write(`[adit-cloud] sync conflict: ${conflict.type}/${conflict.id} — ${conflict.resolution}: ${conflict.reason}\n`);
25
+ }
26
+ }
27
+ }
28
+ //# sourceMappingURL=conflicts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflicts.js","sourceRoot":"","sources":["../../src/sync/conflicts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,SAAyB;IACvD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,iDAAiD;QACjD,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,+BAA+B,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,EAAE,MAAM,QAAQ,CAAC,UAAU,KAAK,QAAQ,CAAC,MAAM,IAAI,CAC7G,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Sync engine — orchestrates cursor-based incremental push.
3
+ *
4
+ * Protocol:
5
+ * 1. GET /api/sync/status → retrieve server's cursor
6
+ * 2. Build batch of local records after cursor
7
+ * 3. POST /api/sync/push → push batch
8
+ * 4. Update local cursor from response
9
+ * 5. Repeat until no more records
10
+ */
11
+ import type Database from "better-sqlite3";
12
+ import type { SyncState } from "@vkenliu/adit-core";
13
+ import type { CloudClient } from "../http/client.js";
14
+ import { type SyncConflict } from "./conflicts.js";
15
+ export type { SyncConflict } from "./conflicts.js";
16
+ export interface SyncResult {
17
+ /** Total records accepted by server */
18
+ accepted: number;
19
+ /** Records already seen by server (de-duplicated) */
20
+ duplicates: number;
21
+ /** Conflicts detected on mutable records */
22
+ conflicts: SyncConflict[];
23
+ /** New sync cursor after all batches */
24
+ newSyncCursor: string | null;
25
+ /** Number of batches pushed */
26
+ batches: number;
27
+ /** Total records sent across all batches */
28
+ totalRecords: number;
29
+ }
30
+ /** Per-project cursor entry returned by the server in projectCursors. */
31
+ interface ProjectCursor {
32
+ lastSyncedEventId: string | null;
33
+ lastSyncedAt: string | null;
34
+ }
35
+ /**
36
+ * Response from GET /api/sync/status.
37
+ *
38
+ * The server tracks cursors per (clientId, projectId) pair and returns them
39
+ * in the `projectCursors` map. The top-level `lastSyncedEventId` and
40
+ * `syncVersion` remain for backward compatibility.
41
+ */
42
+ interface StatusResponse {
43
+ lastSyncedEventId: string | null;
44
+ syncVersion: number;
45
+ lastSyncedAt: string | null;
46
+ /** Per-project cursor map. Key is projectId. Present on updated servers. */
47
+ projectCursors?: Record<string, ProjectCursor>;
48
+ }
49
+ export declare class SyncEngine {
50
+ private readonly db;
51
+ private readonly client;
52
+ private readonly projectId;
53
+ private readonly batchSize;
54
+ private readonly serverUrl;
55
+ private readonly cloudClientId;
56
+ private readonly dataDir;
57
+ constructor(db: Database.Database, client: CloudClient, config: {
58
+ projectId: string;
59
+ batchSize: number;
60
+ serverUrl: string;
61
+ cloudClientId: string;
62
+ dataDir?: string;
63
+ });
64
+ /**
65
+ * Full incremental sync: push all unsynced records in batches.
66
+ *
67
+ * Fetches the server's cursor, then pushes batches until all
68
+ * local records have been synced.
69
+ */
70
+ sync(): Promise<SyncResult>;
71
+ /** Get sync status from server, scoped to this project. */
72
+ getRemoteStatus(): Promise<StatusResponse>;
73
+ /** Get local sync state */
74
+ getLocalStatus(): SyncState | null;
75
+ }
76
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/sync/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,UAAU;IACzB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,wCAAwC;IACxC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC;CACtB;AAUD,yEAAyE;AACzE,UAAU,aAAa;IACrB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,UAAU,cAAc;IACtB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAChD;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;gBAGtC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE;QACN,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB;IAWH;;;;;OAKG;IACG,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;IAkJjC,2DAA2D;IACrD,eAAe,IAAI,OAAO,CAAC,cAAc,CAAC;IAKhD,2BAA2B;IAC3B,cAAc,IAAI,SAAS,GAAG,IAAI;CAGnC"}