trellis 2.0.6 → 2.0.8

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.
@@ -1,7 +1,8 @@
1
1
  // @bun
2
2
  import {
3
- EAVStore
4
- } from "./index-gkvhzm9f.js";
3
+ EAVStore,
4
+ init_eav_store
5
+ } from "./index-5bhe57y9.js";
5
6
  import {
6
7
  BlobStore,
7
8
  addCriterion,
@@ -20,6 +21,14 @@ import {
20
21
  diffOpRange,
21
22
  getActiveIssues,
22
23
  getIssue,
24
+ init_blob_store,
25
+ init_branch,
26
+ init_checkpoint,
27
+ init_decompose,
28
+ init_diff,
29
+ init_issue,
30
+ init_merge,
31
+ init_milestone,
23
32
  listBranches,
24
33
  listCheckpoints,
25
34
  listIssues,
@@ -37,17 +46,23 @@ import {
37
46
  triageIssue,
38
47
  unblockIssue,
39
48
  updateIssue
40
- } from "./index-3s0eak0p.js";
49
+ } from "./index-3ejh8k6v.js";
41
50
  import {
42
51
  getDecision,
43
52
  getDecisionChain,
53
+ init_decisions,
44
54
  queryDecisions,
45
55
  recordDecision
46
- } from "./index-8pce39mh.js";
56
+ } from "./index-65z0xfjw.js";
47
57
  import {
48
58
  DEFAULT_CONFIG,
49
- createVcsOp
50
- } from "./index-fd4e26s4.js";
59
+ createVcsOp,
60
+ init_ops,
61
+ init_types
62
+ } from "./index-v9b4hqa7.js";
63
+ import {
64
+ __esm
65
+ } from "./index-a76rekgs.js";
51
66
 
52
67
  // src/watcher/fs-watcher.ts
53
68
  import { watch } from "fs";
