trellis/vcs

Version control model — operations, branches, milestones, checkpoints, issues, diff, merge, and blob storage.

Overview

The trellis/vcs subpath exposes the operation types and domain-level building blocks for version control. Use it when you want Trellis VCS capabilities without the full platform surface.

import { BranchEntity, MilestoneEntity, VcsOp, VcsOpKind } from "trellis/vcs";

VcsOp

Every change is an immutable, content-addressed operation:

interface VcsOp {
  hash: string; // 'trellis:op:<sha256>' — content address
  kind: VcsOpKind; // Operation type
  timestamp: string; // ISO 8601
  agentId: string; // Author identity (DID)
  previousHash?: string; // Causal chain link
  payload: Record<string, unknown>; // Kind-specific data
  signature?: string; // Ed25519 signature (when signing enabled)
}

Operation Tiers

TierOperationsDescription
1dirAdd, dirDelete, branchCreate, milestoneCreate, …Structural VCS control ops
2fileAdd, fileModify, fileDelete, fileRenameFile lifecycle ops
3astPatchSemantic AST-level patches
4Signatures, governanceCryptographic layer

Branch Entities

Branches are graph entities with a pointer to their current head op:

interface BranchEntity {
  id: string; // 'branch:<name>'
  name: string;
  headHash: string; // Current tip op hash
  createdAt: string;
  policy?: BranchPolicy;
}
// List branches
const branches = await engine.listBranches();

// Create a branch
await engine.createBranch("feature/auth");

// Switch branch
await engine.switchBranch("feature/auth");

// Delete a branch
await engine.deleteBranch("feature/old");

Milestone Entities

Milestones are human-curated markers over a range of ops:

interface MilestoneEntity {
  id: string; // 'milestone:<hash>'
  message: string;
  fromOpHash: string;
  toOpHash: string;
  affectedFiles: string[];
  authorId: string;
  createdAt: string;
}
// Create a milestone
await engine.createMilestone({
  message: "Add user authentication",
  // fromOpHash defaults to last milestone's toOpHash + 1
  // toOpHash defaults to current HEAD
});

// List milestones
const milestones = await engine.listMilestones();

Diff & Merge

File-level Diff

import { diff } from "trellis/vcs";

const result = diff(fromOpHash, toOpHash, { engine });
// { file: string; added: number; removed: number; hunks: DiffHunk[] }[]

Semantic Diff

import { semanticDiff } from "trellis/vcs";

const patches = semanticDiff(oldSource, newSource, "auth.ts");
// SemanticPatch[] — symbolAdd | symbolRemove | symbolModify | symbolRename | …

Three-way Merge

import { merge } from "trellis/vcs";

const result = await merge("feature/auth", { engine, dryRun: false });
result.conflicts; // MergeConflict[] — entity-level, with suggestions
result.clean; // true if no conflicts

Checkpoints

Auto-generated stable-state markers (created automatically when op count crosses a threshold):

interface CheckpointEntity {
  id: string;
  opHash: string; // Op at checkpoint time
  snapshotId: string; // SQLite snapshot reference
  createdAt: string;
}

Issue Tracking

Issues are first-class VCS entities, not an external system:

import { IssueEntity, IssueStatus } from "trellis/vcs";

interface IssueEntity {
  id: string; // 'issue:TRL-<n>'
  title: string;
  description?: string;
  status: IssueStatus; // 'backlog' | 'queued' | 'in_progress' | 'done' | 'closed'
  assignee?: string;
  labels: string[];
  acceptanceCriteria: string[];
  branchId?: string; // Auto-created branch when started
  createdAt: string;
  updatedAt: string;
}

See the Issue Tracking guide for the full lifecycle.

Blob Storage

Large file content is stored in the blob store and referenced by hash — keeping the op log lean:

import { BlobStore } from "trellis/vcs";

const store = new BlobStore({ dbPath: ".trellis/blobs.db" });
const hash = await store.put(Buffer.from(fileContent));
const content = await store.get(hash);