TypeScript SDK
Install and use the official @coregit/sdk package for typed access to the Coregit API.
Installation
npm install @coregit/sdkMigrating 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/sdkThen 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); // trueForks & 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); // 42Forks 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 batchMulti-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.
Search
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,
});Agentic Search
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.
Hybrid Search
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 downwiki.jsonand yourraw/material. There's no dedicatedwiki.initmethod.
// 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");
}