aethel 0.3.8 → 0.4.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.0 (2026-04-06)
4
+
5
+ - Add pull --all for full remote download
6
+
3
7
  ## 0.3.8 (2026-04-06)
4
8
 
5
9
  - Fix Drive upload checksum test stub
package/README.md CHANGED
@@ -78,6 +78,7 @@ aethel add --all # stage default suggested actions
78
78
  aethel commit -m "sync" # execute staged operations
79
79
 
80
80
  aethel pull -m "pull" # fetch remote changes and apply
81
+ aethel pull --all # download the full remote tree to local
81
82
  aethel push -m "push" # push local changes to Drive
82
83
  ```
83
84
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aethel",
3
- "version": "0.3.8",
3
+ "version": "0.4.0",
4
4
  "description": "Git-style Google Drive sync CLI with interactive TUI",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/cli.js CHANGED
@@ -513,6 +513,37 @@ async function handlePull(paths, options) {
513
513
  const repo = await openRepo(options);
514
514
  const { diff, remoteState } = await loadStateWithProgress(repo, { useCache: false });
515
515
 
516
+ if (options.all) {
517
+ let remoteFiles = remoteState.files;
518
+
519
+ if (paths && paths.length > 0) {
520
+ remoteFiles = remoteFiles.filter((file) =>
521
+ paths.some((p) => matchesPattern(file.path, p))
522
+ );
523
+ }
524
+
525
+ if (!remoteFiles.length) {
526
+ console.log("No remote files matched.");
527
+ return;
528
+ }
529
+
530
+ if (options.dryRun) {
531
+ console.log(`Would pull ${remoteFiles.length} remote item(s):`);
532
+ for (const file of remoteFiles) {
533
+ console.log(` +R ${file.path} (full remote download)`);
534
+ }
535
+ return;
536
+ }
537
+
538
+ const count = repo.stageRemoteFilesForDownload(remoteFiles);
539
+ console.log(`Staged ${count} remote item(s). Committing...`);
540
+ await handleCommit({ ...options, message: options.message || "pull" }, {
541
+ repo,
542
+ snapshotHint: { remote: remoteState },
543
+ });
544
+ return;
545
+ }
546
+
516
547
  let remoteChanges = diff.changes.filter((change) =>
517
548
  [
518
549
  ChangeType.REMOTE_ADDED,
@@ -1100,6 +1131,7 @@ async function main() {
1100
1131
  .command("pull")
1101
1132
  .description("Download remote changes")
1102
1133
  .argument("[paths...]", "Specific paths to pull (default: all)")
1134
+ .option("--all", "Download all remote files regardless of snapshot state")
1103
1135
  .option("-m, --message <message>", "Commit message")
1104
1136
  .option("--force", "Force-pull conflicts (remote wins)")
1105
1137
  .option("--dry-run", "Preview changes without applying")
@@ -47,6 +47,7 @@ import {
47
47
  stageChange,
48
48
  stageChanges,
49
49
  stageConflictResolution,
50
+ stageRemoteFilesForDownload,
50
51
  stagedEntries,
51
52
  unstageAll,
52
53
  unstagePath,
@@ -190,6 +191,10 @@ export class Repository {
190
191
  return stageChanges(this._root, changes);
191
192
  }
192
193
 
194
+ stageRemoteFilesForDownload(remoteFiles) {
195
+ return stageRemoteFilesForDownload(this._root, remoteFiles);
196
+ }
197
+
193
198
  unstagePath(targetPath) {
194
199
  return unstagePath(this._root, targetPath);
195
200
  }
@@ -50,6 +50,26 @@ export function stageChanges(root, changes) {
50
50
  return changes.length;
51
51
  }
52
52
 
53
+ export function stageRemoteFilesForDownload(root, remoteFiles) {
54
+ const index = readIndex(root);
55
+ const byPath = new Map((index.staged || []).map((entry) => [entry.path, entry]));
56
+
57
+ for (const remoteFile of remoteFiles) {
58
+ byPath.set(remoteFile.path, {
59
+ action: "download",
60
+ path: remoteFile.path,
61
+ localPath: remoteFile.path,
62
+ fileId: remoteFile.id,
63
+ remotePath: remoteFile.path,
64
+ ...(remoteFile.isFolder ? { isFolder: true } : {}),
65
+ });
66
+ }
67
+
68
+ index.staged = [...byPath.values()];
69
+ writeIndex(root, index);
70
+ return remoteFiles.length;
71
+ }
72
+
53
73
  export function unstagePath(root, targetPath) {
54
74
  const index = readIndex(root);
55
75
  const staged = index.staged || [];