Git Repository Sync
Keep a project canvas in Git alongside the files and documentation it describes. Ideon stores managed board data in a hidden .ideon/ directory so the rest of the repository remains untouched.
Use repository sync to review canvas changes in commits, restore a project from files, or trigger a server-side sync from a CI workflow. It does not replace Git or merge text line by line.
Repository Layout
An exported project contains only the managed directory:
.ideon/
manifest.json
blocks/
<stable-block-id>.json
links/
<stable-link-id>.json
notes/
<stable-block-id>.md
diagrams/
<stable-block-id>.mmd
assets/
<file-name>
canvases.json
The manifest records the project identity, block and link identities, canvas membership, positions, dimensions, parent relationships, and paths to each data file. File entries include a content type, byte size, and SHA-256 checksum. Stable repository IDs are mapped to local database IDs during import.
Positions and dimensions are part of the versioned structure. Moving a block changes its manifest entry; editing a note changes its Markdown file. Sub-canvas documents, rich note snapshots, and viewport state are preserved in canvases.json.
Text blocks are stored as Markdown. Mermaid blocks are stored as .mmd source files. PlantUML .puml files are available when the PlantUML block is supported by the deployed version.
Only files under .ideon/ are read, replaced, or committed by repository sync. Other repository files are left unchanged. Assets are stored as flat files under .ideon/assets/.
Connect a Repository
Add a Git token under Account Settings for private repositories. Ideon encrypts the token using the existing per-user token store; repository settings never contain a token. Public repositories can be used without a token.
Configure the project with an authenticated PATCH /api/projects/{projectId}/repository-sync request:
{
"repositoryUrl": "https://github.com/example/architecture-board.git",
"repositoryUsername": "x-access-token",
"branch": "main",
"repositoryPath": "docs/board"
}
Omit repositoryPath or set it to an empty string to use the repository root. Do not put credentials in the repository URL. repositoryUsername is optional; Ideon uses provider defaults when it is omitted.
For self-hosted Git servers on private networks, allow the exact host (including a non-default port) with GIT_SYNC_ALLOWED_HOSTS, for example git.internal.example,git.internal.example:8443. Requests use HTTPS, disable redirects, and pin DNS results for the duration of the Git operation.
Use GET /api/projects/{projectId}/repository-sync to read the non-secret settings. Use DELETE on the same endpoint to unlink the repository and remove its sync baseline.
Synchronize
The authenticated project export endpoint returns a ZIP containing .ideon/:
GET /api/projects/{projectId}/repository-sync/export
Import or update from a ZIP with Content-Type: application/zip:
POST /api/projects/{projectId}/repository-sync?mode=manual
The request is validated before any project state is changed. A successful import updates the same project and preserves its local database IDs through the stable identity map.
To pull, merge, and commit directly to the configured branch, use:
POST /api/projects/{projectId}/repository-sync/remote?mode=manual
The direct operation fetches the configured branch, commits only .ideon/ (or the configured subdirectory's .ideon/), and pushes without force. A branch update rejected as non-fast-forward returns a conflict response; retry after reviewing the new remote state.
Conflict Modes
Ideon compares the last synchronized baseline, the current canvas, and the incoming repository state. Changes made independently on one side are combined automatically. Select a mode for changes to the same item:
| Mode | Conflicting item |
|---|---|
manual | Report the conflict and make no changes to either side. |
git-wins | Use the repository version. |
ideon-wins | Use the current canvas version. |
Non-conflicting changes are still combined in the two resolving modes. Conflicts are field- or file-level, not line-level: a structural conflict is reported on the specific field that diverged (for example, a block's position.x when both sides moved the same block independently), while independent field changes on the same item are merged automatically. Structural conflicts are reported separately from Markdown and asset conflicts. A delete-versus-edit is a conflict; an item is never silently removed when the other side changed it.
The sync operation is explicit. It does not watch the remote continuously. A failed validation, unresolved manual conflict, or failed push does not apply a partial canvas update. If a remote commit succeeds but local persistence fails, retrying the sync replays the committed state idempotently.
Use MCP from CI
Create an Ideon API key for an owner of the project and store it as a CI secret. Configure the project repository once, then trigger sync after the relevant Git change:
curl --fail-with-body "$IDEON_URL/api/mcp" \
-H "Authorization: Bearer $IDEON_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
--data '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"sync_project_repository","arguments":{"projectId":"'"$IDEON_PROJECT_ID"'","mode":"manual"}}}'
The MCP tools get_project_repository_sync and sync_project_repository require owner access. manual is the recommended CI mode: a conflict returns an error without changing either side. Use git-wins or ideon-wins only when the workflow intentionally establishes that source of truth.
Safety Limits
Ideon rejects unsupported manifest versions, undeclared or missing files, duplicate identities, broken references, unsafe paths, symbolic links, invalid geometry, checksum mismatches, and unknown block types. ZIP extraction is streamed and limited to 10,000 files, 100 MiB per file, 500 MiB total, and a 2 MiB manifest.
Repository access requires HTTPS. Private network hosts are blocked unless explicitly allowlisted by the server administrator. Repository credentials are not exported or returned by the settings endpoint or MCP status tool.