Code sync
Code sync keeps the code graph in step with a connected repository. It needs a project-scoped credential holding fabric:codesync.write. The flow is:
- Sign in with the editor extension or the launcher (Launcher and editor extension). The token is scoped to one organization, department and project.
- Check the scope:
curl -sS -H "Authorization: Bearer $FABRIC_API_KEY" https://fabric.wexa.ai/v1/codesync/names - Register the repository with
POST /v1/codesync/connector, thenPOST /v1/codesync/bootstrapwith{"repo_url":"https://github.com/acme/widgets","repo_name":"acme/widgets","ttl_seconds":3600}. - Catch up with
POST /v1/codesync/ingest-async, then pollGET /v1/codesync/ingest-status/{job_id}. The daemon then sendsPOST /v1/codesync/ingest-eventas you work. - Read the graph with
search-codeandfetch-code.
Limits
| Behavior | Detail |
|---|---|
| Grant | fabric:codesync.write for all credentialled routes except names; project-scoped token required. |
| Scope | Organization and project are overwritten from the token before forwarding. |
| Request size | Bodies over the cap are refused, not truncated. |
| No ingestion target | 502 unconfigured. |
| Status polling | Counts against project and organization quota. |
| Webhook auth | HMAC-SHA256 signature, not a credential. |
More details
The flow in words
- Sign in. A browser authorization grants the client a token scoped to one organization, department and project. That scope decides where the code lands.
- Register the checkout. The client ensures the project's repository connection exists and picks up the addresses it needs. A launcher on a cloud machine can get a short-lived token instead of storing a long-lived one.
- Catch up. The first pass is a bulk ingestion of the existing tree, submitted as a job because it can take a while. The response carries a job identifier and a separate call reports its status. See ingestion.
- Keep up. The daemon sends incremental events as you work, so the graph tracks the working tree rather than the last full pass.
- Read. Agents search and fetch the code graph, which lives beside the rest of the project's context graph under the same isolation and governance.
Code sync keeps the code graph in step with a connected repository, so a codebase becomes context a question can be asked of instead of a folder an agent is handed one file at a time.
You need a project-scoped credential holding the fabric:codesync.write grant, which the sign-in flow gives the client. A token with the grant but no project is refused with "code sync requires a project-scoped token (re-consent with a project selected)".
How it works
The flow is the one the Wexa MCP server's clients use, so an editor can do it without a separate credential.
Three pieces cooperate, and they are usually installed together:
- The daemon does the work.
fabric-syncruns locally, watches the git working tree and pushes what changed to the gateway. It is the only piece that touches your code. - The editor extension drives it. The VS Code extension, which ships as Codegraph, is where you sign in and see whether sync is running and whether anything failed. It activates on a git working tree or an existing sync configuration, writes the configuration file the other clients read, and starts and supervises the daemon.
- The launcher connects an assistant.
fabric-connectregisters the checkout, starts or reuses the daemon, queues a catch-up pass, then proxies a stdio connection to the gateway for an editor agent or desktop client.
Every request is pinned to its token's scope. The organization and project on the payload are overwritten from the token before the request is forwarded, so a client cannot ingest into a project it was not granted whatever it sends. The check happens at the edge, where the caller is. See scope and server-bound arguments.
Check which scope your credential resolves to
GET /v1/codesync/names needs no grant. It tells a client which organization, department, project and user its credential resolves to before it sends data anywhere. Names come back alongside ids where the platform can resolve them, so treat them as present when available.
curl -sS -H "Authorization: Bearer $FABRIC_API_KEY" \
https://fabric.wexa.ai/v1/codesync/namesThe other routes have no SDK method; clients call them over REST.
Register a repository
Two calls prepare a project. Both are idempotent, and the client makes them for you at sign-in.
POST /v1/codesync/connectorfinds or provisions the codebase connector for the token's project and triggers a connector synchronisation, so the codebase ontology exists before the first ingest. Call it once at the start of a session. If the connector authority is unreachable it fails loudly rather than half-succeeding.POST /v1/codesync/bootstrapbinds a repository, by URL and name, to the project's connector and returns the binding the GitHub webhook later looks up. A push for a repository never bootstrapped is refused, and the refusal says so.
curl -sS -X POST https://fabric.wexa.ai/v1/codesync/bootstrap \
-H "Authorization: Bearer $FABRIC_API_KEY" -H "Content-Type: application/json" \
-d '{"repo_url":"https://github.com/acme/widgets","repo_name":"acme/widgets","ttl_seconds":3600}'Send changes to the graph
Choose by what you have. The first three are alternatives, not stages.
| You have | Use |
|---|---|
| one file-save event, want it visible immediately | POST /v1/codesync/ingest-event |
| a batch of files from one scan | POST /v1/codesync/bulk-ingest |
| a whole repository, first extraction | POST /v1/codesync/ingest-async, then poll GET /v1/codesync/ingest-status/{job_id} |
| commits landing on a branch you do not watch locally | the GitHub receiver, after bootstrap |
The two synchronous routes forward a client-shaped body and return the ingestion target's JSON verbatim with its status code. A body over the size cap is refused rather than truncated. With no ingestion target configured they answer 502 unconfigured rather than pretending to have accepted the data.
ingest-async queues the work and returns a job_id at once. The editor extension uses it for a full extraction. The queued payload carries the token's organization and project whatever the client sent.
Poll the status route on an interval, not in a tight loop. It counts against the project and organization quota windows like any other call.
Read the graph directly
GET /v1/codesync/bolt-credentials returns connection details for clients that query the project's graph rather than going through the gateway. These are credentials, so do not log the response and do not cache it where a second project could read it.
Receive GitHub pushes
POST /v1/codesync/webhook/github takes no bearer token. It is authenticated by an HMAC-SHA256 signature over the raw body in X-Hub-Signature-256, and is covered with the other inbound callbacks on Webhooks.
- A
pinganswers200. - A wrong or missing signature answers
401. - Any other non-push event answers
200and names the event as ignored. - A push for a repository never bootstrapped answers
404repo_not_bound.
For a bound repository the receiver collects the added, modified and removed paths across the commits and stamps the repository node with the branch and head commit. It deletes the removed paths, so the graph never drifts worse than stale. The exact responses are in the reference.
Search and read the code
The code graph is the representation of a repository's code: its files, its symbols and the calls between them. Two tools read it, and both are available in every deployment regardless of which services are configured:
search-codefinds code by text, symbol or identifier and returns the matching lines with their file paths.fetch-codereads a span of a file, or one symbol, once you know where to look.
Search first and fetch second, so an agent spends its context on the few spans that matter rather than whole files. Structural questions, such as what calls this or what it imports, are traversals that query-context answers against the same graph.
What this is not
It is not a connector. A repository connection differs from one in four ways:
- It cannot be provisioned. A repository is not in the set
provision-connectorcan provision. See connectors. - The client establishes it, over the code-sync surface, as part of signing in, with no provisioning step first.
- It mints no skills. Provisioning a connector creates one skill per action it supports, and a repository has no actions for an agent to call.
- Its output is a graph, not a capability: a connector gives an agent things it can do, a repository connection gives it code it can read.
The two overlap only in that both end with something queryable in the project. They are governed by different grants and named differently on purpose.
It is not the knowledge base. The code graph is structure, found by searching text and traversing relationships rather than by similarity to a question. Design documents about the code are prose and belong in the knowledge base.
It is not the data catalog. The catalog describes data assets outside Wexa; the code graph holds a representation of the code itself.