1- import {
2- RealmSyncBase ,
3- validateMatrixEnvVars ,
4- isProtectedFile ,
5- type SyncOptions ,
6- } from '../lib/realm-sync-base.js' ;
1+ import type { Command } from 'commander' ;
2+ import { RealmSyncBase , isProtectedFile , type SyncOptions } from '../../lib/realm-sync-base' ;
73import {
84 CheckpointManager ,
95 type CheckpointChange ,
10- } from '../lib/checkpoint-manager.js' ;
6+ } from '../../lib/checkpoint-manager' ;
7+ import {
8+ getProfileManager ,
9+ type ProfileManager ,
10+ } from '../../lib/profile-manager' ;
1111import * as fs from 'fs' ;
1212import * as path from 'path' ;
1313import * as crypto from 'crypto' ;
@@ -49,11 +49,9 @@ class RealmPusher extends RealmSyncBase {
4949
5050 constructor (
5151 private pushOptions : PushOptions ,
52- matrixUrl : string ,
53- username : string ,
54- password : string ,
52+ profileManager : ProfileManager ,
5553 ) {
56- super ( pushOptions , matrixUrl , username , password ) ;
54+ super ( pushOptions , profileManager ) ;
5755 }
5856
5957 async sync ( ) : Promise < void > {
@@ -68,7 +66,7 @@ class RealmPusher extends RealmSyncBase {
6866 console . error ( 'Failed to access workspace:' , error ) ;
6967 throw new Error (
7068 'Cannot proceed with push: Authentication or access failed. ' +
71- 'Please check your Matrix credentials and workspace permissions.' ,
69+ 'Please check your credentials and workspace permissions.' ,
7270 ) ;
7371 }
7472 console . log ( 'Workspace access verified' ) ;
@@ -203,15 +201,45 @@ export interface PushCommandOptions {
203201 delete ?: boolean ;
204202 dryRun ?: boolean ;
205203 force ?: boolean ;
204+ profileManager ?: ProfileManager ;
205+ }
206+
207+ export function registerPushCommand ( realm : Command ) : void {
208+ realm
209+ . command ( 'push' )
210+ . description ( 'Push local files to a Boxel realm' )
211+ . argument ( '<local-dir>' , 'The local directory containing files to sync' )
212+ . argument (
213+ '<workspace-url>' ,
214+ 'The URL of the target workspace (e.g., https://app.boxel.ai/demo/)' ,
215+ )
216+ . option ( '--delete' , 'Delete remote files that do not exist locally' )
217+ . option ( '--dry-run' , 'Show what would be done without making changes' )
218+ . option ( '--force' , 'Upload all files, even if unchanged' )
219+ . action (
220+ async (
221+ localDir : string ,
222+ workspaceUrl : string ,
223+ options : { delete ?: boolean ; dryRun ?: boolean ; force ?: boolean } ,
224+ ) => {
225+ await pushCommand ( localDir , workspaceUrl , options ) ;
226+ } ,
227+ ) ;
206228}
207229
208230export async function pushCommand (
209231 localDir : string ,
210232 workspaceUrl : string ,
211233 options : PushCommandOptions ,
212234) : Promise < void > {
213- const { matrixUrl, username, password } =
214- await validateMatrixEnvVars ( workspaceUrl ) ;
235+ let pm = options . profileManager ?? getProfileManager ( ) ;
236+ let active = pm . getActiveProfile ( ) ;
237+ if ( ! active ) {
238+ console . error (
239+ 'Error: no active profile. Run `boxel profile add` to create one.' ,
240+ ) ;
241+ process . exit ( 1 ) ;
242+ }
215243
216244 if ( ! fs . existsSync ( localDir ) ) {
217245 console . error ( `Local directory does not exist: ${ localDir } ` ) ;
@@ -227,12 +255,9 @@ export async function pushCommand(
227255 dryRun : options . dryRun ,
228256 force : options . force ,
229257 } ,
230- matrixUrl ,
231- username ,
232- password ,
258+ pm ,
233259 ) ;
234260
235- await pusher . initialize ( ) ;
236261 await pusher . sync ( ) ;
237262
238263 if ( pusher . hasError ) {
0 commit comments