aegis-desktop 0.8.22 → 0.8.23

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 (2) hide show
  1. package/package.json +1 -1
  2. package/vendor/platform.js +48 -3
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "aegis-desktop",
3
3
  "productName": "AEGIS Desktop",
4
- "version": "0.8.22",
4
+ "version": "0.8.23",
5
5
  "description": "Thin Electron host for AEGIS — a local chat UI over the shared client/aegis.js transport. Ships transport + UI only; engine logic stays server-side.",
6
6
  "author": {
7
7
  "name": "AEGIS Code",
@@ -89,6 +89,24 @@ function defaultDirExists(dir) {
89
89
  }
90
90
  }
91
91
 
92
+ /**
93
+ * Does this directory hold anything? Used only to break the OneDrive-vs-plain
94
+ * Desktop tie below — OneDrive routinely scaffolds an empty `OneDrive\Desktop`
95
+ * folder on install whether or not the user ever turned Desktop redirection
96
+ * on, so mere existence cannot tell a genuinely redirected Desktop apart from
97
+ * that empty placeholder. An unreadable/missing directory counts as empty
98
+ * rather than throwing, since the caller already confirmed it exists with
99
+ * `dirExists` and a race or permissions quirk here should not crash a
100
+ * best-effort path guess.
101
+ */
102
+ function defaultDirNonEmpty(dir) {
103
+ try {
104
+ return fs.readdirSync(dir).length > 0;
105
+ } catch {
106
+ return false;
107
+ }
108
+ }
109
+
92
110
  /** Read a text file; `null` for every failure (missing, unreadable, not text). */
93
111
  function defaultReadText(file) {
94
112
  try {
@@ -493,15 +511,17 @@ function hasPosixModes(options = {}) {
493
511
  *
494
512
  * macOS is the one host where `~/Desktop` is simply correct.
495
513
  *
496
- * Seams: `dirExists` (default: a real statSync isDirectory probe) and `readText`
497
- * (default: a real utf8 read, `null` on any failure), so all three branches are
498
- * exercised on one host.
514
+ * Seams: `dirExists` (default: a real statSync isDirectory probe), `dirNonEmpty`
515
+ * (default: a real readdirSync length check, used only to break the win32
516
+ * OneDrive-vs-plain tie below) and `readText` (default: a real utf8 read,
517
+ * `null` on any failure), so all three branches are exercised on one host.
499
518
  */
500
519
  function desktopDir(options = {}) {
501
520
  const { platform, env, win32, o } = seams(options);
502
521
  const P = win32 ? path.win32 : path.posix;
503
522
  const home = homeDir(options);
504
523
  const dirExists = typeof o.dirExists === 'function' ? o.dirExists : defaultDirExists;
524
+ const dirNonEmpty = typeof o.dirNonEmpty === 'function' ? o.dirNonEmpty : defaultDirNonEmpty;
505
525
  const readText = typeof o.readText === 'function' ? o.readText : defaultReadText;
506
526
 
507
527
  const candidates = [];
@@ -514,6 +534,31 @@ function desktopDir(options = {}) {
514
534
  if (oneDrive) push(P.join(oneDrive, 'Desktop'));
515
535
  if (home) push(P.join(home, 'OneDrive', 'Desktop'));
516
536
  if (home) push(P.join(home, 'Desktop'));
537
+ // OneDrive is tried first above — real folder redirection moves the live
538
+ // Desktop there and leaves the plain one empty, exactly as the module
539
+ // comment says. But OneDrive also scaffolds an empty `OneDrive\Desktop`
540
+ // on install whether redirection was ever turned on, and that empty
541
+ // placeholder must not outrank a Desktop the user is actually using —
542
+ // reported live: a write landed in an untouched `OneDrive\Desktop` while
543
+ // the populated plain Desktop sat right next to it. Demote every
544
+ // OneDrive candidate below the plain one only in that one unambiguous
545
+ // case (a OneDrive candidate exists but is empty, AND the plain Desktop
546
+ // exists and has something in it); every other combination — including
547
+ // "both empty", which is what a fresh profile and this file's own
548
+ // stubbed tests both look like — keeps the order above, since a guess is
549
+ // still owed and emptiness alone proves nothing there.
550
+ const plainDesktop = home ? P.join(home, 'Desktop') : '';
551
+ const plainIdx = candidates.indexOf(plainDesktop);
552
+ if (plainIdx > 0 && dirExists(plainDesktop) && dirNonEmpty(plainDesktop)) {
553
+ const oneDriveCandidates = candidates.slice(0, plainIdx);
554
+ const allOneDriveEmpty = oneDriveCandidates.every(
555
+ (c) => !dirExists(c) || !dirNonEmpty(c)
556
+ );
557
+ if (allOneDriveEmpty) {
558
+ candidates.splice(plainIdx, 1);
559
+ candidates.unshift(plainDesktop);
560
+ }
561
+ }
517
562
  } else if (platform === 'darwin') {
518
563
  if (home) push(P.join(home, 'Desktop'));
519
564
  } else {