@@ -81,10 +96,23 @@ class FileWatcher {
81
96
  constructor(config) {
82
97
  this.config = config;
83
98
  }
84
- async scan() {
99
+ async scan(opts) {
85
100
  const events = [];
101
+ opts?.onProgress?.({
102
+ phase: "discovering",
103
+ current: 0,
104
+ total: 0,
105
+ message: "Discovering existing files\u2026"
106
+ });
86
107
  const entries = await this.walkDir(this.config.rootPath);
87
- for (const absPath of entries) {
108
+ opts?.onProgress?.({
109
+ phase: "hashing",
110
+ current: 0,
111
+ total: entries.length,
112
+ message: `Hashing ${entries.length} existing files\u2026`
113
+ });
114
+ for (let i = 0;i < entries.length; i++) {
115
+ const absPath = entries[i];
88
116
  const relPath = relative(this.config.rootPath, absPath);
89
117
  if (shouldIgnore(relPath, this.config.ignorePatterns))
90
118
  continue;
@@ -100,7 +128,21 @@ class FileWatcher {
100
128
  timestamp: new Date().toISOString()
101
129
  });
102
130
  } catch {}
131
+ if ((i + 1) % 25 === 0 || i === entries.length - 1) {
132
+ opts?.onProgress?.({
133
+ phase: "hashing",
134
+ current: i + 1,
135
+ total: entries.length,
136
+ message: `Hashed ${i + 1}/${entries.length} files`
137
+ });
138
+ }
103
139
  }
140
+ opts?.onProgress?.({
141
+ phase: "done",
142
+ current: events.length,
143
+ total: events.length,
144
+ message: `Discovered ${events.length} trackable files`
145
+ });
104
146
  return events;
105
147
  }
106
148
  start() {
@@ -206,37 +248,10 @@ class FileWatcher {
206
248
  return results;
207
249
  }
208
250
  }
251
+ var init_fs_watcher = () => {};
209
252
 
210
253
  // src/watcher/ingestion.ts
211
254
  import { extname } from "path";
212
- var EXT_LANGUAGE = {
213
- ".ts": "typescript",
214
- ".tsx": "typescript",
215
- ".js": "javascript",
216
- ".jsx": "javascript",
217
- ".py": "python",
218
- ".rs": "rust",
219
- ".go": "go",
220
- ".rb": "ruby",
221
- ".java": "java",
222
- ".c": "c",
223
- ".cpp": "cpp",
224
- ".h": "c",
225
- ".hpp": "cpp",
226
- ".cs": "csharp",
227
- ".swift": "swift",
228
- ".kt": "kotlin",
229
- ".md": "markdown",
230
- ".json": "json",
231
- ".yaml": "yaml",
232
- ".yml": "yaml",
233
- ".toml": "toml",
234
- ".html": "html",
235
- ".css": "css",
236
- ".scss": "scss",
237
- ".vue": "vue",
238
- ".svelte": "svelte"
239
- };
240
255
  function detectLanguage(filePath) {
241
256
  const ext = extname(filePath).toLowerCase();
242
257
  return EXT_LANGUAGE[ext];
@@ -294,25 +309,40 @@ class Ingestion {
294
309
  return this.lastOpHash;
295
310
  }
296
311
  }
297
-
298
- // src/engine.ts
299
- import {
300
- existsSync,
301
- mkdirSync,
302
- readFileSync,
303
- writeFileSync,
304
- copyFileSync
305
- } from "fs";
306
- import { readFile as readFile2 } from "fs/promises";
307
- import { join as join2, dirname } from "path";
312
+ var EXT_LANGUAGE;
313
+ var init_ingestion = __esm(() => {
314
+ init_ops();
315
+ EXT_LANGUAGE = {
316
+ ".ts": "typescript",
317
+ ".tsx": "typescript",
318
+ ".js": "javascript",
319
+ ".jsx": "javascript",
320
+ ".py": "python",
321
+ ".rs": "rust",
322
+ ".go": "go",
323
+ ".rb": "ruby",
324
+ ".java": "java",
325
+ ".c": "c",
326
+ ".cpp": "cpp",
327
+ ".h": "c",
328
+ ".hpp": "cpp",
329
+ ".cs": "csharp",
330
+ ".swift": "swift",
331
+ ".kt": "kotlin",
332
+ ".md": "markdown",
333
+ ".json": "json",
334
+ ".yaml": "yaml",
335
+ ".yml": "yaml",
336
+ ".toml": "toml",
337
+ ".html": "html",
338
+ ".css": "css",
339
+ ".scss": "scss",
340
+ ".vue": "vue",
341
+ ".svelte": "svelte"
342
+ };
343
+ });
308
344
 
309
345
  // src/garden/cluster.ts
310
- var FILE_OP_KINDS = new Set([
311
- "vcs:fileAdd",
312
- "vcs:fileModify",
313
- "vcs:fileDelete",
314
- "vcs:fileRename"
315
- ]);
316
346
  function isFileOp(op) {
317
347
  return FILE_OP_KINDS.has(op.kind);
318
348
  }
@@ -330,171 +360,181 @@ function generateClusterId(prefix, ops) {
330
360
  const hash = ops[0]?.hash?.slice(0, 8) ?? "unknown";
331
361
  return `cluster:${prefix}-${hash}`;
332
362
  }
333
- var contextSwitchDetector = {
334
- name: "context-switch",
335
- detect(ops, milestonedOpHashes) {
336
- const fileOps = ops.filter((o) => isFileOp(o) && !milestonedOpHashes.has(o.hash));
337
- if (fileOps.length < 2)
338
- return [];
339
- const groups = [];
340
- let currentGroup = [];
341
- let currentFiles = new Set;
342
- for (const op of fileOps) {
343
- const opFile = op.vcs?.filePath;
344
- if (!opFile)
345
- continue;
346
- const opDir = opFile.split("/").slice(0, -1).join("/") || ".";
347
- if (currentGroup.length === 0) {
348
- currentGroup.push(op);
349
- currentFiles.add(opDir);
350
- continue;
351
- }
352
- const currentDirs = [...currentFiles];
353
- const hasOverlap = currentDirs.some((d) => opDir.startsWith(d) || d.startsWith(opDir) || d === opDir);
354
- if (hasOverlap) {
355
- currentGroup.push(op);
356
- currentFiles.add(opDir);
357
- } else {
358
- if (currentGroup.length > 0) {
359
- groups.push(currentGroup);
360
- }
361
- currentGroup = [op];
362
- currentFiles = new Set([opDir]);
363
+ function detectClusters(ops, milestonedOpHashes, detectors = defaultDetectors) {
364
+ const seen = new Set;
365
+ const results = [];
366
+ for (const detector of detectors) {
367
+ const clusters = detector.detect(ops, milestonedOpHashes);
368
+ for (const cluster of clusters) {
369
+ if (!seen.has(cluster.id)) {
370
+ seen.add(cluster.id);
371
+ results.push(cluster);
363
372
  }
364
373
  }
365
- if (currentGroup.length > 0) {
366
- groups.push(currentGroup);
367
- }
368
- const clusters = [];
369
- for (let i = 0;i < groups.length - 1; i++) {
370
- const group = groups[i];
371
- if (group.length < 2)
372
- continue;
373
- clusters.push({
374
- id: generateClusterId("ctx", group),
375
- ops: group,
376
- firstOp: group[0].hash,
377
- lastOp: group[group.length - 1].hash,
378
- affectedFiles: extractFiles(group),
379
- affectedSymbols: [],
380
- estimatedIntent: "",
381
- createdAt: group[0].timestamp,
382
- abandonedAt: group[group.length - 1].timestamp,
383
- status: "abandoned",
384
- detectedBy: "context-switch"
385
- });
386
- }
387
- return clusters;
388
374
  }
389
- };
390
- var revertDetector = {
391
- name: "revert",
392
- detect(ops, milestonedOpHashes) {
393
- const clusters = [];
394
- const hashHistory = new Map;
395
- for (let i = 0;i < ops.length; i++) {
396
- const op = ops[i];
397
- if (!isFileOp(op) || !op.vcs?.filePath || !op.vcs?.contentHash)
398
- continue;
399
- const filePath = op.vcs.filePath;
400
- if (!hashHistory.has(filePath)) {
401
- hashHistory.set(filePath, []);
402
- }
403
- const history = hashHistory.get(filePath);
404
- const currentHash = op.vcs.contentHash;
405
- const priorIdx = history.findIndex((h) => h.hash === currentHash);
406
- if (priorIdx >= 0 && priorIdx < history.length - 1) {
407
- const revertedStartIdx = history[priorIdx + 1].opIdx;
408
- const revertedEndIdx = history[history.length - 1].opIdx;
409
- const revertedOps = ops.slice(revertedStartIdx, revertedEndIdx + 1).filter((o) => isFileOp(o) && o.vcs?.filePath === filePath && !milestonedOpHashes.has(o.hash));
410
- if (revertedOps.length >= 2) {
411
- clusters.push({
412
- id: generateClusterId("rev", revertedOps),
413
- ops: revertedOps,
414
- firstOp: revertedOps[0].hash,
415
- lastOp: revertedOps[revertedOps.length - 1].hash,
416
- affectedFiles: [filePath],
417
- affectedSymbols: [],
418
- estimatedIntent: "",
419
- createdAt: revertedOps[0].timestamp,
420
- abandonedAt: op.timestamp,
421
- status: "abandoned",
422
- detectedBy: "revert"
423
- });
375
+ results.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
376
+ return results;
377
+ }
378
+ var FILE_OP_KINDS, contextSwitchDetector, revertDetector, staleBranchDetector, defaultDetectors;
379
+ var init_cluster = __esm(() => {
380
+ FILE_OP_KINDS = new Set([
381
+ "vcs:fileAdd",
382
+ "vcs:fileModify",
383
+ "vcs:fileDelete",
384
+ "vcs:fileRename"
385
+ ]);
386
+ contextSwitchDetector = {
387
+ name: "context-switch",
388
+ detect(ops, milestonedOpHashes) {
389
+ const fileOps = ops.filter((o) => isFileOp(o) && !milestonedOpHashes.has(o.hash));
390
+ if (fileOps.length < 2)
391
+ return [];
392
+ const groups = [];
393
+ let currentGroup = [];
394
+ let currentFiles = new Set;
395
+ for (const op of fileOps) {
396
+ const opFile = op.vcs?.filePath;
397
+ if (!opFile)
398
+ continue;
399
+ const opDir = opFile.split("/").slice(0, -1).join("/") || ".";
400
+ if (currentGroup.length === 0) {
401
+ currentGroup.push(op);
402
+ currentFiles.add(opDir);
403
+ continue;
424
404
  }
425
- }
426
- history.push({ hash: currentHash, opIdx: i });
427
- }
428
- return clusters;
429
- }
430
- };
431
- var staleBranchDetector = {
432
- name: "stale-branch",
433
- detect(ops, milestonedOpHashes) {
434
- const clusters = [];
435
- const branchOps = new Map;
436
- let currentBranch = "main";
437
- for (const op of ops) {
438
- if (op.kind === "vcs:branchCreate" && op.vcs?.branchName) {
439
- currentBranch = op.vcs.branchName;
440
- if (!branchOps.has(currentBranch)) {
441
- branchOps.set(currentBranch, []);
405
+ const currentDirs = [...currentFiles];
406
+ const hasOverlap = currentDirs.some((d) => opDir.startsWith(d) || d.startsWith(opDir) || d === opDir);
407
+ if (hasOverlap) {
408
+ currentGroup.push(op);
409
+ currentFiles.add(opDir);
410
+ } else {
411
+ if (currentGroup.length > 0) {
412
+ groups.push(currentGroup);
413
+ }
414
+ currentGroup = [op];
415
+ currentFiles = new Set([opDir]);
442
416
  }
443
417
  }
444
- if (isFileOp(op) && !milestonedOpHashes.has(op.hash)) {
445
- if (!branchOps.has(currentBranch)) {
446
- branchOps.set(currentBranch, []);
447
- }
448
- branchOps.get(currentBranch).push(op);
418
+ if (currentGroup.length > 0) {
419
+ groups.push(currentGroup);
449
420
  }
450
- }
451
- for (const [branchName, fileOps] of branchOps) {
452
- if (branchName === "main")
453
- continue;
454
- if (fileOps.length < 2)
455
- continue;
456
- const lastOpTime = new Date(fileOps[fileOps.length - 1].timestamp).getTime();
457
- const now = Date.now();
458
- const daysSinceLastOp = (now - lastOpTime) / (1000 * 60 * 60 * 24);
459
- if (daysSinceLastOp > 7) {
421
+ const clusters = [];
422
+ for (let i = 0;i < groups.length - 1; i++) {
423
+ const group = groups[i];
424
+ if (group.length < 2)
425
+ continue;
460
426
  clusters.push({
461
- id: generateClusterId("stale", fileOps),
462
- ops: fileOps,
463
- firstOp: fileOps[0].hash,
464
- lastOp: fileOps[fileOps.length - 1].hash,
465
- affectedFiles: extractFiles(fileOps),
427
+ id: generateClusterId("ctx", group),
428
+ ops: group,
429
+ firstOp: group[0].hash,
430
+ lastOp: group[group.length - 1].hash,
431
+ affectedFiles: extractFiles(group),
466
432
  affectedSymbols: [],
467
433
  estimatedIntent: "",
468
- createdAt: fileOps[0].timestamp,
469
- abandonedAt: fileOps[fileOps.length - 1].timestamp,
434
+ createdAt: group[0].timestamp,
435
+ abandonedAt: group[group.length - 1].timestamp,
470
436
  status: "abandoned",
471
- detectedBy: "stale-branch"
437
+ detectedBy: "context-switch"
472
438
  });
473
439
  }
440
+ return clusters;
474
441
  }
475
- return clusters;
476
- }
477
- };
478
- var defaultDetectors = [
479
- contextSwitchDetector,
480
- revertDetector,
481
- staleBranchDetector
482
- ];
483
- function detectClusters(ops, milestonedOpHashes, detectors = defaultDetectors) {
484
- const seen = new Set;
485
- const results = [];
486
- for (const detector of detectors) {
487
- const clusters = detector.detect(ops, milestonedOpHashes);
488
- for (const cluster of clusters) {
489
- if (!seen.has(cluster.id)) {
490
- seen.add(cluster.id);
491
- results.push(cluster);
442
+ };
443
+ revertDetector = {
444
+ name: "revert",
445
+ detect(ops, milestonedOpHashes) {
446
+ const clusters = [];
447
+ const hashHistory = new Map;
448
+ for (let i = 0;i < ops.length; i++) {
449
+ const op = ops[i];
450
+ if (!isFileOp(op) || !op.vcs?.filePath || !op.vcs?.contentHash)
451
+ continue;
452
+ const filePath = op.vcs.filePath;
453
+ if (!hashHistory.has(filePath)) {
454
+ hashHistory.set(filePath, []);
455
+ }
456
+ const history = hashHistory.get(filePath);
457
+ const currentHash = op.vcs.contentHash;
458
+ const priorIdx = history.findIndex((h) => h.hash === currentHash);
459
+ if (priorIdx >= 0 && priorIdx < history.length - 1) {
460
+ const revertedStartIdx = history[priorIdx + 1].opIdx;
461
+ const revertedEndIdx = history[history.length - 1].opIdx;
462
+ const revertedOps = ops.slice(revertedStartIdx, revertedEndIdx + 1).filter((o) => isFileOp(o) && o.vcs?.filePath === filePath && !milestonedOpHashes.has(o.hash));
463
+ if (revertedOps.length >= 2) {
464
+ clusters.push({
465
+ id: generateClusterId("rev", revertedOps),
466
+ ops: revertedOps,
467
+ firstOp: revertedOps[0].hash,
468
+ lastOp: revertedOps[revertedOps.length - 1].hash,
469
+ affectedFiles: [filePath],
470
+ affectedSymbols: [],
471
+ estimatedIntent: "",
472
+ createdAt: revertedOps[0].timestamp,
473
+ abandonedAt: op.timestamp,
474
+ status: "abandoned",
475
+ detectedBy: "revert"
476
+ });
477
+ }
478
+ }
479
+ history.push({ hash: currentHash, opIdx: i });
492
480
  }
481
+ return clusters;
493
482
  }
494
- }
495
- results.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
496
- return results;
497
- }
483
+ };
484
+ staleBranchDetector = {
485
+ name: "stale-branch",
486
+ detect(ops, milestonedOpHashes) {
487
+ const clusters = [];
488
+ const branchOps = new Map;
489
+ let currentBranch = "main";
490
+ for (const op of ops) {
491
+ if (op.kind === "vcs:branchCreate" && op.vcs?.branchName) {
492
+ currentBranch = op.vcs.branchName;
493
+ if (!branchOps.has(currentBranch)) {
494
+ branchOps.set(currentBranch, []);
495
+ }
496
+ }
497
+ if (isFileOp(op) && !milestonedOpHashes.has(op.hash)) {
498
+ if (!branchOps.has(currentBranch)) {
499
+ branchOps.set(currentBranch, []);
500
+ }
501
+ branchOps.get(currentBranch).push(op);
502
+ }
503
+ }
504
+ for (const [branchName, fileOps] of branchOps) {
505
+ if (branchName === "main")
506
+ continue;
507
+ if (fileOps.length < 2)
508
+ continue;
509
+ const lastOpTime = new Date(fileOps[fileOps.length - 1].timestamp).getTime();
510
+ const now = Date.now();
511
+ const daysSinceLastOp = (now - lastOpTime) / (1000 * 60 * 60 * 24);
512
+ if (daysSinceLastOp > 7) {
513
+ clusters.push({
514
+ id: generateClusterId("stale", fileOps),
515
+ ops: fileOps,
516
+ firstOp: fileOps[0].hash,
517
+ lastOp: fileOps[fileOps.length - 1].hash,
518
+ affectedFiles: extractFiles(fileOps),
519
+ affectedSymbols: [],
520
+ estimatedIntent: "",
521
+ createdAt: fileOps[0].timestamp,
522
+ abandonedAt: fileOps[fileOps.length - 1].timestamp,
523
+ status: "abandoned",
524
+ detectedBy: "stale-branch"
525
+ });
526
+ }
527
+ }
528
+ return clusters;
529
+ }
530
+ };
531
+ defaultDetectors = [
532
+ contextSwitchDetector,
533
+ revertDetector,
534
+ staleBranchDetector
535
+ ];
536
+ });
537
+
498
538
  // src/garden/garden.ts
499
539
  class IdeaGarden {
500
540
  ctx;
@@ -653,25 +693,17 @@ function buildMilestonedOpHashes(ops) {
653
693
  }
654
694
  return milestoned;
655
695
  }
696
+ var init_garden = __esm(() => {
697
+ init_cluster();
698
+ });
699
+
700
+ // src/garden/index.ts
701
+ var init_garden2 = __esm(() => {
702
+ init_cluster();
703
+ init_garden();
704
+ });
705
+
656
706
  // src/semantic/ts-parser.ts
657
- var typescriptParser = {
658
- languages: ["typescript", "javascript", "tsx", "jsx"],
659
- parse(content, filePath) {
660
- const fileEntityId = `file:${filePath}`;
661
- const language = detectLanguage2(filePath);
662
- return {
663
- fileEntityId,
664
- filePath,
665
- language,
666
- declarations: extractDeclarations(content, filePath),
667
- imports: extractImports(content),
668
- exports: extractExports(content)
669
- };
670
- },
671
- diff(oldResult, newResult) {
672
- return computeSemanticDiff(oldResult, newResult);
673
- }
674
- };
675
707
  function detectLanguage2(filePath) {
676
708
  if (filePath.endsWith(".tsx"))
677
709
  return "tsx";
@@ -1121,24 +1153,29 @@ function makeEntityId(filePath, kind, name) {
1121
1153
  function normalizeSignature(text) {
1122
1154
  return text.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s+/g, " ").replace(/;\s*$/, "").trim();
1123
1155
  }
1156
+ var typescriptParser;
1157
+ var init_ts_parser = __esm(() => {
1158
+ typescriptParser = {
1159
+ languages: ["typescript", "javascript", "tsx", "jsx"],
1160
+ parse(content, filePath) {
1161
+ const fileEntityId = `file:${filePath}`;
1162
+ const language = detectLanguage2(filePath);
1163
+ return {
1164
+ fileEntityId,
1165
+ filePath,
1166
+ language,
1167
+ declarations: extractDeclarations(content, filePath),
1168
+ imports: extractImports(content),
1169
+ exports: extractExports(content)
1170
+ };
1171
+ },
1172
+ diff(oldResult, newResult) {
1173
+ return computeSemanticDiff(oldResult, newResult);
1174
+ }
1175
+ };
1176
+ });
1177
+
1124
1178
  // src/semantic/python-parser.ts
1125
- var pythonParser = {
1126
- languages: ["python"],
1127
- parse(content, filePath) {
1128
- const fileEntityId = `file:${filePath}`;
1129
- return {
1130
- fileEntityId,
1131
- filePath,
1132
- language: "python",
1133
- declarations: extractDeclarations2(content, filePath),
1134
- imports: extractImports2(content),
1135
- exports: extractExports2(content)
1136
- };
1137
- },
1138
- diff(oldResult, newResult) {
1139
- return computeSemanticDiff2(oldResult, newResult);
1140
- }
1141
- };
1142
1179
  function extractDeclarations2(content, filePath) {
1143
1180
  const declarations = [];
1144
1181
  const lines = content.split(`
@@ -1512,24 +1549,28 @@ function makeEntityId2(filePath, kind, name) {
1512
1549
  function normalizeSignature2(text) {
1513
1550
  return text.replace(/#[^\n]*/g, "").replace(/"""[\s\S]*?"""/g, "").replace(/'''[\s\S]*?'''/g, "").replace(/\s+/g, " ").trim();
1514
1551
  }
1552
+ var pythonParser;
1553
+ var init_python_parser = __esm(() => {
1554
+ pythonParser = {
1555
+ languages: ["python"],
1556
+ parse(content, filePath) {
1557
+ const fileEntityId = `file:${filePath}`;
1558
+ return {
1559
+ fileEntityId,
1560
+ filePath,
1561
+ language: "python",
1562
+ declarations: extractDeclarations2(content, filePath),
1563
+ imports: extractImports2(content),
1564
+ exports: extractExports2(content)
1565
+ };
1566
+ },
1567
+ diff(oldResult, newResult) {
1568
+ return computeSemanticDiff2(oldResult, newResult);
1569
+ }
1570
+ };
1571
+ });
1572
+
1515
1573
  // src/semantic/go-parser.ts
1516
- var goParser = {
1517
- languages: ["go"],
1518
- parse(content, filePath) {
1519
- const fileEntityId = `file:${filePath}`;
1520
- return {
1521
- fileEntityId,
1522
- filePath,
1523
- language: "go",
1524
- declarations: extractDeclarations3(content, filePath),
1525
- imports: extractImports3(content),
1526
- exports: extractExports3(content, filePath)
1527
- };
1528
- },
1529
- diff(oldResult, newResult) {
1530
- return computeSemanticDiff3(oldResult, newResult);
1531
- }
1532
- };
1533
1574
  function extractDeclarations3(content, filePath) {
1534
1575
  const declarations = [];
1535
1576
  const lines = content.split(`
@@ -1940,24 +1981,28 @@ function makeEntityId3(filePath, kind, name) {
1940
1981
  function normalizeSignature3(text) {
1941
1982
  return text.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s+/g, " ").trim();
1942
1983
  }
1984
+ var goParser;
1985
+ var init_go_parser = __esm(() => {
1986
+ goParser = {
1987
+ languages: ["go"],
1988
+ parse(content, filePath) {
1989
+ const fileEntityId = `file:${filePath}`;
1990
+ return {
1991
+ fileEntityId,
1992
+ filePath,
1993
+ language: "go",
1994
+ declarations: extractDeclarations3(content, filePath),
1995
+ imports: extractImports3(content),
1996
+ exports: extractExports3(content, filePath)
1997
+ };
1998
+ },
1999
+ diff(oldResult, newResult) {
2000
+ return computeSemanticDiff3(oldResult, newResult);
2001
+ }
2002
+ };
2003
+ });
2004
+
1943
2005
  // src/semantic/rust-parser.ts
1944
- var rustParser = {
1945
- languages: ["rust"],
1946
- parse(content, filePath) {
1947
- const fileEntityId = `file:${filePath}`;
1948
- return {
1949
- fileEntityId,
1950
- filePath,
1951
- language: "rust",
1952
- declarations: extractDeclarations4(content, filePath),
1953
- imports: extractImports4(content),
1954
- exports: extractExports4(content, filePath)
1955
- };
1956
- },
1957
- diff(oldResult, newResult) {
1958
- return computeSemanticDiff4(oldResult, newResult);
1959
- }
1960
- };
1961
2006
  function extractDeclarations4(content, filePath) {
1962
2007
  const declarations = [];
1963
2008
  const lines = content.split(`
@@ -2392,24 +2437,28 @@ function makeEntityId4(filePath, kind, name) {
2392
2437
  function normalizeSignature4(text) {
2393
2438
  return text.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s+/g, " ").trim();
2394
2439
  }
2440
+ var rustParser;
2441
+ var init_rust_parser = __esm(() => {
2442
+ rustParser = {
2443
+ languages: ["rust"],
2444
+ parse(content, filePath) {
2445
+ const fileEntityId = `file:${filePath}`;
2446
+ return {
2447
+ fileEntityId,
2448
+ filePath,
2449
+ language: "rust",
2450
+ declarations: extractDeclarations4(content, filePath),
2451
+ imports: extractImports4(content),
2452
+ exports: extractExports4(content, filePath)
2453
+ };
2454
+ },
2455
+ diff(oldResult, newResult) {
2456
+ return computeSemanticDiff4(oldResult, newResult);
2457
+ }
2458
+ };
2459
+ });
2460
+
2395
2461
  // src/semantic/ruby-parser.ts
2396
- var rubyParser = {
2397
- languages: ["ruby"],
2398
- parse(content, filePath) {
2399
- const fileEntityId = `file:${filePath}`;
2400
- return {
2401
- fileEntityId,
2402
- filePath,
2403
- language: "ruby",
2404
- declarations: extractDeclarations5(content, filePath),
2405
- imports: extractImports5(content),
2406
- exports: extractExports5(content)
2407
- };
2408
- },
2409
- diff(oldResult, newResult) {
2410
- return computeSemanticDiff5(oldResult, newResult);
2411
- }
2412
- };
2413
2462
  function extractDeclarations5(content, filePath) {
2414
2463
  const declarations = [];
2415
2464
  const lines = content.split(`
@@ -2718,28 +2767,28 @@ function makeEntityId5(filePath, kind, name) {
2718
2767
  function normalizeSignature5(text) {
2719
2768
  return text.replace(/#[^\n]*/g, "").replace(/\s+/g, " ").trim();
2720
2769
  }
2770
+ var rubyParser;
2771
+ var init_ruby_parser = __esm(() => {
2772
+ rubyParser = {
2773
+ languages: ["ruby"],
2774
+ parse(content, filePath) {
2775
+ const fileEntityId = `file:${filePath}`;
2776
+ return {
2777
+ fileEntityId,
2778
+ filePath,
2779
+ language: "ruby",
2780
+ declarations: extractDeclarations5(content, filePath),
2781
+ imports: extractImports5(content),
2782
+ exports: extractExports5(content)
2783
+ };
2784
+ },
2785
+ diff(oldResult, newResult) {
2786
+ return computeSemanticDiff5(oldResult, newResult);
2787
+ }
2788
+ };
2789
+ });
2790
+
2721
2791
  // src/semantic/java-parser.ts
2722
- var javaParser = {
2723
- languages: ["java"],
2724
- parse(content, filePath) {
2725
- const fileEntityId = `file:${filePath}`;
2726
- return {
2727
- fileEntityId,
2728
- filePath,
2729
- language: "java",
2730
- declarations: extractDeclarations6(content, filePath),
2731
- imports: extractImports6(content),
2732
- exports: extractExports6(content, filePath)
2733
- };
2734
- },
2735
- diff(oldResult, newResult) {
2736
- return computeSemanticDiff6(oldResult, newResult);
2737
- }
2738
- };
2739
- var MODIFIERS = /(?:(?:public|private|protected|static|final|abstract|synchronized|native|transient|volatile|strictfp|sealed|non-sealed|default)\s+)*/;
2740
- var CLASS_RE = new RegExp(`^${MODIFIERS.source}(class|interface|enum|record|@interface)\\s+(\\w+)`);
2741
- var METHOD_RE = new RegExp(`^${MODIFIERS.source}(?:<[^>]+>\\s+)?(?:\\w[\\w<>\\[\\],\\s?]*?)\\s+(\\w+)\\s*\\(`);
2742
- var FIELD_RE = new RegExp(`^${MODIFIERS.source}(?:\\w[\\w<>\\[\\],\\s?]*?)\\s+(\\w+)\\s*[;=]`);
2743
2792
  function extractDeclarations6(content, filePath) {
2744
2793
  const declarations = [];
2745
2794
  const lines = content.split(`
@@ -3047,29 +3096,32 @@ function makeEntityId6(filePath, kind, name) {
3047
3096
  function normalizeSignature6(text) {
3048
3097
  return text.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s+/g, " ").trim();
3049
3098
  }
3099
+ var javaParser, MODIFIERS, CLASS_RE, METHOD_RE, FIELD_RE;
3100
+ var init_java_parser = __esm(() => {
3101
+ javaParser = {
3102
+ languages: ["java"],
3103
+ parse(content, filePath) {
3104
+ const fileEntityId = `file:${filePath}`;
3105
+ return {
3106
+ fileEntityId,
3107
+ filePath,
3108
+ language: "java",
3109
+ declarations: extractDeclarations6(content, filePath),
3110
+ imports: extractImports6(content),
3111
+ exports: extractExports6(content, filePath)
3112
+ };
3113
+ },
3114
+ diff(oldResult, newResult) {
3115
+ return computeSemanticDiff6(oldResult, newResult);
3116
+ }
3117
+ };
3118
+ MODIFIERS = /(?:(?:public|private|protected|static|final|abstract|synchronized|native|transient|volatile|strictfp|sealed|non-sealed|default)\s+)*/;
3119
+ CLASS_RE = new RegExp(`^${MODIFIERS.source}(class|interface|enum|record|@interface)\\s+(\\w+)`);
3120
+ METHOD_RE = new RegExp(`^${MODIFIERS.source}(?:<[^>]+>\\s+)?(?:\\w[\\w<>\\[\\],\\s?]*?)\\s+(\\w+)\\s*\\(`);
3121
+ FIELD_RE = new RegExp(`^${MODIFIERS.source}(?:\\w[\\w<>\\[\\],\\s?]*?)\\s+(\\w+)\\s*[;=]`);
3122
+ });
3123
+
3050
3124
  // src/semantic/csharp-parser.ts
3051
- var csharpParser = {
3052
- languages: ["csharp"],
3053
- parse(content, filePath) {
3054
- const fileEntityId = `file:${filePath}`;
3055
- return {
3056
- fileEntityId,
3057
- filePath,
3058
- language: "csharp",
3059
- declarations: extractDeclarations7(content, filePath),
3060
- imports: extractImports7(content),
3061
- exports: extractExports7(content)
3062
- };
3063
- },
3064
- diff(oldResult, newResult) {
3065
- return computeSemanticDiff7(oldResult, newResult);
3066
- }
3067
- };
3068
- var MODIFIERS_RE = /(?:(?:public|private|protected|internal|static|abstract|sealed|virtual|override|partial|readonly|async|extern|unsafe|volatile|new)\s+)*/;
3069
- var TYPE_DEF_RE = new RegExp(`^${MODIFIERS_RE.source}(class|interface|struct|enum|record)\\s+(\\w+)`);
3070
- var METHOD_RE2 = new RegExp(`^${MODIFIERS_RE.source}(?:\\w[\\w<>\\[\\],\\s?]*?)\\s+(\\w+)\\s*[(<]`);
3071
- var PROP_RE = new RegExp(`^${MODIFIERS_RE.source}(?:\\w[\\w<>\\[\\],\\s?]*?)\\s+(\\w+)\\s*\\{`);
3072
- var FIELD_RE2 = new RegExp(`^${MODIFIERS_RE.source}(?:\\w[\\w<>\\[\\],\\s?]*?)\\s+(\\w+)\\s*[;=]`);
3073
3125
  function extractDeclarations7(content, filePath) {
3074
3126
  const declarations = [];
3075
3127
  const lines = content.split(`
@@ -3149,7 +3201,6 @@ function extractBraceBlock4(name, kind, lines, startLine, defLine, filePath) {
3149
3201
  endLine
3150
3202
  };
3151
3203
  }
3152
- var CONTROL_FLOW = new Set(["if", "for", "foreach", "while", "switch", "catch", "using", "lock", "try", "else", "return", "throw", "new", "yield", "await"]);
3153
3204
  function extractTypeMembers(lines, startLine, endLine, parentName, filePath) {
3154
3205
  const children = [];
3155
3206
  let depth = 0;
@@ -3403,7 +3454,59 @@ function makeEntityId7(filePath, kind, name) {
3403
3454
  function normalizeSignature7(text) {
3404
3455
  return text.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s+/g, " ").trim();
3405
3456
  }
3457
+ var csharpParser, MODIFIERS_RE, TYPE_DEF_RE, METHOD_RE2, PROP_RE, FIELD_RE2, CONTROL_FLOW;
3458
+ var init_csharp_parser = __esm(() => {
3459
+ csharpParser = {
3460
+ languages: ["csharp"],
3461
+ parse(content, filePath) {
3462
+ const fileEntityId = `file:${filePath}`;
3463
+ return {
3464
+ fileEntityId,
3465
+ filePath,
3466
+ language: "csharp",
3467
+ declarations: extractDeclarations7(content, filePath),
3468
+ imports: extractImports7(content),
3469
+ exports: extractExports7(content)
3470
+ };
3471
+ },
3472
+ diff(oldResult, newResult) {
3473
+ return computeSemanticDiff7(oldResult, newResult);
3474
+ }
3475
+ };
3476
+ MODIFIERS_RE = /(?:(?:public|private|protected|internal|static|abstract|sealed|virtual|override|partial|readonly|async|extern|unsafe|volatile|new)\s+)*/;
3477
+ TYPE_DEF_RE = new RegExp(`^${MODIFIERS_RE.source}(class|interface|struct|enum|record)\\s+(\\w+)`);
3478
+ METHOD_RE2 = new RegExp(`^${MODIFIERS_RE.source}(?:\\w[\\w<>\\[\\],\\s?]*?)\\s+(\\w+)\\s*[(<]`);
3479
+ PROP_RE = new RegExp(`^${MODIFIERS_RE.source}(?:\\w[\\w<>\\[\\],\\s?]*?)\\s+(\\w+)\\s*\\{`);
3480
+ FIELD_RE2 = new RegExp(`^${MODIFIERS_RE.source}(?:\\w[\\w<>\\[\\],\\s?]*?)\\s+(\\w+)\\s*[;=]`);
3481
+ CONTROL_FLOW = new Set(["if", "for", "foreach", "while", "switch", "catch", "using", "lock", "try", "else", "return", "throw", "new", "yield", "await"]);
3482
+ });
3483
+
3484
+ // src/semantic/semantic-merge.ts
3485
+ var init_semantic_merge = () => {};
3486
+
3487
+ // src/semantic/index.ts
3488
+ var init_semantic = __esm(() => {
3489
+ init_ts_parser();
3490
+ init_python_parser();
3491
+ init_go_parser();
3492
+ init_rust_parser();
3493
+ init_ruby_parser();
3494
+ init_java_parser();
3495
+ init_csharp_parser();
3496
+ init_semantic_merge();
3497
+ });
3498
+
3406
3499
  // src/engine.ts
3500
+ import {
3501
+ existsSync,
3502
+ mkdirSync,
3503
+ readFileSync,
3504
+ writeFileSync,
3505
+ copyFileSync
3506
+ } from "fs";
3507
+ import { readFile as readFile2 } from "fs/promises";
3508
+ import { join as join2, dirname } from "path";
3509
+
3407
3510
  class JsonOpLog {
3408
3511
  ops = [];
3409
3512
  filePath;
@@ -3545,7 +3648,7 @@ class TrellisVcsEngine {
3545
3648
  this.store = new EAVStore;
3546
3649
  this.opLog = new JsonOpLog(join2(this.config.rootPath, ".trellis", "ops.json"));
3547
3650
  }
3548
- async initRepo() {
3651
+ async initRepo(opts) {
3549
3652
  const trellisDir = join2(this.config.rootPath, ".trellis");
3550
3653
  if (!existsSync(trellisDir)) {
3551
3654
  mkdirSync(trellisDir, { recursive: true });
@@ -3576,8 +3679,26 @@ class TrellisVcsEngine {
3576
3679
  debounceMs: this.config.debounceMs,
3577
3680
  onEvent: () => {}
3578
3681
  });
3579
- const events = await scanner.scan();
3682
+ const events = await scanner.scan({
3683
+ onProgress: (progress) => {
3684
+ if (progress.phase === "done") {
3685
+ return;
3686
+ }
3687
+ opts?.onProgress?.({
3688
+ phase: progress.phase,
3689
+ current: progress.current,
3690
+ total: progress.total,
3691
+ message: progress.message
3692
+ });
3693
+ }
3694
+ });
3580
3695
  let opsCreated = 1;
3696
+ opts?.onProgress?.({
3697
+ phase: "recording",
3698
+ current: 0,
3699
+ total: events.length,
3700
+ message: `Recording ${events.length} initial file operations\u2026`
3701
+ });
3581
3702
  for (const event of events) {
3582
3703
  if (event.contentHash) {
3583
3704
  try {
@@ -3597,8 +3718,23 @@ class TrellisVcsEngine {
3597
3718
  });
3598
3719
  this.applyOp(op);
3599
3720
  opsCreated++;
3721
+ const recordedFiles = opsCreated - 1;
3722
+ if (recordedFiles % 25 === 0 || recordedFiles === events.length) {
3723
+ opts?.onProgress?.({
3724
+ phase: "recording",
3725
+ current: recordedFiles,
3726
+ total: events.length,
3727
+ message: `Recorded ${recordedFiles}/${events.length} initial file ops`
3728
+ });
3729
+ }
3600
3730
  }
3601
3731
  await this.flushAutoCheckpoint();
3732
+ opts?.onProgress?.({
3733
+ phase: "done",
3734
+ current: opsCreated,
3735
+ total: opsCreated,
3736
+ message: `Initialized repository with ${opsCreated} operations`
3737
+ });
3602
3738
  return { opsCreated };
3603
3739
  }
3604
3740
  open() {
@@ -4034,5 +4170,23 @@ class TrellisVcsEngine {
4034
4170
  }
4035
4171
  }
4036
4172
  }
4173
+ var init_engine = __esm(() => {
4174
+ init_eav_store();
4175
+ init_fs_watcher();
4176
+ init_ingestion();
4177
+ init_decompose();
4178
+ init_ops();
4179
+ init_types();
4180
+ init_blob_store();
4181
+ init_branch();
4182
+ init_milestone();
4183
+ init_checkpoint();
4184
+ init_diff();
4185
+ init_merge();
4186
+ init_issue();
4187
+ init_decisions();
4188
+ init_garden2();
4189
+ init_semantic();
4190
+ });
4037
4191
 
4038
- export { FileWatcher, Ingestion, TrellisVcsEngine };
4192
+ export { FileWatcher, init_fs_watcher, Ingestion, init_ingestion, TrellisVcsEngine, init_engine };