@varveai/adit-core 0.2.1

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 (90) hide show
  1. package/LICENSE +21 -0
  2. package/dist/config/index.d.ts +29 -0
  3. package/dist/config/index.d.ts.map +1 -0
  4. package/dist/config/index.js +107 -0
  5. package/dist/config/index.js.map +1 -0
  6. package/dist/db/connection.d.ts +9 -0
  7. package/dist/db/connection.d.ts.map +1 -0
  8. package/dist/db/connection.js +48 -0
  9. package/dist/db/connection.js.map +1 -0
  10. package/dist/db/diffs.d.ts +22 -0
  11. package/dist/db/diffs.d.ts.map +1 -0
  12. package/dist/db/diffs.js +37 -0
  13. package/dist/db/diffs.js.map +1 -0
  14. package/dist/db/env-snapshots.d.ts +29 -0
  15. package/dist/db/env-snapshots.d.ts.map +1 -0
  16. package/dist/db/env-snapshots.js +57 -0
  17. package/dist/db/env-snapshots.js.map +1 -0
  18. package/dist/db/events.d.ts +91 -0
  19. package/dist/db/events.d.ts.map +1 -0
  20. package/dist/db/events.js +260 -0
  21. package/dist/db/events.js.map +1 -0
  22. package/dist/db/index.d.ts +10 -0
  23. package/dist/db/index.d.ts.map +1 -0
  24. package/dist/db/index.js +10 -0
  25. package/dist/db/index.js.map +1 -0
  26. package/dist/db/migrations.d.ts +13 -0
  27. package/dist/db/migrations.d.ts.map +1 -0
  28. package/dist/db/migrations.js +237 -0
  29. package/dist/db/migrations.js.map +1 -0
  30. package/dist/db/plans.d.ts +21 -0
  31. package/dist/db/plans.d.ts.map +1 -0
  32. package/dist/db/plans.js +52 -0
  33. package/dist/db/plans.js.map +1 -0
  34. package/dist/db/sessions.d.ts +23 -0
  35. package/dist/db/sessions.d.ts.map +1 -0
  36. package/dist/db/sessions.js +57 -0
  37. package/dist/db/sessions.js.map +1 -0
  38. package/dist/db/sync-state.d.ts +21 -0
  39. package/dist/db/sync-state.d.ts.map +1 -0
  40. package/dist/db/sync-state.js +36 -0
  41. package/dist/db/sync-state.js.map +1 -0
  42. package/dist/db/transcript-uploads.d.ts +57 -0
  43. package/dist/db/transcript-uploads.d.ts.map +1 -0
  44. package/dist/db/transcript-uploads.js +132 -0
  45. package/dist/db/transcript-uploads.js.map +1 -0
  46. package/dist/index.d.ts +17 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +17 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/perf/perf-log.d.ts +105 -0
  51. package/dist/perf/perf-log.d.ts.map +1 -0
  52. package/dist/perf/perf-log.js +280 -0
  53. package/dist/perf/perf-log.js.map +1 -0
  54. package/dist/security/content-redaction.d.ts +105 -0
  55. package/dist/security/content-redaction.d.ts.map +1 -0
  56. package/dist/security/content-redaction.js +365 -0
  57. package/dist/security/content-redaction.js.map +1 -0
  58. package/dist/sync/index.d.ts +3 -0
  59. package/dist/sync/index.d.ts.map +1 -0
  60. package/dist/sync/index.js +3 -0
  61. package/dist/sync/index.js.map +1 -0
  62. package/dist/sync/ulid.d.ts +15 -0
  63. package/dist/sync/ulid.d.ts.map +1 -0
  64. package/dist/sync/ulid.js +34 -0
  65. package/dist/sync/ulid.js.map +1 -0
  66. package/dist/sync/vclock.d.ts +33 -0
  67. package/dist/sync/vclock.d.ts.map +1 -0
  68. package/dist/sync/vclock.js +69 -0
  69. package/dist/sync/vclock.js.map +1 -0
  70. package/dist/types/environment.d.ts +53 -0
  71. package/dist/types/environment.d.ts.map +1 -0
  72. package/dist/types/environment.js +8 -0
  73. package/dist/types/environment.js.map +1 -0
  74. package/dist/types/events.d.ts +88 -0
  75. package/dist/types/events.d.ts.map +1 -0
  76. package/dist/types/events.js +40 -0
  77. package/dist/types/events.js.map +1 -0
  78. package/dist/types/index.d.ts +6 -0
  79. package/dist/types/index.d.ts.map +1 -0
  80. package/dist/types/index.js +2 -0
  81. package/dist/types/index.js.map +1 -0
  82. package/dist/types/plan.d.ts +30 -0
  83. package/dist/types/plan.d.ts.map +1 -0
  84. package/dist/types/plan.js +8 -0
  85. package/dist/types/plan.js.map +1 -0
  86. package/dist/types/session.d.ts +44 -0
  87. package/dist/types/session.d.ts.map +1 -0
  88. package/dist/types/session.js +8 -0
  89. package/dist/types/session.js.map +1 -0
  90. package/package.json +29 -0
