Coregit
Getting Started

TypeScript SDK

Install and use the official @coregit/sdk package for typed access to the Coregit API.

Installation

npm install @coregit/sdk

Migrating from @strayl/coregit? The package has been renamed to @coregit/sdk. The API is identical — just update the package name in your package.json and imports:

npm uninstall @strayl/coregit
npm install @coregit/sdk

Then find-and-replace @strayl/coregit@coregit/sdk in your imports. @strayl/coregit is now legacy and will not receive updates.

Quick Start

import { createCoregitClient } from "@coregit/sdk";

const git = createCoregitClient({
  apiKey: process.env.COREGIT_API_KEY!,
});

// Create a repo
const { data: repo, error } = await git.repos.create({
  slug: "my-project",
  visibility: "private",
});

if (error) {
  console.error(error.message); // e.g. "slug already exists"
} else {
  console.log(repo.git_url); // https://api.coregit.dev/org/my-project.git
}

Result Pattern

Every method returns CoregitResult<T>:

interface CoregitResult<T> {
  data: T | null;    // Response payload on success
  error: CoregitError | null; // Error details on failure
  status: number;    // HTTP status code
}

Check error before using data:

const { data, error } = await git.repos.get("my-project");

if (error) {
  if (error.status === 404) {
    // repo doesn't exist
  }
  throw new Error(error.message);
}

console.log(data.default_branch); // "main"

Configuration

const git = createCoregitClient({
  apiKey: "cgk_live_...",       // Required
  baseUrl: "https://api.coregit.dev", // Optional (default)
  fetch: customFetch,           // Optional — custom fetch implementation
});

The fetch option is useful for environments without a global fetch (older Node.js) or for testing with a mock.

Namespaces

All repo-scoped methods accept either a slug string or a { namespace, slug } object:

// Without namespace (backwards compatible)
await git.commits.list("my-repo");

// With namespace
await git.commits.list({ namespace: "alice", slug: "my-repo" });

This works across all clients: repos, branches, commits, files, diff, compare, cherryPick, refs, snapshots, workspace, sync, and graph.

Create a namespaced repo:

const { data } = await git.repos.create({
  slug: "my-repo",
  namespace: "alice",
});
console.log(data.namespace); // "alice"

Filter repos by namespace:

const { data } = await git.repos.list({ namespace: "alice" });

Repos

// Create
const { data } = await git.repos.create({
  slug: "my-repo",
  namespace: "alice", // optional
  description: "A test repo",
  visibility: "private",
  default_branch: "main",
});

// List
const { data } = await git.repos.list({ limit: 20, offset: 0, namespace: "alice" });
console.log(data.repos); // Repo[]

// Get
const { data } = await git.repos.get("my-repo");
// or: await git.repos.get({ namespace: "alice", slug: "my-repo" })
console.log(data.is_empty); // boolean

// Update
const { data } = await git.repos.update("my-repo", {
  description: "Updated",
  visibility: "public",
});

// Delete
const { data } = await git.repos.delete("my-repo");
console.log(data.deleted); // true

Forks & Templates

Create template repos and let users fork them instantly with inherited search and code graph.

// Create a template
await git.repos.create({
  slug: "nextjs-starter",
  is_template: true,
  visibility: "public",
});

// Or mark an existing repo as template
await git.repos.update("nextjs-starter", { is_template: true });

// List only templates
const { data } = await git.repos.list({ is_template: true });

// Fork a template into a user's namespace
const { data: fork } = await git.repos.fork("nextjs-starter", {
  slug: "my-app",
  namespace: "alice",
});

console.log(fork.forked_from.slug);     // "nextjs-starter"
console.log(fork.semantic_inherited);    // true — search works immediately
console.log(fork.graph_copied);         // true — code graph available
console.log(fork.graph_nodes_count);    // 42

Forks get a full copy of git objects and code graph. Semantic search vectors are inherited from the parent without duplication — queries search both namespaces in parallel.

Commits

The core feature — create multi-file commits in a single call.

