Skip to content

feat(helix-cli): make sync ID-first and reconcile local/cloud change safely#869

Merged
xav-db merged 1 commit intodevfrom
sync-improvements
Feb 19, 2026
Merged

feat(helix-cli): make sync ID-first and reconcile local/cloud change safely#869
xav-db merged 1 commit intodevfrom
sync-improvements

Conversation

@xav-db
Copy link
Member

@xav-db xav-db commented Feb 19, 2026

Use project.id as canonical identity, add create-or-choose project resolution, and implement hash/timestamp reconcile with clear push/pull action plans.
Also validate local .hx queries before push, improve sync prompts/output, and harden SSE handling to avoid non-fatal parse noise.

Greptile Summary

This PR significantly enhances the sync command with ID-first project resolution, hash/timestamp-based conflict detection, and safe bidirectional synchronization. The implementation adds SHA256 hashing for content comparison, timestamp-based divergence detection with clock skew tolerance (5s window), and pre-push validation of local .hx queries.

Key improvements:

  • project.id added to config as canonical identity, with fallback to name-based matching for backward compatibility
  • Manifest-based sync with SHA256 hashes prevents unnecessary file transfers
  • Timestamp comparison determines sync authority (local newer vs remote newer vs tie)
  • Interactive prompts guide users through conflict resolution with clear action plans
  • Validation prevents pushing broken queries to cloud
  • 404 responses from cloud are treated as empty remote state (not errors)

Architecture changes:

  • New reconciliation flow replaces simple overwrite logic
  • SSE client switched from progress bar to spinner for better terminal compatibility
  • Project resolution now supports create-or-choose workflow

The implementation is thorough with proper error handling, user confirmations, and detailed sync action plans showing which files will be created/changed/deleted.

Important Files Changed

Filename Overview
helix-cli/src/commands/sync.rs Major refactor introducing ID-first project resolution, hash/timestamp-based reconciliation, and bidirectional sync with validation
helix-cli/src/config.rs Added optional project.id field to ProjectConfig with backward compatibility
helix-cli/src/commands/workspace_flow.rs Updated to accept and use project_id_hint for canonical project identity resolution
helix-cli/src/prompts.rs Added MissingProjectChoice enum and select_missing_project_choice for create-or-choose project flow
helix-cli/src/commands/add.rs Updated to pass project_id_hint and persist resolved project ID to config
helix-cli/src/commands/init.rs Updated to pass project_id_hint and persist resolved project ID to config

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    Start[helix sync command] --> Auth[Authenticate user]
    Auth --> ResolveProject[Resolve project by ID or name]
    ResolveProject --> FetchRemote[Fetch remote snapshot from cloud]
    
    FetchRemote --> BuildManifests[Build local & remote manifests<br/>with SHA256 + timestamps]
    
    BuildManifests --> Compare{Compare<br/>manifests}
    
    Compare -->|Both empty| InSync[Already in sync]
    Compare -->|Identical hashes| InSync
    Compare -->|Local only| ValidateLocal[Validate local .hx queries]
    ValidateLocal -->|Valid| PromptPush{Prompt: Push<br/>to cloud?}
    ValidateLocal -->|Invalid| ErrorValidation[Error: Fix validation issues]
    PromptPush -->|Yes| PushToCloud[Push local snapshot to cloud]
    PromptPush -->|No| NoChange[No changes applied]
    
    Compare -->|Remote only| PromptPull{Prompt: Pull<br/>from cloud?}
    PromptPull -->|Yes| PullFromCloud[Pull remote snapshot to local]
    PromptPull -->|No| NoChange
    
    Compare -->|Diverged| CheckTimestamps{Check file<br/>timestamps}
    
    CheckTimestamps -->|Local newer| LocalNewerFlow[Local newer flow]
    CheckTimestamps -->|Remote newer| RemoteNewerFlow[Remote newer flow]
    CheckTimestamps -->|Tie/Unknown| TieFlow[Tie resolution flow]
    
    LocalNewerFlow --> ValidateLocal2[Validate local queries]
    ValidateLocal2 -->|Valid| PromptPush2{Prompt: Push?}
    ValidateLocal2 -->|Invalid| OfferPull{Offer pull instead?}
    PromptPush2 -->|Yes| PushToCloud
    PromptPush2 -->|No| OfferPull
    OfferPull -->|Yes| PullFromCloud
    OfferPull -->|No| NoChange
    
    RemoteNewerFlow --> PromptPull2{Prompt: Pull?}
    PromptPull2 -->|Yes| PullFromCloud
    PromptPull2 -->|No| NoChange
    
    TieFlow --> ValidateTie[Validate local queries]
    ValidateTie --> PromptTieAction{Prompt: Choose<br/>action}
    PromptTieAction -->|Push| PushToCloud
    PromptTieAction -->|Pull| PullFromCloud
    PromptTieAction -->|No-op| NoChange
    
    PushToCloud --> Success[Sync complete]
    PullFromCloud --> Success
    InSync --> Success
    NoChange --> Success
Loading

Last reviewed commit: 75e0037

… safely

 Use project.id as canonical identity, add create-or-choose project resolution, and implement hash/timestamp reconcile with clear push/pull action plans.
  Also validate local .hx queries before push, improve sync prompts/output, and harden SSE handling to avoid non-fatal parse noise.
@xav-db xav-db merged commit 04280f6 into dev Feb 19, 2026
16 checks passed
@xav-db xav-db deleted the sync-improvements branch February 24, 2026 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant