trellis 2.0.7 → 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.
package/dist/vcs/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  VcsMiddleware
4
- } from "../index-gnw8d7d6.js";
4
+ } from "../index-k5kf7sd0.js";
5
5
  import {
6
6
  BlobStore,
7
7
  addCriterion,
@@ -40,7 +40,7 @@ import {
40
40
  triageIssue,
41
41
  unblockIssue,
42
42
  updateIssue
43
- } from "../index-3s0eak0p.js";
43
+ } from "../index-3ejh8k6v.js";
44
44
  import {
45
45
  DEFAULT_CONFIG,
46
46
  branchEntityId,
@@ -54,7 +54,7 @@ import {
54
54
  isVcsOpKind,
55
55
  issueEntityId,
56
56
  milestoneEntityId
57
- } from "../index-fd4e26s4.js";
57
+ } from "../index-v9b4hqa7.js";
58
58
  import"../index-a76rekgs.js";
59
59
  export {
60
60
  updateIssue,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trellis",
3
- "version": "2.0.7",
3
+ "version": "2.0.8",
4
4
  "description": "Graph-native, code-first version control system — causal ops, semantic patching, wiki-links, embeddings, and decision traces",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -75,7 +75,7 @@
75
75
  "dev": "bun run src/index.ts",
76
76
  "cli": "bun run src/cli/index.ts",
77
77
  "mcp": "bun run src/mcp/index.ts",
78
- "build": "bun build src/index.ts src/core/index.ts src/vcs/index.ts src/embeddings/index.ts src/links/index.ts src/decisions/index.ts src/cli/index.ts --outdir dist --target bun --splitting --format esm --root src --external @xenova/transformers",
78
+ "build": "bun build src/index.ts src/core/index.ts src/vcs/index.ts src/embeddings/index.ts src/links/index.ts src/decisions/index.ts src/cli/index.ts --outdir dist --target bun --splitting --format esm --root src --external @xenova/transformers && mkdir -p dist/ui && cp src/ui/client.html dist/ui/client.html",
79
79
  "test": "bun test test/vcs test/git test/p2 test/p3 test/p4 test/p5 test/p6 test/p7 test/engine.test.ts",
80
80
  "test:all": "bun test",
81
81
  "prepublishOnly": "npm run test && npm run build"
package/src/cli/index.ts CHANGED
@@ -61,7 +61,31 @@ program
61
61
  }
62
62
 
63
63
  const engine = new TrellisVcsEngine({ rootPath });
64
- const result = await engine.initRepo();
64
+ let renderedProgress = false;
65
+ const result = await engine.initRepo({
66
+ onProgress: (progress) => {
67
+ renderedProgress = true;
68
+ if (progress.phase === 'done') {
69
+ process.stdout.write('\r\x1b[2K');
70
+ return;
71
+ }
72
+
73
+ const label =
74
+ progress.phase === 'discovering'
75
+ ? 'Discovering…'
76
+ : progress.phase === 'hashing'
77
+ ? 'Hashing…'
78
+ : 'Recording…';
79
+
80
+ process.stdout.write(
81
+ `\r\x1b[2K ${chalk.dim(label)} ${progress.message}`,
82
+ );
83
+ },
84
+ });
85
+
86
+ if (renderedProgress) {
87
+ process.stdout.write('\n');
88
+ }
65
89
 
66
90
  console.log(chalk.green('✓ Initialized TrellisVCS repository'));
67
91
  console.log(` ${chalk.dim('Path:')} ${rootPath}`);
@@ -2304,6 +2328,59 @@ program
2304
2328
  }
2305
2329
  });
2306
2330
 
2331
+ // ---------------------------------------------------------------------------
2332
+ // trellis ui
2333
+ // ---------------------------------------------------------------------------
2334
+
2335
+ program
2336
+ .command('ui')
2337
+ .description('Launch the interactive graph explorer in your browser')
2338
+ .option('-p, --path <path>', 'Repository path', '.')
2339
+ .option('--port <port>', 'Server port', '3333')
2340
+ .option('--no-open', 'Do not auto-open browser')
2341
+ .action(async (opts) => {
2342
+ const rootPath = resolve(opts.path);
2343
+ if (!TrellisVcsEngine.isRepo(rootPath)) {
2344
+ console.error(
2345
+ chalk.red('Not a TrellisVCS repository. Run `trellis init` first.'),
2346
+ );
2347
+ process.exit(1);
2348
+ }
2349
+
2350
+ const { startUIServer } = require('../ui/server.js');
2351
+ const port = parseInt(opts.port, 10) || 3000;
2352
+
2353
+ try {
2354
+ const server = await startUIServer({ rootPath, port });
2355
+ const url = `http://localhost:${server.port}`;
2356
+ console.log(
2357
+ chalk.green(`✓ Trellis Graph Explorer running at ${chalk.bold(url)}`),
2358
+ );
2359
+ console.log(chalk.dim(' Press Ctrl+C to stop\n'));
2360
+
2361
+ // Auto-open browser
2362
+ if (opts.open !== false) {
2363
+ const { exec } = require('child_process');
2364
+ const cmd =
2365
+ process.platform === 'darwin'
2366
+ ? 'open'
2367
+ : process.platform === 'win32'
2368
+ ? 'start'
2369
+ : 'xdg-open';
2370
+ exec(`${cmd} ${url}`);
2371
+ }
2372
+
2373
+ process.on('SIGINT', () => {
2374
+ server.stop();
2375
+ console.log(chalk.dim('\nServer stopped.'));
2376
+ process.exit(0);
2377
+ });
2378
+ } catch (err: any) {
2379
+ console.error(chalk.red(`Failed to start server: ${err.message}`));
2380
+ process.exit(1);
2381
+ }
2382
+ });
2383
+
2307
2384
  // ---------------------------------------------------------------------------
2308
2385
  // Helpers
2309
2386
  // ---------------------------------------------------------------------------
package/src/engine.ts CHANGED
@@ -22,7 +22,7 @@ import { readFile } from 'fs/promises';
22
22
  import { join, dirname } from 'path';
23
23
  import { EAVStore } from './core/store/eav-store.js';
24
24
  import type { Fact, Link } from './core/store/eav-store.js';
25
- import { FileWatcher } from './watcher/fs-watcher.js';
25
+ import { FileWatcher, type ScanProgress } from './watcher/fs-watcher.js';
26
26
  import { Ingestion } from './watcher/ingestion.js';
27
27
  import { decompose } from './vcs/decompose.js';
28
28
  import { createVcsOp, isVcsOpKind } from './vcs/ops.js';
@@ -235,6 +235,13 @@ interface PersistedConfig {
235
235
  // Engine
236
236
  // ---------------------------------------------------------------------------
237
237
 
238
+ export interface InitProgress {
239
+ phase: 'discovering' | 'hashing' | 'recording' | 'done';
240
+ current: number;
241
+ total: number;
242
+ message: string;
243
+ }
244
+
238
245
  export class TrellisVcsEngine {
239
246
  private config: TrellisVcsConfig;
240
247
  private store: EAVStore;
@@ -281,7 +288,9 @@ export class TrellisVcsEngine {
281
288
  /**
282
289
  * Initialize a new TrellisVCS repo. Creates .trellis/ directory and config.
283
290
  */
284
- async initRepo(): Promise<{ opsCreated: number }> {
291
+ async initRepo(opts?: {
292
+ onProgress?: (progress: InitProgress) => void;
293
+ }): Promise<{ opsCreated: number }> {
285
294
  const trellisDir = join(this.config.rootPath, '.trellis');
286
295
  if (!existsSync(trellisDir)) {
287
296
  mkdirSync(trellisDir, { recursive: true });
@@ -322,9 +331,27 @@ export class TrellisVcsEngine {
322
331
  debounceMs: this.config.debounceMs,
323
332
  onEvent: () => {},
324
333
  });
325
- const events = await scanner.scan();
334
+ const events = await scanner.scan({
335
+ onProgress: (progress: ScanProgress) => {
336
+ if (progress.phase === 'done') {
337
+ return;
338
+ }
339
+ opts?.onProgress?.({
340
+ phase: progress.phase,
341
+ current: progress.current,
342
+ total: progress.total,
343
+ message: progress.message,
344
+ });
345
+ },
346
+ });
326
347
 
327
348
  let opsCreated = 1; // branch op
349
+ opts?.onProgress?.({
350
+ phase: 'recording',
351
+ current: 0,
352
+ total: events.length,
353
+ message: `Recording ${events.length} initial file operations…`,
354
+ });
328
355
  for (const event of events) {
329
356
  // Store file content in blob store
330
357
  if (event.contentHash) {
@@ -346,9 +373,24 @@ export class TrellisVcsEngine {
346
373
  });
347
374
  this.applyOp(op);
348
375
  opsCreated++;
376
+ const recordedFiles = opsCreated - 1;
377
+ if (recordedFiles % 25 === 0 || recordedFiles === events.length) {
378
+ opts?.onProgress?.({
379
+ phase: 'recording',
380
+ current: recordedFiles,
381
+ total: events.length,
382
+ message: `Recorded ${recordedFiles}/${events.length} initial file ops`,
383
+ });
384
+ }
349
385
  }
350
386
 
351
387
  await this.flushAutoCheckpoint();
388
+ opts?.onProgress?.({
389
+ phase: 'done',
390
+ current: opsCreated,
391
+ total: opsCreated,
392
+ message: `Initialized repository with ${opsCreated} operations`,
393
+ });
352
394
  return { opsCreated };
353
395
  }
354
396