const { data: commit } = await git.commits.create("my-repo", {
  branch: "main",
  message: "feat: add authentication",
  author: { name: "AI Agent", email: "agent@example.com" },
  changes: [
    // Create or overwrite a file (default action)
    { path: "src/auth.ts", content: "export function login() { ... }" },

    // Surgical edit — replace exact string match
    {
      path: "src/config.ts",
      action: "edit",
      edits: [
        { old_string: 'const API_URL = "localhost"', new_string: 'const API_URL = "https://api.example.com"' }
      ],
    },

    // Lazy edit — send only the changed span with "// ... existing code ..." markers (paid, server merges via Fast Apply)
    {
      path: "src/auth.ts",
      action: "lazy_edit",
      instruction: "Add user null check before session creation",
      edit_snippet:
        "// ... existing code ...\n" +
        "  const user = db.find(email);\n" +
        "  if (!user) throw new Error(\"User not found\");\n" +
        "  const session = createSession(user);\n" +
        "// ... existing code ...",
    },

    // Binary file (base64)
    { path: "logo.png", content: base64Data, encoding: "base64" },

    // Delete a file
    { path: "old-config.json", action: "delete" },

    // Rename a file
    { path: "src/utils.ts", action: "rename", new_path: "src/lib/utils.ts" },
  ],
});

console.log(commit.sha); // "7f3b..."

Lazy Edits

