@devicelink/dlink 0.3.0 → 0.3.2
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 +36 -25
- package/index.js +230 -135
- package/index.js.map +4 -4
- package/package.json +8 -2
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// agent/src/cli/core/engine.ts
|
|
4
|
-
import
|
|
4
|
+
import crypto5 from "node:crypto";
|
|
5
5
|
|
|
6
6
|
// agent/src/cli/core/types.ts
|
|
7
7
|
var RuntimeFlags = class {
|
|
@@ -48,8 +48,8 @@ var Deferred = class {
|
|
|
48
48
|
};
|
|
49
49
|
this.rejectFn = () => {
|
|
50
50
|
};
|
|
51
|
-
this.promise = new Promise((
|
|
52
|
-
this.resolveFn =
|
|
51
|
+
this.promise = new Promise((resolve3, reject) => {
|
|
52
|
+
this.resolveFn = resolve3;
|
|
53
53
|
this.rejectFn = reject;
|
|
54
54
|
});
|
|
55
55
|
}
|
|
@@ -272,8 +272,8 @@ var ConfigurationContext = class {
|
|
|
272
272
|
};
|
|
273
273
|
|
|
274
274
|
// agent/src/cli/utils/config.builder.ts
|
|
275
|
-
import
|
|
276
|
-
import
|
|
275
|
+
import path4 from "node:path";
|
|
276
|
+
import os3 from "node:os";
|
|
277
277
|
import fs2 from "node:fs";
|
|
278
278
|
import dotenv from "dotenv";
|
|
279
279
|
import get2 from "lodash/get.js";
|
|
@@ -524,8 +524,8 @@ function canonicalizePath(input) {
|
|
|
524
524
|
out = out.toLowerCase();
|
|
525
525
|
return out;
|
|
526
526
|
}
|
|
527
|
-
function getDirectoryTag(
|
|
528
|
-
const canonical = canonicalizePath(
|
|
527
|
+
function getDirectoryTag(path13, groups = [3, 3, 3, 3]) {
|
|
528
|
+
const canonical = canonicalizePath(path13);
|
|
529
529
|
const hash = crypto3.createHash("sha256").update(canonical, "utf8").digest("base64url");
|
|
530
530
|
const clean = hash.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
|
|
531
531
|
const needed = groups.reduce((a, b) => a + b, 0);
|
|
@@ -533,8 +533,8 @@ function getDirectoryTag(path11, groups = [3, 3, 3, 3]) {
|
|
|
533
533
|
let i = 0;
|
|
534
534
|
return groups.map((len) => padded.slice(i, i += len)).join("-");
|
|
535
535
|
}
|
|
536
|
-
function pathToUuidLikeSha256(
|
|
537
|
-
const canonical = canonicalizePath(
|
|
536
|
+
function pathToUuidLikeSha256(path13) {
|
|
537
|
+
const canonical = canonicalizePath(path13);
|
|
538
538
|
const hex = crypto3.createHash("sha256").update(canonical, "utf8").digest("hex");
|
|
539
539
|
const h = hex.slice(0, 32);
|
|
540
540
|
const part1 = h.slice(0, 8);
|
|
@@ -545,6 +545,118 @@ function pathToUuidLikeSha256(path11) {
|
|
|
545
545
|
return `${part1}-${part2}-${part3}-${part4}-${part5}`;
|
|
546
546
|
}
|
|
547
547
|
|
|
548
|
+
// common/src/lib/utils/crypto.utils.ts
|
|
549
|
+
import * as crypto4 from "node:crypto";
|
|
550
|
+
function fingerprintFromPublicKeyPem(publicKeyPem) {
|
|
551
|
+
const keyObj = crypto4.createPublicKey(publicKeyPem);
|
|
552
|
+
if (keyObj.asymmetricKeyType !== "ed25519") {
|
|
553
|
+
throw new Error(`Unexpected key type: ${keyObj.asymmetricKeyType}`);
|
|
554
|
+
}
|
|
555
|
+
const spkiDer = keyObj.export({ format: "der", type: "spki" });
|
|
556
|
+
const hash = crypto4.createHash("sha256").update(spkiDer).digest("base64url");
|
|
557
|
+
return hash.slice(0, 16).toUpperCase();
|
|
558
|
+
}
|
|
559
|
+
function signConnect(params) {
|
|
560
|
+
const payload = Buffer.from(`${params.deviceId}|${params.ts}|${params.nonce}`, "utf8");
|
|
561
|
+
const key = crypto4.createPrivateKey(params.privateKeyPem);
|
|
562
|
+
const sig = crypto4.sign(null, payload, key);
|
|
563
|
+
return sig.toString("base64");
|
|
564
|
+
}
|
|
565
|
+
function signRefresh(params) {
|
|
566
|
+
const hash = crypto4.createHash("sha256").update(params.refreshToken, "utf8").digest("hex");
|
|
567
|
+
const payload = Buffer.from(`${params.deviceId}|${params.ts}|${params.nonce}|${hash}`, "utf8");
|
|
568
|
+
const key = crypto4.createPrivateKey(params.privateKeyPem);
|
|
569
|
+
const sig = crypto4.sign(null, payload, key);
|
|
570
|
+
return sig.toString("base64");
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// common/src/lib/utils/async.utils.ts
|
|
574
|
+
function sleep(ms) {
|
|
575
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// common/src/lib/utils/path.utils.ts
|
|
579
|
+
import * as path2 from "node:path";
|
|
580
|
+
var isCaseInsensitiveFS = process.platform === "win32";
|
|
581
|
+
function pathDedupeKey(p) {
|
|
582
|
+
const resolved = path2.resolve(p);
|
|
583
|
+
return isCaseInsensitiveFS ? resolved.toLowerCase() : resolved;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// common/src/lib/utils/path-display.utils.ts
|
|
587
|
+
import * as path3 from "node:path";
|
|
588
|
+
import * as os2 from "node:os";
|
|
589
|
+
function normalizeSlashes(s) {
|
|
590
|
+
return s.replace(/\\/g, "/");
|
|
591
|
+
}
|
|
592
|
+
function looksLikeWindowsDrivePath(s) {
|
|
593
|
+
return /^[A-Za-z]:[\\/]/.test(s) || /^[A-Za-z]:$/.test(s.trim());
|
|
594
|
+
}
|
|
595
|
+
function normalizeWindowsSeparatorsForMatch(s) {
|
|
596
|
+
if (!looksLikeWindowsDrivePath(s))
|
|
597
|
+
return s;
|
|
598
|
+
return s.replace(/\//g, "\\");
|
|
599
|
+
}
|
|
600
|
+
function toTildeHomePath(absolutePath) {
|
|
601
|
+
if (absolutePath == null)
|
|
602
|
+
return void 0;
|
|
603
|
+
const raw = String(absolutePath).trim();
|
|
604
|
+
if (raw === "")
|
|
605
|
+
return void 0;
|
|
606
|
+
if (raw.startsWith("~")) {
|
|
607
|
+
return normalizeSlashes(raw);
|
|
608
|
+
}
|
|
609
|
+
if (!looksLikeWindowsDrivePath(raw)) {
|
|
610
|
+
try {
|
|
611
|
+
const abs = path3.resolve(raw);
|
|
612
|
+
const home = path3.resolve(os2.homedir());
|
|
613
|
+
const rel = path3.relative(home, abs);
|
|
614
|
+
if (!rel.startsWith("..") && !path3.isAbsolute(rel)) {
|
|
615
|
+
if (rel === "")
|
|
616
|
+
return "~";
|
|
617
|
+
return "~/" + normalizeSlashes(rel);
|
|
618
|
+
}
|
|
619
|
+
} catch {
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
const win = normalizeWindowsSeparatorsForMatch(raw);
|
|
623
|
+
const winUsers = win.match(/^([A-Za-z]:)\\(?:[Uu][Ss][Ee][Rr][Ss])\\([^\\]+)(\\.*)?$/);
|
|
624
|
+
if (winUsers) {
|
|
625
|
+
const rest = (winUsers[3] ?? "").replace(/\\/g, "/");
|
|
626
|
+
return rest ? "~" + rest : "~";
|
|
627
|
+
}
|
|
628
|
+
const wsl = raw.match(/^\/mnt\/[a-z]\/(?:[Uu][Ss][Ee][Rr][Ss])\/[^/]+(\/.*)?$/i);
|
|
629
|
+
if (wsl) {
|
|
630
|
+
const rest = wsl[1] ?? "";
|
|
631
|
+
return rest ? "~" + normalizeSlashes(rest) : "~";
|
|
632
|
+
}
|
|
633
|
+
const mac = raw.match(/^\/Users\/[^/]+(\/.*)?$/);
|
|
634
|
+
if (mac) {
|
|
635
|
+
const rest = mac[1] ?? "";
|
|
636
|
+
return rest ? "~" + normalizeSlashes(rest) : "~";
|
|
637
|
+
}
|
|
638
|
+
const lin = raw.match(/^\/home\/[^/]+(\/.*)?$/);
|
|
639
|
+
if (lin) {
|
|
640
|
+
const rest = lin[1] ?? "";
|
|
641
|
+
return rest ? "~" + normalizeSlashes(rest) : "~";
|
|
642
|
+
}
|
|
643
|
+
const fbsd = raw.match(/^\/usr\/home\/[^/]+(\/.*)?$/);
|
|
644
|
+
if (fbsd) {
|
|
645
|
+
const rest = fbsd[1] ?? "";
|
|
646
|
+
return rest ? "~" + normalizeSlashes(rest) : "~";
|
|
647
|
+
}
|
|
648
|
+
const exp = raw.match(/^\/export\/home\/[^/]+(\/.*)?$/);
|
|
649
|
+
if (exp) {
|
|
650
|
+
const rest = exp[1] ?? "";
|
|
651
|
+
return rest ? "~" + normalizeSlashes(rest) : "~";
|
|
652
|
+
}
|
|
653
|
+
try {
|
|
654
|
+
return path3.basename(path3.resolve(raw));
|
|
655
|
+
} catch {
|
|
656
|
+
return raw.split(/[/\\]/).pop() ?? raw;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
548
660
|
// agent/src/cli/utils/config.builder.ts
|
|
549
661
|
var DEFAULT_CONFIG = {
|
|
550
662
|
version: 1,
|
|
@@ -576,9 +688,9 @@ var ConfigLoader = class {
|
|
|
576
688
|
loadProductionEnv() {
|
|
577
689
|
const candidates = [
|
|
578
690
|
// npm install: .env.production alongside index.js
|
|
579
|
-
|
|
691
|
+
path4.resolve(path4.dirname(process.argv[1] ?? "."), ".env.production"),
|
|
580
692
|
// monorepo dev: agent/.env.production
|
|
581
|
-
|
|
693
|
+
path4.resolve(process.cwd(), ".env.production")
|
|
582
694
|
];
|
|
583
695
|
for (const candidate of candidates) {
|
|
584
696
|
try {
|
|
@@ -626,7 +738,7 @@ var ConfigLoader = class {
|
|
|
626
738
|
withConfigFile(filename) {
|
|
627
739
|
try {
|
|
628
740
|
const configFolder = this.getApplicationConfigFolder();
|
|
629
|
-
const configPath =
|
|
741
|
+
const configPath = path4.join(configFolder, filename);
|
|
630
742
|
if (fs2.existsSync(configPath)) {
|
|
631
743
|
const raw = fs2.readFileSync(configPath, "utf8");
|
|
632
744
|
const parsed = JSON.parse(raw);
|
|
@@ -664,36 +776,49 @@ var ConfigLoader = class {
|
|
|
664
776
|
return this.argv?.bridgeWsUrl ?? this.safeGetEnvValue("DLINK_BRIDGE_URL") ?? this.safeGetConfigValue("bridgeWsUrl") ?? this.processEnv["DLINK_BRIDGE_URL"] ?? this.productionEnv["DLINK_BRIDGE_URL"] ?? void 0;
|
|
665
777
|
}
|
|
666
778
|
getDirectories() {
|
|
779
|
+
const collected = [];
|
|
780
|
+
collected.push(this.createDirectoryFromPath(process.cwd()));
|
|
667
781
|
if (this.argv?.rootPath) {
|
|
668
782
|
try {
|
|
669
|
-
|
|
783
|
+
collected.push(...this.parseDirectoriesFromString(this.argv.rootPath));
|
|
670
784
|
} catch {
|
|
671
|
-
|
|
785
|
+
collected.push(this.createDirectoryFromPath(this.argv.rootPath));
|
|
672
786
|
}
|
|
673
787
|
}
|
|
674
788
|
const envDirs = this.safeGetEnvValue("DLINK_DIRECTORIES") ?? this.safeGetEnvValue("DLINK_ROOTS");
|
|
675
789
|
if (envDirs) {
|
|
676
790
|
try {
|
|
677
|
-
|
|
791
|
+
collected.push(...this.parseDirectoriesFromString(envDirs));
|
|
678
792
|
} catch {
|
|
679
793
|
}
|
|
680
794
|
}
|
|
681
795
|
const configDirs = this.safeGetConfigValue("directories") ?? this.safeGetConfigValue("roots");
|
|
682
796
|
if (configDirs) {
|
|
683
797
|
try {
|
|
684
|
-
|
|
798
|
+
collected.push(...this.parseDirectoriesFromValue(configDirs));
|
|
685
799
|
} catch {
|
|
686
800
|
}
|
|
687
801
|
}
|
|
688
802
|
const processDirs = this.processEnv["DLINK_DIRECTORIES"] ?? this.processEnv["DLINK_ROOTS"];
|
|
689
803
|
if (processDirs) {
|
|
690
804
|
try {
|
|
691
|
-
|
|
805
|
+
collected.push(...this.parseDirectoriesFromString(processDirs));
|
|
692
806
|
} catch {
|
|
693
807
|
}
|
|
694
808
|
}
|
|
695
|
-
|
|
696
|
-
|
|
809
|
+
return this.deduplicateDirectories(collected);
|
|
810
|
+
}
|
|
811
|
+
deduplicateDirectories(dirs) {
|
|
812
|
+
const seen = /* @__PURE__ */ new Set();
|
|
813
|
+
const result = [];
|
|
814
|
+
for (const dir of dirs) {
|
|
815
|
+
const key = pathDedupeKey(dir.path);
|
|
816
|
+
if (seen.has(key))
|
|
817
|
+
continue;
|
|
818
|
+
seen.add(key);
|
|
819
|
+
result.push(dir);
|
|
820
|
+
}
|
|
821
|
+
return result;
|
|
697
822
|
}
|
|
698
823
|
getDevice() {
|
|
699
824
|
const deviceId = this.getDeviceId();
|
|
@@ -703,7 +828,7 @@ var ConfigLoader = class {
|
|
|
703
828
|
}
|
|
704
829
|
let deviceName = this.getDeviceName();
|
|
705
830
|
if (!deviceName) {
|
|
706
|
-
deviceName =
|
|
831
|
+
deviceName = os3.hostname() || "Unknown Device";
|
|
707
832
|
}
|
|
708
833
|
const deviceTag = this.getDeviceTag();
|
|
709
834
|
const keyBuilder = new KeyBuilder({
|
|
@@ -767,7 +892,7 @@ var ConfigLoader = class {
|
|
|
767
892
|
const processName = this.processEnv["DLINK_DEVICE_NAME"];
|
|
768
893
|
if (processName && !isEmpty2(processName))
|
|
769
894
|
return processName;
|
|
770
|
-
const hostname =
|
|
895
|
+
const hostname = os3.hostname();
|
|
771
896
|
if (hostname && !isEmpty2(hostname))
|
|
772
897
|
return hostname;
|
|
773
898
|
return void 0;
|
|
@@ -842,7 +967,7 @@ var ConfigLoader = class {
|
|
|
842
967
|
const directoryPath = get2(obj, "path");
|
|
843
968
|
const name = defaultTo(
|
|
844
969
|
get2(obj, "name"),
|
|
845
|
-
directoryPath ?
|
|
970
|
+
directoryPath ? path4.basename(directoryPath) : ""
|
|
846
971
|
);
|
|
847
972
|
if (!isEmpty2(id) && !isEmpty2(directoryPath)) {
|
|
848
973
|
const tag = getDirectoryTag(directoryPath);
|
|
@@ -857,18 +982,18 @@ var ConfigLoader = class {
|
|
|
857
982
|
return null;
|
|
858
983
|
}
|
|
859
984
|
createDirectoryFromPath(directoryPath) {
|
|
860
|
-
const normalizedPath =
|
|
985
|
+
const normalizedPath = path4.resolve(directoryPath);
|
|
861
986
|
const id = pathToUuidLikeSha256(normalizedPath);
|
|
862
|
-
const name =
|
|
987
|
+
const name = path4.basename(normalizedPath);
|
|
863
988
|
const tag = getDirectoryTag(normalizedPath);
|
|
864
989
|
return { id, name, path: normalizedPath, tag };
|
|
865
990
|
}
|
|
866
991
|
getApplicationConfigFolder() {
|
|
867
992
|
const appData = defaultTo(
|
|
868
993
|
this.processEnv["APPDATA"],
|
|
869
|
-
|
|
994
|
+
path4.join(os3.homedir(), "AppData", "Roaming")
|
|
870
995
|
);
|
|
871
|
-
return
|
|
996
|
+
return path4.join(appData, "DeviceLink");
|
|
872
997
|
}
|
|
873
998
|
};
|
|
874
999
|
|
|
@@ -1131,7 +1256,7 @@ var Engine2 = class {
|
|
|
1131
1256
|
await this.loopOnce();
|
|
1132
1257
|
} catch (err) {
|
|
1133
1258
|
this.notifier.error(`Engine loop error: ${String(err)}`, { scope: "system" /* System */ });
|
|
1134
|
-
await new Promise((
|
|
1259
|
+
await new Promise((resolve3) => setTimeout(resolve3, 250));
|
|
1135
1260
|
}
|
|
1136
1261
|
}
|
|
1137
1262
|
}
|
|
@@ -1414,12 +1539,12 @@ var Engine2 = class {
|
|
|
1414
1539
|
this.wakeFn();
|
|
1415
1540
|
}
|
|
1416
1541
|
resetWake() {
|
|
1417
|
-
return new Promise((
|
|
1418
|
-
this.wakeFn =
|
|
1542
|
+
return new Promise((resolve3) => {
|
|
1543
|
+
this.wakeFn = resolve3;
|
|
1419
1544
|
});
|
|
1420
1545
|
}
|
|
1421
1546
|
newId() {
|
|
1422
|
-
return
|
|
1547
|
+
return crypto5.randomBytes(8).toString("hex");
|
|
1423
1548
|
}
|
|
1424
1549
|
};
|
|
1425
1550
|
function backoffMs(attempt) {
|
|
@@ -1462,10 +1587,10 @@ var EventBus = class {
|
|
|
1462
1587
|
};
|
|
1463
1588
|
|
|
1464
1589
|
// agent/src/storage/index.ts
|
|
1465
|
-
import * as
|
|
1590
|
+
import * as crypto6 from "node:crypto";
|
|
1466
1591
|
import * as fs3 from "node:fs/promises";
|
|
1467
|
-
import * as
|
|
1468
|
-
import * as
|
|
1592
|
+
import * as path5 from "node:path";
|
|
1593
|
+
import * as os4 from "node:os";
|
|
1469
1594
|
import defaultTo2 from "lodash/defaultTo.js";
|
|
1470
1595
|
var SALT = "DeviceLink-SecretStorage-v1";
|
|
1471
1596
|
var IV_LENGTH = 12;
|
|
@@ -1475,12 +1600,12 @@ var SECRETS_FILENAME = "secrets.enc.json";
|
|
|
1475
1600
|
function getSecretsPath() {
|
|
1476
1601
|
const appData = defaultTo2(
|
|
1477
1602
|
process.env["APPDATA"],
|
|
1478
|
-
|
|
1603
|
+
path5.join(os4.homedir(), "AppData", "Roaming")
|
|
1479
1604
|
);
|
|
1480
|
-
return
|
|
1605
|
+
return path5.join(appData, "DeviceLink", SECRETS_FILENAME);
|
|
1481
1606
|
}
|
|
1482
1607
|
function deriveKey(machineId) {
|
|
1483
|
-
return
|
|
1608
|
+
return crypto6.pbkdf2Sync(
|
|
1484
1609
|
machineId,
|
|
1485
1610
|
SALT,
|
|
1486
1611
|
1e5,
|
|
@@ -1510,7 +1635,7 @@ var EncryptedFileStorage = class {
|
|
|
1510
1635
|
this.loaded = true;
|
|
1511
1636
|
}
|
|
1512
1637
|
async save() {
|
|
1513
|
-
await fs3.mkdir(
|
|
1638
|
+
await fs3.mkdir(path5.dirname(this.secretsPath), { recursive: true });
|
|
1514
1639
|
const plain = JSON.stringify(this.cache);
|
|
1515
1640
|
const encrypted = this.encrypt(plain);
|
|
1516
1641
|
const tmp = this.secretsPath + ".tmp";
|
|
@@ -1518,8 +1643,8 @@ var EncryptedFileStorage = class {
|
|
|
1518
1643
|
await fs3.rename(tmp, this.secretsPath);
|
|
1519
1644
|
}
|
|
1520
1645
|
encrypt(plain) {
|
|
1521
|
-
const iv =
|
|
1522
|
-
const cipher =
|
|
1646
|
+
const iv = crypto6.randomBytes(IV_LENGTH);
|
|
1647
|
+
const cipher = crypto6.createCipheriv("aes-256-gcm", this.key, iv, {
|
|
1523
1648
|
authTagLength: TAG_LENGTH
|
|
1524
1649
|
});
|
|
1525
1650
|
const enc = Buffer.concat([
|
|
@@ -1534,7 +1659,7 @@ var EncryptedFileStorage = class {
|
|
|
1534
1659
|
const iv = buf.subarray(0, IV_LENGTH);
|
|
1535
1660
|
const tag = buf.subarray(IV_LENGTH, IV_LENGTH + TAG_LENGTH);
|
|
1536
1661
|
const enc = buf.subarray(IV_LENGTH + TAG_LENGTH);
|
|
1537
|
-
const decipher =
|
|
1662
|
+
const decipher = crypto6.createDecipheriv("aes-256-gcm", this.key, iv, {
|
|
1538
1663
|
authTagLength: TAG_LENGTH
|
|
1539
1664
|
});
|
|
1540
1665
|
decipher.setAuthTag(tag);
|
|
@@ -1655,7 +1780,7 @@ var ConsoleCommandJob = class extends JobType {
|
|
|
1655
1780
|
}
|
|
1656
1781
|
async run(input, ctx) {
|
|
1657
1782
|
ctx.notifier.info(`Executing console command: ${input.kind}`);
|
|
1658
|
-
await new Promise((
|
|
1783
|
+
await new Promise((resolve3) => setTimeout(resolve3, 2e3));
|
|
1659
1784
|
ctx.notifier.info(`Console command executed: ${input.kind}`);
|
|
1660
1785
|
ctx.notifier.success(`Console command executed: ${input.kind}`);
|
|
1661
1786
|
return new ConsoleCommandOutput(true);
|
|
@@ -1685,7 +1810,7 @@ var ContactServerJob = class extends JobType {
|
|
|
1685
1810
|
}
|
|
1686
1811
|
async run(input, ctx) {
|
|
1687
1812
|
ctx.notifier.info(`contact server mode=${input.mode}`, { scope: "system" /* System */ });
|
|
1688
|
-
await new Promise((
|
|
1813
|
+
await new Promise((resolve3) => setTimeout(resolve3, 200));
|
|
1689
1814
|
return new ContactServerOutput(true);
|
|
1690
1815
|
}
|
|
1691
1816
|
};
|
|
@@ -1713,7 +1838,7 @@ var SendServerResultJob = class extends JobType {
|
|
|
1713
1838
|
}
|
|
1714
1839
|
async run(input, ctx) {
|
|
1715
1840
|
ctx.notifier.info(`send result requestId=${input.requestId}`, { scope: "system" /* System */ });
|
|
1716
|
-
await new Promise((
|
|
1841
|
+
await new Promise((resolve3) => setTimeout(resolve3, 10));
|
|
1717
1842
|
return new SendServerResultOutput(true);
|
|
1718
1843
|
}
|
|
1719
1844
|
};
|
|
@@ -1732,8 +1857,8 @@ var ApiCall = class {
|
|
|
1732
1857
|
return this.handler(this.context, input);
|
|
1733
1858
|
}
|
|
1734
1859
|
};
|
|
1735
|
-
async function fetchJson(context,
|
|
1736
|
-
const url = `${context.configuration.controlBaseUrl}${
|
|
1860
|
+
async function fetchJson(context, path13, init) {
|
|
1861
|
+
const url = `${context.configuration.controlBaseUrl}${path13}`;
|
|
1737
1862
|
const res = await fetch(url, init);
|
|
1738
1863
|
if (!res.ok) {
|
|
1739
1864
|
const text = await res.text().catch(() => "");
|
|
@@ -1990,36 +2115,6 @@ var Api = class {
|
|
|
1990
2115
|
}
|
|
1991
2116
|
};
|
|
1992
2117
|
|
|
1993
|
-
// common/src/lib/utils/crypto.utils.ts
|
|
1994
|
-
import * as crypto6 from "node:crypto";
|
|
1995
|
-
function fingerprintFromPublicKeyPem(publicKeyPem) {
|
|
1996
|
-
const keyObj = crypto6.createPublicKey(publicKeyPem);
|
|
1997
|
-
if (keyObj.asymmetricKeyType !== "ed25519") {
|
|
1998
|
-
throw new Error(`Unexpected key type: ${keyObj.asymmetricKeyType}`);
|
|
1999
|
-
}
|
|
2000
|
-
const spkiDer = keyObj.export({ format: "der", type: "spki" });
|
|
2001
|
-
const hash = crypto6.createHash("sha256").update(spkiDer).digest("base64url");
|
|
2002
|
-
return hash.slice(0, 16).toUpperCase();
|
|
2003
|
-
}
|
|
2004
|
-
function signConnect(params) {
|
|
2005
|
-
const payload = Buffer.from(`${params.deviceId}|${params.ts}|${params.nonce}`, "utf8");
|
|
2006
|
-
const key = crypto6.createPrivateKey(params.privateKeyPem);
|
|
2007
|
-
const sig = crypto6.sign(null, payload, key);
|
|
2008
|
-
return sig.toString("base64");
|
|
2009
|
-
}
|
|
2010
|
-
function signRefresh(params) {
|
|
2011
|
-
const hash = crypto6.createHash("sha256").update(params.refreshToken, "utf8").digest("hex");
|
|
2012
|
-
const payload = Buffer.from(`${params.deviceId}|${params.ts}|${params.nonce}|${hash}`, "utf8");
|
|
2013
|
-
const key = crypto6.createPrivateKey(params.privateKeyPem);
|
|
2014
|
-
const sig = crypto6.sign(null, payload, key);
|
|
2015
|
-
return sig.toString("base64");
|
|
2016
|
-
}
|
|
2017
|
-
|
|
2018
|
-
// common/src/lib/utils/async.utils.ts
|
|
2019
|
-
function sleep(ms) {
|
|
2020
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2021
|
-
}
|
|
2022
|
-
|
|
2023
2118
|
// agent/src/cli/jobs/refreshTokens.ts
|
|
2024
2119
|
function isWrappedOk(x) {
|
|
2025
2120
|
if (typeof x !== "object" || x === null)
|
|
@@ -3578,7 +3673,7 @@ var RecoverableSocket = class {
|
|
|
3578
3673
|
}
|
|
3579
3674
|
async connectWebSocketOnce() {
|
|
3580
3675
|
const myConnId = ++this.connId;
|
|
3581
|
-
return new Promise((
|
|
3676
|
+
return new Promise((resolve3, reject) => {
|
|
3582
3677
|
if (this.stopped) {
|
|
3583
3678
|
reject(new Error("Socket is stopped"));
|
|
3584
3679
|
return;
|
|
@@ -3596,7 +3691,7 @@ var RecoverableSocket = class {
|
|
|
3596
3691
|
return;
|
|
3597
3692
|
settled = true;
|
|
3598
3693
|
cleanup();
|
|
3599
|
-
|
|
3694
|
+
resolve3();
|
|
3600
3695
|
};
|
|
3601
3696
|
const settleReject = (error, ws2) => {
|
|
3602
3697
|
if (settled)
|
|
@@ -4017,8 +4112,8 @@ var WebSocketOrchestrator = class {
|
|
|
4017
4112
|
|
|
4018
4113
|
// agent/src/cli/utils/configuration.writer.ts
|
|
4019
4114
|
import fs4 from "node:fs";
|
|
4020
|
-
import
|
|
4021
|
-
import
|
|
4115
|
+
import path6 from "node:path";
|
|
4116
|
+
import os5 from "node:os";
|
|
4022
4117
|
import defaultTo3 from "lodash/defaultTo.js";
|
|
4023
4118
|
var ConfigurationWriter = class {
|
|
4024
4119
|
/**
|
|
@@ -4027,7 +4122,7 @@ var ConfigurationWriter = class {
|
|
|
4027
4122
|
*/
|
|
4028
4123
|
static save(config) {
|
|
4029
4124
|
const configDir = this.getApplicationConfigFolder();
|
|
4030
|
-
const configPath =
|
|
4125
|
+
const configPath = path6.join(configDir, "config.json");
|
|
4031
4126
|
const safe = this.stripSecrets(config);
|
|
4032
4127
|
fs4.mkdirSync(configDir, { recursive: true });
|
|
4033
4128
|
fs4.writeFileSync(configPath, JSON.stringify(safe, null, 2), "utf8");
|
|
@@ -4054,9 +4149,9 @@ var ConfigurationWriter = class {
|
|
|
4054
4149
|
static getApplicationConfigFolder() {
|
|
4055
4150
|
const appData = defaultTo3(
|
|
4056
4151
|
process.env["APPDATA"],
|
|
4057
|
-
|
|
4152
|
+
path6.join(os5.homedir(), "AppData", "Roaming")
|
|
4058
4153
|
);
|
|
4059
|
-
return
|
|
4154
|
+
return path6.join(appData, "DeviceLink");
|
|
4060
4155
|
}
|
|
4061
4156
|
};
|
|
4062
4157
|
|
|
@@ -5526,7 +5621,7 @@ var AuthOrchestrator = class {
|
|
|
5526
5621
|
|
|
5527
5622
|
// agent/src/cli/orchestrators/tools/executers/fs-list.ts
|
|
5528
5623
|
import fs7 from "node:fs/promises";
|
|
5529
|
-
import
|
|
5624
|
+
import path9 from "node:path";
|
|
5530
5625
|
|
|
5531
5626
|
// agent/src/cli/orchestrators/tools/executers/base-executer.ts
|
|
5532
5627
|
var BaseExecuter = class {
|
|
@@ -5562,7 +5657,7 @@ var BaseExecuter = class {
|
|
|
5562
5657
|
};
|
|
5563
5658
|
|
|
5564
5659
|
// agent/src/cli/orchestrators/tools/util/ignore.ts
|
|
5565
|
-
import
|
|
5660
|
+
import path7 from "node:path";
|
|
5566
5661
|
import fs5 from "node:fs";
|
|
5567
5662
|
function matchesDefaultDenylist(relPath) {
|
|
5568
5663
|
const normalized = relPath.replace(/\\/g, "/");
|
|
@@ -5613,7 +5708,7 @@ function loadIgnoreRules(cfg, directory_id, workspace_id) {
|
|
|
5613
5708
|
return DEFAULT_IGNORE_PATTERNS;
|
|
5614
5709
|
}
|
|
5615
5710
|
const rules = [];
|
|
5616
|
-
const ignoreFilePath =
|
|
5711
|
+
const ignoreFilePath = path7.join(directory.path, ".devicelinkignore");
|
|
5617
5712
|
if (fs5.existsSync(ignoreFilePath)) {
|
|
5618
5713
|
try {
|
|
5619
5714
|
const content = fs5.readFileSync(ignoreFilePath, "utf-8");
|
|
@@ -5661,7 +5756,7 @@ function shouldIgnore(relPath, isDir, ctx, cfg) {
|
|
|
5661
5756
|
}
|
|
5662
5757
|
return { shouldIgnore: false };
|
|
5663
5758
|
}
|
|
5664
|
-
function matchesGlob(
|
|
5759
|
+
function matchesGlob(path13, pattern, isDir) {
|
|
5665
5760
|
let regexStr = "^";
|
|
5666
5761
|
let i = 0;
|
|
5667
5762
|
while (i < pattern.length) {
|
|
@@ -5688,15 +5783,15 @@ function matchesGlob(path11, pattern, isDir) {
|
|
|
5688
5783
|
regexStr += "$";
|
|
5689
5784
|
try {
|
|
5690
5785
|
const regex = new RegExp(regexStr, "i");
|
|
5691
|
-
return regex.test(
|
|
5786
|
+
return regex.test(path13);
|
|
5692
5787
|
} catch {
|
|
5693
|
-
return
|
|
5788
|
+
return path13.toLowerCase().includes(pattern.toLowerCase());
|
|
5694
5789
|
}
|
|
5695
5790
|
}
|
|
5696
5791
|
|
|
5697
5792
|
// agent/src/cli/orchestrators/tools/util/_util.ts
|
|
5698
5793
|
import fs6 from "node:fs/promises";
|
|
5699
|
-
import
|
|
5794
|
+
import path8 from "node:path";
|
|
5700
5795
|
function normalizeRelPath(input) {
|
|
5701
5796
|
const raw = (input ?? "").trim();
|
|
5702
5797
|
if (!raw)
|
|
@@ -5715,7 +5810,7 @@ function normalizeRelPath(input) {
|
|
|
5715
5810
|
});
|
|
5716
5811
|
}
|
|
5717
5812
|
const posixish = raw.replace(/\\/g, "/");
|
|
5718
|
-
const norm =
|
|
5813
|
+
const norm = path8.posix.normalize(posixish);
|
|
5719
5814
|
if (norm === ".." || norm.startsWith("../")) {
|
|
5720
5815
|
throw toolErr("PATH_ESCAPE", "Path escapes the root.", {
|
|
5721
5816
|
hint: 'Paths cannot use ".." to escape the configured root directory. Use paths relative to the root, like "src/file.ts" or "subdir/file.ts".'
|
|
@@ -5730,19 +5825,19 @@ function normalizeRelPath(input) {
|
|
|
5730
5825
|
}
|
|
5731
5826
|
async function resolveInRoot(rootPath, inputRel) {
|
|
5732
5827
|
const rel = normalizeRelPath(inputRel);
|
|
5733
|
-
const absRoot =
|
|
5828
|
+
const absRoot = path8.resolve(rootPath);
|
|
5734
5829
|
const realRoot = await fs6.realpath(absRoot);
|
|
5735
|
-
const candidate =
|
|
5736
|
-
const relToRoot =
|
|
5737
|
-
if (relToRoot.startsWith("..") ||
|
|
5830
|
+
const candidate = path8.resolve(realRoot, rel === "." ? "" : rel);
|
|
5831
|
+
const relToRoot = path8.relative(realRoot, candidate);
|
|
5832
|
+
if (relToRoot.startsWith("..") || path8.isAbsolute(relToRoot)) {
|
|
5738
5833
|
throw toolErr("PATH_ESCAPE", "Path escapes the root.", {
|
|
5739
5834
|
hint: "The resolved path escapes the configured root directory. Ensure the path stays within the root boundaries."
|
|
5740
5835
|
});
|
|
5741
5836
|
}
|
|
5742
5837
|
try {
|
|
5743
5838
|
const realCandidate = await fs6.realpath(candidate);
|
|
5744
|
-
const rel2 =
|
|
5745
|
-
if (rel2.startsWith("..") ||
|
|
5839
|
+
const rel2 = path8.relative(realRoot, realCandidate);
|
|
5840
|
+
if (rel2.startsWith("..") || path8.isAbsolute(rel2)) {
|
|
5746
5841
|
throw toolErr("PATH_ESCAPE", "Symlink/junction escape detected.", {
|
|
5747
5842
|
hint: "A symlink or junction in the path resolves outside the configured root directory. Ensure all symlinks stay within the root boundaries."
|
|
5748
5843
|
});
|
|
@@ -5755,16 +5850,16 @@ async function resolveInRoot(rootPath, inputRel) {
|
|
|
5755
5850
|
for (let i = parts.length; i > 0; i--) {
|
|
5756
5851
|
const parentRel = parts.slice(0, i).join("/");
|
|
5757
5852
|
const restRel = parts.slice(i).join("/");
|
|
5758
|
-
const parentCandidate =
|
|
5853
|
+
const parentCandidate = path8.resolve(realRoot, parentRel);
|
|
5759
5854
|
try {
|
|
5760
5855
|
const realParent = await fs6.realpath(parentCandidate);
|
|
5761
|
-
const relParent =
|
|
5762
|
-
if (relParent.startsWith("..") ||
|
|
5856
|
+
const relParent = path8.relative(realRoot, realParent);
|
|
5857
|
+
if (relParent.startsWith("..") || path8.isAbsolute(relParent)) {
|
|
5763
5858
|
throw toolErr("PATH_ESCAPE", "Symlink/junction escape detected.", {
|
|
5764
5859
|
hint: "A symlink or junction in the path resolves outside the configured root directory. Ensure all symlinks stay within the root boundaries."
|
|
5765
5860
|
});
|
|
5766
5861
|
}
|
|
5767
|
-
return { absTarget: restRel ?
|
|
5862
|
+
return { absTarget: restRel ? path8.join(realParent, restRel) : realParent, rel };
|
|
5768
5863
|
} catch (err) {
|
|
5769
5864
|
if (err?.code === "ENOENT")
|
|
5770
5865
|
continue;
|
|
@@ -5946,8 +6041,8 @@ var FsListExecuter = class extends BaseExecuter {
|
|
|
5946
6041
|
directory_path: directory.path
|
|
5947
6042
|
};
|
|
5948
6043
|
for (const d of visibleDirents) {
|
|
5949
|
-
const full =
|
|
5950
|
-
const rawRelPath = rel === "." ? d.name :
|
|
6044
|
+
const full = path9.join(absTarget, d.name);
|
|
6045
|
+
const rawRelPath = rel === "." ? d.name : path9.posix.join(rel, d.name);
|
|
5951
6046
|
const entryRelPath = rawRelPath.replace(/\\/g, "/");
|
|
5952
6047
|
let type = "other";
|
|
5953
6048
|
if (d.isDirectory())
|
|
@@ -5985,7 +6080,7 @@ var FsListExecuter = class extends BaseExecuter {
|
|
|
5985
6080
|
} catch {
|
|
5986
6081
|
}
|
|
5987
6082
|
}
|
|
5988
|
-
const ext = type === "file" ?
|
|
6083
|
+
const ext = type === "file" ? path9.extname(d.name).slice(1) : void 0;
|
|
5989
6084
|
if (ext && (detail === "stat" || detail === "digest")) {
|
|
5990
6085
|
extCounts.set(ext, (extCounts.get(ext) ?? 0) + 1);
|
|
5991
6086
|
}
|
|
@@ -6197,11 +6292,11 @@ var FsInfoExecuter = class extends BaseExecuter {
|
|
|
6197
6292
|
|
|
6198
6293
|
// agent/src/cli/orchestrators/tools/executers/fs-tree.ts
|
|
6199
6294
|
import fs11 from "node:fs/promises";
|
|
6200
|
-
import
|
|
6295
|
+
import path11 from "node:path";
|
|
6201
6296
|
|
|
6202
6297
|
// agent/src/cli/orchestrators/tools/executers/fs-grep.ts
|
|
6203
6298
|
import fs10 from "node:fs/promises";
|
|
6204
|
-
import
|
|
6299
|
+
import path10 from "node:path";
|
|
6205
6300
|
function matchesFileGlob(relPath, fileGlob) {
|
|
6206
6301
|
let regexStr = "^";
|
|
6207
6302
|
let i = 0;
|
|
@@ -6297,8 +6392,8 @@ async function grepDirectory(absPath, relPath, rootPath, query, mode, fileGlob,
|
|
|
6297
6392
|
for (const entry of entries) {
|
|
6298
6393
|
if (filesScanned.value >= maxFiles || matches.length >= maxMatches)
|
|
6299
6394
|
break;
|
|
6300
|
-
const entryAbsPath =
|
|
6301
|
-
const entryRelPath = relPath === "." ? entry.name :
|
|
6395
|
+
const entryAbsPath = path10.join(absPath, entry.name);
|
|
6396
|
+
const entryRelPath = relPath === "." ? entry.name : path10.posix.join(relPath, entry.name);
|
|
6302
6397
|
const ignoreResult = shouldIgnore(entryRelPath, entry.isDirectory(), ignoreCtx, cfg);
|
|
6303
6398
|
if (ignoreResult.shouldIgnore) {
|
|
6304
6399
|
ignoredCount.value++;
|
|
@@ -6591,10 +6686,10 @@ async function buildTree(absPath, relPath, depth, maxDepth, only, includeHidden,
|
|
|
6591
6686
|
const errorMessage = toolError2?.message ?? e?.message ?? String(e) ?? "Unknown error";
|
|
6592
6687
|
summary.total_entries++;
|
|
6593
6688
|
const node2 = {
|
|
6594
|
-
name:
|
|
6689
|
+
name: path11.basename(relPath) || relPath,
|
|
6595
6690
|
type: "other",
|
|
6596
6691
|
path: entryRel,
|
|
6597
|
-
hidden:
|
|
6692
|
+
hidden: path11.basename(relPath)?.startsWith("."),
|
|
6598
6693
|
ignored: false
|
|
6599
6694
|
};
|
|
6600
6695
|
if (errorMap) {
|
|
@@ -6628,10 +6723,10 @@ async function buildTree(absPath, relPath, depth, maxDepth, only, includeHidden,
|
|
|
6628
6723
|
summary.dirs++;
|
|
6629
6724
|
else if (type === "symlink")
|
|
6630
6725
|
summary.symlinks++;
|
|
6631
|
-
const isHidden =
|
|
6726
|
+
const isHidden = path11.basename(relPath)?.startsWith(".");
|
|
6632
6727
|
if (isHidden)
|
|
6633
6728
|
summary.hidden++;
|
|
6634
|
-
const ext = type === "file" ?
|
|
6729
|
+
const ext = type === "file" ? path11.extname(path11.basename(relPath) || relPath).slice(1) : void 0;
|
|
6635
6730
|
if (ext && (detail === "stat" || detail === "digest")) {
|
|
6636
6731
|
extCounts.set(ext, (extCounts.get(ext) ?? 0) + 1);
|
|
6637
6732
|
}
|
|
@@ -6639,7 +6734,7 @@ async function buildTree(absPath, relPath, depth, maxDepth, only, includeHidden,
|
|
|
6639
6734
|
summary.total_file_bytes = (summary.total_file_bytes ?? 0) + (stat.size ?? 0);
|
|
6640
6735
|
}
|
|
6641
6736
|
const node = {
|
|
6642
|
-
name:
|
|
6737
|
+
name: path11.basename(relPath) || relPath,
|
|
6643
6738
|
type,
|
|
6644
6739
|
path: entryRel,
|
|
6645
6740
|
size: (detail === "stat" || detail === "digest") && stat.isFile() ? stat.size : void 0,
|
|
@@ -6686,8 +6781,8 @@ async function buildTree(absPath, relPath, depth, maxDepth, only, includeHidden,
|
|
|
6686
6781
|
for (const entry of filtered) {
|
|
6687
6782
|
if (currentCount.value >= maxEntries)
|
|
6688
6783
|
break;
|
|
6689
|
-
const childAbs =
|
|
6690
|
-
const childRelPath = relPath === "." ? entry.name :
|
|
6784
|
+
const childAbs = path11.join(absPath, entry.name);
|
|
6785
|
+
const childRelPath = relPath === "." ? entry.name : path11.posix.join(relPath, entry.name);
|
|
6691
6786
|
const childRel = childRelPath.replace(/\\/g, "/");
|
|
6692
6787
|
const preIgnore = shouldIgnore(childRel, entry.isDirectory(), ignoreCtx, cfg);
|
|
6693
6788
|
if (preIgnore.shouldIgnore) {
|
|
@@ -6728,10 +6823,10 @@ async function buildTree(absPath, relPath, depth, maxDepth, only, includeHidden,
|
|
|
6728
6823
|
}
|
|
6729
6824
|
summary.total_entries++;
|
|
6730
6825
|
const errorNode = {
|
|
6731
|
-
name:
|
|
6826
|
+
name: path11.basename(childRelPath) || childRelPath,
|
|
6732
6827
|
type: "other",
|
|
6733
6828
|
path: childRel,
|
|
6734
|
-
hidden:
|
|
6829
|
+
hidden: path11.basename(childRelPath)?.startsWith("."),
|
|
6735
6830
|
ignored: false
|
|
6736
6831
|
};
|
|
6737
6832
|
if (only === "files" || only === "dirs") {
|
|
@@ -6918,7 +7013,7 @@ var FsTreeExecuter = class extends BaseExecuter {
|
|
|
6918
7013
|
|
|
6919
7014
|
// agent/src/cli/orchestrators/tools/executers/fs-search.ts
|
|
6920
7015
|
import fs12 from "node:fs/promises";
|
|
6921
|
-
import
|
|
7016
|
+
import path12 from "node:path";
|
|
6922
7017
|
function matchesGlob2(name, pattern) {
|
|
6923
7018
|
let regexStr = "^";
|
|
6924
7019
|
let i = 0;
|
|
@@ -7040,8 +7135,8 @@ async function searchDirectory(absPath, relPath, rootPath, query, mode, recursiv
|
|
|
7040
7135
|
for (const entry of visibleEntries) {
|
|
7041
7136
|
if (results.length >= maxResults)
|
|
7042
7137
|
break;
|
|
7043
|
-
const entryAbsPath =
|
|
7044
|
-
const entryRelPath = relPath === "." ? entry.name :
|
|
7138
|
+
const entryAbsPath = path12.join(absPath, entry.name);
|
|
7139
|
+
const entryRelPath = relPath === "." ? entry.name : path12.posix.join(relPath, entry.name);
|
|
7045
7140
|
const ignoreResult = shouldIgnore(entryRelPath, entry.isDirectory(), ignoreCtx, cfg);
|
|
7046
7141
|
if (ignoreResult.shouldIgnore) {
|
|
7047
7142
|
ignoredCount.value++;
|
|
@@ -7091,7 +7186,7 @@ async function searchDirectory(absPath, relPath, rootPath, query, mode, recursiv
|
|
|
7091
7186
|
} catch {
|
|
7092
7187
|
}
|
|
7093
7188
|
}
|
|
7094
|
-
const ext = type === "file" ?
|
|
7189
|
+
const ext = type === "file" ? path12.extname(entry.name).slice(1) : void 0;
|
|
7095
7190
|
const score = calculateScore({ name: entry.name, path: entryRelPath }, preferPaths, avoidPaths);
|
|
7096
7191
|
results.push({
|
|
7097
7192
|
name: entry.name,
|
|
@@ -7159,8 +7254,8 @@ var FsSearchExecuter = class extends BaseExecuter {
|
|
|
7159
7254
|
const st = await fs12.stat(absTarget);
|
|
7160
7255
|
if (!st.isDirectory()) {
|
|
7161
7256
|
if (st.isFile()) {
|
|
7162
|
-
searchPath =
|
|
7163
|
-
const parentRelPath =
|
|
7257
|
+
searchPath = path12.dirname(absTarget);
|
|
7258
|
+
const parentRelPath = path12.posix.dirname(rel);
|
|
7164
7259
|
searchRelPath = parentRelPath === "." ? "." : parentRelPath;
|
|
7165
7260
|
messages.push({
|
|
7166
7261
|
type: "warning",
|
|
@@ -7455,7 +7550,7 @@ var FsListResult = class extends BaseToolResult {
|
|
|
7455
7550
|
const itemCount = items?.length ?? 0;
|
|
7456
7551
|
const totalCount = meta?.count ?? 0;
|
|
7457
7552
|
const ignoredCount = filtered?.ignored_count ?? 0;
|
|
7458
|
-
const
|
|
7553
|
+
const path13 = context?.path ?? "unknown";
|
|
7459
7554
|
const parts = [];
|
|
7460
7555
|
if (itemCount > 0) {
|
|
7461
7556
|
parts.push(`${itemCount} item${itemCount !== 1 ? "s" : ""}`);
|
|
@@ -7467,7 +7562,7 @@ var FsListResult = class extends BaseToolResult {
|
|
|
7467
7562
|
parts.push("has_more");
|
|
7468
7563
|
}
|
|
7469
7564
|
const description = parts.length > 0 ? parts.join(", ") : "empty";
|
|
7470
|
-
return `path=${
|
|
7565
|
+
return `path=${path13}, ${description}`;
|
|
7471
7566
|
}
|
|
7472
7567
|
};
|
|
7473
7568
|
|
|
@@ -7490,10 +7585,10 @@ var FsReadResult = class extends BaseToolResult {
|
|
|
7490
7585
|
return "no result";
|
|
7491
7586
|
}
|
|
7492
7587
|
const { bytes_read, eof, context } = this.output;
|
|
7493
|
-
const
|
|
7588
|
+
const path13 = context?.path ?? "unknown";
|
|
7494
7589
|
const size = bytes_read ?? 0;
|
|
7495
7590
|
const truncated = !eof;
|
|
7496
|
-
const parts = [`path=${
|
|
7591
|
+
const parts = [`path=${path13}`, `${size} bytes`];
|
|
7497
7592
|
if (truncated) {
|
|
7498
7593
|
parts.push("truncated");
|
|
7499
7594
|
}
|
|
@@ -7520,9 +7615,9 @@ var FsInfoResult = class extends BaseToolResult {
|
|
|
7520
7615
|
return "no result";
|
|
7521
7616
|
}
|
|
7522
7617
|
const { type, size, context } = this.output;
|
|
7523
|
-
const
|
|
7618
|
+
const path13 = context?.path ?? "unknown";
|
|
7524
7619
|
const sizeStr = size !== void 0 ? `${size} bytes` : "no size";
|
|
7525
|
-
return `path=${
|
|
7620
|
+
return `path=${path13}, type=${type}, ${sizeStr}`;
|
|
7526
7621
|
}
|
|
7527
7622
|
};
|
|
7528
7623
|
|
|
@@ -7545,9 +7640,9 @@ var FsTreeResult = class extends BaseToolResult {
|
|
|
7545
7640
|
return "no result";
|
|
7546
7641
|
}
|
|
7547
7642
|
const { tree, filtered, summary, context } = this.output;
|
|
7548
|
-
const
|
|
7643
|
+
const path13 = context?.path ?? "unknown";
|
|
7549
7644
|
const ignoredCount = filtered?.ignored_count ?? 0;
|
|
7550
|
-
const parts = [`path=${
|
|
7645
|
+
const parts = [`path=${path13}`];
|
|
7551
7646
|
if (summary) {
|
|
7552
7647
|
const { total_entries, files, dirs } = summary;
|
|
7553
7648
|
if (total_entries !== void 0) {
|
|
@@ -7601,10 +7696,10 @@ var FsSearchResult = class extends BaseToolResult {
|
|
|
7601
7696
|
return "no result";
|
|
7602
7697
|
}
|
|
7603
7698
|
const { results, meta, filtered, context } = this.output;
|
|
7604
|
-
const
|
|
7699
|
+
const path13 = context?.path ?? "unknown";
|
|
7605
7700
|
const resultCount = results?.length ?? 0;
|
|
7606
7701
|
const ignoredCount = filtered?.ignored_count ?? 0;
|
|
7607
|
-
const parts = [`path=${
|
|
7702
|
+
const parts = [`path=${path13}`, `${resultCount} result${resultCount !== 1 ? "s" : ""}`];
|
|
7608
7703
|
if (ignoredCount > 0) {
|
|
7609
7704
|
parts.push(`${ignoredCount} ignored`);
|
|
7610
7705
|
}
|
|
@@ -7634,12 +7729,12 @@ var FsGrepResult = class extends BaseToolResult {
|
|
|
7634
7729
|
return "no result";
|
|
7635
7730
|
}
|
|
7636
7731
|
const { matches, meta, filtered, context } = this.output;
|
|
7637
|
-
const
|
|
7732
|
+
const path13 = context?.path ?? "unknown";
|
|
7638
7733
|
const matchCount = matches?.length ?? 0;
|
|
7639
7734
|
const filesScanned = meta?.files_scanned ?? 0;
|
|
7640
7735
|
const ignoredCount = filtered?.ignored_count ?? 0;
|
|
7641
7736
|
const parts = [
|
|
7642
|
-
`path=${
|
|
7737
|
+
`path=${path13}`,
|
|
7643
7738
|
`${matchCount} match${matchCount !== 1 ? "es" : ""}`,
|
|
7644
7739
|
`${filesScanned} file${filesScanned !== 1 ? "s" : ""} scanned`
|
|
7645
7740
|
];
|
|
@@ -8004,7 +8099,7 @@ var DirectoriesJob = class extends JobType {
|
|
|
8004
8099
|
return {
|
|
8005
8100
|
id: r.id,
|
|
8006
8101
|
name: r.name,
|
|
8007
|
-
path: r.path,
|
|
8102
|
+
path: toTildeHomePath(r.path) ?? r.name,
|
|
8008
8103
|
path_hint: r.tag || void 0
|
|
8009
8104
|
};
|
|
8010
8105
|
});
|