@instawp/cli 0.0.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +129 -0
  3. package/dist/commands/exec.d.ts +3 -0
  4. package/dist/commands/exec.js +126 -0
  5. package/dist/commands/exec.js.map +1 -0
  6. package/dist/commands/login.d.ts +2 -0
  7. package/dist/commands/login.js +63 -0
  8. package/dist/commands/login.js.map +1 -0
  9. package/dist/commands/sites.d.ts +3 -0
  10. package/dist/commands/sites.js +343 -0
  11. package/dist/commands/sites.js.map +1 -0
  12. package/dist/commands/ssh.d.ts +2 -0
  13. package/dist/commands/ssh.js +41 -0
  14. package/dist/commands/ssh.js.map +1 -0
  15. package/dist/commands/sync.d.ts +2 -0
  16. package/dist/commands/sync.js +131 -0
  17. package/dist/commands/sync.js.map +1 -0
  18. package/dist/commands/teams.d.ts +2 -0
  19. package/dist/commands/teams.js +122 -0
  20. package/dist/commands/teams.js.map +1 -0
  21. package/dist/commands/whoami.d.ts +2 -0
  22. package/dist/commands/whoami.js +60 -0
  23. package/dist/commands/whoami.js.map +1 -0
  24. package/dist/index.d.ts +2 -0
  25. package/dist/index.js +101 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/lib/api.d.ts +4 -0
  28. package/dist/lib/api.js +45 -0
  29. package/dist/lib/api.js.map +1 -0
  30. package/dist/lib/auth.d.ts +1 -0
  31. package/dist/lib/auth.js +75 -0
  32. package/dist/lib/auth.js.map +1 -0
  33. package/dist/lib/config.d.ts +11 -0
  34. package/dist/lib/config.js +66 -0
  35. package/dist/lib/config.js.map +1 -0
  36. package/dist/lib/output.d.ts +14 -0
  37. package/dist/lib/output.js +63 -0
  38. package/dist/lib/output.js.map +1 -0
  39. package/dist/lib/site-resolver.d.ts +2 -0
  40. package/dist/lib/site-resolver.js +78 -0
  41. package/dist/lib/site-resolver.js.map +1 -0
  42. package/dist/lib/ssh-connection.d.ts +8 -0
  43. package/dist/lib/ssh-connection.js +70 -0
  44. package/dist/lib/ssh-connection.js.map +1 -0
  45. package/dist/lib/ssh-keys.d.ts +2 -0
  46. package/dist/lib/ssh-keys.js +232 -0
  47. package/dist/lib/ssh-keys.js.map +1 -0
  48. package/dist/types.d.ts +76 -0
  49. package/dist/types.js +2 -0
  50. package/dist/types.js.map +1 -0
  51. package/package.json +55 -0