action: "lazy_edit" lets your agent send only the changed bytes (with // ... existing code ... markers) instead of the full file. Coregit merges server-side via Fast Apply and commits the result as a regular blob — one atomic commit, whether you mix lazy edits with plain content writes or not.

const { data, error } = await git.commits.create("my-repo", {
  branch: "main",
  message: "fix: null-check user",
  author: { name: "AI Agent", email: "agent@example.com" },
  changes: [
    {
      path: "src/auth.ts",
      action: "lazy_edit",
      instruction: "Add user null check before session creation", // optional, disambiguates ambiguous merges
      edit_snippet:
        "// ... existing code ...\n" +
        "  if (!user) throw new Error(\"User not found\");\n" +
        "// ... existing code ...",
    },
  ],
});

if (error?.status === 402) {
  // Free-tier — upgrade required
  console.log("Upgrade at", error.message);
}

Why: turns a 5 000-token file rewrite into a ~200-token snippet from your agent's LLM — roughly 50× fewer output tokens. Billed only on success at $1.32 / 1M merge tokens. See Commits → Lazy Edits for snippet conventions, limits, and error codes.

Conflict Detection

Use parent_sha to detect concurrent changes:

// Get current head
const { data: branch } = await git.branches.get("my-repo", "main");

const { data, error } = await git.commits.create("my-repo", {
  branch: "main",
  message: "update config",
  author: { name: "Agent", email: "agent@example.com" },
  parent_sha: branch.sha, // Returns 409 if branch moved
  changes: [{ path: "config.json", content: '{"v": 2}' }],
});

if (error?.status === 409) {
  // Branch was updated — re-read and retry
}

List & Get

// List commits on a branch
const { data } = await git.commits.list("my-repo", {
  ref: "main",
  limit: 50,
});
console.log(data.commits); // Commit[]
console.log(data.has_more); // boolean

// Get single commit
const { data } = await git.commits.get("my-repo", "7f3b...");
console.log(data.parents); // string[]

Branches

// Create from branch name
await git.branches.create("my-repo", { name: "feature-x", from: "main" });

// Create from specific SHA
await git.branches.create("my-repo", { name: "hotfix", from_sha: "abc123" });

// List
const { data } = await git.branches.list("my-repo");
console.log(data.branches); // Branch[]
console.log(data.default_branch); // "main"

// Get
const { data } = await git.branches.get("my-repo", "feature-x");
console.log(data.sha); // head commit SHA

// Merge (fast-forward)
const { data } = await git.branches.merge("my-repo", "main", {
  source: "feature-x",
});
console.log(data.strategy); // "fast-forward" | "already_up_to_date"

// Merge (merge-commit — supports diverged branches)
const { data } = await git.branches.merge("my-repo", "main", {
  source: "feature-x",
  strategy: "merge-commit",
  message: "Merge feature-x into main",
});
console.log(data.merge_sha); // merge commit SHA

// Merge (squash — all changes as a single commit)
const { data } = await git.branches.merge("my-repo", "main", {
  source: "feature-x",
  strategy: "squash",
});

// Delete
await git.branches.delete("my-repo", "feature-x");

Files

// Browse directory
const { data } = await git.files.tree("my-repo", "main", "src");
for (const entry of data.items) {
  console.log(entry.name, entry.type); // "auth.ts" "file"
}

// Recursive tree (all files in one call)
const { data: all } = await git.files.tree("my-repo", "main", "", { recursive: true });
console.log(all.items.length, all.truncated); // 142 false

// Read file
const { data } = await git.files.blob("my-repo", "main", "src/auth.ts");
console.log(data.content); // file content (utf-8 or base64)
console.log(data.encoding); // "utf-8" | "base64"
console.log(data.size); // bytes

// List all refs (branches + tags)
const { data } = await git.files.refs("my-repo");
console.log(data.branches); // Ref[]
console.log(data.tags); // Ref[]

Diff

const { data } = await git.diff.compare("my-repo", "main", "feature-x");

console.log(data.total_files_changed); // 3
for (const file of data.files) {
  console.log(file.path, file.status); // "src/auth.ts" "modified"
}

// With unified diff patches
const { data } = await git.diff.compare("my-repo", "main", "feature-x", {
  patch: true,
  context: 5,
});
for (const file of data.files) {
  if (file.patch) console.log(file.patch); // unified diff
}

Compare

Full comparison between two refs — merge base, ahead/behind counts, and mergeability.

const { data } = await git.compare.compare("my-repo", "main", "feature-x");

console.log(data.merge_base);  // common ancestor SHA
console.log(data.ahead_by);    // 3
console.log(data.behind_by);   // 1
console.log(data.mergeable);   // true | false | null

for (const commit of data.commits) {
  console.log(commit.sha, commit.message);
}

if (data.conflicts.length > 0) {
  console.log("Conflicts:", data.conflicts); // ["src/auth.ts"]
}

Cherry-Pick

Replay a range of commits onto a new base.

// Cherry-pick commits from feature branch onto main
const { data, error } = await git.cherryPick.execute("my-repo", {
  base: "d4e5...",   // range start (exclusive)
  head: "a1c2...",   // range end (inclusive)
  onto: "main",
  branch: "result-branch", // optional: update this branch
});

if (data.success) {
  console.log(data.head_sha);        // new head after cherry-pick
  console.log(data.commits_created); // 3
} else {
  console.log(data.conflicts);       // ["src/auth.ts"]
  console.log(data.last_clean_sha);  // last successful commit
}

With CAS

const { data, error } = await git.cherryPick.execute("my-repo", {
  base: mergeBase,
  head: featureHead,
  onto: "main",
  branch: "dev",
  expected_sha: currentDevHead, // fails 409 if dev moved
});

Refs

Low-level ref management with atomic compare-and-swap.

// List all refs (branches + tags)
const { data } = await git.refs.list("my-repo");
for (const branch of data.branches) {
  console.log(branch.name, branch.sha); // "main" "7f3b..."
}
for (const tag of data.tags) {
  console.log(tag.name, tag.sha); // "v1.0" "a1c2..."
}

// Get single ref
const { data } = await git.refs.get("my-repo", "refs/heads/main");
console.log(data.sha);

// Update with CAS
const { data, error } = await git.refs.update("my-repo", "refs/heads/main", {
  sha: newSha,
  expected_sha: currentSha, // atomic — fails if ref moved
});

if (error?.status === 409) {
  // Ref was updated concurrently — re-read and retry
}

// Delete
await git.refs.delete("my-repo", "refs/heads/feature-x");

Snapshots

Named restore points for branches.

// Create before risky changes
await git.snapshots.create("my-repo", {
  name: "before-refactor",
  branch: "main",
  metadata: { agent: "claude", task: "refactor-auth" },
});

// List
const { data } = await git.snapshots.list("my-repo");

// Restore if something breaks
const { data } = await git.snapshots.restore("my-repo", "before-refactor", {
  target_branch: "main",
});
console.log(data.sha); // restored commit SHA

// Clean up
await git.snapshots.delete("my-repo", "before-refactor");

Workspace

Execute shell commands against a repository. The filesystem is backed by git objects — optionally commit changes back. Use ref to execute on any commit in history.

// Run a command on branch HEAD
const { data } = await git.workspace.exec("my-repo", {
  command: "ls -la",
  branch: "main",
});
console.log(data.stdout);
console.log(data.exit_code); // 0

// Execute on a specific commit in history
const { data } = await git.workspace.exec("my-repo", {
  command: "cat package.json",
  ref: "a1b2c3d4...", // any commit SHA, branch, or tag
});

// Execute on old commit and commit result to a branch
const { data } = await git.workspace.exec("my-repo", {
  command: "npm run fix-legacy",
  ref: "v1.0.0",
  branch: "hotfix",
  commit: true,
  commit_message: "fix: backport patch",
  author: { name: "Agent", email: "agent@example.com" },
});
console.log(data.commit_sha); // new commit SHA
console.log(data.changed_files); // ["package.json", "package-lock.json"]

Multi-Repo Execution

Execute commands across multiple repos at once. Each repo is mounted at /{slug}/.

const { data } = await git.workspace.multiExec({
  repos: [
    { slug: "frontend", branch: "main" },
    { slug: "backend", branch: "main" },
  ],
  command: "grep -r 'API_VERSION' .",
});
console.log(data.stdout);
console.log(data.repos_mounted); // ["frontend", "backend"]

// Modify across repos and commit
const { data } = await git.workspace.multiExec({
  repos: [{ slug: "frontend" }, { slug: "backend" }],
  command: "sed -i 's/v1/v2/g' */src/config.ts",
  commit: true,
  commit_message: "chore: bump API version",
  author: { name: "Agent", email: "agent@example.com" },
});
console.log(data.commits); // { frontend: "a1b2...", backend: "d4e5..." }

Filesystem (fs.mount)

Higher-level wrapper over /blob, /tree, /commits, and /exec. Returns a MountedFS handle with POSIX-style methods plus a bash() sub-helper. Throws on error — this is the one place we use the POSIX-feel API instead of { data, error }.

const fs = await git.fs.mount({
  repos: [{ slug: "my-repo" }],
  mode: "rw",
  author: { name: "Agent", email: "agent@example.com" },
});

await fs.writeFile("/my-repo/src/README.md", "hello world");
const text = await fs.readFile("/my-repo/src/README.md");

const r = await fs.bash().exec("npm install && npm test");
console.log(r.stdout, r.exitCode);

await fs.unmount();

Three commit modes drive when buffered writes turn into git commits:

// auto (default) — every writeFile commits immediately
const fs = await git.fs.mount({ repos: [{ slug: "my-repo" }] });

// manual — accumulate, then explicit commit({message})
const fs = await git.fs.mount({
  repos: [{ slug: "my-repo" }],
  commitMode: "manual",
});
await fs.writeFile("/my-repo/a.md", "...");
await fs.writeFile("/my-repo/b.md", "...");
const shas = await fs.commit({ message: "draft a/b" });
// → { "my-repo": "a1b2c3..." }

// on-exec — buffered writes flush into the next bash().exec()
const fs = await git.fs.mount({
  repos: [{ slug: "my-repo" }],
  commitMode: "on-exec",
});
await fs.writeFile("/my-repo/foo.md", "hi");
const r = await fs.bash().exec("cat /my-repo/foo.md"); // sees "hi", commits the batch

Multi-repo paths are namespaced as /<slug>/<rest>; single-repo mounts also accept the slug-less form. Up to 10 repos per mount. Errors come as MountError / MountReadOnlyError / MountPathError / MountConflictError (importable from @coregit/sdk).

See Filesystem API reference for the full method list, options, and error model.

Full-text code search across repositories.

// Simple search
const { data } = await git.search.query({
  q: "TODO",
  repos: ["my-app", "shared-lib"],
});
console.log(`Found ${data.total} matches in ${data.repos_searched} repos`);

for (const match of data.matches) {
  console.log(`${match.repo_slug}:${match.path}:${match.line} — ${match.content}`);
}

// Regex search with path filter
const { data } = await git.search.query({
  q: "function\\s+\\w+Async",
  regex: true,
  path_pattern: "src/**/*.ts",
  max_results: 200,
});

Ask a natural-language question about your codebase. A model runs a short grep/read/list loop server-side against a materialized snapshot of the repo and comes back with an answer plus file locations — not a ranked dump of chunks. Two modes: buffered JSON or streaming SSE.

// Buffered — one JSON response at the end
const { data, error } = await git.search.agentic("my-repo", {
  q: "Where is JWT verification implemented?",
  ref: "main",           // optional — default branch
  max_turns: 6,          // optional — default 6, hard cap 10
  structure_depth: 2,    // optional — initial <repo_structure> depth, default 2
});

if (error) {
  if (error.status === 402) console.log("Paid plan required");
  throw new Error(error.message);
}

console.log(data.answer);
// "JWT verification happens in src/auth/middleware.ts, line 42 (verifyJWT function)."

for (const loc of data.locations) {
  console.log(`  ${loc.path}:${loc.start_line}-${loc.end_line}`);
}

console.log(`${data.total_turns} turns, ${data.total_tokens} tokens, commit ${data.commit_sha}`);

Streaming

Use agenticStream to render per-turn progress. The callback receives a discriminated union of events; the promise resolves with the final finish payload (or null if the stream errored).

const result = await git.search.agenticStream(
  "my-repo",
  { q: "Find the rate limiter implementation", ref: "main" },
  (event) => {
    switch (event.type) {
      case "start":
        console.log(`materialized ${event.commit_sha.slice(0, 7)} in ${event.workspace_ms}ms`);
        break;
      case "turn_start":
        console.log(`[turn ${event.turn}]`);
        break;
      case "tool_call":
        console.log(`  → ${event.tool}(${JSON.stringify(event.args)})`);
        break;
      case "tool_result":
        console.log(`  ← ${event.content.slice(0, 100)}${event.truncated ? "…" : ""}`);
        break;
      case "turn_end":
        console.log(`  tokens in=${event.prompt_tokens} out=${event.completion_tokens}`);
        break;
      case "error":
        console.error(`[error] ${event.code}: ${event.message}`);
        break;
    }
  }
);

if (result) {
  console.log("Final answer:", result.answer);
  console.log("Locations:", result.locations);
}

Paid-tier only. Billed per upstream output token at $1.56 / 1M (covers multi-turn orchestration). Typical short search runs 3–4 turns at a few hundred tokens — fractions of a cent. Full details in Agentic Search API.

Connections

Manage GitHub and GitLab access tokens for sync.

// Create a GitHub connection
const { data: conn } = await git.connections.create({
  provider: "github",
  label: "CI Token",
  access_token: "ghp_xxxxxxxxxxxx",
});
console.log(conn.external_username); // "octocat"

// List all connections
const { data } = await git.connections.list();

// Test if a token is still valid
const { data: test } = await git.connections.test(conn.id);
console.log(test.valid); // true or false

// Rotate a token
await git.connections.update(conn.id, { access_token: "ghp_new_token" });

// Delete
await git.connections.delete(conn.id);

Sync

Synchronize repositories from GitHub or GitLab.

// Create sync config (import from GitHub)
const { data: config } = await git.sync.createConfig("my-repo", {
  connection_id: conn.id,
  remote: "octocat/my-repo",
  direction: "import",
  auto_sync: true,
});

// Trigger sync manually
const { data } = await git.sync.trigger("my-repo", {
  sync_id: config.id,
});

if (data.synced) {
  console.log(`Synced ${data.files_changed} files`);
  console.log(`Commit: ${data.commit_sha}`);
}

// Get sync config
const { data: current } = await git.sync.getConfig("my-repo");

// Update config (switch to export)
await git.sync.updateConfig("my-repo", { direction: "export" });

// View sync history
const { data: history } = await git.sync.history("my-repo", { limit: 10 });
for (const run of history.runs) {
  console.log(run.status, run.message);
}

// Delete sync config
await git.sync.deleteConfig("my-repo");

Tokens

Create scoped, time-limited API tokens.

// Create a read-only token (1 hour)
const { data } = await git.tokens.create({
  name: "agent-readonly",
  scopes: { "repos:*": ["read"] },
  expires_in: 3600,
});
console.log(data.token); // cgt_... — shown once, save it

// List active tokens
const { data: list } = await git.tokens.list();

// Revoke
await git.tokens.revoke(data.id);

Webhooks

Receive real-time notifications when events occur.

// Create webhook
const { data } = await git.webhooks.create({
  url: "https://example.com/hook",
  events: ["push", "branch.created"],
});
console.log(data.secret); // whsec_... — save this!

// List
const { data: list } = await git.webhooks.list();

// Update (disable)
await git.webhooks.update(data.id, { active: false });

// Delete
await git.webhooks.delete(data.id);

Usage

// Current month summary
const { data } = await git.usage.summary();
console.log(data.api_calls); // 4521
console.log(data.storage_bytes); // 5242880

// Specific month
const { data } = await git.usage.summary("2025-03");

// Detailed events
const { data } = await git.usage.details({ limit: 100 });
for (const event of data.events) {
  console.log(event.event_type, event.quantity);
}

Audit

View an immutable log of all security-relevant actions.

// List recent events
const { data } = await git.audit.list({ limit: 20 });
for (const event of data.events) {
  console.log(event.action, event.resource_type, event.resource_id);
}

// Filter by action and time range
const { data } = await git.audit.list({
  action: "repo.create",
  since: "2026-04-01T00:00:00Z",
  limit: 50,
});

// Paginate
if (data.next_cursor) {
  const { data: page2 } = await git.audit.list({ cursor: data.next_cursor });
}

LFS

Manage Git LFS objects and file locks via the REST API.

// List LFS objects in a repo
const { data } = await git.lfs.listObjects("my-repo");
for (const obj of data.objects) {
  console.log(obj.oid, obj.size);
}

// List file locks
const { data } = await git.lfs.listLocks("my-repo");

// Lock a file before editing
await git.lfs.createLock("my-repo", "assets/logo.psd");

// Verify which locks are yours vs others'
const { data: verify } = await git.lfs.verifyLocks("my-repo");
console.log("Mine:", verify.ours);
console.log("Theirs:", verify.theirs);

// Unlock when done
await git.lfs.unlock("my-repo", "lock_abc");

// Force unlock (master key only)
await git.lfs.unlock("my-repo", "lock_abc", { force: true });

LFS file upload/download happens automatically via git lfs push / git lfs pull. The SDK provides access to metadata and locking — not the file transfer itself. See the LFS Guide for git command usage.

Code Graph

Structural code intelligence — query call graphs, dependencies, impact analysis across 30+ languages.

// Trigger graph reindex
await git.graph.triggerIndex("my-repo", { branch: "main" });

// Check status
const { data: status } = await git.graph.indexStatus("my-repo");
console.log(status.status); // "ready"
console.log(status.nodes_count); // 1247

// Who calls this function?
const { data } = await git.graph.query("my-repo", {
  type: "callers",
  name: "createUser",
});
for (const node of data.nodes) {
  console.log(node.name, node.file_path, node.type);
}

// What breaks if I change UserModel?
const { data: impact } = await git.graph.query("my-repo", {
  type: "impact_analysis",
  name: "UserModel",
  max_depth: 3,
});
console.log(impact.nodes); // affected entities
console.log(impact.edges); // edge chain

// All entities in a file
const { data: structure } = await git.graph.query("my-repo", {
  type: "file_structure",
  file_path: "src/auth.ts",
});

// Dead code detection
const { data: unused } = await git.graph.query("my-repo", {
  type: "unused_exports",
});

// Delete graph index
await git.graph.deleteIndex("my-repo");

Query types: callers, callees, dependencies, dependents, type_hierarchy, impact_analysis, file_structure, symbol_lookup, community, tests_for, unused_exports, circular_deps, api_routes, data_flow.

See the Code Graph API reference for full details.

Fuses semantic (AI embeddings), graph (structural), and keyword results into a single ranked list.

// Auto strategy — classifies query and adjusts weights
const { data } = await git.graph.hybridSearch("my-repo", {
  q: "authentication handler",
  top_k: 10,
});
console.log(data.strategy_used); // "semantic"
for (const r of data.results) {
  console.log(r.name, r.score, r.sources); // ["semantic", "graph"]
}

// Force graph-heavy search
const { data: deps } = await git.graph.hybridSearch("my-repo", {
  q: "what calls processPayment",
  strategy: "graph",
});

// Include graph relationships in results
const { data: detailed } = await git.graph.hybridSearch("my-repo", {
  q: "user service",
  include_graph: true,
});
console.log(detailed.results[0].relationships);

LLM Wiki

Read parsed wiki pages, sources, knowledge graphs, and activity logs from a wiki-shaped repo. Inspired by the LLM Wiki pattern by Andrej Karpathy.

Creating a wiki repo is just git.repos.create({ slug }) followed by an initial commit that lays down wiki.json and your raw/ material. There's no dedicated wiki.init method.

// List pages with parsed frontmatter
const { data: pages } = await git.wiki.listPages("my-research");
for (const page of pages.pages) {
  console.log(page.title, page.tags, page.word_count);
}

// Read a single page (with or without leading "wiki/")
const { data: page } = await git.wiki.getPage("my-research", "wiki/transformers.md");
console.log(page.frontmatter.summary);
console.log(page.compiled_truth, page.timeline);

// List and read raw sources
const { data: sources } = await git.wiki.listSources("my-research");
const { data: source }  = await git.wiki.getSource("my-research", "raw/attention-paper.md");

// Generate llms.txt (structured text for external LLMs)
const { data: llmsTxt } = await git.wiki.llmsTxt("my-research", { format: "full" });

// Knowledge graph (nodes, edges, tag clusters)
const { data: graph } = await git.wiki.graph("my-research");
console.log(graph.stats); // { pages: 42, sources: 15, links: 87, orphans: 3 }

// Wiki health stats
const { data: stats } = await git.wiki.stats("my-research");
console.log(stats.pages, stats.sources, stats.dual_section_pages);

wiki.listPages, getPage, listSources, getSource, llmsTxt, graph, stats are the SDK-mapped methods today. History (/wiki/pages/:path/history, /as-of, /restore), document upload (/wiki/documents), workflow runs (/wiki/run, /wiki/runs, /wiki/cancel), and sandboxes (/wiki/sandboxes/*) are available as REST endpoints and don't yet have dedicated SDK helpers — call them through fetch or via the REST examples in the LLM Wiki API reference.

Writing to the Wiki

Wiki SDK methods are read-only. Use the standard commits API to write pages — Karpathy's "one ingest = one atomic commit touching multiple files" pattern is a single round-trip:

await git.commits.create("my-research", {
  branch: "main",
  message: "ingest: Attention Is All You Need",
  author: { name: "wiki-agent", email: "agent@example.com" },
  changes: [
    { path: "raw/attention-paper.md", content: paperContent },
    {
      path: "wiki/transformers.md",
      content: `---
title: "Transformer Architecture"
summary: "..."
tags: [deep-learning]
type: concept
sources: [raw/attention-paper.md]
related: [wiki/attention.md]
updated: 2026-04-10
---

## Truth

A transformer is...

## Timeline

- **2026-04-10 (ingest)**: created from raw/attention-paper.md.
`,
    },
  ],
});

Full Example: AI Agent Workflow

import { createCoregitClient } from "@coregit/sdk";

const git = createCoregitClient({ apiKey: process.env.COREGIT_API_KEY! });

// 1. Create repo in a namespace
await git.repos.create({ slug: "agent-output", namespace: "agents" });

const repo = { namespace: "agents", slug: "agent-output" };

// 2. Commit generated code
await git.commits.create(repo, {
  branch: "main",
  message: "feat: implement auth",
  author: { name: "AI Agent", email: "agent@example.com" },
  changes: [
    { path: "src/auth.ts", content: authCode, action: "create" },
    { path: "src/middleware.ts", content: middlewareCode, action: "create" },
  ],
});

// 3. Snapshot before risky refactor
await git.snapshots.create(repo, {
  name: "pre-refactor",
  branch: "main",
});

// 4. Run tests via workspace
const { data: test } = await git.workspace.exec(repo, {
  command: "npm test",
  branch: "main",
});

if (test.exit_code !== 0) {
  // 5. Restore if tests fail
  await git.snapshots.restore(repo, "pre-refactor");
}

On this page