@@ -0,0 +1,365 @@
1
+ /**
2
+ * Content-aware secret redaction.
3
+ *
4
+ * Scans text content for secrets using two complementary techniques:
5
+ * 1. Shannon entropy scoring — flags high-entropy strings that look like
6
+ * randomly generated secrets (API keys, tokens, passwords).
7
+ * 2. Pattern matching — regex-based detection of known secret formats
8
+ * (AWS keys, GitHub tokens, JWTs, private keys, etc.).
9
+ *
10
+ * Inspired by gitleaks/trufflehog approaches. Designed to run on transcript
11
+ * data (prompts, responses, tool I/O) before writing to the database.
12
+ */
13
+ /**
14
+ * Built-in secret patterns based on common formats.
15
+ * Covers major cloud providers, VCS platforms, payment processors,
16
+ * communication tools, and generic credential formats.
17
+ */
18
+ export const builtinPatterns = [
19
+ // AWS
20
+ { name: "aws-access-key", pattern: /\bAKIA[0-9A-Z]{16}\b/ },
21
+ { name: "aws-secret-key", pattern: /\b[A-Za-z0-9/+=]{40}\b(?=.*aws|.*secret)/i },
22
+ // GitHub
23
+ { name: "github-pat-fine", pattern: /\bgithub_pat_[A-Za-z0-9_]{22,82}\b/ },
24
+ { name: "github-pat", pattern: /\bghp_[A-Za-z0-9]{36,}\b/ },
25
+ { name: "github-oauth", pattern: /\bgho_[A-Za-z0-9]{36,}\b/ },
26
+ { name: "github-app-token", pattern: /\bghu_[A-Za-z0-9]{36,}\b/ },
27
+ { name: "github-refresh-token", pattern: /\bghr_[A-Za-z0-9]{36,}\b/ },
28
+ // GitLab
29
+ { name: "gitlab-pat", pattern: /\bglpat-[A-Za-z0-9\-_]{20,}\b/ },
30
+ { name: "gitlab-pipeline-token", pattern: /\bglptt-[A-Za-z0-9\-_]{20,}\b/ },
31
+ { name: "gitlab-runner-token", pattern: /\bGR1348941[A-Za-z0-9\-_]{20,}\b/ },
32
+ // GCP / Google
33
+ { name: "gcp-api-key", pattern: /\bAIza[0-9A-Za-z\-_]{35}\b/ },
34
+ { name: "gcp-service-account", pattern: /"type"\s*:\s*"service_account"/ },
35
+ // Azure
36
+ { name: "azure-storage-key", pattern: /\b[A-Za-z0-9+/]{86}==\b/ },
37
+ // Stripe
38
+ { name: "stripe-secret-key", pattern: /\bsk_live_[A-Za-z0-9]{24,}\b/ },
39
+ { name: "stripe-publishable", pattern: /\bpk_live_[A-Za-z0-9]{24,}\b/ },
40
+ { name: "stripe-restricted", pattern: /\brk_live_[A-Za-z0-9]{24,}\b/ },
41
+ // Slack
42
+ { name: "slack-token", pattern: /\bxox[baprs]-[A-Za-z0-9\-]{10,}\b/ },
43
+ { name: "slack-webhook", pattern: /https:\/\/hooks\.slack\.com\/services\/T[A-Z0-9]+\/B[A-Z0-9]+\/[A-Za-z0-9]+/ },
44
+ // Discord
45
+ { name: "discord-token", pattern: /\b[MN][A-Za-z0-9]{23,}\.[A-Za-z0-9\-_]{6}\.[A-Za-z0-9\-_]{27,}\b/ },
46
+ { name: "discord-webhook", pattern: /https:\/\/discord(?:app)?\.com\/api\/webhooks\/\d+\/[A-Za-z0-9\-_]+/ },
47
+ // Twilio
48
+ { name: "twilio-api-key", pattern: /\bSK[0-9a-fA-F]{32}\b/ },
49
+ // SendGrid
50
+ { name: "sendgrid-api-key", pattern: /\bSG\.[A-Za-z0-9\-_]{22,}\.[A-Za-z0-9\-_]{22,}\b/ },
51
+ // npm
52
+ { name: "npm-token", pattern: /\bnpm_[A-Za-z0-9]{36,}\b/ },
53
+ // PyPI
54
+ { name: "pypi-token", pattern: /\bpypi-[A-Za-z0-9\-_]{16,}\b/ },
55
+ // Heroku
56
+ { name: "heroku-api-key", pattern: /\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b/ },
57
+ // Private keys
58
+ { name: "private-key-rsa", pattern: /-----BEGIN RSA PRIVATE KEY-----/ },
59
+ { name: "private-key-dsa", pattern: /-----BEGIN DSA PRIVATE KEY-----/ },
60
+ { name: "private-key-ec", pattern: /-----BEGIN EC PRIVATE KEY-----/ },
61
+ { name: "private-key-openssh", pattern: /-----BEGIN OPENSSH PRIVATE KEY-----/ },
62
+ { name: "private-key-pgp", pattern: /-----BEGIN PGP PRIVATE KEY BLOCK-----/ },
63
+ { name: "private-key-generic", pattern: /-----BEGIN PRIVATE KEY-----/ },
64
+ // Generic credential patterns
65
+ { name: "bearer-token", pattern: /\bBearer\s+[A-Za-z0-9\-_\.]{20,}\b/ },
66
+ { name: "basic-auth", pattern: /\bBasic\s+[A-Za-z0-9+/=]{20,}\b/ },
67
+ { name: "jwt", pattern: /\beyJ[A-Za-z0-9\-_]+\.eyJ[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+\b/ },
68
+ // Database connection strings
69
+ { name: "postgres-uri", pattern: /postgres(?:ql)?:\/\/[^\s'"]+:[^\s'"]+@[^\s'"]+/ },
70
+ { name: "mysql-uri", pattern: /mysql:\/\/[^\s'"]+:[^\s'"]+@[^\s'"]+/ },
71
+ { name: "mongodb-uri", pattern: /mongodb(?:\+srv)?:\/\/[^\s'"]+:[^\s'"]+@[^\s'"]+/ },
72
+ { name: "redis-uri", pattern: /redis(?:s)?:\/\/[^\s'"]+:[^\s'"]+@[^\s'"]+/ },
73
+ // Generic password/secret in assignments
74
+ { name: "password-assignment", pattern: /(?:password|passwd|pwd)\s*[:=]\s*["'][^"']{8,}["']/i },
75
+ { name: "secret-assignment", pattern: /(?:secret|api_?key|access_?key|auth_?token)\s*[:=]\s*["'][^"']{8,}["']/i },
76
+ ];
77
+ /**
78
+ * Default field names to skip when scanning structured data.
79
+ * These commonly contain high-entropy but non-secret data.
80
+ */
81
+ export const defaultSkipFields = [
82
+ "id",
83
+ "ids",
84
+ "signature",
85
+ "hash",
86
+ "sha",
87
+ "checksum",
88
+ "digest",
89
+ "uuid",
90
+ "ulid",
91
+ ];
92
+ /**
93
+ * Compute Shannon entropy for a string.
94
+ *
95
+ * Shannon entropy measures the randomness/information density of a string.
96
+ * Random strings (like API keys) typically have entropy > 4.5 bits per character,
97
+ * while natural language text is usually below 4.0.
98
+ *
99
+ * @param s - The string to analyze
100
+ * @returns Entropy in bits per character (0 to log2(charset_size))
101
+ */
102
+ export function shannonEntropy(s) {
103
+ if (s.length === 0)
104
+ return 0;
105
+ const freq = new Map();
106
+ for (const ch of s) {
107
+ freq.set(ch, (freq.get(ch) ?? 0) + 1);
108
+ }
109
+ let entropy = 0;
110
+ const len = s.length;
111
+ for (const count of freq.values()) {
112
+ const p = count / len;
113
+ if (p > 0) {
114
+ entropy -= p * Math.log2(p);
115
+ }
116
+ }
117
+ return entropy;
118
+ }
119
+ /**
120
+ * Extract candidate tokens from text that might be secrets.
121
+ *
122
+ * Tokens are contiguous sequences of non-whitespace characters that
123
+ * meet minimum length requirements. We split on whitespace and common
124
+ * delimiters to isolate individual tokens.
125
+ */
126
+ function extractTokens(text, minLength, maxLength) {
127
+ const results = [];
128
+ // Match contiguous non-whitespace tokens
129
+ const tokenRegex = /\S+/g;
130
+ let match;
131
+ while ((match = tokenRegex.exec(text)) !== null) {
132
+ const raw = match[0];
133
+ const offset = match.index;
134
+ // Strip common surrounding quotes/brackets
135
+ let token = raw;
136
+ let tokenOffset = offset;
137
+ if (/^["'`({[]/.test(token)) {
138
+ token = token.slice(1);
139
+ tokenOffset += 1;
140
+ }
141
+ if (/["'`)};\],.]$/.test(token)) {
142
+ token = token.slice(0, -1);
143
+ }
144
+ if (token.length >= minLength && token.length <= maxLength) {
145
+ results.push({ token, offset: tokenOffset });
146
+ }
147
+ }
148
+ return results;
149
+ }
150
+ /**
151
+ * Scan text for secrets using entropy-based detection.
152
+ *
153
+ * Extracts tokens and checks each for high Shannon entropy,
154
+ * which indicates randomly generated strings like API keys.
155
+ */
156
+ function scanEntropy(text, threshold, minTokenLength, maxTokenLength) {
157
+ const detections = [];
158
+ const tokens = extractTokens(text, minTokenLength, maxTokenLength);
159
+ for (const { token, offset } of tokens) {
160
+ // Skip tokens that look like file paths, URLs, or common code patterns
161
+ if (looksLikeNonSecret(token))
162
+ continue;
163
+ const entropy = shannonEntropy(token);
164
+ if (entropy >= threshold) {
165
+ detections.push({
166
+ method: "entropy",
167
+ offset,
168
+ length: token.length,
169
+ });
170
+ }
171
+ }
172
+ return detections;
173
+ }
174
+ /**
175
+ * Check if a token looks like a non-secret high-entropy string.
176
+ * Helps reduce false positives from file paths, import statements, etc.
177
+ */
178
+ function looksLikeNonSecret(token) {
179
+ // File paths
180
+ if (token.startsWith("/") || token.startsWith("./") || token.startsWith("../"))
181
+ return true;
182
+ if (token.includes("/src/") || token.includes("/node_modules/"))
183
+ return true;
184
+ // URLs without credentials
185
+ if (/^https?:\/\/[^:@]*$/.test(token))
186
+ return true;
187
+ // Package names and imports
188
+ if (token.startsWith("@") && token.includes("/"))
189
+ return true;
190
+ // Common code patterns (hex colors, version numbers, etc.)
191
+ if (/^#[0-9a-fA-F]{3,8}$/.test(token))
192
+ return true;
193
+ if (/^\d+\.\d+\.\d+/.test(token))
194
+ return true;
195
+ // Base64-encoded image data markers
196
+ if (token.startsWith("data:image/"))
197
+ return true;
198
+ return false;
199
+ }
200
+ /**
201
+ * Scan text for secrets using pattern matching.
202
+ */
203
+ function scanPatterns(text, patterns) {
204
+ const detections = [];
205
+ for (const { name, pattern } of patterns) {
206
+ // Create a global version of the pattern for scanning
207
+ const globalPattern = new RegExp(pattern.source, pattern.flags.includes("g") ? pattern.flags : pattern.flags + "g");
208
+ let match;
209
+ while ((match = globalPattern.exec(text)) !== null) {
210
+ detections.push({
211
+ method: "pattern",
212
+ patternName: name,
213
+ offset: match.index,
214
+ length: match[0].length,
215
+ });
216
+ }
217
+ }
218
+ return detections;
219
+ }
220
+ /**
221
+ * Merge overlapping detection ranges and sort by offset.
222
+ * When both entropy and pattern detection flag the same region,
223
+ * we keep the pattern-based detection (more specific).
224
+ */
225
+ function mergeDetections(detections) {
226
+ if (detections.length <= 1)
227
+ return detections;
228
+ // Sort by offset
229
+ const sorted = [...detections].sort((a, b) => a.offset - b.offset);
230
+ const merged = [sorted[0]];
231
+ for (let i = 1; i < sorted.length; i++) {
232
+ const prev = merged[merged.length - 1];
233
+ const curr = sorted[i];
234
+ // Check overlap
235
+ if (curr.offset <= prev.offset + prev.length) {
236
+ // Overlapping — keep the one that covers more or prefer pattern-based
237
+ if (curr.method === "pattern" && prev.method === "entropy") {
238
+ // Replace entropy detection with pattern detection
239
+ merged[merged.length - 1] = {
240
+ method: curr.method,
241
+ patternName: curr.patternName,
242
+ offset: Math.min(prev.offset, curr.offset),
243
+ length: Math.max(prev.offset + prev.length, curr.offset + curr.length) - Math.min(prev.offset, curr.offset),
244
+ };
245
+ }
246
+ else {
247
+ // Extend the previous detection
248
+ const newEnd = Math.max(prev.offset + prev.length, curr.offset + curr.length);
249
+ merged[merged.length - 1] = {
250
+ ...prev,
251
+ length: newEnd - prev.offset,
252
+ };
253
+ }
254
+ }
255
+ else {
256
+ merged.push(curr);
257
+ }
258
+ }
259
+ return merged;
260
+ }
261
+ /**
262
+ * Redact secrets from a text string.
263
+ *
264
+ * Combines entropy-based and pattern-based scanning to detect
265
+ * and replace secrets with a configurable placeholder.
266
+ *
267
+ * @param text - The text to scan and redact
268
+ * @param config - Optional configuration overrides
269
+ * @returns The redacted text and detection details
270
+ */
271
+ export function redactContent(text, config = {}) {
272
+ const { entropyThreshold = 4.5, minTokenLength = 8, maxTokenLength = 256, replacement = "[REDACTED]", customPatterns = [], } = config;
273
+ if (!text || text.length === 0) {
274
+ return { redacted: text, secretsFound: 0, detections: [] };
275
+ }
276
+ // Run both detection methods
277
+ const entropyDetections = scanEntropy(text, entropyThreshold, minTokenLength, maxTokenLength);
278
+ const allPatterns = [...builtinPatterns, ...customPatterns];
279
+ const patternDetections = scanPatterns(text, allPatterns);
280
+ // Merge and deduplicate
281
+ const allDetections = mergeDetections([...entropyDetections, ...patternDetections]);
282
+ if (allDetections.length === 0) {
283
+ return { redacted: text, secretsFound: 0, detections: [] };
284
+ }
285
+ // Apply replacements from end to start to preserve offsets
286
+ let redacted = text;
287
+ for (let i = allDetections.length - 1; i >= 0; i--) {
288
+ const det = allDetections[i];
289
+ redacted =
290
+ redacted.substring(0, det.offset) +
291
+ replacement +
292
+ redacted.substring(det.offset + det.length);
293
+ }
294
+ return {
295
+ redacted,
296
+ secretsFound: allDetections.length,
297
+ detections: allDetections,
298
+ };
299
+ }
300
+ /**
301
+ * Check if a field name should be skipped during structured data scanning.
302
+ *
303
+ * Fields like "id", "signature", "hash" etc. often contain high-entropy
304
+ * strings that are not secrets.
305
+ */
306
+ export function shouldSkipField(fieldName, skipFields) {
307
+ const fields = skipFields ?? defaultSkipFields;
308
+ const lower = fieldName.toLowerCase();
309
+ for (const skip of fields) {
310
+ const skipLower = skip.toLowerCase();
311
+ if (lower === skipLower)
312
+ return true;
313
+ if (lower.endsWith(skipLower))
314
+ return true;
315
+ }
316
+ // Skip fields whose values are image/base64 data
317
+ if (lower === "type" || lower === "content_type")
318
+ return true;
319
+ return false;
320
+ }
321
+ /**
322
+ * Recursively redact secrets from a structured object.
323
+ *
324
+ * Walks through all string values in the object tree and applies
325
+ * content-aware redaction. Skips fields that commonly contain
326
+ * non-secret high-entropy data (IDs, signatures, hashes).
327
+ *
328
+ * @param obj - The object to scan
329
+ * @param config - Optional redaction configuration
330
+ * @returns A new object with secrets redacted
331
+ */
332
+ export function redactObject(obj, config = {}) {
333
+ if (obj === null || obj === undefined)
334
+ return obj;
335
+ if (typeof obj === "string") {
336
+ return redactContent(obj, config).redacted;
337
+ }
338
+ if (Array.isArray(obj)) {
339
+ return obj.map((item) => redactObject(item, config));
340
+ }
341
+ if (typeof obj === "object") {
342
+ const result = {};
343
+ const skipFields = config.skipFields ?? defaultSkipFields;
344
+ for (const [key, value] of Object.entries(obj)) {
345
+ if (shouldSkipField(key, skipFields)) {
346
+ result[key] = value;
347
+ }
348
+ else if (typeof value === "string") {
349
+ // Check if this is an image/base64 value
350
+ if (typeof value === "string" && (value.startsWith("data:image/") || value.startsWith("base64,"))) {
351
+ result[key] = value;
352
+ }
353
+ else {
354
+ result[key] = redactContent(value, config).redacted;
355
+ }
356
+ }
357
+ else {
358
+ result[key] = redactObject(value, config);
359
+ }
360
+ }
361
+ return result;
362
+ }
363
+ return obj;
364
+ }
365
+ //# sourceMappingURL=content-redaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-redaction.js","sourceRoot":"","sources":["../../src/security/content-redaction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { generateId, generateIdAt, extractTimestamp } from "./ulid.js";
2
+ export { type VectorClock, createClock, tick, merge, compare, serialize, deserialize, } from "./vclock.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EACL,KAAK,WAAW,EAChB,WAAW,EACX,IAAI,EACJ,KAAK,EACL,OAAO,EACP,SAAS,EACT,WAAW,GACZ,MAAM,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { generateId, generateIdAt, extractTimestamp } from "./ulid.js";
2
+ export { createClock, tick, merge, compare, serialize, deserialize, } from "./vclock.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAEL,WAAW,EACX,IAAI,EACJ,KAAK,EACL,OAAO,EACP,SAAS,EACT,WAAW,GACZ,MAAM,aAAa,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * ULID generation for globally unique, time-sortable identifiers.
3
+ *
4
+ * ULIDs are used as primary keys across all tables because:
5
+ * 1. They are time-sortable (first 48 bits = timestamp)
6
+ * 2. They are globally unique without coordination
7
+ * 3. They sort lexicographically = natural merge ordering for cloud sync
8
+ */
9
+ /** Generate a new ULID (monotonic within same millisecond) */
10
+ export declare function generateId(): string;
11
+ /** Generate a ULID with a specific timestamp (for testing or import) */
12
+ export declare function generateIdAt(timestamp: number): string;
13
+ /** Extract the timestamp from a ULID */
14
+ export declare function extractTimestamp(id: string): number;
15
+ //# sourceMappingURL=ulid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ulid.d.ts","sourceRoot":"","sources":["../../src/sync/ulid.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,8DAA8D;AAC9D,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wCAAwC;AACxC,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAWnD"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * ULID generation for globally unique, time-sortable identifiers.
3
+ *
4
+ * ULIDs are used as primary keys across all tables because:
5
+ * 1. They are time-sortable (first 48 bits = timestamp)
6
+ * 2. They are globally unique without coordination
7
+ * 3. They sort lexicographically = natural merge ordering for cloud sync
8
+ */
9
+ import { ulid, monotonicFactory } from "ulid";
10
+ /** Monotonic factory ensures ULIDs created in the same ms are still ordered */
11
+ const monotonic = monotonicFactory();
12
+ /** Generate a new ULID (monotonic within same millisecond) */
13
+ export function generateId() {
14
+ return monotonic();
15
+ }
16
+ /** Generate a ULID with a specific timestamp (for testing or import) */
17
+ export function generateIdAt(timestamp) {
18
+ return ulid(timestamp);
19
+ }
20
+ /** Extract the timestamp from a ULID */
21
+ export function extractTimestamp(id) {
22
+ // ULID encodes time in first 10 chars (Crockford Base32)
23
+ const ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
24
+ let time = 0;
25
+ const chars = id.substring(0, 10).toUpperCase();
26
+ for (const char of chars) {
27
+ const idx = ENCODING.indexOf(char);
28
+ if (idx === -1)
29
+ throw new Error(`Invalid ULID character: ${char}`);
30
+ time = time * 32 + idx;
31
+ }
32
+ return time;
33
+ }
34
+ //# sourceMappingURL=ulid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ulid.js","sourceRoot":"","sources":["../../src/sync/ulid.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,MAAM,CAAC;AAE9C,+EAA+E;AAC/E,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAC;AAErC,8DAA8D;AAC9D,MAAM,UAAU,UAAU;IACxB,OAAO,SAAS,EAAE,CAAC;AACrB,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC;AACzB,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,gBAAgB,CAAC,EAAU;IACzC,yDAAyD;IACzD,MAAM,QAAQ,GAAG,kCAAkC,CAAC;IACpD,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,MAAM,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAChD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;QACnE,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG,GAAG,CAAC;IACzB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Vector clock implementation for conflict detection.
3
+ *
4
+ * Each client maintains its own counter. When syncing to cloud:
5
+ * - If clock A dominates clock B → A is newer, no conflict
6
+ * - If neither dominates → concurrent edits, needs merge
7
+ *
8
+ * For ADIT's append-only events, conflicts are rare (two clients
9
+ * can't create the same ULID). Vector clocks primarily help with
10
+ * mutable records like sessions and plans.
11
+ */
12
+ export interface VectorClock {
13
+ [clientId: string]: number;
14
+ }
15
+ /** Create a new vector clock with initial tick for this client */
16
+ export declare function createClock(clientId: string): VectorClock;
17
+ /** Increment this client's counter */
18
+ export declare function tick(clock: VectorClock, clientId: string): VectorClock;
19
+ /** Merge two clocks (take max of each client's counter) */
20
+ export declare function merge(a: VectorClock, b: VectorClock): VectorClock;
21
+ /**
22
+ * Compare two vector clocks.
23
+ * Returns:
24
+ * -1 if a < b (a happened before b)
25
+ * 0 if concurrent (neither dominates)
26
+ * 1 if a > b (a happened after b)
27
+ */
28
+ export declare function compare(a: VectorClock, b: VectorClock): -1 | 0 | 1;
29
+ /** Serialize a vector clock to JSON string */
30
+ export declare function serialize(clock: VectorClock): string;
31
+ /** Deserialize a JSON string to vector clock */
32
+ export declare function deserialize(json: string): VectorClock;
33
+ //# sourceMappingURL=vclock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vclock.d.ts","sourceRoot":"","sources":["../../src/sync/vclock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,WAAW;IAC1B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAED,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAEzD;AAED,sCAAsC;AACtC,wBAAgB,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAKtE;AAED,2DAA2D;AAC3D,wBAAgB,KAAK,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,GAAG,WAAW,CAMjE;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAiBlE;AAED,8CAA8C;AAC9C,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEpD;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAMrD"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Vector clock implementation for conflict detection.
3
+ *
4
+ * Each client maintains its own counter. When syncing to cloud:
5
+ * - If clock A dominates clock B → A is newer, no conflict
6
+ * - If neither dominates → concurrent edits, needs merge
7
+ *
8
+ * For ADIT's append-only events, conflicts are rare (two clients
9
+ * can't create the same ULID). Vector clocks primarily help with
10
+ * mutable records like sessions and plans.
11
+ */
12
+ /** Create a new vector clock with initial tick for this client */
13
+ export function createClock(clientId) {
14
+ return { [clientId]: 1 };
15
+ }
16
+ /** Increment this client's counter */
17
+ export function tick(clock, clientId) {
18
+ return {
19
+ ...clock,
20
+ [clientId]: (clock[clientId] ?? 0) + 1,
21
+ };
22
+ }
23
+ /** Merge two clocks (take max of each client's counter) */
24
+ export function merge(a, b) {
25
+ const result = { ...a };
26
+ for (const [client, count] of Object.entries(b)) {
27
+ result[client] = Math.max(result[client] ?? 0, count);
28
+ }
29
+ return result;
30
+ }
31
+ /**
32
+ * Compare two vector clocks.
33
+ * Returns:
34
+ * -1 if a < b (a happened before b)
35
+ * 0 if concurrent (neither dominates)
36
+ * 1 if a > b (a happened after b)
37
+ */
38
+ export function compare(a, b) {
39
+ const allClients = new Set([...Object.keys(a), ...Object.keys(b)]);
40
+ let aGreater = false;
41
+ let bGreater = false;
42
+ for (const client of allClients) {
43
+ const aVal = a[client] ?? 0;
44
+ const bVal = b[client] ?? 0;
45
+ if (aVal > bVal)
46
+ aGreater = true;
47
+ if (bVal > aVal)
48
+ bGreater = true;
49
+ }
50
+ if (aGreater && !bGreater)
51
+ return 1;
52
+ if (bGreater && !aGreater)
53
+ return -1;
54
+ return 0; // concurrent or equal
55
+ }
56
+ /** Serialize a vector clock to JSON string */
57
+ export function serialize(clock) {
58
+ return JSON.stringify(clock);
59
+ }
60
+ /** Deserialize a JSON string to vector clock */
61
+ export function deserialize(json) {
62
+ try {
63
+ return JSON.parse(json);
64
+ }
65
+ catch {
66
+ return {};
67
+ }
68
+ }
69
+ //# sourceMappingURL=vclock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vclock.js","sourceRoot":"","sources":["../../src/sync/vclock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,kEAAkE;AAClE,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;AAC3B,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,IAAI,CAAC,KAAkB,EAAE,QAAgB;IACvD,OAAO;QACL,GAAG,KAAK;QACR,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC;KACvC,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,KAAK,CAAC,CAAc,EAAE,CAAc;IAClD,MAAM,MAAM,GAAgB,EAAE,GAAG,CAAC,EAAE,CAAC;IACrC,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,CAAc,EAAE,CAAc;IACpD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEnE,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE5B,IAAI,IAAI,GAAG,IAAI;YAAE,QAAQ,GAAG,IAAI,CAAC;QACjC,IAAI,IAAI,GAAG,IAAI;YAAE,QAAQ,GAAG,IAAI,CAAC;IACnC,CAAC;IAED,IAAI,QAAQ,IAAI,CAAC,QAAQ;QAAE,OAAO,CAAC,CAAC;IACpC,IAAI,QAAQ,IAAI,CAAC,QAAQ;QAAE,OAAO,CAAC,CAAC,CAAC;IACrC,OAAO,CAAC,CAAC,CAAC,sBAAsB;AAClC,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,SAAS,CAAC,KAAkB;IAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Environment snapshot types.
3
+ *
4
+ * Captures the execution context at a point in time —
5
+ * not just code, but the world around it.
6
+ */
7
+ export interface EnvSnapshot {
8
+ /** ULID */
9
+ id: string;
10
+ sessionId: string;
11
+ gitBranch: string;
12
+ gitHeadSha: string;
13
+ /** JSON array of modified file paths */
14
+ modifiedFiles: string | null;
15
+ /** Hash of the dependency lockfile */
16
+ depLockHash: string | null;
17
+ /** Which lockfile (package-lock.json, pnpm-lock.yaml, etc.) */
18
+ depLockPath: string | null;
19
+ /** Selected safe environment variables */
20
+ envVarsJson: string | null;
21
+ nodeVersion: string | null;
22
+ pythonVersion: string | null;
23
+ osInfo: string | null;
24
+ /** JSON: {inDocker: bool, image?: string} */
25
+ containerInfo: string | null;
26
+ /** JSON: {rust?, go?, java?, ruby?, ...} */
27
+ runtimeVersionsJson: string | null;
28
+ /** JSON: {shell, version} */
29
+ shellInfo: string | null;
30
+ /** JSON: {arch, cpuModel, totalMem, freeMem, diskFree?} */
31
+ systemResourcesJson: string | null;
32
+ /** JSON: {name, version, globalVersion?} */
33
+ packageManagerJson: string | null;
34
+ capturedAt: string;
35
+ /** Vector clock */
36
+ vclockJson: string;
37
+ /** Soft delete */
38
+ deletedAt: string | null;
39
+ }
40
+ /** Structured diff between two environment snapshots */
41
+ export interface EnvDiff {
42
+ changes: EnvChange[];
43
+ severity: "none" | "info" | "warning" | "breaking";
44
+ }
45
+ /** A single field-level change in the environment */
46
+ export interface EnvChange {
47
+ field: string;
48
+ category: "git" | "dependency" | "runtime" | "system";
49
+ oldValue: string | null;
50
+ newValue: string | null;
51
+ severity: "info" | "warning" | "breaking";
52
+ }
53
+ //# sourceMappingURL=environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/types/environment.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,WAAW;IAC1B,WAAW;IACX,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,sCAAsC;IACtC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,+DAA+D;IAC/D,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,0CAA0C;IAC1C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,6CAA6C;IAC7C,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,4CAA4C;IAC5C,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,6BAA6B;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,2DAA2D;IAC3D,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,4CAA4C;IAC5C,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,wDAAwD;AACxD,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;CACpD;AAED,qDAAqD;AACrD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;IACtD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;CAC3C"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Environment snapshot types.
3
+ *
4
+ * Captures the execution context at a point in time —
5
+ * not just code, but the world around it.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/types/environment.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}