@@ -0,0 +1,343 @@
1
+ import chalk from 'chalk';
2
+ import { requireAuth, getClient } from '../lib/api.js';
3
+ import { resolveSite } from '../lib/site-resolver.js';
4
+ import { success, error, table, spinner, info, isJsonMode } from '../lib/output.js';
5
+ export function registerSitesCommand(program) {
6
+ const sites = program
7
+ .command('sites')
8
+ .description('Manage WordPress sites');
9
+ // sites list
10
+ sites
11
+ .command('list')
12
+ .description('List all sites')
13
+ .option('--status <status>', 'Filter by status')
14
+ .option('--page <page>', 'Page number', '1')
15
+ .option('--per-page <count>', 'Results per page', '20')
16
+ .action(async (opts) => {
17
+ requireAuth();
18
+ const spin = spinner('Fetching sites...');
19
+ spin.start();
20
+ try {
21
+ const client = getClient();
22
+ const params = {
23
+ page: parseInt(opts.page),
24
+ per_page: parseInt(opts.perPage),
25
+ };
26
+ if (opts.status)
27
+ params.status = opts.status;
28
+ const res = await client.get('/sites', { params });
29
+ spin.stop();
30
+ const sites = res.data?.data || [];
31
+ if (sites.length === 0) {
32
+ if (isJsonMode()) {
33
+ console.log(JSON.stringify([]));
34
+ }
35
+ else {
36
+ info('No sites found.');
37
+ }
38
+ return;
39
+ }
40
+ const rows = sites.map((s) => ({
41
+ id: s.id,
42
+ name: s.name || '',
43
+ domain: s.domain?.name || s.sub_domain || '',
44
+ url: s.url || '',
45
+ status: s.status === 0 ? 'Active' : s.is_expired ? 'Expired' : s.status || 'Unknown',
46
+ wp_version: s.wp_version || '',
47
+ php_version: s.php_version || '',
48
+ created_at: s.created_at || '',
49
+ }));
50
+ table(['ID', 'Name', 'URL', 'Status', 'WP Version', 'PHP Version'], rows);
51
+ }
52
+ catch (err) {
53
+ spin.fail('Failed to fetch sites');
54
+ error('Could not list sites', err.response?.data?.message || err.message);
55
+ process.exit(1);
56
+ }
57
+ });
58
+ // sites create
59
+ sites
60
+ .command('create')
61
+ .description('Create a new WordPress site')
62
+ .requiredOption('--name <name>', 'Site name')
63
+ .option('--php <version>', 'PHP version (e.g., 8.2)')
64
+ .option('--config <id>', 'Configuration ID')
65
+ .option('--no-wait', 'Do not wait for site to become active')
66
+ .action(createSiteAction);
67
+ // sites delete
68
+ sites
69
+ .command('delete <site>')
70
+ .description('Delete a site (by ID, name, or domain)')
71
+ .option('--force', 'Skip confirmation')
72
+ .action(async (siteIdentifier, opts) => {
73
+ requireAuth();
74
+ const spin = spinner('Resolving site...');
75
+ spin.start();
76
+ let site;
77
+ try {
78
+ site = await resolveSite(siteIdentifier);
79
+ spin.stop();
80
+ }
81
+ catch {
82
+ spin.fail('Site resolution failed');
83
+ process.exit(1);
84
+ }
85
+ const label = site.name || site.sub_domain || String(site.id);
86
+ if (!opts.force) {
87
+ if (isJsonMode()) {
88
+ error('Use --force flag to delete in JSON mode');
89
+ process.exit(1);
90
+ }
91
+ // Interactive confirmation
92
+ const readline = await import('node:readline');
93
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
94
+ const answer = await new Promise((resolve) => {
95
+ rl.question(`Are you sure you want to delete site "${label}" (ID: ${site.id})? (y/N) `, resolve);
96
+ });
97
+ rl.close();
98
+ if (answer.toLowerCase() !== 'y') {
99
+ info('Cancelled.');
100
+ return;
101
+ }
102
+ }
103
+ const spin2 = spinner(`Deleting site ${label}...`);
104
+ spin2.start();
105
+ try {
106
+ const client = getClient();
107
+ await client.delete(`/sites/${site.id}`);
108
+ spin2.stop();
109
+ success(`Site "${label}" (ID: ${site.id}) has been deleted`);
110
+ }
111
+ catch (err) {
112
+ spin2.fail('Failed to delete site');
113
+ error('Could not delete site', err.response?.data?.message || err.message);
114
+ process.exit(1);
115
+ }
116
+ });
117
+ }
118
+ // Shared create action used by both `sites create` and top-level `create`
119
+ async function createSiteAction(opts) {
120
+ requireAuth();
121
+ const json = isJsonMode();
122
+ const startTime = Date.now();
123
+ const elapsed = () => ((Date.now() - startTime) / 1000).toFixed(1);
124
+ // Step indicator helpers for human mode
125
+ const step = (msg) => { if (!json)
126
+ console.log(chalk.green('\u2713') + ' ' + msg); };
127
+ const heading = (msg) => { if (!json)
128
+ console.log('\n' + chalk.dim('#') + ' ' + msg); };
129
+ const spin = spinner('Submitting site request...');
130
+ spin.start();
131
+ try {
132
+ const client = getClient();
133
+ const payload = {
134
+ site_name: opts.name,
135
+ };
136
+ if (opts.php)
137
+ payload.php_version = opts.php;
138
+ if (opts.config)
139
+ payload.configuration_id = parseInt(opts.config);
140
+ const res = await client.post('/sites', payload);
141
+ const site = res.data?.data;
142
+ if (!site?.id) {
143
+ spin.fail('Site creation failed');
144
+ error('Unexpected response from API', res.data);
145
+ process.exit(1);
146
+ }
147
+ spin.stop();
148
+ // If --no-wait or JSON mode without wait, return immediately
149
+ if (!opts.wait) {
150
+ if (json) {
151
+ console.log(JSON.stringify({ success: true, data: { id: site.id, status: 'provisioning' } }));
152
+ }
153
+ else {
154
+ success('Site creation initiated', {
155
+ id: site.id,
156
+ status: site.status || 'provisioning',
157
+ });
158
+ info('Use --wait to wait for provisioning (default). Pass --no-wait to skip.');
159
+ }
160
+ return;
161
+ }
162
+ // Progressive provisioning output
163
+ heading(`Provisioning WordPress...`);
164
+ const maxWait = 5 * 60 * 1000; // 5 minutes
165
+ const pollInterval = 3000; // 3 seconds
166
+ const taskId = site.task_id;
167
+ // Fetch site details once for php_version (available immediately at creation)
168
+ let phpVersion = opts.php || '8.x';
169
+ try {
170
+ const initDetail = await client.get(`/sites/${site.id}/details`);
171
+ phpVersion = initDetail.data?.data?.php_version || phpVersion;
172
+ }
173
+ catch { /* use fallback */ }
174
+ const provSpin = spinner('Setting up server environment...');
175
+ provSpin.start();
176
+ // Track which steps we've shown based on task percentage:
177
+ // ~38% = server environment ready (PHP configured)
178
+ // ~66% = domain/SSL setup done
179
+ // ~79% = WordPress being installed
180
+ // 100% = completed
181
+ const shown = { php: false, ssl: false, wp: false };
182
+ // Helper to update spinner with percentage
183
+ const spinText = (label, pct) => pct > 0 ? `${label} ${chalk.dim(`(${Math.round(pct)}%)`)}` : label;
184
+ while (Date.now() - startTime < maxWait) {
185
+ try {
186
+ // Poll task status for real provisioning progress
187
+ let pct = 0;
188
+ let taskDone = false;
189
+ if (taskId) {
190
+ try {
191
+ const taskRes = await client.get(`/tasks/${taskId}/status`);
192
+ const task = taskRes.data?.data;
193
+ pct = parseFloat(task?.percentage_complete) || 0;
194
+ taskDone = task?.status === 'completed';
195
+ if (task?.status === 'error') {
196
+ provSpin.fail('Provisioning failed');
197
+ error('Site provisioning failed', task?.comment || 'Unknown error');
198
+ process.exit(1);
199
+ }
200
+ }
201
+ catch { /* task endpoint may not be available, fall through */ }
202
+ }
203
+ // Update spinner with current percentage
204
+ if (!shown.php) {
205
+ provSpin.text = spinText('Setting up server environment...', pct);
206
+ }
207
+ else if (!shown.ssl) {
208
+ provSpin.text = spinText('Issuing SSL certificate...', pct);
209
+ }
210
+ else if (!shown.wp) {
211
+ provSpin.text = spinText('Installing WordPress...', pct);
212
+ }
213
+ // Show progressive steps based on actual task percentage
214
+ if (!shown.php && pct >= 38) {
215
+ provSpin.text = 'Setting up server environment...';
216
+ provSpin.stop();
217
+ step(`PHP ${phpVersion} configured`);
218
+ shown.php = true;
219
+ provSpin.start();
220
+ }
221
+ if (!shown.ssl && pct >= 66) {
222
+ if (!shown.php) {
223
+ provSpin.text = 'Setting up server environment...';
224
+ provSpin.stop();
225
+ step(`PHP ${phpVersion} configured`);
226
+ shown.php = true;
227
+ }
228
+ provSpin.text = 'Issuing SSL certificate...';
229
+ provSpin.stop();
230
+ step('SSL certificate issued');
231
+ shown.ssl = true;
232
+ provSpin.start();
233
+ }
234
+ if (taskDone || pct >= 100) {
235
+ if (!shown.php) {
236
+ provSpin.stop();
237
+ step(`PHP ${phpVersion} configured`);
238
+ shown.php = true;
239
+ provSpin.start();
240
+ }
241
+ if (!shown.ssl) {
242
+ provSpin.stop();
243
+ step('SSL certificate issued');
244
+ shown.ssl = true;
245
+ provSpin.start();
246
+ }
247
+ provSpin.stop();
248
+ step('WordPress installed');
249
+ // Fetch final site details for the output
250
+ const detailRes = await client.get(`/sites/${site.id}/details`);
251
+ const siteData = detailRes.data?.data;
252
+ const siteInfo = siteData?.site || siteData;
253
+ const meta = siteInfo?.site_meta || siteData?.site_meta || {};
254
+ const siteUrl = siteInfo?.url || site.wp_url || '';
255
+ const domain = siteInfo?.main_domain || siteInfo?.sub_domain
256
+ || siteInfo?.domain?.name || siteInfo?.domain
257
+ || siteData?.domain?.name || siteData?.domain || '';
258
+ const wpVersion = siteInfo?.wp_version || '';
259
+ if (json) {
260
+ // If credentials not yet in details, try list endpoint
261
+ let creds = meta;
262
+ if (!creds.wp_username) {
263
+ try {
264
+ const listRes = await client.get('/sites', { params: { per_page: 50 } });
265
+ const match = (listRes.data?.data || []).find((s) => s.id === site.id);
266
+ if (match?.site_meta?.wp_username)
267
+ creds = match.site_meta;
268
+ }
269
+ catch { /* ignore */ }
270
+ }
271
+ console.log(JSON.stringify({
272
+ success: true,
273
+ data: {
274
+ id: site.id,
275
+ url: siteUrl,
276
+ domain,
277
+ wp_version: wpVersion,
278
+ php_version: siteInfo?.php_version || '',
279
+ wp_username: creds.wp_username || '',
280
+ wp_password: creds.wp_password || '',
281
+ wp_admin_url: siteUrl ? `${siteUrl}/wp-admin` : '',
282
+ magic_login_url: creds.wp_magic_login_url || (siteUrl ? `${siteUrl}/wp-login.php?instawp-magic-login=1` : ''),
283
+ status: 'Active',
284
+ elapsed: elapsed() + 's',
285
+ },
286
+ }));
287
+ }
288
+ else {
289
+ // Fetch credentials for human output too
290
+ let creds = meta;
291
+ if (!creds.wp_username) {
292
+ try {
293
+ const listRes = await client.get('/sites', { params: { per_page: 50 } });
294
+ const match = (listRes.data?.data || []).find((s) => s.id === site.id);
295
+ if (match?.site_meta?.wp_username)
296
+ creds = match.site_meta;
297
+ }
298
+ catch { /* ignore */ }
299
+ }
300
+ const displayUrl = siteUrl || (domain ? `https://${domain}` : '');
301
+ console.log(`\n${chalk.bold.green('Ready')} in ${elapsed()}s ${chalk.dim('\u2192')} ${chalk.cyan.underline(displayUrl)}`);
302
+ if (creds.wp_username) {
303
+ console.log(`\n ${chalk.dim('Username:')} ${creds.wp_username}`);
304
+ console.log(` ${chalk.dim('Password:')} ${creds.wp_password}`);
305
+ }
306
+ const adminUrl = displayUrl ? `${displayUrl}/wp-admin` : '';
307
+ if (adminUrl) {
308
+ console.log(` ${chalk.dim('WP Admin:')} ${chalk.cyan.underline(adminUrl)}`);
309
+ }
310
+ const magicUrl = creds.wp_magic_login_url || (siteUrl ? `${siteUrl}/wp-login.php?instawp-magic-login=1` : '');
311
+ if (magicUrl) {
312
+ console.log(` ${chalk.dim('Magic Login:')} ${chalk.cyan.underline(magicUrl)}`);
313
+ }
314
+ }
315
+ return;
316
+ }
317
+ }
318
+ catch {
319
+ // Ignore polling errors, keep trying
320
+ }
321
+ await new Promise(resolve => setTimeout(resolve, pollInterval));
322
+ }
323
+ provSpin.fail('Timed out waiting for site');
324
+ info(`Site ID ${site.id} was created but may still be provisioning.`);
325
+ info(`Check status with: instawp sites list`);
326
+ }
327
+ catch (err) {
328
+ error('Could not create site', err.response?.data?.message || err.message);
329
+ process.exit(1);
330
+ }
331
+ }
332
+ // Register top-level `create` alias
333
+ export function registerCreateAlias(program) {
334
+ program
335
+ .command('create')
336
+ .description('Create a new WordPress site (alias for sites create)')
337
+ .requiredOption('--name <name>', 'Site name')
338
+ .option('--php <version>', 'PHP version (e.g., 8.2)')
339
+ .option('--config <id>', 'Configuration ID')
340
+ .option('--no-wait', 'Do not wait for site to become active')
341
+ .action(createSiteAction);
342
+ }
343
+ //# sourceMappingURL=sites.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sites.js","sourceRoot":"","sources":["../../src/commands/sites.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerSshCommand(program: Command): void;
@@ -0,0 +1,41 @@
1
+ import { requireAuth } from '../lib/api.js';
2
+ import { resolveSite } from '../lib/site-resolver.js';
3
+ import { ensureSshAccess } from '../lib/ssh-keys.js';
4
+ import { spawnInteractiveSsh } from '../lib/ssh-connection.js';
5
+ import { spinner, isJsonMode } from '../lib/output.js';
6
+ export function registerSshCommand(program) {
7
+ program
8
+ .command('ssh <site>')
9
+ .description('Open an interactive SSH shell on a site')
10
+ .action(async (siteIdentifier) => {
11
+ requireAuth();
12
+ const spin = spinner('Resolving site...');
13
+ spin.start();
14
+ let site;
15
+ try {
16
+ site = await resolveSite(siteIdentifier);
17
+ spin.succeed(`Site: ${site.name || site.sub_domain} (ID: ${site.id})`);
18
+ }
19
+ catch (err) {
20
+ spin.fail('Site resolution failed');
21
+ process.exit(1);
22
+ }
23
+ const conn = await ensureSshAccess(site.id);
24
+ if (isJsonMode()) {
25
+ console.log(JSON.stringify({
26
+ success: true,
27
+ data: {
28
+ host: conn.host,
29
+ username: conn.username,
30
+ port: conn.port,
31
+ private_key: conn.privateKeyPath,
32
+ command: `ssh -i ${conn.privateKeyPath} -p ${conn.port} ${conn.username}@${conn.host}`,
33
+ },
34
+ }));
35
+ return;
36
+ }
37
+ const exitCode = spawnInteractiveSsh(conn);
38
+ process.exit(exitCode);
39
+ });
40
+ }
41
+ //# sourceMappingURL=ssh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh.js","sourceRoot":"","sources":["../../src/commands/ssh.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAS,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9D,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,CAAC,yCAAyC,CAAC;SACtD,MAAM,CAAC,KAAK,EAAE,cAAsB,EAAE,EAAE;QACvC,WAAW,EAAE,CAAC;QAEd,MAAM,IAAI,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,IAAI,IAAI,CAAC;QACT,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,WAAW,CAAC,cAAc,CAAC,CAAC;YACzC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,SAAS,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAE5C,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;gBACzB,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE;oBACJ,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,WAAW,EAAE,IAAI,CAAC,cAAc;oBAChC,OAAO,EAAE,UAAU,IAAI,CAAC,cAAc,OAAO,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE;iBACvF;aACF,CAAC,CAAC,CAAC;YACJ,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerSyncCommand(program: Command): void;
@@ -0,0 +1,131 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { requireAuth } from '../lib/api.js';
3
+ import { resolveSite } from '../lib/site-resolver.js';
4
+ import { ensureSshAccess } from '../lib/ssh-keys.js';
5
+ import { rsyncViaSsh } from '../lib/ssh-connection.js';
6
+ import { success, error, spinner, info } from '../lib/output.js';
7
+ function checkRsync() {
8
+ const result = spawnSync('which', ['rsync'], { stdio: 'ignore' });
9
+ return result.status === 0;
10
+ }
11
+ function getRsyncInstallInstructions() {
12
+ const platform = process.platform;
13
+ if (platform === 'darwin')
14
+ return 'Install rsync: brew install rsync';
15
+ if (platform === 'linux')
16
+ return 'Install rsync: sudo apt install rsync (or equivalent for your distro)';
17
+ return 'Install rsync for your platform.';
18
+ }
19
+ function buildRemotePath(conn) {
20
+ return `/home/${conn.username}/web/${conn.domain}/public_html/wp-content/`;
21
+ }
22
+ export function registerSyncCommand(program) {
23
+ const sync = program
24
+ .command('sync')
25
+ .description('Sync wp-content files with a remote site via rsync');
26
+ sync
27
+ .command('push <site>')
28
+ .description('Push local wp-content/ to remote site')
29
+ .option('--path <path>', 'Local wp-content path', './wp-content/')
30
+ .option('--exclude <pattern...>', 'Additional exclude patterns')
31
+ .option('--include <pattern...>', 'Include patterns')
32
+ .option('--dry-run', 'Show what would be transferred')
33
+ .action(async (siteIdentifier, opts) => {
34
+ requireAuth();
35
+ if (!checkRsync()) {
36
+ error('rsync is required for sync.');
37
+ info(getRsyncInstallInstructions());
38
+ process.exit(1);
39
+ }
40
+ const spin = spinner('Resolving site...');
41
+ spin.start();
42
+ let site;
43
+ try {
44
+ site = await resolveSite(siteIdentifier);
45
+ spin.succeed(`Site: ${site.name || site.sub_domain} (ID: ${site.id})`);
46
+ }
47
+ catch {
48
+ spin.fail('Site resolution failed');
49
+ process.exit(1);
50
+ }
51
+ const conn = await ensureSshAccess(site.id);
52
+ const localPath = opts.path.endsWith('/') ? opts.path : opts.path + '/';
53
+ const remotePath = buildRemotePath(conn);
54
+ const remoteTarget = `${conn.username}@${conn.host}:${remotePath}`;
55
+ const extraArgs = [];
56
+ if (opts.exclude) {
57
+ for (const pattern of opts.exclude) {
58
+ extraArgs.push(`--exclude=${pattern}`);
59
+ }
60
+ }
61
+ if (opts.include) {
62
+ for (const pattern of opts.include) {
63
+ extraArgs.push(`--include=${pattern}`);
64
+ }
65
+ }
66
+ info(`Pushing ${localPath} -> ${conn.host}:${remotePath}`);
67
+ if (opts.dryRun)
68
+ info('(dry run)');
69
+ const exitCode = rsyncViaSsh(conn, localPath, remoteTarget, extraArgs, !!opts.dryRun, true);
70
+ if (exitCode === 0) {
71
+ success('Push complete');
72
+ }
73
+ else {
74
+ error(`rsync exited with code ${exitCode}`);
75
+ process.exit(exitCode);
76
+ }
77
+ });
78
+ sync
79
+ .command('pull <site>')
80
+ .description('Pull remote wp-content/ to local')
81
+ .option('--path <path>', 'Local destination path', './wp-content/')
82
+ .option('--exclude <pattern...>', 'Additional exclude patterns')
83
+ .option('--include <pattern...>', 'Include patterns')
84
+ .option('--dry-run', 'Show what would be transferred')
85
+ .action(async (siteIdentifier, opts) => {
86
+ requireAuth();
87
+ if (!checkRsync()) {
88
+ error('rsync is required for sync.');
89
+ info(getRsyncInstallInstructions());
90
+ process.exit(1);
91
+ }
92
+ const spin = spinner('Resolving site...');
93
+ spin.start();
94
+ let site;
95
+ try {
96
+ site = await resolveSite(siteIdentifier);
97
+ spin.succeed(`Site: ${site.name || site.sub_domain} (ID: ${site.id})`);
98
+ }
99
+ catch {
100
+ spin.fail('Site resolution failed');
101
+ process.exit(1);
102
+ }
103
+ const conn = await ensureSshAccess(site.id);
104
+ const localPath = opts.path.endsWith('/') ? opts.path : opts.path + '/';
105
+ const remotePath = buildRemotePath(conn);
106
+ const remoteSource = `${conn.username}@${conn.host}:${remotePath}`;
107
+ const extraArgs = [];
108
+ if (opts.exclude) {
109
+ for (const pattern of opts.exclude) {
110
+ extraArgs.push(`--exclude=${pattern}`);
111
+ }
112
+ }
113
+ if (opts.include) {
114
+ for (const pattern of opts.include) {
115
+ extraArgs.push(`--include=${pattern}`);
116
+ }
117
+ }
118
+ info(`Pulling ${conn.host}:${remotePath} -> ${localPath}`);
119
+ if (opts.dryRun)
120
+ info('(dry run)');
121
+ const exitCode = rsyncViaSsh(conn, remoteSource, localPath, extraArgs, !!opts.dryRun, true);
122
+ if (exitCode === 0) {
123
+ success('Pull complete');
124
+ }
125
+ else {
126
+ error(`rsync exited with code ${exitCode}`);
127
+ process.exit(exitCode);
128
+ }
129
+ });
130
+ }
131
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerTeamsCommand(program: Command): void;