island-bridge 1.1.0 → 2.0.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.
- package/README.md +120 -1
- package/dist/bin/cli.d.ts +2 -0
- package/dist/bin/cli.js +327 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/lib/args.d.ts +6 -0
- package/dist/lib/args.js +128 -0
- package/dist/lib/args.js.map +1 -0
- package/dist/lib/backup.d.ts +26 -0
- package/dist/lib/backup.js +96 -0
- package/dist/lib/backup.js.map +1 -0
- package/dist/lib/config.d.ts +25 -0
- package/dist/lib/config.js +216 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/history.d.ts +9 -0
- package/dist/lib/history.js +84 -0
- package/dist/lib/history.js.map +1 -0
- package/dist/lib/hooks.d.ts +11 -0
- package/dist/lib/hooks.js +36 -0
- package/dist/lib/hooks.js.map +1 -0
- package/dist/lib/init.d.ts +28 -0
- package/dist/lib/init.js +90 -0
- package/dist/lib/init.js.map +1 -0
- package/dist/lib/interactive.d.ts +9 -0
- package/dist/lib/interactive.js +41 -0
- package/dist/lib/interactive.js.map +1 -0
- package/dist/lib/progress.d.ts +18 -0
- package/dist/lib/progress.js +65 -0
- package/dist/lib/progress.js.map +1 -0
- package/dist/lib/reporter.d.ts +59 -0
- package/dist/lib/reporter.js +189 -0
- package/dist/lib/reporter.js.map +1 -0
- package/dist/lib/status.d.ts +41 -0
- package/dist/lib/status.js +123 -0
- package/dist/lib/status.js.map +1 -0
- package/dist/lib/summary.d.ts +19 -0
- package/dist/lib/summary.js +56 -0
- package/dist/lib/summary.js.map +1 -0
- package/dist/lib/sync.d.ts +32 -0
- package/dist/lib/sync.js +237 -0
- package/dist/lib/sync.js.map +1 -0
- package/dist/lib/types.d.ts +91 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/watch.d.ts +10 -0
- package/dist/lib/watch.js +73 -0
- package/dist/lib/watch.js.map +1 -0
- package/package.json +11 -5
- package/bin/cli.js +0 -200
- package/lib/args.js +0 -75
- package/lib/config.js +0 -193
- package/lib/history.js +0 -94
- package/lib/hooks.js +0 -26
- package/lib/interactive.js +0 -46
- package/lib/progress.js +0 -56
- package/lib/summary.js +0 -35
- package/lib/sync.js +0 -235
- package/lib/watch.js +0 -64
package/README.md
CHANGED
|
@@ -21,9 +21,28 @@ npx island-bridge push
|
|
|
21
21
|
- `rsync` installed on both local and remote machines
|
|
22
22
|
- SSH access to remote server (uses system `~/.ssh/config`)
|
|
23
23
|
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Create config interactively
|
|
28
|
+
island-bridge init
|
|
29
|
+
|
|
30
|
+
# Or create config via flags (AI/script friendly)
|
|
31
|
+
island-bridge init --host 192.168.1.100 --user deploy --paths "/var/www/app,/etc/nginx/conf.d"
|
|
32
|
+
|
|
33
|
+
# Check environment is ready
|
|
34
|
+
island-bridge status
|
|
35
|
+
|
|
36
|
+
# Pull remote folders to local
|
|
37
|
+
island-bridge pull
|
|
38
|
+
|
|
39
|
+
# Push local changes back
|
|
40
|
+
island-bridge push
|
|
41
|
+
```
|
|
42
|
+
|
|
24
43
|
## Usage
|
|
25
44
|
|
|
26
|
-
1. Create `island-bridge.json` in your working directory:
|
|
45
|
+
1. Create `island-bridge.json` in your working directory (or run `island-bridge init`):
|
|
27
46
|
|
|
28
47
|
```json
|
|
29
48
|
{
|
|
@@ -68,6 +87,9 @@ island-bridge push
|
|
|
68
87
|
| `watch` | Watch local folders and auto-push on changes |
|
|
69
88
|
| `diff` | Preview changes without syncing |
|
|
70
89
|
| `history` | Show sync history |
|
|
90
|
+
| `init` | Create config file interactively or via flags |
|
|
91
|
+
| `status` | Show config, SSH, rsync, and paths status |
|
|
92
|
+
| `backup` | Manage sync backups (list, restore, clean) |
|
|
71
93
|
|
|
72
94
|
## Options
|
|
73
95
|
|
|
@@ -80,9 +102,80 @@ island-bridge push
|
|
|
80
102
|
| `--env <name>` | Use named profile from config |
|
|
81
103
|
| `--bwlimit <KB/s>` | Limit transfer bandwidth |
|
|
82
104
|
| `-s, --select` | Interactively select folders to sync |
|
|
105
|
+
| `--path <name>` | Sync specific folder by name (repeatable) |
|
|
106
|
+
| `--json` | Output in JSON format (for scripts/AI) |
|
|
107
|
+
| `--no-backup` | Skip backup for this sync |
|
|
83
108
|
| `-V, --version` | Show version |
|
|
84
109
|
| `-h, --help` | Show help |
|
|
85
110
|
|
|
111
|
+
## Backup & Restore
|
|
112
|
+
|
|
113
|
+
Backups are **enabled by default**. Before each sync, files that will be overwritten are automatically saved to a timestamped backup directory.
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# List available backups
|
|
117
|
+
island-bridge backup list
|
|
118
|
+
|
|
119
|
+
# Restore a specific backup
|
|
120
|
+
island-bridge backup restore 2026-04-07T14-30-00
|
|
121
|
+
|
|
122
|
+
# Clean old backups, keep 5 most recent
|
|
123
|
+
island-bridge backup clean --keep 5
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Backup Config
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"backup": {
|
|
131
|
+
"enabled": true,
|
|
132
|
+
"maxCount": 10,
|
|
133
|
+
"localDir": ".island-bridge-backups",
|
|
134
|
+
"remoteDir": "~/.island-bridge-backups"
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Use `--no-backup` to skip backup for a single sync operation.
|
|
140
|
+
|
|
141
|
+
## JSON Output (AI/Script Friendly)
|
|
142
|
+
|
|
143
|
+
Add `--json` to any command for structured JSON output — no colors, no progress bars, no interactive prompts:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Check environment before syncing
|
|
147
|
+
island-bridge status --json
|
|
148
|
+
|
|
149
|
+
# Sync and parse results programmatically
|
|
150
|
+
island-bridge pull --json
|
|
151
|
+
|
|
152
|
+
# Create config non-interactively
|
|
153
|
+
island-bridge init --json --host example.com --user deploy --paths "/var/www/app"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Example JSON output:
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"version": "2.0.0",
|
|
161
|
+
"command": "pull",
|
|
162
|
+
"success": true,
|
|
163
|
+
"results": [
|
|
164
|
+
{
|
|
165
|
+
"folder": "app",
|
|
166
|
+
"remotePath": "/var/www/app",
|
|
167
|
+
"success": true,
|
|
168
|
+
"changes": [
|
|
169
|
+
{ "type": "add", "file": "index.js" },
|
|
170
|
+
{ "type": "delete", "file": "old.css" }
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
],
|
|
174
|
+
"messages": [],
|
|
175
|
+
"errors": []
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
86
179
|
## Advanced Config
|
|
87
180
|
|
|
88
181
|
```json
|
|
@@ -94,6 +187,10 @@ island-bridge push
|
|
|
94
187
|
},
|
|
95
188
|
"exclude": ["node_modules", ".DS_Store", "*.log"],
|
|
96
189
|
"bwlimit": 1000,
|
|
190
|
+
"backup": {
|
|
191
|
+
"enabled": true,
|
|
192
|
+
"maxCount": 10
|
|
193
|
+
},
|
|
97
194
|
"hooks": {
|
|
98
195
|
"beforeSync": "echo 'Starting sync...'",
|
|
99
196
|
"afterSync": "pm2 restart app"
|
|
@@ -162,6 +259,12 @@ island-bridge pull --config /path/to/my-config.json
|
|
|
162
259
|
## Examples
|
|
163
260
|
|
|
164
261
|
```bash
|
|
262
|
+
# Create config interactively
|
|
263
|
+
island-bridge init
|
|
264
|
+
|
|
265
|
+
# Check everything is working
|
|
266
|
+
island-bridge status
|
|
267
|
+
|
|
165
268
|
# Preview what would change
|
|
166
269
|
island-bridge pull --dry-run
|
|
167
270
|
|
|
@@ -171,6 +274,9 @@ island-bridge diff
|
|
|
171
274
|
# Sync with bandwidth limit
|
|
172
275
|
island-bridge pull --bwlimit 500
|
|
173
276
|
|
|
277
|
+
# Sync only specific folder
|
|
278
|
+
island-bridge pull --path app
|
|
279
|
+
|
|
174
280
|
# Auto-push on file changes
|
|
175
281
|
island-bridge watch
|
|
176
282
|
|
|
@@ -183,8 +289,15 @@ island-bridge pull --env staging
|
|
|
183
289
|
# Quiet mode for CI/scripts
|
|
184
290
|
island-bridge push --quiet
|
|
185
291
|
|
|
292
|
+
# JSON output for AI/scripts
|
|
293
|
+
island-bridge pull --json
|
|
294
|
+
|
|
186
295
|
# View sync history
|
|
187
296
|
island-bridge history
|
|
297
|
+
|
|
298
|
+
# List and restore backups
|
|
299
|
+
island-bridge backup list
|
|
300
|
+
island-bridge backup restore 2026-04-07T14-30-00
|
|
188
301
|
```
|
|
189
302
|
|
|
190
303
|
## Features
|
|
@@ -207,6 +320,12 @@ island-bridge history
|
|
|
207
320
|
- **Config search** — finds config in parent directories
|
|
208
321
|
- **Fault tolerant** — skips failed transfers, reports summary at end
|
|
209
322
|
- **Zero dependencies** — pure Node.js, no npm dependencies
|
|
323
|
+
- **Auto backup** — files backed up before overwrite, with restore support
|
|
324
|
+
- **JSON output** — structured output for AI agents and scripts
|
|
325
|
+
- **Init command** — interactive or flag-based config setup
|
|
326
|
+
- **Status check** — diagnose SSH, rsync, and path issues
|
|
327
|
+
- **Path filter** — sync specific folders with `--path`
|
|
328
|
+
- **Error hints** — actionable suggestions on every error
|
|
210
329
|
|
|
211
330
|
## License
|
|
212
331
|
|
package/dist/bin/cli.js
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parseArgs } from '../lib/args.js';
|
|
3
|
+
import { loadConfig, extractFolderName } from '../lib/config.js';
|
|
4
|
+
import { checkRsync, syncAll, diffPreview } from '../lib/sync.js';
|
|
5
|
+
import { Reporter } from '../lib/reporter.js';
|
|
6
|
+
import { startWatch } from '../lib/watch.js';
|
|
7
|
+
import { recordSync, showHistory } from '../lib/history.js';
|
|
8
|
+
import { runHook } from '../lib/hooks.js';
|
|
9
|
+
import { selectPaths } from '../lib/interactive.js';
|
|
10
|
+
import { runInit } from '../lib/init.js';
|
|
11
|
+
import { runStatus } from '../lib/status.js';
|
|
12
|
+
import { listBackups, restoreBackup, cleanBackups } from '../lib/backup.js';
|
|
13
|
+
import { getErrorHint } from '../lib/summary.js';
|
|
14
|
+
import { readFileSync } from 'node:fs';
|
|
15
|
+
import { fileURLToPath } from 'node:url';
|
|
16
|
+
import { dirname, join } from 'node:path';
|
|
17
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
18
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', 'package.json'), 'utf-8'));
|
|
19
|
+
const USAGE = `
|
|
20
|
+
island-bridge v${pkg.version} - Sync remote folders via rsync over SSH
|
|
21
|
+
|
|
22
|
+
Usage:
|
|
23
|
+
island-bridge <command> [options]
|
|
24
|
+
|
|
25
|
+
Commands:
|
|
26
|
+
pull Pull remote folders to local directory
|
|
27
|
+
push Push local folders to remote server
|
|
28
|
+
watch Watch local folders and auto-push on changes
|
|
29
|
+
diff Preview changes without syncing
|
|
30
|
+
history Show sync history
|
|
31
|
+
init Create island-bridge.json config interactively
|
|
32
|
+
status Show config, SSH, rsync, and paths status
|
|
33
|
+
backup Manage sync backups (list, restore, clean)
|
|
34
|
+
|
|
35
|
+
Options:
|
|
36
|
+
-n, --dry-run Preview sync without making changes
|
|
37
|
+
-v, --verbose Show detailed output
|
|
38
|
+
-q, --quiet Suppress output (exit code only)
|
|
39
|
+
-c, --config <path> Use specific config file
|
|
40
|
+
--env <name> Use named profile from config
|
|
41
|
+
--bwlimit <KB/s> Limit transfer bandwidth
|
|
42
|
+
-s, --select Interactively select folders to sync
|
|
43
|
+
--path <name> Sync specific folder by name (repeatable)
|
|
44
|
+
--json Output in JSON format (for scripts/AI)
|
|
45
|
+
--no-backup Skip backup for this sync
|
|
46
|
+
-V, --version Show version
|
|
47
|
+
-h, --help Show this help message
|
|
48
|
+
|
|
49
|
+
Backup subcommands:
|
|
50
|
+
backup list List available backups
|
|
51
|
+
backup restore <timestamp> Restore files from a backup
|
|
52
|
+
backup clean --keep <N> Remove old backups, keep N most recent
|
|
53
|
+
`.trim();
|
|
54
|
+
async function main() {
|
|
55
|
+
let args;
|
|
56
|
+
try {
|
|
57
|
+
args = parseArgs();
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
console.error(`\x1b[31mError: ${err.message}\x1b[0m`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
const reporter = new Reporter(args.json ? 'json' : 'human');
|
|
64
|
+
if (args.help || (!args.command && !args.version)) {
|
|
65
|
+
console.log(USAGE);
|
|
66
|
+
process.exit(0);
|
|
67
|
+
}
|
|
68
|
+
if (args.version) {
|
|
69
|
+
if (args.json) {
|
|
70
|
+
reporter.setCommand('version');
|
|
71
|
+
reporter.info(pkg.version);
|
|
72
|
+
reporter.flush();
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
console.log(`island-bridge v${pkg.version}`);
|
|
76
|
+
}
|
|
77
|
+
process.exit(0);
|
|
78
|
+
}
|
|
79
|
+
const validCommands = ['pull', 'push', 'watch', 'diff', 'history', 'init', 'status', 'backup'];
|
|
80
|
+
if (!validCommands.includes(args.command)) {
|
|
81
|
+
reporter.error(`Unknown command: ${args.command}`, `Valid commands: ${validCommands.join(', ')}`);
|
|
82
|
+
if (args.json)
|
|
83
|
+
reporter.flush();
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
reporter.setCommand(args.command);
|
|
87
|
+
// === Init ===
|
|
88
|
+
if (args.command === 'init') {
|
|
89
|
+
const ok = await runInit(args, reporter);
|
|
90
|
+
if (args.json)
|
|
91
|
+
reporter.flush();
|
|
92
|
+
process.exit(ok ? 0 : 1);
|
|
93
|
+
}
|
|
94
|
+
// === History (doesn't need rsync) ===
|
|
95
|
+
if (args.command === 'history') {
|
|
96
|
+
let config;
|
|
97
|
+
try {
|
|
98
|
+
config = loadConfig({ configPath: args.config ?? undefined, env: args.env ?? undefined });
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// Show history from cwd if no config found
|
|
102
|
+
}
|
|
103
|
+
if (args.json) {
|
|
104
|
+
const { readFileSync: rfs, existsSync: efs } = await import('node:fs');
|
|
105
|
+
const { dirname: dn, join: jn } = await import('node:path');
|
|
106
|
+
const historyFile = config?._filePath
|
|
107
|
+
? jn(dn(config._filePath), '.island-bridge-history.json')
|
|
108
|
+
: '.island-bridge-history.json';
|
|
109
|
+
let entries = [];
|
|
110
|
+
if (efs(historyFile)) {
|
|
111
|
+
try {
|
|
112
|
+
const parsed = JSON.parse(rfs(historyFile, 'utf-8'));
|
|
113
|
+
entries = Array.isArray(parsed) ? parsed : [];
|
|
114
|
+
}
|
|
115
|
+
catch { /* ignore */ }
|
|
116
|
+
}
|
|
117
|
+
reporter.historyReport(entries);
|
|
118
|
+
reporter.flush();
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
showHistory(config?._filePath);
|
|
122
|
+
}
|
|
123
|
+
process.exit(0);
|
|
124
|
+
}
|
|
125
|
+
// === Backup ===
|
|
126
|
+
if (args.command === 'backup') {
|
|
127
|
+
let config;
|
|
128
|
+
try {
|
|
129
|
+
config = loadConfig({ configPath: args.config ?? undefined, env: args.env ?? undefined });
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
config = { backup: { enabled: true, localDir: '.island-bridge-backups', remoteDir: '~/.island-bridge-backups', maxCount: 10 } };
|
|
133
|
+
}
|
|
134
|
+
const backupConfig = config.backup;
|
|
135
|
+
if (args.subcommand === 'list') {
|
|
136
|
+
const backups = listBackups(backupConfig.localDir);
|
|
137
|
+
if (args.json) {
|
|
138
|
+
reporter.historyReport(backups.map((b) => ({ timestamp: b.name, date: b.date.toISOString() })));
|
|
139
|
+
reporter.flush();
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
if (backups.length === 0) {
|
|
143
|
+
console.log('No backups found.');
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
console.log('\n--- Backups ---\n');
|
|
147
|
+
for (const b of backups) {
|
|
148
|
+
console.log(` ${b.name} (${b.date.toLocaleString()})`);
|
|
149
|
+
}
|
|
150
|
+
console.log(`\n${backups.length} backup(s) found.`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
process.exit(0);
|
|
154
|
+
}
|
|
155
|
+
if (args.subcommand === 'restore') {
|
|
156
|
+
if (!args.backupTimestamp) {
|
|
157
|
+
reporter.error('backup restore requires a timestamp', 'Run "island-bridge backup list" to see available backups');
|
|
158
|
+
if (args.json)
|
|
159
|
+
reporter.flush();
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
try {
|
|
163
|
+
const results = restoreBackup(backupConfig.localDir, args.backupTimestamp);
|
|
164
|
+
if (args.json) {
|
|
165
|
+
for (const r of results) {
|
|
166
|
+
reporter.syncEnd(r.folder, r);
|
|
167
|
+
}
|
|
168
|
+
reporter.flush();
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
for (const r of results) {
|
|
172
|
+
if (r.success) {
|
|
173
|
+
console.log(` \x1b[32m\u2713\x1b[0m ${r.folder} restored`);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
console.log(` \x1b[31m\u2717\x1b[0m ${r.folder} \u2014 ${r.error}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
reporter.error(err.message, 'Run "island-bridge backup list" to see available backups');
|
|
183
|
+
if (args.json)
|
|
184
|
+
reporter.flush();
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
process.exit(0);
|
|
188
|
+
}
|
|
189
|
+
if (args.subcommand === 'clean') {
|
|
190
|
+
const keep = args.keep || backupConfig.maxCount || 10;
|
|
191
|
+
const removed = cleanBackups(backupConfig.localDir, keep);
|
|
192
|
+
if (args.json) {
|
|
193
|
+
reporter.info(`Removed ${removed.length} backup(s), keeping ${keep}`);
|
|
194
|
+
reporter.flush();
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
if (removed.length === 0) {
|
|
198
|
+
console.log(`No backups to remove (keeping ${keep}).`);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
for (const name of removed) {
|
|
202
|
+
console.log(` Removed: ${name}`);
|
|
203
|
+
}
|
|
204
|
+
console.log(`\nRemoved ${removed.length} backup(s), keeping ${keep}.`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
process.exit(0);
|
|
208
|
+
}
|
|
209
|
+
reporter.error('Unknown backup subcommand', 'Usage: island-bridge backup <list|restore|clean>');
|
|
210
|
+
if (args.json)
|
|
211
|
+
reporter.flush();
|
|
212
|
+
process.exit(1);
|
|
213
|
+
}
|
|
214
|
+
// === Pre-flight: check rsync ===
|
|
215
|
+
const rsyncOk = await checkRsync();
|
|
216
|
+
if (!rsyncOk) {
|
|
217
|
+
reporter.error('rsync is required but not found in PATH', getErrorHint('rsync-not-found'));
|
|
218
|
+
if (args.json)
|
|
219
|
+
reporter.flush();
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
// === Load config ===
|
|
223
|
+
let config;
|
|
224
|
+
try {
|
|
225
|
+
config = loadConfig({ configPath: args.config ?? undefined, env: args.env ?? undefined });
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
const hint = err.message.includes('Cannot find')
|
|
229
|
+
? getErrorHint('config-not-found')
|
|
230
|
+
: null;
|
|
231
|
+
reporter.error(err.message, hint);
|
|
232
|
+
if (args.json)
|
|
233
|
+
reporter.flush();
|
|
234
|
+
process.exit(1);
|
|
235
|
+
}
|
|
236
|
+
if (args.env) {
|
|
237
|
+
reporter.info(`Using profile: ${args.env}`);
|
|
238
|
+
}
|
|
239
|
+
if (config._filePath) {
|
|
240
|
+
reporter.info(`Config: ${config._filePath}`);
|
|
241
|
+
}
|
|
242
|
+
// === Status ===
|
|
243
|
+
if (args.command === 'status') {
|
|
244
|
+
await runStatus(config, reporter);
|
|
245
|
+
if (args.json)
|
|
246
|
+
reporter.flush();
|
|
247
|
+
process.exit(0);
|
|
248
|
+
}
|
|
249
|
+
// === --path filter ===
|
|
250
|
+
if (args.path.length > 0) {
|
|
251
|
+
const allNames = config.remote.paths.map((p) => extractFolderName(p));
|
|
252
|
+
const invalid = args.path.filter((name) => !allNames.includes(name));
|
|
253
|
+
if (invalid.length > 0) {
|
|
254
|
+
reporter.error(`Unknown folder name(s): ${invalid.join(', ')}`, `Available folders: ${allNames.join(', ')}`);
|
|
255
|
+
if (args.json)
|
|
256
|
+
reporter.flush();
|
|
257
|
+
process.exit(1);
|
|
258
|
+
}
|
|
259
|
+
config.remote.paths = config.remote.paths.filter((p) => args.path.includes(extractFolderName(p)));
|
|
260
|
+
}
|
|
261
|
+
// === Interactive selection ===
|
|
262
|
+
if (args.select && !args.json && ['pull', 'push', 'diff'].includes(args.command)) {
|
|
263
|
+
config.remote.paths = await selectPaths(config.remote.paths, reporter);
|
|
264
|
+
}
|
|
265
|
+
// === Watch mode ===
|
|
266
|
+
if (args.command === 'watch') {
|
|
267
|
+
startWatch(config, {
|
|
268
|
+
dryRun: args.dryRun,
|
|
269
|
+
verbose: args.verbose,
|
|
270
|
+
quiet: args.quiet,
|
|
271
|
+
bwlimit: args.bwlimit,
|
|
272
|
+
noBackup: args.noBackup,
|
|
273
|
+
}, reporter);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
// === Diff preview ===
|
|
277
|
+
if (args.command === 'diff') {
|
|
278
|
+
const diffs = await diffPreview(config, 'pull', {
|
|
279
|
+
bwlimit: args.bwlimit,
|
|
280
|
+
exclude: config.exclude,
|
|
281
|
+
});
|
|
282
|
+
reporter.diffReport(diffs);
|
|
283
|
+
if (args.json)
|
|
284
|
+
reporter.flush();
|
|
285
|
+
process.exit(0);
|
|
286
|
+
}
|
|
287
|
+
// === Pull or Push ===
|
|
288
|
+
const options = {
|
|
289
|
+
dryRun: args.dryRun,
|
|
290
|
+
verbose: args.verbose,
|
|
291
|
+
quiet: args.quiet,
|
|
292
|
+
bwlimit: args.bwlimit,
|
|
293
|
+
noBackup: args.noBackup,
|
|
294
|
+
};
|
|
295
|
+
// Disable hooks from configs found via upward search
|
|
296
|
+
if (!config._explicitConfig && config._filePath !== join(process.cwd(), 'island-bridge.json')) {
|
|
297
|
+
if (config.hooks.beforeSync || config.hooks.afterSync) {
|
|
298
|
+
reporter.warn(`hooks ignored from inherited config ${config._filePath}`);
|
|
299
|
+
reporter.warn(`Use --config ${config._filePath} to explicitly enable hooks.`);
|
|
300
|
+
config.hooks = {};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Run beforeSync hook
|
|
304
|
+
if (config.hooks.beforeSync) {
|
|
305
|
+
runHook('beforeSync', config.hooks.beforeSync, args.quiet, reporter);
|
|
306
|
+
}
|
|
307
|
+
const results = await syncAll(config, args.command, options, reporter);
|
|
308
|
+
// Run afterSync hook
|
|
309
|
+
if (config.hooks.afterSync) {
|
|
310
|
+
runHook('afterSync', config.hooks.afterSync, args.quiet, reporter);
|
|
311
|
+
}
|
|
312
|
+
// Record history
|
|
313
|
+
recordSync(config._filePath, args.command, results);
|
|
314
|
+
// Print summary
|
|
315
|
+
if (!args.quiet || args.json) {
|
|
316
|
+
reporter.summary(results);
|
|
317
|
+
if (!args.json && args.dryRun) {
|
|
318
|
+
reporter.info('(dry-run mode \u2014 no changes were made)');
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (args.json)
|
|
322
|
+
reporter.flush();
|
|
323
|
+
const hasFailed = results.some((r) => !r.success);
|
|
324
|
+
process.exit(hasFailed ? 1 : 0);
|
|
325
|
+
}
|
|
326
|
+
main();
|
|
327
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/args.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
export function parseArgs(argv = process.argv.slice(2)) {
|
|
2
|
+
const args = {
|
|
3
|
+
command: null,
|
|
4
|
+
subcommand: null,
|
|
5
|
+
dryRun: false,
|
|
6
|
+
verbose: false,
|
|
7
|
+
quiet: false,
|
|
8
|
+
json: false,
|
|
9
|
+
config: null,
|
|
10
|
+
env: null,
|
|
11
|
+
bwlimit: null,
|
|
12
|
+
select: false,
|
|
13
|
+
noBackup: false,
|
|
14
|
+
path: [],
|
|
15
|
+
help: false,
|
|
16
|
+
version: false,
|
|
17
|
+
// init-specific
|
|
18
|
+
host: null,
|
|
19
|
+
user: null,
|
|
20
|
+
paths: null,
|
|
21
|
+
// backup-specific
|
|
22
|
+
backupTimestamp: null,
|
|
23
|
+
keep: null,
|
|
24
|
+
};
|
|
25
|
+
for (let i = 0; i < argv.length; i++) {
|
|
26
|
+
const arg = argv[i];
|
|
27
|
+
switch (arg) {
|
|
28
|
+
case '--dry-run':
|
|
29
|
+
case '-n':
|
|
30
|
+
args.dryRun = true;
|
|
31
|
+
break;
|
|
32
|
+
case '--verbose':
|
|
33
|
+
case '-v':
|
|
34
|
+
args.verbose = true;
|
|
35
|
+
break;
|
|
36
|
+
case '--quiet':
|
|
37
|
+
case '-q':
|
|
38
|
+
args.quiet = true;
|
|
39
|
+
break;
|
|
40
|
+
case '--json':
|
|
41
|
+
args.json = true;
|
|
42
|
+
break;
|
|
43
|
+
case '--config':
|
|
44
|
+
case '-c':
|
|
45
|
+
args.config = argv[++i];
|
|
46
|
+
if (!args.config || args.config.startsWith('-'))
|
|
47
|
+
throw new Error('--config requires a file path');
|
|
48
|
+
break;
|
|
49
|
+
case '--env':
|
|
50
|
+
args.env = argv[++i];
|
|
51
|
+
if (!args.env || args.env.startsWith('-'))
|
|
52
|
+
throw new Error('--env requires a profile name');
|
|
53
|
+
break;
|
|
54
|
+
case '--bwlimit': {
|
|
55
|
+
const bwRaw = argv[++i];
|
|
56
|
+
if (!bwRaw || isNaN(Number(bwRaw))) {
|
|
57
|
+
throw new Error('--bwlimit requires a numeric value (KB/s)');
|
|
58
|
+
}
|
|
59
|
+
args.bwlimit = Number(bwRaw);
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
case '--select':
|
|
63
|
+
case '-s':
|
|
64
|
+
args.select = true;
|
|
65
|
+
break;
|
|
66
|
+
case '--no-backup':
|
|
67
|
+
args.noBackup = true;
|
|
68
|
+
break;
|
|
69
|
+
case '--path':
|
|
70
|
+
{
|
|
71
|
+
const val = argv[++i];
|
|
72
|
+
if (!val || val.startsWith('-'))
|
|
73
|
+
throw new Error('--path requires a folder name');
|
|
74
|
+
args.path.push(val);
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
case '--host':
|
|
78
|
+
args.host = argv[++i];
|
|
79
|
+
if (!args.host)
|
|
80
|
+
throw new Error('--host requires a value');
|
|
81
|
+
break;
|
|
82
|
+
case '--user':
|
|
83
|
+
args.user = argv[++i];
|
|
84
|
+
if (!args.user)
|
|
85
|
+
throw new Error('--user requires a value');
|
|
86
|
+
break;
|
|
87
|
+
case '--paths':
|
|
88
|
+
args.paths = argv[++i];
|
|
89
|
+
if (!args.paths)
|
|
90
|
+
throw new Error('--paths requires a value');
|
|
91
|
+
break;
|
|
92
|
+
case '--keep': {
|
|
93
|
+
const keepRaw = argv[++i];
|
|
94
|
+
if (!keepRaw || isNaN(Number(keepRaw))) {
|
|
95
|
+
throw new Error('--keep requires a numeric value');
|
|
96
|
+
}
|
|
97
|
+
args.keep = Number(keepRaw);
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
case '--help':
|
|
101
|
+
case '-h':
|
|
102
|
+
args.help = true;
|
|
103
|
+
break;
|
|
104
|
+
case '--version':
|
|
105
|
+
case '-V':
|
|
106
|
+
args.version = true;
|
|
107
|
+
break;
|
|
108
|
+
default:
|
|
109
|
+
if (!arg.startsWith('-')) {
|
|
110
|
+
if (!args.command) {
|
|
111
|
+
args.command = arg;
|
|
112
|
+
}
|
|
113
|
+
else if (args.command === 'backup' && !args.subcommand) {
|
|
114
|
+
args.subcommand = arg;
|
|
115
|
+
}
|
|
116
|
+
else if (args.command === 'backup' && args.subcommand === 'restore' && !args.backupTimestamp) {
|
|
117
|
+
args.backupTimestamp = arg;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (args.verbose && args.quiet) {
|
|
124
|
+
throw new Error('Cannot use --verbose and --quiet together');
|
|
125
|
+
}
|
|
126
|
+
return args;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/lib/args.ts"],"names":[],"mappings":"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"}
|