{"id":50807142,"url":"https://github.com/oculairmedia/vibesync","last_synced_at":"2026-06-13T02:09:24.390Z","repository":{"id":321090700,"uuid":"1084445180","full_name":"oculairmedia/vibesync","owner":"oculairmedia","description":"Bidirectional synchronization service between Huly and Vibe Kanban using Model Context Protocol (MCP)","archived":false,"fork":false,"pushed_at":"2026-06-02T16:12:29.000Z","size":17152,"stargazers_count":3,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-02T16:23:53.162Z","etag":null,"topics":["bidirectional-sync","docker","huly","mcp","model-context-protocol","nodejs","sync","vibe-kanban"],"latest_commit_sha":null,"homepage":"https://docs.oculair.ca","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oculairmedia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-10-27T17:30:54.000Z","updated_at":"2026-06-02T16:00:37.000Z","dependencies_parsed_at":"2025-10-27T19:26:32.538Z","dependency_job_id":null,"html_url":"https://github.com/oculairmedia/vibesync","commit_stats":null,"previous_names":["oculairmedia/huly-vibe-sync","oculairmedia/vibesync"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/oculairmedia/vibesync","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oculairmedia%2Fvibesync","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oculairmedia%2Fvibesync/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oculairmedia%2Fvibesync/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oculairmedia%2Fvibesync/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oculairmedia","download_url":"https://codeload.github.com/oculairmedia/vibesync/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oculairmedia%2Fvibesync/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34269429,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bidirectional-sync","docker","huly","mcp","model-context-protocol","nodejs","sync","vibe-kanban"],"created_at":"2026-06-13T02:09:23.582Z","updated_at":"2026-06-13T02:09:24.379Z","avatar_url":"https://github.com/oculairmedia.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vibesync Service\n\nBeads-backed project tracker and Letta PM-agent coordination service for Oculair project workspaces.\n\n## Current Scope\n\n- Project registry API for discovering and managing workspace projects.\n- Beads-backed issue, ready-work, mutation, and remote-provisioning APIs.\n- Android-friendly project and issue endpoints for lightweight mobile clients.\n- Letta PM-agent metadata, reporting, and orchestration integrations.\n- Formula orchestration controls for Beads-backed project work.\n- Dockerized runtime with health checks and optional Temporal workers.\n\n## Quick Start\n\nHost runtime with Bun:\n\n```bash\ncd /opt/stacks/vibesync\nbun install --frozen-lockfile\nbun run type-check:all\nbun run start\n```\n\nBuild a host-runnable binary:\n\n```bash\nbun run build:binary\n./dist/vibesync\n```\n\nThe binary bundles the Bun service entrypoint. Runtime integrations that shell\nout to host tools, Python helpers, Beads, Dolt, Git, or mounted workspace paths\nstill need those tools/files available on the host.\n\nDocker remains available for the current deployment topology:\n\n```bash\ncd /opt/stacks/vibesync\ncp .env.example .env\ndocker-compose up -d\ndocker-compose logs -f\n```\n\nFor production restarts that need the DoltHub provisioning token, use the\nVaultwarden-backed compose wrapper instead of storing the token in `.env`:\n\n```bash\n./scripts/vibesync-compose-vaultwarden.sh pull vibesync\n./scripts/vibesync-compose-vaultwarden.sh up -d vibesync\n```\n\nThe wrapper reads the `DoltHub API Token` item from Vaultwarden at runtime and\nexports `DOLTHUB_API_TOKEN` only for that `docker compose` invocation.\n\n## Configuration\n\nSee `.env.example` for supported settings. Core settings include:\n\n```bash\nVIBE_MCP_URL=http://192.168.50.90:9717/mcp\nLETTA_BASE_URL=http://localhost:8283\nENABLE_ORCHESTRATION=true\nVIBESYNC_ORCHESTRATION_TOKEN=\n```\n\n## Project Registry API\n\n### List projects\n\n`GET /api/projects`\n\nReturns lightweight project summaries suitable for mobile first paint, including repo metadata, PM-agent metadata, tracker capabilities, activity timestamps, and version/etag fields.\n\n### Project detail\n\n`GET /api/projects/:id`\n\nReturns a compact project detail summary. Large collections are exposed through separate paginated subresources.\nIf tracker/work-item hydration fails, the project detail still returns `200` with the normal project fields and marks only `project.tracker.data_freshness.status` as `\"error\"`. Error messages in freshness metadata are sanitized for UI display and never expose raw stack traces or low-level exception text.\n\n### Project subresources\n\n- `GET /api/projects/:id/agents`\n- `GET /api/projects/:id/conversations`\n- `GET /api/projects/:id/work-items`\n- `GET /api/projects/:id/activity`\n- `GET /api/projects/:id/issues`\n- `GET /api/projects/:id/ready-work`\n\nSubresources use cursor-style pagination envelopes with `page.next_cursor`, `page.has_more`, and `page.total_known`.\nIf a subresource cannot be hydrated, the endpoint returns the project-scoped envelope normally with an empty collection for that subresource and `data_freshness.status = \"error\"`; the `data_freshness.error` value is a sanitized, user-safe summary.\n\nProject `etag` values change only when project summary/detail fields change. Tracker freshness and subresource availability do not change the project `etag`; each subresource response exposes its own `etag` and `data_freshness.last_sync_at` for cache invalidation and stale/error UI states.\n\n### Android issue/work contract\n\n`GET /api/projects/:id/ready-work` is the Android equivalent of `bd ready`: it returns open, actionable, unblocked work without requiring the client to reconstruct readiness from raw issue lists.\n\n`GET /api/projects/:id/issues` returns compact, paginated issue summaries. It supports Android-friendly filters including `status`, `priority`, `assignee`, `type`, `ready=true|false`, text query via `q`, and incremental refresh via `updatedSince` / `updated_since`. Sorting currently supports `priority`, `updated`, and `created`.\n\n`GET /api/issues/:id` returns full issue detail by stable opaque issue ID, including description, acceptance criteria, labels, normalized status, blocker references, child references, timestamps, and validation warnings.\n\nMutation endpoints are first-class and conflict-aware. Send either an `If-Match` header or `if_match` body field with the issue `etag`; stale mutations return `409` with a structured `conflict` object. Send `Idempotency-Key` or `idempotency_key` for offline-safe retries.\n\n- `POST /api/issues/:id/claim`\n- `POST /api/issues/:id/unclaim`\n- `PATCH /api/issues/:id/status`\n- `POST /api/issues/:id/notes`\n- `POST /api/issues/:id/close`\n- `POST /api/issues/:id/reopen`\n\nExample mutation request:\n\n```http\nPOST /api/issues/letta-mobile-qmbg/claim\nIf-Match: letta-mobile-qmbg:1778416496000\nIdempotency-Key: android-queue-42\nContent-Type: application/json\n\n{\n  \"assignee\": \"emmanuel\"\n}\n```\n\nConflict response:\n\n```json\n{\n  \"error\": \"Issue conflict\",\n  \"statusCode\": 409,\n  \"conflict\": {\n    \"reason\": \"etag_mismatch\",\n    \"expected\": \"letta-mobile-qmbg:stale\",\n    \"current\": \"letta-mobile-qmbg:1778416496000\",\n    \"issueId\": \"letta-mobile-qmbg\"\n  }\n}\n```\n\nIssue payloads are deterministic and schema-versioned:\n\n```json\n{\n  \"id\": \"letta-mobile-qmbg\",\n  \"projectId\": \"letta-mobile\",\n  \"provider\": \"beads\",\n  \"title\": \"Define Android Beads data contract for project workspaces\",\n  \"type\": \"task\",\n  \"priority\": \"high\",\n  \"status\": \"open\",\n  \"statusLabel\": \"todo\",\n  \"ready\": true,\n  \"assignee\": null,\n  \"blockedBy\": [],\n  \"blocks\": [],\n  \"isBlocked\": false,\n  \"updatedAt\": \"2026-05-10T12:34:56.000Z\",\n  \"summary\": \"Short list-safe summary\",\n  \"acceptanceCriteria\": [\"Criterion one\"],\n  \"labels\": [\"android\", \"project-workspace\"],\n  \"validationWarnings\": [],\n  \"etag\": \"letta-mobile-qmbg:1778416496000\"\n}\n```\n\nNormalized machine-readable statuses are `open`, `in_progress`, `blocked`, `deferred`, and `closed`; the original tracker status remains available as `statusLabel` for display/debugging.\n\n### Register a project\n\n`POST /api/registry/projects`\n\n```json\n{\n  \"filesystem_path\": \"/opt/stacks/letta-mobile\",\n  \"name\": \"Letta Mobile\",\n  \"git_url\": \"https://github.com/oculairmedia/letta-mobile.git\"\n}\n```\n\n- `filesystem_path` is required and must be an absolute path.\n- `name` and `git_url` are optional.\n- The path must exist and be a git repository.\n\n### Update a project\n\n`PATCH /api/registry/projects/:id`\n\n```json\n{\n  \"filesystem_path\": \"/opt/stacks/letta-mobile\",\n  \"git_url\": \"https://github.com/oculairmedia/letta-mobile.git\"\n}\n```\n\n### Beads/DoltHub remote provisioning\n\n`POST /api/projects/:id/beads-remote/provision`\n\nCreates or reuses a project-scoped DoltHub database, configures the project's Beads remote, and pushes the local Beads database by default. Database names are normalized from the project folder name, for example `/opt/stacks/letta-mobile` becomes the DoltHub remote `https://doltremoteapi.dolthub.com/oulair/letta_mobile`.\n\n```json\n{\n  \"push\": true\n}\n```\n\nProvisioning is idempotent: an already-existing DoltHub database is treated as success, and an existing local or mismatched Beads remote is replaced with the configured DoltHub remote. Use `GET /api/projects/:id/beads-remote` to inspect stored provisioning metadata.\n\nThe DoltHub API token is only used for private database creation. Routine `bd dolt push`/`pull` operations use the server's `dolt login` credentials from `~/.dolt/creds`, so keep those credentials provisioned separately.\n\nCLI helpers:\n\n```bash\nnpm run vibesync -- project-beads-remote HVSYN\nnpm run vibesync -- project-provision-beads-remote HVSYN\nnpm run vibesync -- project-provision-beads-remote HVSYN --no-push\n```\n\n## Beads Workflow\n\nUse Beads for issue tracking in this repository. Vibesync reads and mutates project work through Beads:\n\n```bash\nbd ready\nbd show \u003cid\u003e\nbd update \u003cid\u003e --claim\nbd close \u003cid\u003e\n```\n\nDo not route project issue operations through external issue tools.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foculairmedia%2Fvibesync","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foculairmedia%2Fvibesync","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foculairmedia%2Fvibesync/lists"}