Feature: Real-Time Project Metadata & Status Sync
Problem
Project metadata — tags, favorites, groups, colors, notes, "in-progress" status — is currently trapped in globalState on a single machine. Eric has no visibility into which projects he was actively working on when he switches from Ventress to Snoke. The mental overhead of reconstructing context ("what was I doing yesterday on the other machine?") slows down multi-device workflows.
Proposed Solution
Extend the File Location Index (FLI) with a Project Metadata Layer that syncs lightweight status updates across all connected devices in near-real-time.
Data Model
type ProjectMetadata = {
projectId: string;
version: number; // monotonic counter for conflict resolution
updatedAt: number;
updatedBy: MachineId;
// User-facing fields
status: 'active' | 'archived' | 'idea' | 'blocked' | 'review';
priority: 'low' | 'medium' | 'high' | 'urgent';
note?: string; // free-text scratchpad (max 500 chars)
lastBranch?: string; // last git branch checked out (auto-captured)
lastOpenedAt?: number; // timestamp of last open
// Structural fields (synced)
tags: string[];
color?: number;
favoriteGroup?: string;
};
type MetadataIndex = {
schemaVersion: 1;
machines: MachineHeartbeat[];
projects: Record<string, ProjectMetadata>;
};
type MachineHeartbeat = {
machineId: MachineId;
lastSeen: number;
vscodeVersion: string;
extensionVersion: string;
};
Sync Strategy: Event-Stream over Gist Polling
Because Gists don't support push/webhooks, we use short-poll + diff:
- On activation, pull the Gist and merge metadata into local state.
- Every 60s (configurable), poll for Gist updates.
- On local change (tag added, color changed, note edited), increment
version, update updatedAt, and push immediately.
- On pull, if remote
version > local version, merge using last-writer-wins per field (fine-grained because each field is independent).
For users who opt into the self-hosted backend, upgrade to WebSocket/SSE for true real-time.
Implementation Plan
Acceptance Criteria
Open Questions
- Should we support custom status values (user-defined strings) or keep a fixed enum?
- Is 60s polling too aggressive for Gist rate limits? (Gist unauthenticated reads are generous; with a PAT, essentially unlimited.)
Feature: Real-Time Project Metadata & Status Sync
Problem
Project metadata — tags, favorites, groups, colors, notes, "in-progress" status — is currently trapped in
globalStateon a single machine. Eric has no visibility into which projects he was actively working on when he switches from Ventress to Snoke. The mental overhead of reconstructing context ("what was I doing yesterday on the other machine?") slows down multi-device workflows.Proposed Solution
Extend the File Location Index (FLI) with a Project Metadata Layer that syncs lightweight status updates across all connected devices in near-real-time.
Data Model
Sync Strategy: Event-Stream over Gist Polling
Because Gists don't support push/webhooks, we use short-poll + diff:
version, updateupdatedAt, and push immediately.version > local version, merge using last-writer-wins per field (fine-grained because each field is independent).For users who opt into the self-hosted backend, upgrade to WebSocket/SSE for true real-time.
Implementation Plan
src/states/MetadataState.tsthat mirrors the existingTagsState/FavoritesStateAPIs but reads from the merged metadata index instead of rawglobalState.globalStatebecomes a local cache;MetadataStateis the source of truth.onDidChangeWorkspaceto auto-updatelastOpenedAtandlastBranch.vscode.git) to capture current branch on workspace switch.Project Name | Status | Last Branch | Note.priority(red = urgent, gray = archived).Projects: Resolve Sync Conflict— side-by-side local vs. remote, pick one or merge.Projects Sync."[ventress] updated 'cafe-justo' status → active (2 min ago)".Acceptance Criteria
lastOpenedAtandlastBranchin the synced metadata.Open Questions