aegis-desktop 0.8.21 → 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.
- package/lib/local/local.js +17 -0
- package/package.json +1 -1
- package/vendor/aegis.js +17 -0
- package/vendor/platform.js +48 -3
package/lib/local/local.js
CHANGED
|
@@ -95,6 +95,12 @@ const DSML_RE_LEADER = /<\s*\/?\s*|\s*(?:DSML\s*)?|\s*(?:(?:tool|function)[_
|
|
|
95
95
|
const DSML_RE_ANY_TAG = /<\s*\/?\s*|\s*(?:DSML\s*)?|\s*[A-Za-z_][A-Za-z0-9_]*[^>]{0,120}>/g;
|
|
96
96
|
const DSML_RE_SKELETON = /<\s*\/?\s*(?:tool_calls|function_calls|invoke|parameter|param|reasoning)\b[^>]{0,120}>/gi;
|
|
97
97
|
const DSML_RE_JSON_CALLS = /|[ \t]*(?:tool|function)[_▁ ]*calls?[_▁ ]*begin[ \t]*|([\s\S]*?)|[ \t]*(?:tool|function)[_▁ ]*calls?[_▁ ]*end[ \t]*|/gi;
|
|
98
|
+
// The leader/closer halves of DSML_RE_JSON_CALLS above, split out so the hold
|
|
99
|
+
// logic can detect "the leader arrived but its closer has not" — an arbitrary
|
|
100
|
+
// JSON blob sits between them with no '<' or recognizable structure of its
|
|
101
|
+
// own, so nothing else below would otherwise hold it back.
|
|
102
|
+
const DSML_RE_JSON_CALLS_OPEN = /|[ \t]*(?:tool|function)[_▁ ]*calls?[_▁ ]*begin[ \t]*|/gi;
|
|
103
|
+
const DSML_RE_JSON_CALLS_CLOSE = /|[ \t]*(?:tool|function)[_▁ ]*calls?[_▁ ]*end[ \t]*|/gi;
|
|
98
104
|
const DSML_RE_ENVELOPE_TOKEN = /|[ \t]?[A-Za-z0-9_▁]*[ \t]?|/g;
|
|
99
105
|
const DSML_RE_DRIFT_INVOKE = /<\s*|\s*(?:DSML\s*)?|\s*(?:invoke|call|tool_call)\b\s*([^>]*?)\s*>/gi;
|
|
100
106
|
const DSML_RE_DRIFT_PARAM = /<\s*|\s*(?:DSML\s*)?|\s*(?:parameter|param|arg)\b\s*([^>]*?)\s*>/gi;
|
|
@@ -296,6 +302,17 @@ function dsmlUnterminated(s) {
|
|
|
296
302
|
function dsmlHoldFrom(buf) {
|
|
297
303
|
const tagStart = buf.search(/<\s*\/?\s*|/);
|
|
298
304
|
if (tagStart !== -1) return tagStart;
|
|
305
|
+
// The older JSON-array envelope (DSML_RE_JSON_CALLS): once its leader token
|
|
306
|
+
// has arrived, hold everything until the matching closer token lands. An
|
|
307
|
+
// arbitrary JSON blob sits between them with no '<' and no recognizable
|
|
308
|
+
// per-character structure, so without this check it streams straight
|
|
309
|
+
// through as visible prose the instant the leader's own closing '|'
|
|
310
|
+
// arrives — the hold rule below only looks at ONE pipe token at a time and
|
|
311
|
+
// has no notion of "waiting for a second, different token later on".
|
|
312
|
+
const jsonOpenIdx = buf.search(DSML_RE_JSON_CALLS_OPEN);
|
|
313
|
+
if (jsonOpenIdx !== -1 && buf.slice(jsonOpenIdx).search(DSML_RE_JSON_CALLS_CLOSE) === -1) {
|
|
314
|
+
return jsonOpenIdx;
|
|
315
|
+
}
|
|
299
316
|
const lt = DSML_RE_TRAILING_LT.exec(buf);
|
|
300
317
|
if (lt) return lt.index;
|
|
301
318
|
const openIdx = buf.indexOf('|');
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aegis-desktop",
|
|
3
3
|
"productName": "AEGIS Desktop",
|
|
4
|
-
"version": "0.8.
|
|
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",
|
package/vendor/aegis.js
CHANGED
|
@@ -100,6 +100,12 @@ const DSML_RE_LEADER = /<\s*\/?\s*|\s*(?:DSML\s*)?|\s*(?:(?:tool|function)[_
|
|
|
100
100
|
const DSML_RE_ANY_TAG = /<\s*\/?\s*|\s*(?:DSML\s*)?|\s*[A-Za-z_][A-Za-z0-9_]*[^>]{0,120}>/g;
|
|
101
101
|
const DSML_RE_SKELETON = /<\s*\/?\s*(?:tool_calls|function_calls|invoke|parameter|param|reasoning)\b[^>]{0,120}>/gi;
|
|
102
102
|
const DSML_RE_JSON_CALLS = /|[ \t]*(?:tool|function)[_▁ ]*calls?[_▁ ]*begin[ \t]*|([\s\S]*?)|[ \t]*(?:tool|function)[_▁ ]*calls?[_▁ ]*end[ \t]*|/gi;
|
|
103
|
+
// The leader/closer halves of DSML_RE_JSON_CALLS above, split out so the hold
|
|
104
|
+
// logic can detect "the leader arrived but its closer has not" — an arbitrary
|
|
105
|
+
// JSON blob sits between them with no '<' or recognizable structure of its
|
|
106
|
+
// own, so nothing else below would otherwise hold it back.
|
|
107
|
+
const DSML_RE_JSON_CALLS_OPEN = /|[ \t]*(?:tool|function)[_▁ ]*calls?[_▁ ]*begin[ \t]*|/gi;
|
|
108
|
+
const DSML_RE_JSON_CALLS_CLOSE = /|[ \t]*(?:tool|function)[_▁ ]*calls?[_▁ ]*end[ \t]*|/gi;
|
|
103
109
|
const DSML_RE_ENVELOPE_TOKEN = /|[ \t]?[A-Za-z0-9_▁]*[ \t]?|/g;
|
|
104
110
|
const DSML_RE_DRIFT_INVOKE = /<\s*|\s*(?:DSML\s*)?|\s*(?:invoke|call|tool_call)\b\s*([^>]*?)\s*>/gi;
|
|
105
111
|
const DSML_RE_DRIFT_PARAM = /<\s*|\s*(?:DSML\s*)?|\s*(?:parameter|param|arg)\b\s*([^>]*?)\s*>/gi;
|
|
@@ -301,6 +307,17 @@ function dsmlUnterminated(s) {
|
|
|
301
307
|
function dsmlHoldFrom(buf) {
|
|
302
308
|
const tagStart = buf.search(/<\s*\/?\s*|/);
|
|
303
309
|
if (tagStart !== -1) return tagStart;
|
|
310
|
+
// The older JSON-array envelope (DSML_RE_JSON_CALLS): once its leader token
|
|
311
|
+
// has arrived, hold everything until the matching closer token lands. An
|
|
312
|
+
// arbitrary JSON blob sits between them with no '<' and no recognizable
|
|
313
|
+
// per-character structure, so without this check it streams straight
|
|
314
|
+
// through as visible prose the instant the leader's own closing '|'
|
|
315
|
+
// arrives — the hold rule below only looks at ONE pipe token at a time and
|
|
316
|
+
// has no notion of "waiting for a second, different token later on".
|
|
317
|
+
const jsonOpenIdx = buf.search(DSML_RE_JSON_CALLS_OPEN);
|
|
318
|
+
if (jsonOpenIdx !== -1 && buf.slice(jsonOpenIdx).search(DSML_RE_JSON_CALLS_CLOSE) === -1) {
|
|
319
|
+
return jsonOpenIdx;
|
|
320
|
+
}
|
|
304
321
|
const lt = DSML_RE_TRAILING_LT.exec(buf);
|
|
305
322
|
if (lt) return lt.index;
|
|
306
323
|
const openIdx = buf.indexOf('|');
|
package/vendor/platform.js
CHANGED
|
@@ -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)
|
|
497
|
-
* (default: a real
|
|
498
|
-
*
|
|
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 {
|