@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.
- package/LICENSE +21 -0
- package/dist/auth/credentials.d.ts +62 -0
- package/dist/auth/credentials.d.ts.map +1 -0
- package/dist/auth/credentials.js +151 -0
- package/dist/auth/credentials.js.map +1 -0
- package/dist/auth/device-auth.d.ts +40 -0
- package/dist/auth/device-auth.d.ts.map +1 -0
- package/dist/auth/device-auth.js +84 -0
- package/dist/auth/device-auth.js.map +1 -0
- package/dist/config.d.ts +48 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +80 -0
- package/dist/config.js.map +1 -0
- package/dist/http/client.d.ts +28 -0
- package/dist/http/client.d.ts.map +1 -0
- package/dist/http/client.js +229 -0
- package/dist/http/client.js.map +1 -0
- package/dist/http/errors.d.ts +19 -0
- package/dist/http/errors.d.ts.map +1 -0
- package/dist/http/errors.js +31 -0
- package/dist/http/errors.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/project-link/auto-link.d.ts +30 -0
- package/dist/project-link/auto-link.d.ts.map +1 -0
- package/dist/project-link/auto-link.js +91 -0
- package/dist/project-link/auto-link.js.map +1 -0
- package/dist/project-link/bulk-task.d.ts +15 -0
- package/dist/project-link/bulk-task.d.ts.map +1 -0
- package/dist/project-link/bulk-task.js +107 -0
- package/dist/project-link/bulk-task.js.map +1 -0
- package/dist/project-link/cache.d.ts +22 -0
- package/dist/project-link/cache.d.ts.map +1 -0
- package/dist/project-link/cache.js +82 -0
- package/dist/project-link/cache.js.map +1 -0
- package/dist/project-link/doc-discovery.d.ts +35 -0
- package/dist/project-link/doc-discovery.d.ts.map +1 -0
- package/dist/project-link/doc-discovery.js +260 -0
- package/dist/project-link/doc-discovery.js.map +1 -0
- package/dist/project-link/git-collector.d.ts +88 -0
- package/dist/project-link/git-collector.d.ts.map +1 -0
- package/dist/project-link/git-collector.js +250 -0
- package/dist/project-link/git-collector.js.map +1 -0
- package/dist/project-link/index.d.ts +15 -0
- package/dist/project-link/index.d.ts.map +1 -0
- package/dist/project-link/index.js +20 -0
- package/dist/project-link/index.js.map +1 -0
- package/dist/project-link/intent-command.d.ts +23 -0
- package/dist/project-link/intent-command.d.ts.map +1 -0
- package/dist/project-link/intent-command.js +104 -0
- package/dist/project-link/intent-command.js.map +1 -0
- package/dist/project-link/link-command.d.ts +26 -0
- package/dist/project-link/link-command.d.ts.map +1 -0
- package/dist/project-link/link-command.js +350 -0
- package/dist/project-link/link-command.js.map +1 -0
- package/dist/project-link/qualify.d.ts +25 -0
- package/dist/project-link/qualify.d.ts.map +1 -0
- package/dist/project-link/qualify.js +45 -0
- package/dist/project-link/qualify.js.map +1 -0
- package/dist/project-link/types.d.ts +254 -0
- package/dist/project-link/types.d.ts.map +1 -0
- package/dist/project-link/types.js +8 -0
- package/dist/project-link/types.js.map +1 -0
- package/dist/sync/auto-sync.d.ts +42 -0
- package/dist/sync/auto-sync.d.ts.map +1 -0
- package/dist/sync/auto-sync.js +136 -0
- package/dist/sync/auto-sync.js.map +1 -0
- package/dist/sync/conflicts.d.ts +27 -0
- package/dist/sync/conflicts.d.ts.map +1 -0
- package/dist/sync/conflicts.js +28 -0
- package/dist/sync/conflicts.js.map +1 -0
- package/dist/sync/engine.d.ts +76 -0
- package/dist/sync/engine.d.ts.map +1 -0
- package/dist/sync/engine.js +152 -0
- package/dist/sync/engine.js.map +1 -0
- package/dist/sync/serializer.d.ts +123 -0
- package/dist/sync/serializer.d.ts.map +1 -0
- package/dist/sync/serializer.js +280 -0
- package/dist/sync/serializer.js.map +1 -0
- package/dist/transcript/auto-upload.d.ts +25 -0
- package/dist/transcript/auto-upload.d.ts.map +1 -0
- package/dist/transcript/auto-upload.js +75 -0
- package/dist/transcript/auto-upload.js.map +1 -0
- package/dist/transcript/index.d.ts +4 -0
- package/dist/transcript/index.d.ts.map +1 -0
- package/dist/transcript/index.js +4 -0
- package/dist/transcript/index.js.map +1 -0
- package/dist/transcript/manager.d.ts +63 -0
- package/dist/transcript/manager.d.ts.map +1 -0
- package/dist/transcript/manager.js +143 -0
- package/dist/transcript/manager.js.map +1 -0
- package/dist/transcript/uploader.d.ts +135 -0
- package/dist/transcript/uploader.d.ts.map +1 -0
- package/dist/transcript/uploader.js +235 -0
- package/dist/transcript/uploader.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,152 @@
|
|
|
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 { getSyncState, upsertSyncState, withPerf } from "@vkenliu/adit-core";
|
|
12
|
+
import { buildSyncBatch, batchRecordCount, countUnsyncedRecords } from "./serializer.js";
|
|
13
|
+
import { handleConflicts } from "./conflicts.js";
|
|
14
|
+
export class SyncEngine {
|
|
15
|
+
db;
|
|
16
|
+
client;
|
|
17
|
+
projectId;
|
|
18
|
+
batchSize;
|
|
19
|
+
serverUrl;
|
|
20
|
+
cloudClientId;
|
|
21
|
+
dataDir;
|
|
22
|
+
constructor(db, client, config) {
|
|
23
|
+
this.db = db;
|
|
24
|
+
this.client = client;
|
|
25
|
+
this.projectId = config.projectId;
|
|
26
|
+
this.batchSize = config.batchSize;
|
|
27
|
+
this.serverUrl = config.serverUrl;
|
|
28
|
+
this.cloudClientId = config.cloudClientId;
|
|
29
|
+
this.dataDir = config.dataDir ?? null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Full incremental sync: push all unsynced records in batches.
|
|
33
|
+
*
|
|
34
|
+
* Fetches the server's cursor, then pushes batches until all
|
|
35
|
+
* local records have been synced.
|
|
36
|
+
*/
|
|
37
|
+
async sync() {
|
|
38
|
+
const doSync = async () => {
|
|
39
|
+
// 1. Get server's current cursor
|
|
40
|
+
const serverStatus = await this.getRemoteStatus();
|
|
41
|
+
// 2. Extract per-project cursor (preferred) or fall back to global cursor.
|
|
42
|
+
// The server returns projectCursors[projectId] with the watermark
|
|
43
|
+
// for this specific project. If the server hasn't seen any events
|
|
44
|
+
// for this project yet, the entry will be absent — meaning send all.
|
|
45
|
+
let cursor;
|
|
46
|
+
let lastSyncedAt;
|
|
47
|
+
let syncVersion = serverStatus.syncVersion;
|
|
48
|
+
const projectEntry = serverStatus.projectCursors?.[this.projectId];
|
|
49
|
+
if (projectEntry !== undefined) {
|
|
50
|
+
// Server has a per-project cursor — use it directly.
|
|
51
|
+
cursor = projectEntry.lastSyncedEventId;
|
|
52
|
+
lastSyncedAt = projectEntry.lastSyncedAt;
|
|
53
|
+
if (process.env.ADIT_DEBUG) {
|
|
54
|
+
process.stderr.write(`[adit-cloud] sync: using per-project cursor for ${this.projectId}: ${cursor ?? "null"}\n`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else if (serverStatus.projectCursors !== undefined) {
|
|
58
|
+
// Server supports per-project cursors but has no entry for this
|
|
59
|
+
// project — it has never seen events for it. Send everything.
|
|
60
|
+
cursor = null;
|
|
61
|
+
lastSyncedAt = null;
|
|
62
|
+
if (process.env.ADIT_DEBUG) {
|
|
63
|
+
process.stderr.write(`[adit-cloud] sync: no per-project cursor for ${this.projectId} — full push\n`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// Legacy server without projectCursors — fall back to global cursor
|
|
68
|
+
// with the cursor-ahead guard for safety.
|
|
69
|
+
cursor = serverStatus.lastSyncedEventId;
|
|
70
|
+
lastSyncedAt = serverStatus.lastSyncedAt;
|
|
71
|
+
if (cursor) {
|
|
72
|
+
const unsyncedWithCursor = countUnsyncedRecords(this.db, cursor, lastSyncedAt, this.projectId);
|
|
73
|
+
const totalLocal = countUnsyncedRecords(this.db, null, null, this.projectId);
|
|
74
|
+
if (unsyncedWithCursor === 0 && totalLocal > 0) {
|
|
75
|
+
if (process.env.ADIT_DEBUG) {
|
|
76
|
+
process.stderr.write(`[adit-cloud] sync: legacy global cursor ${cursor} is ahead of all ${totalLocal} local records — resetting to full push\n`);
|
|
77
|
+
}
|
|
78
|
+
cursor = null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const result = {
|
|
83
|
+
accepted: 0,
|
|
84
|
+
duplicates: 0,
|
|
85
|
+
conflicts: [],
|
|
86
|
+
newSyncCursor: cursor,
|
|
87
|
+
batches: 0,
|
|
88
|
+
totalRecords: 0,
|
|
89
|
+
};
|
|
90
|
+
// 3. Push batches until no more records
|
|
91
|
+
while (true) {
|
|
92
|
+
const batch = buildSyncBatch(this.db, cursor, lastSyncedAt, this.projectId, this.cloudClientId, this.batchSize);
|
|
93
|
+
const count = batchRecordCount(batch);
|
|
94
|
+
if (count === 0)
|
|
95
|
+
break; // All synced
|
|
96
|
+
const response = await this.client.post("/api/sync/push", {
|
|
97
|
+
clientId: this.cloudClientId,
|
|
98
|
+
syncVersion,
|
|
99
|
+
batch,
|
|
100
|
+
});
|
|
101
|
+
result.accepted += response.accepted;
|
|
102
|
+
result.duplicates += response.duplicates;
|
|
103
|
+
result.conflicts.push(...response.conflicts);
|
|
104
|
+
result.batches++;
|
|
105
|
+
result.totalRecords += count;
|
|
106
|
+
// Handle conflicts
|
|
107
|
+
if (response.conflicts.length > 0) {
|
|
108
|
+
handleConflicts(response.conflicts);
|
|
109
|
+
}
|
|
110
|
+
// Update cursor
|
|
111
|
+
const prevCursor = cursor;
|
|
112
|
+
cursor = response.newSyncCursor;
|
|
113
|
+
syncVersion = response.newSyncVersion;
|
|
114
|
+
result.newSyncCursor = cursor;
|
|
115
|
+
// Guard against infinite loop: if all records were duplicates and
|
|
116
|
+
// the cursor didn't advance, the same batch would repeat forever.
|
|
117
|
+
if (response.accepted === 0 && cursor === prevCursor) {
|
|
118
|
+
if (process.env.ADIT_DEBUG) {
|
|
119
|
+
process.stderr.write(`[adit-cloud] sync: all ${count} records were duplicates and cursor unchanged — stopping\n`);
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
// Persist progress after each batch (crash-safe)
|
|
124
|
+
upsertSyncState(this.db, {
|
|
125
|
+
serverUrl: this.serverUrl,
|
|
126
|
+
clientId: this.cloudClientId,
|
|
127
|
+
lastSyncedEventId: cursor,
|
|
128
|
+
lastSyncedAt: new Date().toISOString(),
|
|
129
|
+
syncVersion,
|
|
130
|
+
});
|
|
131
|
+
// If batch was smaller than limit, we're done
|
|
132
|
+
if (count < this.batchSize)
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
};
|
|
137
|
+
if (this.dataDir) {
|
|
138
|
+
return withPerf(this.dataDir, "network", "cloud-sync", doSync);
|
|
139
|
+
}
|
|
140
|
+
return doSync();
|
|
141
|
+
}
|
|
142
|
+
/** Get sync status from server, scoped to this project. */
|
|
143
|
+
async getRemoteStatus() {
|
|
144
|
+
const params = new URLSearchParams({ projectId: this.projectId });
|
|
145
|
+
return this.client.get(`/api/sync/status?${params.toString()}`);
|
|
146
|
+
}
|
|
147
|
+
/** Get local sync state */
|
|
148
|
+
getLocalStatus() {
|
|
149
|
+
return getSyncState(this.db, this.serverUrl);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/sync/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data serializer — builds sync batches from local SQLite data.
|
|
3
|
+
*
|
|
4
|
+
* Queries local tables for records not yet synced (after the cursor),
|
|
5
|
+
* converts them to the server's expected format, and respects the
|
|
6
|
+
* batch size limit (max 500 records per push).
|
|
7
|
+
*/
|
|
8
|
+
import type Database from "better-sqlite3";
|
|
9
|
+
/**
|
|
10
|
+
* Server-facing record types.
|
|
11
|
+
* These use snake_case field names matching the adit-cloud PostgreSQL schema.
|
|
12
|
+
*/
|
|
13
|
+
export interface SyncSession {
|
|
14
|
+
id: string;
|
|
15
|
+
project_id: string;
|
|
16
|
+
client_id: string;
|
|
17
|
+
session_type: string;
|
|
18
|
+
platform: string;
|
|
19
|
+
started_at: string;
|
|
20
|
+
ended_at: string | null;
|
|
21
|
+
status: string;
|
|
22
|
+
metadata_json: string | null;
|
|
23
|
+
vclock_json: string | null;
|
|
24
|
+
deleted_at: string | null;
|
|
25
|
+
}
|
|
26
|
+
export interface SyncEvent {
|
|
27
|
+
id: string;
|
|
28
|
+
session_id: string;
|
|
29
|
+
client_id: string;
|
|
30
|
+
parent_event_id: string | null;
|
|
31
|
+
sequence: number;
|
|
32
|
+
event_type: string;
|
|
33
|
+
actor: string;
|
|
34
|
+
status: string;
|
|
35
|
+
prompt_text: string | null;
|
|
36
|
+
cot_text: string | null;
|
|
37
|
+
response_text: string | null;
|
|
38
|
+
tool_name: string | null;
|
|
39
|
+
tool_input_json: string | null;
|
|
40
|
+
tool_output_json: string | null;
|
|
41
|
+
checkpoint_sha: string | null;
|
|
42
|
+
checkpoint_ref: string | null;
|
|
43
|
+
diff_stat_json: string | null;
|
|
44
|
+
git_branch: string | null;
|
|
45
|
+
git_head_sha: string | null;
|
|
46
|
+
env_snapshot_id: string | null;
|
|
47
|
+
started_at: string;
|
|
48
|
+
ended_at: string | null;
|
|
49
|
+
error_json: string | null;
|
|
50
|
+
labels_json: string | null;
|
|
51
|
+
plan_task_id: string | null;
|
|
52
|
+
vclock_json: string | null;
|
|
53
|
+
deleted_at: string | null;
|
|
54
|
+
}
|
|
55
|
+
export interface SyncEnvSnapshot {
|
|
56
|
+
id: string;
|
|
57
|
+
session_id: string;
|
|
58
|
+
client_id: string;
|
|
59
|
+
git_branch: string | null;
|
|
60
|
+
git_head_sha: string | null;
|
|
61
|
+
modified_files: string | null;
|
|
62
|
+
lockfile_hash: string | null;
|
|
63
|
+
lockfile_path: string | null;
|
|
64
|
+
env_vars: string | null;
|
|
65
|
+
node_version: string | null;
|
|
66
|
+
python_version: string | null;
|
|
67
|
+
os_info: string | null;
|
|
68
|
+
container_info: string | null;
|
|
69
|
+
runtime_versions: string | null;
|
|
70
|
+
shell_info: string | null;
|
|
71
|
+
system_resources: string | null;
|
|
72
|
+
package_manager: string | null;
|
|
73
|
+
captured_at: string;
|
|
74
|
+
vclock_json: string | null;
|
|
75
|
+
deleted_at: string | null;
|
|
76
|
+
}
|
|
77
|
+
export interface SyncPlan {
|
|
78
|
+
id: string;
|
|
79
|
+
project_id: string;
|
|
80
|
+
client_id: string;
|
|
81
|
+
plan_type: string;
|
|
82
|
+
parent_plan_id: string | null;
|
|
83
|
+
title: string;
|
|
84
|
+
content_md: string;
|
|
85
|
+
status: string;
|
|
86
|
+
created_at: string;
|
|
87
|
+
updated_at: string | null;
|
|
88
|
+
vclock_json: string | null;
|
|
89
|
+
deleted_at: string | null;
|
|
90
|
+
}
|
|
91
|
+
export interface SyncDiff {
|
|
92
|
+
id: string;
|
|
93
|
+
event_id: string;
|
|
94
|
+
client_id: string;
|
|
95
|
+
diff_text: string;
|
|
96
|
+
file_filter: string | null;
|
|
97
|
+
created_at: string;
|
|
98
|
+
}
|
|
99
|
+
export interface SyncBatch {
|
|
100
|
+
sessions: SyncSession[];
|
|
101
|
+
events: SyncEvent[];
|
|
102
|
+
envSnapshots: SyncEnvSnapshot[];
|
|
103
|
+
plans: SyncPlan[];
|
|
104
|
+
diffs: SyncDiff[];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Build a sync batch of records after the given cursor.
|
|
108
|
+
*
|
|
109
|
+
* For append-only records (events, env_snapshots, diffs), only selects
|
|
110
|
+
* new records with id > cursor.
|
|
111
|
+
*
|
|
112
|
+
* For mutable records (sessions, plans), also includes records modified
|
|
113
|
+
* since lastSyncedAt so updates are captured.
|
|
114
|
+
*
|
|
115
|
+
* Priority ordering: sessions first (parents), then events, env_snapshots,
|
|
116
|
+
* plans, diffs — maintaining referential integrity on the server.
|
|
117
|
+
*/
|
|
118
|
+
export declare function buildSyncBatch(db: Database.Database, afterEventId: string | null, lastSyncedAt: string | null, projectId: string, cloudClientId: string, batchSize: number): SyncBatch;
|
|
119
|
+
/** Count total unsynced records across all tables */
|
|
120
|
+
export declare function countUnsyncedRecords(db: Database.Database, afterEventId: string | null, lastSyncedAt: string | null, projectId: string): number;
|
|
121
|
+
/** Get total record count in a batch */
|
|
122
|
+
export declare function batchRecordCount(batch: SyncBatch): number;
|
|
123
|
+
//# sourceMappingURL=serializer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../../src/sync/serializer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data serializer — builds sync batches from local SQLite data.
|
|
3
|
+
*
|
|
4
|
+
* Queries local tables for records not yet synced (after the cursor),
|
|
5
|
+
* converts them to the server's expected format, and respects the
|
|
6
|
+
* batch size limit (max 500 records per push).
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Build a sync batch of records after the given cursor.
|
|
10
|
+
*
|
|
11
|
+
* For append-only records (events, env_snapshots, diffs), only selects
|
|
12
|
+
* new records with id > cursor.
|
|
13
|
+
*
|
|
14
|
+
* For mutable records (sessions, plans), also includes records modified
|
|
15
|
+
* since lastSyncedAt so updates are captured.
|
|
16
|
+
*
|
|
17
|
+
* Priority ordering: sessions first (parents), then events, env_snapshots,
|
|
18
|
+
* plans, diffs — maintaining referential integrity on the server.
|
|
19
|
+
*/
|
|
20
|
+
export function buildSyncBatch(db, afterEventId, lastSyncedAt, projectId, cloudClientId, batchSize) {
|
|
21
|
+
const batch = {
|
|
22
|
+
sessions: [],
|
|
23
|
+
events: [],
|
|
24
|
+
envSnapshots: [],
|
|
25
|
+
plans: [],
|
|
26
|
+
diffs: [],
|
|
27
|
+
};
|
|
28
|
+
let remaining = batchSize;
|
|
29
|
+
// 1. Sessions — new or modified since last sync
|
|
30
|
+
if (remaining > 0) {
|
|
31
|
+
batch.sessions = querySessions(db, afterEventId, lastSyncedAt, projectId, cloudClientId, remaining);
|
|
32
|
+
remaining -= batch.sessions.length;
|
|
33
|
+
}
|
|
34
|
+
// 2. Events — append-only, only new records
|
|
35
|
+
if (remaining > 0) {
|
|
36
|
+
batch.events = queryEvents(db, afterEventId, projectId, cloudClientId, remaining);
|
|
37
|
+
remaining -= batch.events.length;
|
|
38
|
+
}
|
|
39
|
+
// 3. Env snapshots — append-only, filtered by project
|
|
40
|
+
if (remaining > 0) {
|
|
41
|
+
batch.envSnapshots = queryEnvSnapshots(db, afterEventId, projectId, cloudClientId, remaining);
|
|
42
|
+
remaining -= batch.envSnapshots.length;
|
|
43
|
+
}
|
|
44
|
+
// 4. Plans — mutable, include modified
|
|
45
|
+
if (remaining > 0) {
|
|
46
|
+
batch.plans = queryPlans(db, afterEventId, lastSyncedAt, projectId, cloudClientId, remaining);
|
|
47
|
+
remaining -= batch.plans.length;
|
|
48
|
+
}
|
|
49
|
+
// 5. Diffs — keyed by event_id, only for events in this batch
|
|
50
|
+
if (batch.events.length > 0 && remaining > 0) {
|
|
51
|
+
const eventIds = batch.events.map((e) => e.id);
|
|
52
|
+
batch.diffs = queryDiffs(db, eventIds, cloudClientId, remaining);
|
|
53
|
+
}
|
|
54
|
+
return batch;
|
|
55
|
+
}
|
|
56
|
+
/** Count total unsynced records across all tables */
|
|
57
|
+
export function countUnsyncedRecords(db, afterEventId, lastSyncedAt, projectId) {
|
|
58
|
+
let total = 0;
|
|
59
|
+
// Events
|
|
60
|
+
if (afterEventId) {
|
|
61
|
+
const eventRow = db
|
|
62
|
+
.prepare(`SELECT COUNT(*) as cnt FROM events e
|
|
63
|
+
JOIN sessions s ON e.session_id = s.id
|
|
64
|
+
WHERE e.id > ? AND s.project_id = ?`)
|
|
65
|
+
.get(afterEventId, projectId);
|
|
66
|
+
total += eventRow.cnt;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
const eventRow = db
|
|
70
|
+
.prepare(`SELECT COUNT(*) as cnt FROM events e
|
|
71
|
+
JOIN sessions s ON e.session_id = s.id
|
|
72
|
+
WHERE s.project_id = ?`)
|
|
73
|
+
.get(projectId);
|
|
74
|
+
total += eventRow.cnt;
|
|
75
|
+
}
|
|
76
|
+
// Sessions (new or modified)
|
|
77
|
+
if (afterEventId) {
|
|
78
|
+
const params = [projectId];
|
|
79
|
+
let sql = `SELECT COUNT(*) as cnt FROM sessions WHERE project_id = ? AND (id > ?`;
|
|
80
|
+
params.push(afterEventId);
|
|
81
|
+
if (lastSyncedAt) {
|
|
82
|
+
sql += ` OR ended_at > ?`;
|
|
83
|
+
params.push(lastSyncedAt);
|
|
84
|
+
}
|
|
85
|
+
sql += `)`;
|
|
86
|
+
const row = db.prepare(sql).get(...params);
|
|
87
|
+
total += row.cnt;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const row = db
|
|
91
|
+
.prepare(`SELECT COUNT(*) as cnt FROM sessions WHERE project_id = ?`)
|
|
92
|
+
.get(projectId);
|
|
93
|
+
total += row.cnt;
|
|
94
|
+
}
|
|
95
|
+
return total;
|
|
96
|
+
}
|
|
97
|
+
/** Get total record count in a batch */
|
|
98
|
+
export function batchRecordCount(batch) {
|
|
99
|
+
return (batch.sessions.length +
|
|
100
|
+
batch.events.length +
|
|
101
|
+
batch.envSnapshots.length +
|
|
102
|
+
batch.plans.length +
|
|
103
|
+
batch.diffs.length);
|
|
104
|
+
}
|
|
105
|
+
// --- Internal query helpers ---
|
|
106
|
+
function querySessions(db, afterId, lastSyncedAt, projectId, cloudClientId, limit) {
|
|
107
|
+
let sql;
|
|
108
|
+
const params = [];
|
|
109
|
+
if (afterId) {
|
|
110
|
+
const conditions = ["project_id = ?", "(id > ?"];
|
|
111
|
+
params.push(projectId, afterId);
|
|
112
|
+
if (lastSyncedAt) {
|
|
113
|
+
conditions[1] += " OR ended_at > ?";
|
|
114
|
+
params.push(lastSyncedAt);
|
|
115
|
+
}
|
|
116
|
+
conditions[1] += ")";
|
|
117
|
+
sql = `SELECT * FROM sessions WHERE ${conditions.join(" AND ")} ORDER BY id ASC LIMIT ?`;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
sql = `SELECT * FROM sessions WHERE project_id = ? ORDER BY id ASC LIMIT ?`;
|
|
121
|
+
params.push(projectId);
|
|
122
|
+
}
|
|
123
|
+
params.push(limit);
|
|
124
|
+
const rows = db.prepare(sql).all(...params);
|
|
125
|
+
return rows.map((r) => ({
|
|
126
|
+
id: r.id,
|
|
127
|
+
project_id: r.project_id,
|
|
128
|
+
client_id: cloudClientId,
|
|
129
|
+
session_type: r.session_type,
|
|
130
|
+
platform: r.platform,
|
|
131
|
+
started_at: r.started_at,
|
|
132
|
+
ended_at: r.ended_at ?? null,
|
|
133
|
+
status: r.status,
|
|
134
|
+
metadata_json: r.metadata_json ?? null,
|
|
135
|
+
vclock_json: r.vclock_json ?? null,
|
|
136
|
+
deleted_at: r.deleted_at ?? null,
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
function queryEvents(db, afterId, projectId, cloudClientId, limit) {
|
|
140
|
+
let sql;
|
|
141
|
+
const params = [];
|
|
142
|
+
if (afterId) {
|
|
143
|
+
sql = `SELECT e.* FROM events e
|
|
144
|
+
JOIN sessions s ON e.session_id = s.id
|
|
145
|
+
WHERE e.id > ? AND s.project_id = ?
|
|
146
|
+
ORDER BY e.id ASC LIMIT ?`;
|
|
147
|
+
params.push(afterId, projectId, limit);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
sql = `SELECT e.* FROM events e
|
|
151
|
+
JOIN sessions s ON e.session_id = s.id
|
|
152
|
+
WHERE s.project_id = ?
|
|
153
|
+
ORDER BY e.id ASC LIMIT ?`;
|
|
154
|
+
params.push(projectId, limit);
|
|
155
|
+
}
|
|
156
|
+
const rows = db.prepare(sql).all(...params);
|
|
157
|
+
return rows.map((r) => ({
|
|
158
|
+
id: r.id,
|
|
159
|
+
session_id: r.session_id,
|
|
160
|
+
client_id: cloudClientId,
|
|
161
|
+
parent_event_id: r.parent_event_id ?? null,
|
|
162
|
+
sequence: r.sequence,
|
|
163
|
+
event_type: r.event_type,
|
|
164
|
+
actor: r.actor,
|
|
165
|
+
status: r.status,
|
|
166
|
+
prompt_text: r.prompt_text ?? null,
|
|
167
|
+
cot_text: r.cot_text ?? null,
|
|
168
|
+
response_text: r.response_text ?? null,
|
|
169
|
+
tool_name: r.tool_name ?? null,
|
|
170
|
+
tool_input_json: r.tool_input_json ?? null,
|
|
171
|
+
tool_output_json: r.tool_output_json ?? null,
|
|
172
|
+
checkpoint_sha: r.checkpoint_sha ?? null,
|
|
173
|
+
checkpoint_ref: r.checkpoint_ref ?? null,
|
|
174
|
+
diff_stat_json: r.diff_stat_json ?? null,
|
|
175
|
+
git_branch: r.git_branch ?? null,
|
|
176
|
+
git_head_sha: r.git_head_sha ?? null,
|
|
177
|
+
env_snapshot_id: r.env_snapshot_id ?? null,
|
|
178
|
+
started_at: r.started_at,
|
|
179
|
+
ended_at: r.ended_at ?? null,
|
|
180
|
+
error_json: r.error_json ?? null,
|
|
181
|
+
labels_json: r.labels_json ?? null,
|
|
182
|
+
plan_task_id: r.plan_task_id ?? null,
|
|
183
|
+
vclock_json: r.vclock_json ?? null,
|
|
184
|
+
deleted_at: r.deleted_at ?? null,
|
|
185
|
+
}));
|
|
186
|
+
}
|
|
187
|
+
function queryEnvSnapshots(db, afterId, projectId, cloudClientId, limit) {
|
|
188
|
+
let sql;
|
|
189
|
+
const params = [];
|
|
190
|
+
// Join on sessions to filter by project_id (prevents cross-project leaks)
|
|
191
|
+
if (afterId) {
|
|
192
|
+
sql = `SELECT es.* FROM env_snapshots es
|
|
193
|
+
JOIN sessions s ON es.session_id = s.id
|
|
194
|
+
WHERE es.id > ? AND s.project_id = ?
|
|
195
|
+
ORDER BY es.id ASC LIMIT ?`;
|
|
196
|
+
params.push(afterId, projectId, limit);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
sql = `SELECT es.* FROM env_snapshots es
|
|
200
|
+
JOIN sessions s ON es.session_id = s.id
|
|
201
|
+
WHERE s.project_id = ?
|
|
202
|
+
ORDER BY es.id ASC LIMIT ?`;
|
|
203
|
+
params.push(projectId, limit);
|
|
204
|
+
}
|
|
205
|
+
const rows = db.prepare(sql).all(...params);
|
|
206
|
+
return rows.map((r) => ({
|
|
207
|
+
id: r.id,
|
|
208
|
+
session_id: r.session_id,
|
|
209
|
+
client_id: cloudClientId,
|
|
210
|
+
git_branch: r.git_branch ?? null,
|
|
211
|
+
git_head_sha: r.git_head_sha ?? null,
|
|
212
|
+
modified_files: r.modified_files ?? null,
|
|
213
|
+
lockfile_hash: r.dep_lock_hash ?? null,
|
|
214
|
+
lockfile_path: r.dep_lock_path ?? null,
|
|
215
|
+
env_vars: r.env_vars_json ?? null,
|
|
216
|
+
node_version: r.node_version ?? null,
|
|
217
|
+
python_version: r.python_version ?? null,
|
|
218
|
+
os_info: r.os_info ?? null,
|
|
219
|
+
container_info: r.container_info ?? null,
|
|
220
|
+
runtime_versions: r.runtime_versions_json ?? null,
|
|
221
|
+
shell_info: r.shell_info ?? null,
|
|
222
|
+
system_resources: r.system_resources_json ?? null,
|
|
223
|
+
package_manager: r.package_manager_json ?? null,
|
|
224
|
+
captured_at: r.captured_at,
|
|
225
|
+
vclock_json: r.vclock_json ?? null,
|
|
226
|
+
deleted_at: r.deleted_at ?? null,
|
|
227
|
+
}));
|
|
228
|
+
}
|
|
229
|
+
function queryPlans(db, afterId, lastSyncedAt, projectId, cloudClientId, limit) {
|
|
230
|
+
let sql;
|
|
231
|
+
const params = [];
|
|
232
|
+
if (afterId) {
|
|
233
|
+
const conditions = ["project_id = ?", "(id > ?"];
|
|
234
|
+
params.push(projectId, afterId);
|
|
235
|
+
if (lastSyncedAt) {
|
|
236
|
+
conditions[1] += " OR updated_at > ?";
|
|
237
|
+
params.push(lastSyncedAt);
|
|
238
|
+
}
|
|
239
|
+
conditions[1] += ")";
|
|
240
|
+
sql = `SELECT * FROM plans WHERE ${conditions.join(" AND ")} ORDER BY id ASC LIMIT ?`;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
sql = `SELECT * FROM plans WHERE project_id = ? ORDER BY id ASC LIMIT ?`;
|
|
244
|
+
params.push(projectId);
|
|
245
|
+
}
|
|
246
|
+
params.push(limit);
|
|
247
|
+
const rows = db.prepare(sql).all(...params);
|
|
248
|
+
return rows.map((r) => ({
|
|
249
|
+
id: r.id,
|
|
250
|
+
project_id: r.project_id,
|
|
251
|
+
client_id: cloudClientId,
|
|
252
|
+
plan_type: r.plan_type,
|
|
253
|
+
parent_plan_id: r.parent_plan_id ?? null,
|
|
254
|
+
title: r.title,
|
|
255
|
+
content_md: r.content_md,
|
|
256
|
+
status: r.status,
|
|
257
|
+
created_at: r.created_at,
|
|
258
|
+
updated_at: r.updated_at ?? null,
|
|
259
|
+
vclock_json: r.vclock_json ?? null,
|
|
260
|
+
deleted_at: r.deleted_at ?? null,
|
|
261
|
+
}));
|
|
262
|
+
}
|
|
263
|
+
function queryDiffs(db, eventIds, cloudClientId, limit) {
|
|
264
|
+
if (eventIds.length === 0)
|
|
265
|
+
return [];
|
|
266
|
+
const placeholders = eventIds.map(() => "?").join(",");
|
|
267
|
+
const sql = `SELECT * FROM diffs WHERE event_id IN (${placeholders}) LIMIT ?`;
|
|
268
|
+
const rows = db
|
|
269
|
+
.prepare(sql)
|
|
270
|
+
.all(...eventIds, limit);
|
|
271
|
+
return rows.map((r) => ({
|
|
272
|
+
id: r.id,
|
|
273
|
+
event_id: r.event_id,
|
|
274
|
+
client_id: cloudClientId,
|
|
275
|
+
diff_text: r.diff_text,
|
|
276
|
+
file_filter: r.file_filter ?? null,
|
|
277
|
+
created_at: r.created_at,
|
|
278
|
+
}));
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=serializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.js","sourceRoot":"","sources":["../../src/sync/serializer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-upload trigger — fire-and-forget transcript upload 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
|
+
* Designed to be called on every hook event. Internally deduplicates
|
|
8
|
+
* by checking if there's actually new data to upload before doing work.
|
|
9
|
+
*/
|
|
10
|
+
import type Database from "better-sqlite3";
|
|
11
|
+
import type { SyncUploadType } from "./uploader.js";
|
|
12
|
+
/**
|
|
13
|
+
* Register a transcript and trigger pending uploads.
|
|
14
|
+
*
|
|
15
|
+
* Call this from hook handlers whenever a transcript_path is seen.
|
|
16
|
+
* The function is idempotent — calling it multiple times with the
|
|
17
|
+
* same path is safe and cheap.
|
|
18
|
+
*
|
|
19
|
+
* @param db - Open database connection
|
|
20
|
+
* @param sessionId - Current session ID
|
|
21
|
+
* @param transcriptPath - Absolute path to the transcript JSONL file
|
|
22
|
+
* @param type - Upload type (default: "transcript")
|
|
23
|
+
*/
|
|
24
|
+
export declare function triggerTranscriptUpload(db: Database.Database, sessionId: string, transcriptPath: string, type?: SyncUploadType): Promise<void>;
|
|
25
|
+
//# sourceMappingURL=auto-upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-upload.d.ts","sourceRoot":"","sources":["../../src/transcript/auto-upload.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAM3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;;;;;;;GAWG;AACH,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,IAAI,GAAE,cAA6B,GAClC,OAAO,CAAC,IAAI,CAAC,CAiDf"}
|