@moxt-ai/mobius 0.0.9 → 0.0.10
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/dist/acp/session-manager.d.ts.map +1 -1
- package/dist/acp/session-manager.js +11 -2
- package/dist/acp/session-manager.js.map +1 -1
- package/dist/agent-catalog/agent-diagnostics.d.ts.map +1 -1
- package/dist/agent-catalog/agent-diagnostics.js +6 -2
- package/dist/agent-catalog/agent-diagnostics.js.map +1 -1
- package/dist/agent-catalog/discover-local-agents.d.ts +35 -7
- package/dist/agent-catalog/discover-local-agents.d.ts.map +1 -1
- package/dist/agent-catalog/discover-local-agents.js +137 -26
- package/dist/agent-catalog/discover-local-agents.js.map +1 -1
- package/dist/agent-catalog/local-agent.d.ts +2 -1
- package/dist/agent-catalog/local-agent.d.ts.map +1 -1
- package/dist/agent-catalog/local-agent.js +7 -1
- package/dist/agent-catalog/local-agent.js.map +1 -1
- package/dist/agent-installation/fixed-agent-install-recipes.d.ts +1 -0
- package/dist/agent-installation/fixed-agent-install-recipes.d.ts.map +1 -1
- package/dist/agent-installation/fixed-agent-install-recipes.js +48 -0
- package/dist/agent-installation/fixed-agent-install-recipes.js.map +1 -1
- package/dist/agent-installation/fixed-installation-executor.d.ts.map +1 -1
- package/dist/agent-installation/fixed-installation-executor.js +2 -0
- package/dist/agent-installation/fixed-installation-executor.js.map +1 -1
- package/dist/agent-installation/managed-adapter-installer.d.ts +3 -2
- package/dist/agent-installation/managed-adapter-installer.d.ts.map +1 -1
- package/dist/agent-installation/managed-adapter-installer.js +25 -126
- package/dist/agent-installation/managed-adapter-installer.js.map +1 -1
- package/dist/agent-installation/managed-npm-package.d.ts +24 -0
- package/dist/agent-installation/managed-npm-package.d.ts.map +1 -0
- package/dist/agent-installation/managed-npm-package.js +227 -0
- package/dist/agent-installation/managed-npm-package.js.map +1 -0
- package/dist/agent-installation/pi-managed-packages.d.ts +4 -0
- package/dist/agent-installation/pi-managed-packages.d.ts.map +1 -0
- package/dist/agent-installation/pi-managed-packages.js +4 -0
- package/dist/agent-installation/pi-managed-packages.js.map +1 -0
- package/dist/cli.js +610 -159
- package/dist/cli.js.map +4 -4
- package/dist/index.js +601 -152
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -10,11 +10,12 @@ import { mkdir as mkdir4 } from "node:fs/promises";
|
|
|
10
10
|
|
|
11
11
|
// src/agent-catalog/discover-local-agents.ts
|
|
12
12
|
import { spawn as spawn2 } from "node:child_process";
|
|
13
|
-
import { isAbsolute, join as
|
|
13
|
+
import { isAbsolute as isAbsolute2, join as join6 } from "node:path";
|
|
14
14
|
import {
|
|
15
15
|
methods as methods2,
|
|
16
16
|
ndJsonStream,
|
|
17
|
-
PROTOCOL_VERSION
|
|
17
|
+
PROTOCOL_VERSION,
|
|
18
|
+
RequestError
|
|
18
19
|
} from "@agentclientprotocol/sdk";
|
|
19
20
|
|
|
20
21
|
// src/acp/create-client.ts
|
|
@@ -77,6 +78,9 @@ async function readGrantedAgents(stateDirectory) {
|
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
// src/agent-installation/managed-adapter-installer.ts
|
|
81
|
+
import { join as join4 } from "node:path";
|
|
82
|
+
|
|
83
|
+
// src/agent-installation/managed-npm-package.ts
|
|
80
84
|
import {
|
|
81
85
|
mkdir,
|
|
82
86
|
mkdtemp,
|
|
@@ -86,7 +90,7 @@ import {
|
|
|
86
90
|
rm,
|
|
87
91
|
stat as stat2
|
|
88
92
|
} from "node:fs/promises";
|
|
89
|
-
import { delimiter, dirname, join as join3, relative } from "node:path";
|
|
93
|
+
import { delimiter, dirname, isAbsolute, join as join3, relative, sep } from "node:path";
|
|
90
94
|
|
|
91
95
|
// src/process/executable.ts
|
|
92
96
|
import { spawn } from "node:child_process";
|
|
@@ -424,15 +428,35 @@ async function runBoundedProcess(options) {
|
|
|
424
428
|
}
|
|
425
429
|
}
|
|
426
430
|
|
|
427
|
-
// src/agent-installation/managed-
|
|
428
|
-
var
|
|
431
|
+
// src/agent-installation/managed-npm-package.ts
|
|
432
|
+
var INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
|
|
429
433
|
var PACKAGE_METADATA_LIMIT_BYTES = 64 * 1024;
|
|
430
|
-
var
|
|
434
|
+
var PACKAGE_LOCK_LIMIT_BYTES = 8 * 1024 * 1024;
|
|
435
|
+
var ManagedNpmPackageDefinition = class {
|
|
436
|
+
executableName;
|
|
437
|
+
packageName;
|
|
438
|
+
version;
|
|
439
|
+
constructor(packageName, version2, executableName) {
|
|
440
|
+
this.executableName = executableName;
|
|
441
|
+
this.packageName = packageName;
|
|
442
|
+
this.version = version2;
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
var SriManagedNpmPackageDefinition = class extends ManagedNpmPackageDefinition {
|
|
446
|
+
integrity;
|
|
447
|
+
tarballUrl;
|
|
448
|
+
constructor(packageName, version2, executableName, integrity, tarballUrl) {
|
|
449
|
+
super(packageName, version2, executableName);
|
|
450
|
+
this.integrity = integrity;
|
|
451
|
+
this.tarballUrl = tarballUrl;
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
var ManagedNpmPackageError = class extends Error {
|
|
431
455
|
code;
|
|
432
456
|
constructor(code, message, options = {}) {
|
|
433
457
|
super(message, options);
|
|
434
458
|
this.code = code;
|
|
435
|
-
this.name = "
|
|
459
|
+
this.name = "ManagedNpmPackageError";
|
|
436
460
|
}
|
|
437
461
|
};
|
|
438
462
|
function isRecord2(value) {
|
|
@@ -441,28 +465,43 @@ function isRecord2(value) {
|
|
|
441
465
|
function packagePath(root, packageName) {
|
|
442
466
|
return join3(root, "node_modules", ...packageName.split("/"));
|
|
443
467
|
}
|
|
444
|
-
|
|
445
|
-
const
|
|
468
|
+
function isContainedPath(root, candidate) {
|
|
469
|
+
const difference = relative(root, candidate);
|
|
470
|
+
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep}`) && !isAbsolute(difference);
|
|
471
|
+
}
|
|
472
|
+
async function readJsonRecord(path2, maximumBytes) {
|
|
446
473
|
try {
|
|
447
|
-
const
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
474
|
+
const handle = await open2(path2, "r");
|
|
475
|
+
try {
|
|
476
|
+
const metadata = await handle.stat();
|
|
477
|
+
if (!metadata.isFile() || metadata.size > maximumBytes) {
|
|
478
|
+
throw new ManagedNpmPackageError(
|
|
479
|
+
"managed_package_verification_failed",
|
|
480
|
+
"The managed npm package metadata is invalid"
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
const value = JSON.parse(
|
|
484
|
+
await handle.readFile({ encoding: "utf8" })
|
|
452
485
|
);
|
|
486
|
+
if (!isRecord2(value)) {
|
|
487
|
+
throw new ManagedNpmPackageError(
|
|
488
|
+
"managed_package_verification_failed",
|
|
489
|
+
"The managed npm package metadata is invalid"
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
return value;
|
|
493
|
+
} finally {
|
|
494
|
+
await handle.close();
|
|
453
495
|
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
if (!isRecord2(value)) {
|
|
458
|
-
throw new ManagedAdapterInstallError(
|
|
459
|
-
"adapter_verification_failed",
|
|
460
|
-
"The managed adapter package metadata is invalid"
|
|
461
|
-
);
|
|
496
|
+
} catch (error61) {
|
|
497
|
+
if (error61 instanceof ManagedNpmPackageError) {
|
|
498
|
+
throw error61;
|
|
462
499
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
500
|
+
throw new ManagedNpmPackageError(
|
|
501
|
+
"managed_package_verification_failed",
|
|
502
|
+
"The managed npm package metadata is invalid",
|
|
503
|
+
{ cause: error61 }
|
|
504
|
+
);
|
|
466
505
|
}
|
|
467
506
|
}
|
|
468
507
|
function readBinPath(packageMetadata, executableName) {
|
|
@@ -473,83 +512,125 @@ function readBinPath(packageMetadata, executableName) {
|
|
|
473
512
|
if (isRecord2(bin) && typeof bin[executableName] === "string") {
|
|
474
513
|
return bin[executableName];
|
|
475
514
|
}
|
|
476
|
-
throw new
|
|
477
|
-
"
|
|
478
|
-
"The managed
|
|
515
|
+
throw new ManagedNpmPackageError(
|
|
516
|
+
"managed_package_verification_failed",
|
|
517
|
+
"The managed npm package executable declaration is invalid"
|
|
479
518
|
);
|
|
480
519
|
}
|
|
481
|
-
|
|
520
|
+
function verifyPackageLock(lock, definition) {
|
|
521
|
+
if (lock["lockfileVersion"] !== 3) {
|
|
522
|
+
throw new ManagedNpmPackageError(
|
|
523
|
+
"managed_package_verification_failed",
|
|
524
|
+
"The managed npm package lockfile is invalid"
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
const packages = lock["packages"];
|
|
528
|
+
if (!isRecord2(packages)) {
|
|
529
|
+
throw new ManagedNpmPackageError(
|
|
530
|
+
"managed_package_verification_failed",
|
|
531
|
+
"The managed npm package lockfile is invalid"
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
const suffix = `node_modules/${definition.packageName}`;
|
|
535
|
+
let entry;
|
|
536
|
+
let matches = 0;
|
|
537
|
+
for (const [key, candidate] of Object.entries(packages)) {
|
|
538
|
+
const normalizedKey = key.replaceAll("\\", "/");
|
|
539
|
+
if (normalizedKey === suffix || normalizedKey.endsWith(`/${suffix}`)) {
|
|
540
|
+
entry = candidate;
|
|
541
|
+
matches += 1;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
if (matches !== 1 || !isRecord2(entry) || entry["integrity"] !== definition.integrity || entry["resolved"] !== definition.tarballUrl || entry["version"] !== definition.version) {
|
|
545
|
+
throw new ManagedNpmPackageError(
|
|
546
|
+
"managed_package_verification_failed",
|
|
547
|
+
"The managed npm package lockfile does not match the pinned artifact"
|
|
548
|
+
);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
async function validateManagedNpmPackage(root, definition) {
|
|
552
|
+
try {
|
|
553
|
+
return await validateManagedNpmPackageContents(root, definition);
|
|
554
|
+
} catch (error61) {
|
|
555
|
+
if (error61 instanceof ManagedNpmPackageError) {
|
|
556
|
+
throw error61;
|
|
557
|
+
}
|
|
558
|
+
throw new ManagedNpmPackageError(
|
|
559
|
+
"managed_package_verification_failed",
|
|
560
|
+
"The managed npm package is invalid",
|
|
561
|
+
{ cause: error61 }
|
|
562
|
+
);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
async function validateManagedNpmPackageContents(root, definition) {
|
|
482
566
|
const rootPath = await realpath2(root);
|
|
483
567
|
const packageRoot = await realpath2(
|
|
484
|
-
packagePath(rootPath,
|
|
568
|
+
packagePath(rootPath, definition.packageName)
|
|
569
|
+
);
|
|
570
|
+
if (!isContainedPath(rootPath, packageRoot)) {
|
|
571
|
+
throw new ManagedNpmPackageError(
|
|
572
|
+
"managed_package_verification_failed",
|
|
573
|
+
"The managed npm package escaped its private cache"
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
const metadata = await readJsonRecord(
|
|
577
|
+
join3(packageRoot, "package.json"),
|
|
578
|
+
PACKAGE_METADATA_LIMIT_BYTES
|
|
485
579
|
);
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
"
|
|
490
|
-
"The managed adapter package escaped its private cache"
|
|
580
|
+
if (metadata["name"] !== definition.packageName || metadata["version"] !== definition.version) {
|
|
581
|
+
throw new ManagedNpmPackageError(
|
|
582
|
+
"managed_package_verification_failed",
|
|
583
|
+
"The managed npm package identity is invalid"
|
|
491
584
|
);
|
|
492
585
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
586
|
+
if (definition instanceof SriManagedNpmPackageDefinition) {
|
|
587
|
+
verifyPackageLock(
|
|
588
|
+
await readJsonRecord(
|
|
589
|
+
join3(rootPath, "package-lock.json"),
|
|
590
|
+
PACKAGE_LOCK_LIMIT_BYTES
|
|
591
|
+
),
|
|
592
|
+
definition
|
|
498
593
|
);
|
|
499
594
|
}
|
|
500
|
-
const declaredBin = readBinPath(metadata,
|
|
595
|
+
const declaredBin = readBinPath(metadata, definition.executableName);
|
|
501
596
|
const executable = await resolveExecutablePath(
|
|
502
597
|
join3(packageRoot, declaredBin)
|
|
503
598
|
);
|
|
504
|
-
if (executable === null) {
|
|
505
|
-
throw new
|
|
506
|
-
"
|
|
507
|
-
"The managed
|
|
508
|
-
);
|
|
509
|
-
}
|
|
510
|
-
const executableDifference = relative(rootPath, executable.path);
|
|
511
|
-
if (executableDifference.startsWith("..") || executableDifference.length === 0) {
|
|
512
|
-
throw new ManagedAdapterInstallError(
|
|
513
|
-
"adapter_verification_failed",
|
|
514
|
-
"The managed adapter executable escaped its private cache"
|
|
599
|
+
if (executable === null || !isContainedPath(rootPath, executable.path)) {
|
|
600
|
+
throw new ManagedNpmPackageError(
|
|
601
|
+
"managed_package_verification_failed",
|
|
602
|
+
"The managed npm package executable is invalid"
|
|
515
603
|
);
|
|
516
604
|
}
|
|
517
605
|
return executable;
|
|
518
606
|
}
|
|
519
|
-
var
|
|
520
|
-
|
|
521
|
-
#stateDirectory;
|
|
522
|
-
constructor(options) {
|
|
523
|
-
this.#environment = options.environment;
|
|
524
|
-
this.#stateDirectory = options.stateDirectory;
|
|
525
|
-
}
|
|
526
|
-
install = async (specification, signal) => {
|
|
607
|
+
var ManagedNpmPackageInstaller = class {
|
|
608
|
+
install = async (root, definition, environment, signal) => {
|
|
527
609
|
signal.throwIfAborted();
|
|
528
|
-
const agentCache = join3(this.#stateDirectory, "adapters", specification.id);
|
|
529
|
-
const published = join3(agentCache, specification.adapterVersion);
|
|
530
610
|
try {
|
|
531
|
-
const metadata = await stat2(
|
|
611
|
+
const metadata = await stat2(root);
|
|
532
612
|
if (metadata.isDirectory()) {
|
|
533
|
-
return await
|
|
613
|
+
return await validateManagedNpmPackage(root, definition);
|
|
534
614
|
}
|
|
535
615
|
} catch (error61) {
|
|
536
616
|
if (!(error61 instanceof Error) || !("code" in error61) || error61.code !== "ENOENT") {
|
|
537
617
|
throw error61;
|
|
538
618
|
}
|
|
539
619
|
}
|
|
540
|
-
|
|
620
|
+
const parent = dirname(root);
|
|
621
|
+
await mkdir(parent, { mode: 448, recursive: true });
|
|
541
622
|
const staging = await mkdtemp(
|
|
542
|
-
join3(
|
|
623
|
+
join3(parent, `.${definition.version}.staging-`)
|
|
543
624
|
);
|
|
544
625
|
try {
|
|
545
626
|
const npm = await findExecutableOnPath(
|
|
546
627
|
process.platform === "win32" ? "npm.cmd" : "npm",
|
|
547
|
-
|
|
628
|
+
environment
|
|
548
629
|
);
|
|
549
630
|
if (npm === null) {
|
|
550
|
-
throw new
|
|
631
|
+
throw new ManagedNpmPackageError(
|
|
551
632
|
"package_manager_not_found",
|
|
552
|
-
"A supported npm executable is required to install the
|
|
633
|
+
"A supported npm executable is required to install the managed package"
|
|
553
634
|
);
|
|
554
635
|
}
|
|
555
636
|
await runBoundedProcess({
|
|
@@ -561,51 +642,57 @@ var ManagedAdapterInstaller = class {
|
|
|
561
642
|
"--ignore-scripts",
|
|
562
643
|
"--no-audit",
|
|
563
644
|
"--no-fund",
|
|
564
|
-
"--package-lock=
|
|
565
|
-
"--save
|
|
645
|
+
"--package-lock=true",
|
|
646
|
+
"--save-exact",
|
|
566
647
|
"--registry=https://registry.npmjs.org/",
|
|
567
|
-
`${
|
|
648
|
+
`${definition.packageName}@${definition.version}`
|
|
568
649
|
],
|
|
569
650
|
command: npm.path,
|
|
570
651
|
cwd: staging,
|
|
571
652
|
environment: {
|
|
572
653
|
HOME: join3(staging, "home"),
|
|
573
654
|
NPM_CONFIG_AUDIT: "false",
|
|
655
|
+
NPM_CONFIG_CACHE: join3(staging, ".npm-cache"),
|
|
574
656
|
NPM_CONFIG_FUND: "false",
|
|
575
657
|
NPM_CONFIG_IGNORE_SCRIPTS: "true",
|
|
576
658
|
NPM_CONFIG_OMIT: "optional",
|
|
659
|
+
NPM_CONFIG_PACKAGE_LOCK: "true",
|
|
577
660
|
NPM_CONFIG_REGISTRY: "https://registry.npmjs.org/",
|
|
578
661
|
PATH: `${dirname(process.execPath)}${delimiter}/usr/bin${delimiter}/bin`
|
|
579
662
|
},
|
|
580
663
|
outputLimitBytes: 64 * 1024,
|
|
581
664
|
signal,
|
|
582
|
-
timeoutMilliseconds:
|
|
665
|
+
timeoutMilliseconds: INSTALL_TIMEOUT_MILLISECONDS
|
|
583
666
|
});
|
|
584
|
-
await
|
|
667
|
+
await Promise.all([
|
|
668
|
+
rm(join3(staging, ".npm-cache"), { force: true, recursive: true }),
|
|
669
|
+
rm(join3(staging, "home"), { force: true, recursive: true })
|
|
670
|
+
]);
|
|
671
|
+
await validateManagedNpmPackage(staging, definition);
|
|
585
672
|
try {
|
|
586
|
-
await rename(staging,
|
|
673
|
+
await rename(staging, root);
|
|
587
674
|
} catch (error61) {
|
|
588
675
|
try {
|
|
589
|
-
return await
|
|
676
|
+
return await validateManagedNpmPackage(root, definition);
|
|
590
677
|
} catch {
|
|
591
|
-
throw new
|
|
592
|
-
"
|
|
593
|
-
"The managed
|
|
678
|
+
throw new ManagedNpmPackageError(
|
|
679
|
+
"managed_package_publish_failed",
|
|
680
|
+
"The managed npm package could not be published",
|
|
594
681
|
{ cause: error61 }
|
|
595
682
|
);
|
|
596
683
|
}
|
|
597
684
|
}
|
|
598
|
-
return await
|
|
685
|
+
return await validateManagedNpmPackage(root, definition);
|
|
599
686
|
} catch (error61) {
|
|
600
687
|
if (signal.aborted) {
|
|
601
688
|
signal.throwIfAborted();
|
|
602
689
|
}
|
|
603
|
-
if (error61 instanceof
|
|
690
|
+
if (error61 instanceof ManagedNpmPackageError) {
|
|
604
691
|
throw error61;
|
|
605
692
|
}
|
|
606
|
-
throw new
|
|
607
|
-
"
|
|
608
|
-
"The pinned
|
|
693
|
+
throw new ManagedNpmPackageError(
|
|
694
|
+
"managed_package_install_failed",
|
|
695
|
+
"The pinned npm package could not be installed",
|
|
609
696
|
{ cause: error61 }
|
|
610
697
|
);
|
|
611
698
|
} finally {
|
|
@@ -614,15 +701,115 @@ var ManagedAdapterInstaller = class {
|
|
|
614
701
|
};
|
|
615
702
|
};
|
|
616
703
|
|
|
704
|
+
// src/agent-installation/managed-adapter-installer.ts
|
|
705
|
+
var ManagedAdapterInstallError = class extends Error {
|
|
706
|
+
code;
|
|
707
|
+
constructor(code, message, options = {}) {
|
|
708
|
+
super(message, options);
|
|
709
|
+
this.code = code;
|
|
710
|
+
this.name = "ManagedAdapterInstallError";
|
|
711
|
+
}
|
|
712
|
+
};
|
|
713
|
+
function translateError(error61) {
|
|
714
|
+
if (error61 instanceof ManagedAdapterInstallError) {
|
|
715
|
+
return error61;
|
|
716
|
+
}
|
|
717
|
+
if (error61 instanceof ManagedNpmPackageError) {
|
|
718
|
+
if (error61.code === "package_manager_not_found") {
|
|
719
|
+
return new ManagedAdapterInstallError(
|
|
720
|
+
error61.code,
|
|
721
|
+
"A supported npm executable is required to install the ACP adapter",
|
|
722
|
+
{ cause: error61 }
|
|
723
|
+
);
|
|
724
|
+
}
|
|
725
|
+
if (error61.code === "managed_package_verification_failed") {
|
|
726
|
+
return new ManagedAdapterInstallError(
|
|
727
|
+
"adapter_verification_failed",
|
|
728
|
+
"The managed adapter did not match its pinned artifact",
|
|
729
|
+
{ cause: error61 }
|
|
730
|
+
);
|
|
731
|
+
}
|
|
732
|
+
if (error61.code === "managed_package_publish_failed") {
|
|
733
|
+
return new ManagedAdapterInstallError(
|
|
734
|
+
"adapter_publish_failed",
|
|
735
|
+
"The managed adapter could not be published",
|
|
736
|
+
{ cause: error61 }
|
|
737
|
+
);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
return new ManagedAdapterInstallError(
|
|
741
|
+
"adapter_install_failed",
|
|
742
|
+
"The pinned ACP adapter could not be installed",
|
|
743
|
+
{ cause: error61 }
|
|
744
|
+
);
|
|
745
|
+
}
|
|
746
|
+
async function validateManagedAdapter(root, specification) {
|
|
747
|
+
try {
|
|
748
|
+
return await validateManagedNpmPackage(
|
|
749
|
+
root,
|
|
750
|
+
specification.adapterPackageDefinition
|
|
751
|
+
);
|
|
752
|
+
} catch (error61) {
|
|
753
|
+
throw translateError(error61);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
var ManagedAdapterInstaller = class {
|
|
757
|
+
#environment;
|
|
758
|
+
#npmInstaller;
|
|
759
|
+
#stateDirectory;
|
|
760
|
+
constructor(options, npmInstaller = new ManagedNpmPackageInstaller()) {
|
|
761
|
+
this.#environment = options.environment;
|
|
762
|
+
this.#npmInstaller = npmInstaller;
|
|
763
|
+
this.#stateDirectory = options.stateDirectory;
|
|
764
|
+
}
|
|
765
|
+
install = async (specification, signal) => {
|
|
766
|
+
const root = join4(
|
|
767
|
+
this.#stateDirectory,
|
|
768
|
+
"adapters",
|
|
769
|
+
specification.id,
|
|
770
|
+
specification.adapterVersion
|
|
771
|
+
);
|
|
772
|
+
try {
|
|
773
|
+
return await this.#npmInstaller.install(
|
|
774
|
+
root,
|
|
775
|
+
specification.adapterPackageDefinition,
|
|
776
|
+
this.#environment,
|
|
777
|
+
signal
|
|
778
|
+
);
|
|
779
|
+
} catch (error61) {
|
|
780
|
+
if (signal.aborted) {
|
|
781
|
+
signal.throwIfAborted();
|
|
782
|
+
}
|
|
783
|
+
throw translateError(error61);
|
|
784
|
+
}
|
|
785
|
+
};
|
|
786
|
+
};
|
|
787
|
+
|
|
788
|
+
// src/agent-installation/pi-managed-packages.ts
|
|
789
|
+
var PI_ACP_PACKAGE = new SriManagedNpmPackageDefinition(
|
|
790
|
+
"pi-acp",
|
|
791
|
+
"0.0.33",
|
|
792
|
+
"pi-acp",
|
|
793
|
+
"sha512-vX9kY1tK14E72G4dBAx+RGCk/k7XPjTHls6dLUxA8WSkBav6B6JHuSBv3eusp50LCR/GTRsR2kIKsG0Z5jANzw==",
|
|
794
|
+
"https://registry.npmjs.org/pi-acp/-/pi-acp-0.0.33.tgz"
|
|
795
|
+
);
|
|
796
|
+
var PI_AGENT_PACKAGE = new SriManagedNpmPackageDefinition(
|
|
797
|
+
"@earendil-works/pi-coding-agent",
|
|
798
|
+
"0.85.0",
|
|
799
|
+
"pi",
|
|
800
|
+
"sha512-INxVkLAVfAMju5MojJpmyu/0bMP+r+ffZuS7UqVv32E2JwHBRbcHfELDfmFNvapEbgYfKN2r9OYO1p3TqDBR+g==",
|
|
801
|
+
"https://registry.npmjs.org/@earendil-works/pi-coding-agent/-/pi-coding-agent-0.85.0.tgz"
|
|
802
|
+
);
|
|
803
|
+
|
|
617
804
|
// src/storage/state-directory.ts
|
|
618
805
|
import { homedir } from "node:os";
|
|
619
|
-
import { join as
|
|
806
|
+
import { join as join5, resolve as resolve2 } from "node:path";
|
|
620
807
|
function readStateDirectory(environment = process.env) {
|
|
621
808
|
const configured = environment["MOBIUS_STATE_DIRECTORY"]?.trim();
|
|
622
809
|
if (configured !== void 0 && configured.length > 0) {
|
|
623
810
|
return resolve2(configured);
|
|
624
811
|
}
|
|
625
|
-
return
|
|
812
|
+
return join5(homedir(), ".mobius");
|
|
626
813
|
}
|
|
627
814
|
|
|
628
815
|
// src/agent-catalog/local-agent.ts
|
|
@@ -650,7 +837,11 @@ var LocalAgentDefinition = class {
|
|
|
650
837
|
environment;
|
|
651
838
|
id;
|
|
652
839
|
label;
|
|
653
|
-
|
|
840
|
+
promptTimeoutMilliseconds;
|
|
841
|
+
constructor(id, label, command, arguments_, environment = {}, adapterVersion = "", agentVersion = "", adapterIdentity = readTrustedIdentity(command), agentIdentity = adapterIdentity, promptTimeoutMilliseconds = 30 * 60 * 1e3) {
|
|
842
|
+
if (!Number.isSafeInteger(promptTimeoutMilliseconds) || promptTimeoutMilliseconds < 1) {
|
|
843
|
+
throw new Error("The local Agent prompt deadline is invalid");
|
|
844
|
+
}
|
|
654
845
|
this.adapterIdentity = adapterIdentity;
|
|
655
846
|
this.adapterPath = adapterIdentity.realPath;
|
|
656
847
|
this.adapterVersion = adapterVersion;
|
|
@@ -658,6 +849,7 @@ var LocalAgentDefinition = class {
|
|
|
658
849
|
this.agentVersion = agentVersion;
|
|
659
850
|
this.id = id;
|
|
660
851
|
this.label = label;
|
|
852
|
+
this.promptTimeoutMilliseconds = promptTimeoutMilliseconds;
|
|
661
853
|
this.command = adapterIdentity.realPath;
|
|
662
854
|
this.arguments = Object.freeze([...arguments_]);
|
|
663
855
|
this.environment = Object.freeze({ ...environment });
|
|
@@ -729,16 +921,48 @@ var LocalAgentCatalog = class {
|
|
|
729
921
|
var VERSION_PROBE_TIMEOUT_MILLISECONDS = 3e3;
|
|
730
922
|
var ACP_PROBE_TIMEOUT_MILLISECONDS = 5e3;
|
|
731
923
|
var ACP_OUTPUT_LIMIT_BYTES = 1024 * 1024;
|
|
924
|
+
var DEFAULT_PROMPT_TIMEOUT_MILLISECONDS = 30 * 60 * 1e3;
|
|
925
|
+
var PI_ACP_PROBE_TIMEOUT_MILLISECONDS = 3e4;
|
|
926
|
+
var PI_PROMPT_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
|
|
732
927
|
var LocalAgentSpecification = class {
|
|
928
|
+
acpProbeTimeoutMilliseconds = ACP_PROBE_TIMEOUT_MILLISECONDS;
|
|
929
|
+
authenticationCommand = () => "";
|
|
930
|
+
adapterVersionArguments = ["--version"];
|
|
931
|
+
agentVersionArguments = ["--version"];
|
|
932
|
+
promptTimeoutMilliseconds = DEFAULT_PROMPT_TIMEOUT_MILLISECONDS;
|
|
933
|
+
get adapterExecutable() {
|
|
934
|
+
return this.adapterPackageDefinition.executableName;
|
|
935
|
+
}
|
|
936
|
+
get adapterPackage() {
|
|
937
|
+
return this.adapterPackageDefinition.packageName;
|
|
938
|
+
}
|
|
939
|
+
get adapterVersion() {
|
|
940
|
+
return this.adapterPackageDefinition.version;
|
|
941
|
+
}
|
|
942
|
+
resolveManagedAgent = async (stateDirectory, platform) => {
|
|
943
|
+
const executable = await resolveExecutablePath(
|
|
944
|
+
join6(stateDirectory, ...this.managedAgentExecutablePath),
|
|
945
|
+
platform
|
|
946
|
+
);
|
|
947
|
+
if (executable === null) {
|
|
948
|
+
throw new Error("The managed Agent executable is unavailable");
|
|
949
|
+
}
|
|
950
|
+
return executable;
|
|
951
|
+
};
|
|
733
952
|
recoveryCommand = () => `npm install -g --omit=optional ${this.adapterPackage}@${this.adapterVersion}`;
|
|
734
953
|
supportsInstallation = (platform, architecture) => (platform === "darwin" || platform === "linux") && (architecture === "arm64" || architecture === "x64");
|
|
954
|
+
verifyAcp = (_connection, _initialized, _defaultWorkspace, _signal) => Promise.resolve();
|
|
735
955
|
};
|
|
736
|
-
var
|
|
956
|
+
var BridgedAcpAgentDefinition = class extends LocalAgentSpecification {
|
|
957
|
+
};
|
|
958
|
+
var CodexAgentSpecification = class extends BridgedAcpAgentDefinition {
|
|
737
959
|
adapterEnvironmentVariable = "CODEX_PATH";
|
|
738
|
-
adapterExecutable = "codex-acp";
|
|
739
960
|
adapterOverrideVariable = "MOBIUS_CODEX_ACP_PATH";
|
|
740
|
-
|
|
741
|
-
|
|
961
|
+
adapterPackageDefinition = new ManagedNpmPackageDefinition(
|
|
962
|
+
"@agentclientprotocol/codex-acp",
|
|
963
|
+
"1.8.0",
|
|
964
|
+
"codex-acp"
|
|
965
|
+
);
|
|
742
966
|
agentExecutable = "codex";
|
|
743
967
|
agentOverrideVariable = "MOBIUS_CODEX_PATH";
|
|
744
968
|
id = "codex";
|
|
@@ -755,12 +979,14 @@ var CodexAgentSpecification = class extends LocalAgentSpecification {
|
|
|
755
979
|
];
|
|
756
980
|
managedAgentExecutablePath = ["agents", "codex", "bin", "codex"];
|
|
757
981
|
};
|
|
758
|
-
var ClaudeCodeAgentSpecification = class extends
|
|
982
|
+
var ClaudeCodeAgentSpecification = class extends BridgedAcpAgentDefinition {
|
|
759
983
|
adapterEnvironmentVariable = "CLAUDE_CODE_EXECUTABLE";
|
|
760
|
-
adapterExecutable = "claude-agent-acp";
|
|
761
984
|
adapterOverrideVariable = "MOBIUS_CLAUDE_ACP_PATH";
|
|
762
|
-
|
|
763
|
-
|
|
985
|
+
adapterPackageDefinition = new ManagedNpmPackageDefinition(
|
|
986
|
+
"@agentclientprotocol/claude-agent-acp",
|
|
987
|
+
"0.73.0",
|
|
988
|
+
"claude-agent-acp"
|
|
989
|
+
);
|
|
764
990
|
agentExecutable = "claude";
|
|
765
991
|
agentOverrideVariable = "MOBIUS_CLAUDE_PATH";
|
|
766
992
|
id = "claude";
|
|
@@ -784,10 +1010,86 @@ var ClaudeCodeAgentSpecification = class extends LocalAgentSpecification {
|
|
|
784
1010
|
"claude"
|
|
785
1011
|
];
|
|
786
1012
|
};
|
|
1013
|
+
var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
|
|
1014
|
+
acpProbeTimeoutMilliseconds = PI_ACP_PROBE_TIMEOUT_MILLISECONDS;
|
|
1015
|
+
adapterEnvironmentVariable = "PI_ACP_PI_COMMAND";
|
|
1016
|
+
adapterOverrideVariable = "MOBIUS_PI_ACP_PATH";
|
|
1017
|
+
adapterPackageDefinition = PI_ACP_PACKAGE;
|
|
1018
|
+
adapterVersionArguments = [];
|
|
1019
|
+
authenticationCommand = () => "pi-acp --terminal-login";
|
|
1020
|
+
agentExecutable = "pi";
|
|
1021
|
+
agentOverrideVariable = "MOBIUS_PI_PATH";
|
|
1022
|
+
id = "pi";
|
|
1023
|
+
label = "Pi";
|
|
1024
|
+
managedAdapterExecutablePath = [
|
|
1025
|
+
"adapters",
|
|
1026
|
+
"pi",
|
|
1027
|
+
PI_ACP_PACKAGE.version,
|
|
1028
|
+
"node_modules",
|
|
1029
|
+
"pi-acp",
|
|
1030
|
+
"dist",
|
|
1031
|
+
"index.js"
|
|
1032
|
+
];
|
|
1033
|
+
managedAgentExecutablePath = [
|
|
1034
|
+
"agents",
|
|
1035
|
+
"pi",
|
|
1036
|
+
PI_AGENT_PACKAGE.version,
|
|
1037
|
+
"node_modules",
|
|
1038
|
+
"@earendil-works",
|
|
1039
|
+
"pi-coding-agent",
|
|
1040
|
+
"dist",
|
|
1041
|
+
"bundle",
|
|
1042
|
+
"cli.js"
|
|
1043
|
+
];
|
|
1044
|
+
promptTimeoutMilliseconds = PI_PROMPT_TIMEOUT_MILLISECONDS;
|
|
1045
|
+
resolveManagedAgent = async (stateDirectory, _platform) => await validateManagedNpmPackage(
|
|
1046
|
+
join6(stateDirectory, "agents", this.id, PI_AGENT_PACKAGE.version),
|
|
1047
|
+
PI_AGENT_PACKAGE
|
|
1048
|
+
);
|
|
1049
|
+
verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
|
|
1050
|
+
const capabilities = initialized.agentCapabilities ?? {};
|
|
1051
|
+
if (capabilities.loadSession !== true) {
|
|
1052
|
+
throw new AgentProbeError(
|
|
1053
|
+
"acp_incompatible",
|
|
1054
|
+
"Pi ACP adapter does not support session recovery"
|
|
1055
|
+
);
|
|
1056
|
+
}
|
|
1057
|
+
const session = await connection.agent.request(
|
|
1058
|
+
methods2.agent.session.new,
|
|
1059
|
+
{
|
|
1060
|
+
additionalDirectories: [],
|
|
1061
|
+
cwd: defaultWorkspace,
|
|
1062
|
+
mcpServers: []
|
|
1063
|
+
},
|
|
1064
|
+
{ cancellationSignal: signal }
|
|
1065
|
+
);
|
|
1066
|
+
if (session.sessionId.length === 0) {
|
|
1067
|
+
throw new AgentProbeError(
|
|
1068
|
+
"acp_incompatible",
|
|
1069
|
+
"Pi ACP adapter returned an invalid session"
|
|
1070
|
+
);
|
|
1071
|
+
}
|
|
1072
|
+
const prompt = await connection.agent.request(
|
|
1073
|
+
methods2.agent.session.prompt,
|
|
1074
|
+
{
|
|
1075
|
+
prompt: [{ text: "/session", type: "text" }],
|
|
1076
|
+
sessionId: session.sessionId
|
|
1077
|
+
},
|
|
1078
|
+
{ cancellationSignal: signal }
|
|
1079
|
+
);
|
|
1080
|
+
if (prompt.stopReason !== "end_turn") {
|
|
1081
|
+
throw new AgentProbeError(
|
|
1082
|
+
"acp_incompatible",
|
|
1083
|
+
"Pi ACP adapter did not complete its conformance prompt"
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
};
|
|
787
1088
|
function supportedLocalAgentSpecifications() {
|
|
788
1089
|
return Object.freeze([
|
|
789
1090
|
new CodexAgentSpecification(),
|
|
790
|
-
new ClaudeCodeAgentSpecification()
|
|
1091
|
+
new ClaudeCodeAgentSpecification(),
|
|
1092
|
+
new PiAgentSpecification()
|
|
791
1093
|
]);
|
|
792
1094
|
}
|
|
793
1095
|
var AgentDiscovery = class {
|
|
@@ -840,6 +1142,14 @@ var IncompatibleAdapter = class extends UnavailableAgent {
|
|
|
840
1142
|
super(specification);
|
|
841
1143
|
}
|
|
842
1144
|
};
|
|
1145
|
+
var AuthenticationRequiredAgent = class extends UnavailableAgent {
|
|
1146
|
+
code = "authentication_required";
|
|
1147
|
+
message = "Agent authentication is required";
|
|
1148
|
+
status = "authentication_required";
|
|
1149
|
+
constructor(specification) {
|
|
1150
|
+
super(specification);
|
|
1151
|
+
}
|
|
1152
|
+
};
|
|
843
1153
|
var LocalAgentInventory = class {
|
|
844
1154
|
available;
|
|
845
1155
|
discoveries;
|
|
@@ -861,7 +1171,10 @@ var LocalAgentInventory = class {
|
|
|
861
1171
|
this.discoveries = Object.freeze([...discoveries]);
|
|
862
1172
|
this.installable = Object.freeze(
|
|
863
1173
|
unavailable.filter(
|
|
864
|
-
(discovery) => discovery.specification.supportsInstallation(
|
|
1174
|
+
(discovery) => !(discovery instanceof AuthenticationRequiredAgent) && discovery.specification.supportsInstallation(
|
|
1175
|
+
platform,
|
|
1176
|
+
architecture
|
|
1177
|
+
)
|
|
865
1178
|
).map(
|
|
866
1179
|
(discovery) => new InstallableAgentDefinition(
|
|
867
1180
|
discovery.specification.id,
|
|
@@ -888,17 +1201,21 @@ var DiscoveryAcpHandler = class {
|
|
|
888
1201
|
onPermission = (_request, _signal) => Promise.reject(new Error("ACP probe does not grant permissions"));
|
|
889
1202
|
onUpdate = (_notification) => Promise.resolve();
|
|
890
1203
|
};
|
|
891
|
-
async function resolveManagedExecutable(
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
1204
|
+
async function resolveManagedExecutable(specification, options) {
|
|
1205
|
+
try {
|
|
1206
|
+
return await specification.resolveManagedAgent(
|
|
1207
|
+
readStateDirectory(options.environment),
|
|
1208
|
+
options.platform ?? process.platform
|
|
1209
|
+
);
|
|
1210
|
+
} catch {
|
|
1211
|
+
return null;
|
|
1212
|
+
}
|
|
896
1213
|
}
|
|
897
1214
|
async function resolveManagedAdapterExecutable(specification, options) {
|
|
898
1215
|
let managed;
|
|
899
1216
|
try {
|
|
900
1217
|
managed = await validateManagedAdapter(
|
|
901
|
-
|
|
1218
|
+
join6(
|
|
902
1219
|
readStateDirectory(options.environment),
|
|
903
1220
|
"adapters",
|
|
904
1221
|
specification.id,
|
|
@@ -914,7 +1231,7 @@ async function resolveManagedAdapterExecutable(specification, options) {
|
|
|
914
1231
|
async function resolveSpecificationExecutables(executableName, overrideVariable, resolveManaged, options) {
|
|
915
1232
|
const override = options.environment[overrideVariable];
|
|
916
1233
|
if (override !== void 0) {
|
|
917
|
-
if (override.length === 0 || !
|
|
1234
|
+
if (override.length === 0 || !isAbsolute2(override)) {
|
|
918
1235
|
return [];
|
|
919
1236
|
}
|
|
920
1237
|
const executable = await resolveExecutablePath(override, options.platform);
|
|
@@ -938,10 +1255,7 @@ async function resolveAgentExecutables(specification, options) {
|
|
|
938
1255
|
return await resolveSpecificationExecutables(
|
|
939
1256
|
specification.agentExecutable,
|
|
940
1257
|
specification.agentOverrideVariable,
|
|
941
|
-
async () => await resolveManagedExecutable(
|
|
942
|
-
specification.managedAgentExecutablePath,
|
|
943
|
-
options
|
|
944
|
-
),
|
|
1258
|
+
async () => await resolveManagedExecutable(specification, options),
|
|
945
1259
|
options
|
|
946
1260
|
);
|
|
947
1261
|
}
|
|
@@ -964,9 +1278,9 @@ async function resolveAdapterExecutable(specification, options) {
|
|
|
964
1278
|
function normalizedVersion(output2) {
|
|
965
1279
|
return output2.trim().split(/\r?\n/, 1)[0]?.trim().slice(0, 128) ?? "";
|
|
966
1280
|
}
|
|
967
|
-
async function probeVersion(executable, environment, defaultWorkspace, signal) {
|
|
1281
|
+
async function probeVersion(executable, arguments_, environment, defaultWorkspace, signal) {
|
|
968
1282
|
const result = await runBoundedProcess({
|
|
969
|
-
arguments:
|
|
1283
|
+
arguments: arguments_,
|
|
970
1284
|
command: executable.path,
|
|
971
1285
|
cwd: defaultWorkspace,
|
|
972
1286
|
environment,
|
|
@@ -996,6 +1310,7 @@ async function findVerifiedAgentExecutable(specification, options) {
|
|
|
996
1310
|
try {
|
|
997
1311
|
const version2 = await probeVersion(
|
|
998
1312
|
executable,
|
|
1313
|
+
specification.agentVersionArguments,
|
|
999
1314
|
options.environment,
|
|
1000
1315
|
options.defaultWorkspace,
|
|
1001
1316
|
options.signal
|
|
@@ -1064,14 +1379,14 @@ function writableAcpStream(output2) {
|
|
|
1064
1379
|
}
|
|
1065
1380
|
});
|
|
1066
1381
|
}
|
|
1067
|
-
async function probeAcp(agent, environment, defaultWorkspace, signal) {
|
|
1382
|
+
async function probeAcp(specification, agent, environment, defaultWorkspace, signal) {
|
|
1068
1383
|
signal.throwIfAborted();
|
|
1069
1384
|
const controller = new AbortController();
|
|
1070
1385
|
let timedOut = false;
|
|
1071
1386
|
const timeout = setTimeout(() => {
|
|
1072
1387
|
timedOut = true;
|
|
1073
1388
|
controller.abort(new Error("ACP probe timed out"));
|
|
1074
|
-
},
|
|
1389
|
+
}, specification.acpProbeTimeoutMilliseconds);
|
|
1075
1390
|
const abort = () => controller.abort(signal.reason);
|
|
1076
1391
|
signal.addEventListener("abort", abort, { once: true });
|
|
1077
1392
|
if (signal.aborted) {
|
|
@@ -1130,6 +1445,13 @@ async function probeAcp(agent, environment, defaultWorkspace, signal) {
|
|
|
1130
1445
|
"ACP adapter selected an unsupported protocol version"
|
|
1131
1446
|
);
|
|
1132
1447
|
}
|
|
1448
|
+
await specification.verifyAcp(
|
|
1449
|
+
connection,
|
|
1450
|
+
initialized,
|
|
1451
|
+
defaultWorkspace,
|
|
1452
|
+
controller.signal
|
|
1453
|
+
);
|
|
1454
|
+
return normalizedVersion(initialized.agentInfo?.version ?? "");
|
|
1133
1455
|
} catch (error61) {
|
|
1134
1456
|
if (signal.aborted) {
|
|
1135
1457
|
signal.throwIfAborted();
|
|
@@ -1144,6 +1466,13 @@ async function probeAcp(agent, environment, defaultWorkspace, signal) {
|
|
|
1144
1466
|
if (error61 instanceof AgentProbeError) {
|
|
1145
1467
|
throw error61;
|
|
1146
1468
|
}
|
|
1469
|
+
if (error61 instanceof RequestError && error61.code === -32e3 && specification.authenticationCommand().length > 0) {
|
|
1470
|
+
throw new AgentProbeError(
|
|
1471
|
+
"authentication_required",
|
|
1472
|
+
"Agent authentication is required",
|
|
1473
|
+
{ cause: error61 }
|
|
1474
|
+
);
|
|
1475
|
+
}
|
|
1147
1476
|
throw new AgentProbeError(
|
|
1148
1477
|
"acp_incompatible",
|
|
1149
1478
|
"ACP adapter initialization failed",
|
|
@@ -1160,6 +1489,9 @@ async function probeAcp(agent, environment, defaultWorkspace, signal) {
|
|
|
1160
1489
|
}
|
|
1161
1490
|
function probeFailure(specification, executableKind, error61) {
|
|
1162
1491
|
if (error61 instanceof AgentProbeError) {
|
|
1492
|
+
if (error61.code === "authentication_required") {
|
|
1493
|
+
return new AuthenticationRequiredAgent(specification);
|
|
1494
|
+
}
|
|
1163
1495
|
return error61.code === "acp_incompatible" ? new IncompatibleAdapter(specification) : new ProbeFailed(specification, error61.code, error61.message);
|
|
1164
1496
|
}
|
|
1165
1497
|
if (error61 instanceof ProcessExecutionError) {
|
|
@@ -1194,6 +1526,7 @@ async function discoverSpecification(specification, options) {
|
|
|
1194
1526
|
try {
|
|
1195
1527
|
agentVersion = await probeVersion(
|
|
1196
1528
|
agent,
|
|
1529
|
+
specification.agentVersionArguments,
|
|
1197
1530
|
options.environment,
|
|
1198
1531
|
options.defaultWorkspace,
|
|
1199
1532
|
options.signal
|
|
@@ -1208,15 +1541,18 @@ async function discoverSpecification(specification, options) {
|
|
|
1208
1541
|
for (const adapter of adapters) {
|
|
1209
1542
|
let adapterVersion = "";
|
|
1210
1543
|
try {
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1544
|
+
if (specification.adapterVersionArguments.length > 0) {
|
|
1545
|
+
adapterVersion = await probeVersion(
|
|
1546
|
+
adapter,
|
|
1547
|
+
specification.adapterVersionArguments,
|
|
1548
|
+
{
|
|
1549
|
+
...options.environment,
|
|
1550
|
+
[specification.adapterEnvironmentVariable]: agent.path
|
|
1551
|
+
},
|
|
1552
|
+
options.defaultWorkspace,
|
|
1553
|
+
options.signal
|
|
1554
|
+
);
|
|
1555
|
+
}
|
|
1220
1556
|
} catch (error61) {
|
|
1221
1557
|
if (options.signal.aborted) {
|
|
1222
1558
|
options.signal.throwIfAborted();
|
|
@@ -1233,16 +1569,39 @@ async function discoverSpecification(specification, options) {
|
|
|
1233
1569
|
adapterVersion,
|
|
1234
1570
|
agentVersion,
|
|
1235
1571
|
adapter.identity,
|
|
1236
|
-
agent.identity
|
|
1572
|
+
agent.identity,
|
|
1573
|
+
specification.promptTimeoutMilliseconds
|
|
1237
1574
|
);
|
|
1238
1575
|
try {
|
|
1239
|
-
await probeAcp(
|
|
1576
|
+
const acpVersion = await probeAcp(
|
|
1577
|
+
specification,
|
|
1240
1578
|
definition,
|
|
1241
1579
|
options.environment,
|
|
1242
1580
|
options.defaultWorkspace,
|
|
1243
1581
|
options.signal
|
|
1244
1582
|
);
|
|
1245
|
-
|
|
1583
|
+
const verifiedAdapterVersion = adapterVersion.length > 0 ? adapterVersion : acpVersion;
|
|
1584
|
+
if (verifiedAdapterVersion.length === 0) {
|
|
1585
|
+
throw new AgentProbeError(
|
|
1586
|
+
"acp_incompatible",
|
|
1587
|
+
"ACP adapter did not report a version"
|
|
1588
|
+
);
|
|
1589
|
+
}
|
|
1590
|
+
return new AvailableAgent(
|
|
1591
|
+
specification,
|
|
1592
|
+
new LocalAgentDefinition(
|
|
1593
|
+
specification.id,
|
|
1594
|
+
specification.label,
|
|
1595
|
+
adapter.path,
|
|
1596
|
+
[],
|
|
1597
|
+
{ [specification.adapterEnvironmentVariable]: agent.path },
|
|
1598
|
+
verifiedAdapterVersion,
|
|
1599
|
+
agentVersion,
|
|
1600
|
+
adapter.identity,
|
|
1601
|
+
agent.identity,
|
|
1602
|
+
specification.promptTimeoutMilliseconds
|
|
1603
|
+
)
|
|
1604
|
+
);
|
|
1246
1605
|
} catch (error61) {
|
|
1247
1606
|
if (options.signal.aborted) {
|
|
1248
1607
|
options.signal.throwIfAborted();
|
|
@@ -1301,7 +1660,7 @@ var UnavailableAgentDiagnostic = class {
|
|
|
1301
1660
|
this.id = discovery.specification.id;
|
|
1302
1661
|
this.label = discovery.specification.label;
|
|
1303
1662
|
this.message = discovery.message;
|
|
1304
|
-
this.recoveryCommand = discovery instanceof MissingAdapter ? discovery.specification.recoveryCommand() : "";
|
|
1663
|
+
this.recoveryCommand = discovery instanceof MissingAdapter ? discovery.specification.recoveryCommand() : discovery.code === "authentication_required" ? discovery.specification.authenticationCommand() : "";
|
|
1305
1664
|
this.status = discovery.status;
|
|
1306
1665
|
}
|
|
1307
1666
|
};
|
|
@@ -1341,7 +1700,9 @@ function formatAgentDiagnostics(inventory, json2) {
|
|
|
1341
1700
|
humanLine(unavailable.label, unavailable.status, unavailable.message)
|
|
1342
1701
|
);
|
|
1343
1702
|
if (unavailable.recoveryCommand.length > 0) {
|
|
1344
|
-
lines.push(
|
|
1703
|
+
lines.push(
|
|
1704
|
+
unavailable.code === "authentication_required" ? ` Authenticate locally: ${unavailable.recoveryCommand}` : ` Install adapter: ${unavailable.recoveryCommand}`
|
|
1705
|
+
);
|
|
1345
1706
|
}
|
|
1346
1707
|
}
|
|
1347
1708
|
return `${lines.join("\n")}
|
|
@@ -1399,10 +1760,10 @@ var AuditStore = class {
|
|
|
1399
1760
|
};
|
|
1400
1761
|
|
|
1401
1762
|
// src/config.ts
|
|
1402
|
-
import { join as
|
|
1763
|
+
import { join as join7 } from "node:path";
|
|
1403
1764
|
function loadDefaultWorkspace() {
|
|
1404
1765
|
const { MOBIUS_DEFAULT_WORKSPACE: configuredWorkspace } = process.env;
|
|
1405
|
-
return configuredWorkspace ??
|
|
1766
|
+
return configuredWorkspace ?? join7(readStateDirectory(), "workspace");
|
|
1406
1767
|
}
|
|
1407
1768
|
function createDaemonConfig(connection, agents = [], installableAgents = []) {
|
|
1408
1769
|
return {
|
|
@@ -1428,7 +1789,7 @@ import {
|
|
|
1428
1789
|
writeFile
|
|
1429
1790
|
} from "node:fs/promises";
|
|
1430
1791
|
import { hostname } from "node:os";
|
|
1431
|
-
import { basename, join as
|
|
1792
|
+
import { basename, join as join8, resolve as resolve3 } from "node:path";
|
|
1432
1793
|
import { fetch } from "undici";
|
|
1433
1794
|
|
|
1434
1795
|
// src/network/environment-proxy.ts
|
|
@@ -1688,10 +2049,10 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
|
|
|
1688
2049
|
return decodeClaimResponse(value);
|
|
1689
2050
|
}
|
|
1690
2051
|
async function persistConnection(channelId, relayOrigin, daemonToken, defaultWorkspace) {
|
|
1691
|
-
const connectionsDirectory =
|
|
2052
|
+
const connectionsDirectory = join8(readStateDirectory(), "connections");
|
|
1692
2053
|
await mkdir2(connectionsDirectory, { mode: 448, recursive: true });
|
|
1693
|
-
const connectionPath =
|
|
1694
|
-
const temporaryPath =
|
|
2054
|
+
const connectionPath = join8(connectionsDirectory, `${channelId}.json`);
|
|
2055
|
+
const temporaryPath = join8(
|
|
1695
2056
|
connectionsDirectory,
|
|
1696
2057
|
`.${channelId}.${randomUUID()}.tmp`
|
|
1697
2058
|
);
|
|
@@ -1738,7 +2099,7 @@ function decodeSavedConnection(value, expectedChannelId) {
|
|
|
1738
2099
|
};
|
|
1739
2100
|
}
|
|
1740
2101
|
async function readSavedConnection(channelId) {
|
|
1741
|
-
const connectionPath =
|
|
2102
|
+
const connectionPath = join8(
|
|
1742
2103
|
readStateDirectory(),
|
|
1743
2104
|
"connections",
|
|
1744
2105
|
`${channelId}.json`
|
|
@@ -1793,7 +2154,7 @@ function buildPairedDaemon(connection, connectionPath, inventory) {
|
|
|
1793
2154
|
);
|
|
1794
2155
|
relayUrl.protocol = relayUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
1795
2156
|
relayUrl.searchParams.set("token", connection.daemonToken);
|
|
1796
|
-
const auditDatabasePath =
|
|
2157
|
+
const auditDatabasePath = join8(
|
|
1797
2158
|
readStateDirectory(),
|
|
1798
2159
|
"audit",
|
|
1799
2160
|
`${connection.channelId}.sqlite`
|
|
@@ -1852,7 +2213,7 @@ async function pairLocalMachine(arguments_, signal = new AbortController().signa
|
|
|
1852
2213
|
}
|
|
1853
2214
|
async function resumeLocalMachine(arguments_, signal = new AbortController().signal) {
|
|
1854
2215
|
const channelId = parseChannelArgument(arguments_);
|
|
1855
|
-
const connectionPath =
|
|
2216
|
+
const connectionPath = join8(
|
|
1856
2217
|
readStateDirectory(),
|
|
1857
2218
|
"connections",
|
|
1858
2219
|
`${channelId}.json`
|
|
@@ -24937,12 +25298,27 @@ var AcpSessionManager = class {
|
|
|
24937
25298
|
"session_busy"
|
|
24938
25299
|
);
|
|
24939
25300
|
}
|
|
25301
|
+
const deadlineController = new AbortController();
|
|
25302
|
+
const deadlineError = new AcpExecutionError(
|
|
25303
|
+
"The local Agent prompt exceeded its deadline",
|
|
25304
|
+
{},
|
|
25305
|
+
"prompt_timeout"
|
|
25306
|
+
);
|
|
25307
|
+
const deadline = setTimeout(
|
|
25308
|
+
() => deadlineController.abort(deadlineError),
|
|
25309
|
+
options.agent.promptTimeoutMilliseconds
|
|
25310
|
+
);
|
|
25311
|
+
deadline.unref();
|
|
25312
|
+
const boundedOptions = {
|
|
25313
|
+
...options,
|
|
25314
|
+
signal: AbortSignal.any([options.signal, deadlineController.signal])
|
|
25315
|
+
};
|
|
24940
25316
|
this.#activeSessionIds.add(options.sessionId);
|
|
24941
25317
|
try {
|
|
24942
25318
|
if (this.#cancellationRequests.has(options.sessionId)) {
|
|
24943
25319
|
return { stopReason: "cancelled" };
|
|
24944
25320
|
}
|
|
24945
|
-
const runtime = await this.ensureSession(
|
|
25321
|
+
const runtime = await this.ensureSession(boundedOptions);
|
|
24946
25322
|
if (this.#nativeOperations.has(
|
|
24947
25323
|
`${options.agent.id}:${runtime.nativeSessionId()}`
|
|
24948
25324
|
))
|
|
@@ -24954,7 +25330,7 @@ var AcpSessionManager = class {
|
|
|
24954
25330
|
if (this.#cancellationRequests.has(options.sessionId)) {
|
|
24955
25331
|
return { stopReason: "cancelled" };
|
|
24956
25332
|
}
|
|
24957
|
-
return await runtime.prompt(
|
|
25333
|
+
return await runtime.prompt(boundedOptions);
|
|
24958
25334
|
} catch (error61) {
|
|
24959
25335
|
const failedRuntime = this.#sessions.get(options.sessionId);
|
|
24960
25336
|
if (failedRuntime !== void 0) {
|
|
@@ -24968,6 +25344,7 @@ var AcpSessionManager = class {
|
|
|
24968
25344
|
cause: error61
|
|
24969
25345
|
});
|
|
24970
25346
|
} finally {
|
|
25347
|
+
clearTimeout(deadline);
|
|
24971
25348
|
this.#activeSessionIds.delete(options.sessionId);
|
|
24972
25349
|
this.#cancellationRequests.delete(options.sessionId);
|
|
24973
25350
|
}
|
|
@@ -25777,7 +26154,7 @@ import { resolve as resolve4 } from "node:path";
|
|
|
25777
26154
|
|
|
25778
26155
|
// src/agent-installation/fixed-agent-install-recipes.ts
|
|
25779
26156
|
import { mkdir as mkdir3, mkdtemp as mkdtemp2, rm as rm2 } from "node:fs/promises";
|
|
25780
|
-
import { join as
|
|
26157
|
+
import { join as join9 } from "node:path";
|
|
25781
26158
|
|
|
25782
26159
|
// src/agent-installation/verified-download.ts
|
|
25783
26160
|
import { createHash } from "node:crypto";
|
|
@@ -26001,18 +26378,18 @@ var CodexInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
26001
26378
|
releaseChannel = "latest";
|
|
26002
26379
|
install = async (options) => {
|
|
26003
26380
|
this.assertSupportedPlatform();
|
|
26004
|
-
const root =
|
|
26005
|
-
const temporaryRoot =
|
|
26381
|
+
const root = join9(options.stateDirectory, "agents", this.id);
|
|
26382
|
+
const temporaryRoot = join9(options.stateDirectory, "temporary");
|
|
26006
26383
|
await Promise.all([
|
|
26007
26384
|
mkdir3(root, { mode: 448, recursive: true }),
|
|
26008
26385
|
mkdir3(temporaryRoot, { mode: 448, recursive: true })
|
|
26009
26386
|
]);
|
|
26010
26387
|
const temporaryDirectory = await mkdtemp2(
|
|
26011
|
-
|
|
26388
|
+
join9(temporaryRoot, ".codex-install-")
|
|
26012
26389
|
);
|
|
26013
|
-
const installerPath =
|
|
26014
|
-
const installDirectory =
|
|
26015
|
-
const codexHome =
|
|
26390
|
+
const installerPath = join9(temporaryDirectory, "install.sh");
|
|
26391
|
+
const installDirectory = join9(root, "bin");
|
|
26392
|
+
const codexHome = join9(root, "home");
|
|
26016
26393
|
try {
|
|
26017
26394
|
await Promise.all([
|
|
26018
26395
|
mkdir3(installDirectory, { mode: 448, recursive: true }),
|
|
@@ -26056,7 +26433,7 @@ var CodexInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
26056
26433
|
timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
|
|
26057
26434
|
});
|
|
26058
26435
|
return await this.requireInstalledExecutable(
|
|
26059
|
-
|
|
26436
|
+
join9(installDirectory, "codex")
|
|
26060
26437
|
);
|
|
26061
26438
|
} catch (error61) {
|
|
26062
26439
|
if (options.signal.aborted) {
|
|
@@ -26080,17 +26457,17 @@ var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
26080
26457
|
releaseChannel = "stable";
|
|
26081
26458
|
install = async (options) => {
|
|
26082
26459
|
this.assertSupportedPlatform();
|
|
26083
|
-
const root =
|
|
26084
|
-
const managedHome =
|
|
26085
|
-
const temporaryRoot =
|
|
26460
|
+
const root = join9(options.stateDirectory, "agents", this.id);
|
|
26461
|
+
const managedHome = join9(root, "home");
|
|
26462
|
+
const temporaryRoot = join9(options.stateDirectory, "temporary");
|
|
26086
26463
|
await Promise.all([
|
|
26087
26464
|
mkdir3(managedHome, { mode: 448, recursive: true }),
|
|
26088
26465
|
mkdir3(temporaryRoot, { mode: 448, recursive: true })
|
|
26089
26466
|
]);
|
|
26090
26467
|
const temporaryDirectory = await mkdtemp2(
|
|
26091
|
-
|
|
26468
|
+
join9(temporaryRoot, ".claude-install-")
|
|
26092
26469
|
);
|
|
26093
|
-
const installerPath =
|
|
26470
|
+
const installerPath = join9(temporaryDirectory, "install.sh");
|
|
26094
26471
|
try {
|
|
26095
26472
|
await options.report("downloading");
|
|
26096
26473
|
const download = await downloadVerifiedFile({
|
|
@@ -26127,7 +26504,7 @@ var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
26127
26504
|
timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
|
|
26128
26505
|
});
|
|
26129
26506
|
return await this.requireInstalledExecutable(
|
|
26130
|
-
|
|
26507
|
+
join9(managedHome, ".local", "bin", "claude")
|
|
26131
26508
|
);
|
|
26132
26509
|
} catch (error61) {
|
|
26133
26510
|
if (options.signal.aborted) {
|
|
@@ -26145,10 +26522,82 @@ var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
26145
26522
|
}
|
|
26146
26523
|
};
|
|
26147
26524
|
};
|
|
26525
|
+
var PiInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
26526
|
+
#npmInstaller;
|
|
26527
|
+
id = "pi";
|
|
26528
|
+
label = "Pi";
|
|
26529
|
+
releaseChannel = PI_AGENT_PACKAGE.version;
|
|
26530
|
+
constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
|
|
26531
|
+
super();
|
|
26532
|
+
this.#npmInstaller = npmInstaller;
|
|
26533
|
+
}
|
|
26534
|
+
install = async (options) => {
|
|
26535
|
+
this.assertSupportedPlatform();
|
|
26536
|
+
try {
|
|
26537
|
+
await options.report("downloading");
|
|
26538
|
+
await options.report("verifying");
|
|
26539
|
+
await options.report("installing_agent");
|
|
26540
|
+
const executable = await this.#npmInstaller.install(
|
|
26541
|
+
join9(
|
|
26542
|
+
options.stateDirectory,
|
|
26543
|
+
"agents",
|
|
26544
|
+
this.id,
|
|
26545
|
+
PI_AGENT_PACKAGE.version
|
|
26546
|
+
),
|
|
26547
|
+
PI_AGENT_PACKAGE,
|
|
26548
|
+
options.environment,
|
|
26549
|
+
options.signal
|
|
26550
|
+
);
|
|
26551
|
+
options.audit.record(
|
|
26552
|
+
"agent_npm_package_verified",
|
|
26553
|
+
options.requestId,
|
|
26554
|
+
this.id,
|
|
26555
|
+
{
|
|
26556
|
+
integrity: PI_AGENT_PACKAGE.integrity,
|
|
26557
|
+
package: PI_AGENT_PACKAGE.packageName,
|
|
26558
|
+
version: PI_AGENT_PACKAGE.version
|
|
26559
|
+
}
|
|
26560
|
+
);
|
|
26561
|
+
return executable;
|
|
26562
|
+
} catch (error61) {
|
|
26563
|
+
if (options.signal.aborted) {
|
|
26564
|
+
options.signal.throwIfAborted();
|
|
26565
|
+
}
|
|
26566
|
+
if (error61 instanceof ManagedNpmPackageError) {
|
|
26567
|
+
if (error61.code === "managed_package_verification_failed") {
|
|
26568
|
+
throw new InstallationManagerError(
|
|
26569
|
+
"agent_verification_failed",
|
|
26570
|
+
"The managed Pi package did not match its pinned artifact",
|
|
26571
|
+
{ cause: error61 }
|
|
26572
|
+
);
|
|
26573
|
+
}
|
|
26574
|
+
if (error61.code === "managed_package_publish_failed") {
|
|
26575
|
+
throw new InstallationManagerError(
|
|
26576
|
+
"agent_publish_failed",
|
|
26577
|
+
"The managed Pi package could not be published",
|
|
26578
|
+
{ cause: error61 }
|
|
26579
|
+
);
|
|
26580
|
+
}
|
|
26581
|
+
throw new InstallationManagerError(error61.code, error61.message, {
|
|
26582
|
+
cause: error61
|
|
26583
|
+
});
|
|
26584
|
+
}
|
|
26585
|
+
if (error61 instanceof InstallationManagerError) {
|
|
26586
|
+
throw error61;
|
|
26587
|
+
}
|
|
26588
|
+
throw new InstallationManagerError(
|
|
26589
|
+
"agent_install_failed",
|
|
26590
|
+
"The fixed Pi installation recipe failed",
|
|
26591
|
+
{ cause: error61 }
|
|
26592
|
+
);
|
|
26593
|
+
}
|
|
26594
|
+
};
|
|
26595
|
+
};
|
|
26148
26596
|
function fixedAgentInstallRecipes() {
|
|
26149
26597
|
return Object.freeze([
|
|
26150
26598
|
new CodexInstallRecipe(),
|
|
26151
|
-
new ClaudeCodeInstallRecipe()
|
|
26599
|
+
new ClaudeCodeInstallRecipe(),
|
|
26600
|
+
new PiInstallRecipe()
|
|
26152
26601
|
]);
|
|
26153
26602
|
}
|
|
26154
26603
|
|
|
@@ -26278,6 +26727,7 @@ var FixedInstallationExecutor = class {
|
|
|
26278
26727
|
if (agent === null) {
|
|
26279
26728
|
agent = await recipe.install({
|
|
26280
26729
|
audit: this.#audit,
|
|
26730
|
+
environment: this.#environment,
|
|
26281
26731
|
report,
|
|
26282
26732
|
requestId,
|
|
26283
26733
|
signal,
|
|
@@ -26359,6 +26809,7 @@ var FixedInstallationExecutor = class {
|
|
|
26359
26809
|
if (!installedAgent && (requiresAgentReplacement(unavailable.code) || unavailable.code === "acp_incompatible")) {
|
|
26360
26810
|
agent = await recipe.install({
|
|
26361
26811
|
audit: this.#audit,
|
|
26812
|
+
environment: this.#environment,
|
|
26362
26813
|
report,
|
|
26363
26814
|
requestId,
|
|
26364
26815
|
signal,
|
|
@@ -26431,8 +26882,8 @@ import { homedir as homedir2 } from "node:os";
|
|
|
26431
26882
|
import {
|
|
26432
26883
|
basename as basename2,
|
|
26433
26884
|
dirname as dirname4,
|
|
26434
|
-
isAbsolute as
|
|
26435
|
-
join as
|
|
26885
|
+
isAbsolute as isAbsolute3,
|
|
26886
|
+
join as join10,
|
|
26436
26887
|
normalize,
|
|
26437
26888
|
relative as relative2
|
|
26438
26889
|
} from "node:path";
|
|
@@ -26484,20 +26935,20 @@ var WorkspaceDirectoryService = class {
|
|
|
26484
26935
|
if (id === "home") return homedir2();
|
|
26485
26936
|
if (id.startsWith("path-")) {
|
|
26486
26937
|
const path2 = decodePath(id, "path-");
|
|
26487
|
-
if (
|
|
26938
|
+
if (isAbsolute3(path2)) return path2;
|
|
26488
26939
|
}
|
|
26489
26940
|
throw new LocalAuthorizationError("The directory identifier is invalid");
|
|
26490
26941
|
};
|
|
26491
26942
|
resolvePath = async (requested, signal) => {
|
|
26492
26943
|
signal.throwIfAborted();
|
|
26493
|
-
if (!
|
|
26944
|
+
if (!isAbsolute3(requested) || requested.includes("\0") || normalize(requested) !== requested)
|
|
26494
26945
|
throw new LocalAuthorizationError("The local directory path is invalid");
|
|
26495
26946
|
try {
|
|
26496
26947
|
const target = await realpath4(requested);
|
|
26497
26948
|
signal.throwIfAborted();
|
|
26498
26949
|
const metadata = await stat4(target);
|
|
26499
26950
|
signal.throwIfAborted();
|
|
26500
|
-
if (!
|
|
26951
|
+
if (!isAbsolute3(target) || normalize(target) !== target || !metadata.isDirectory())
|
|
26501
26952
|
throw new LocalAuthorizationError(
|
|
26502
26953
|
"The selected location is not a directory"
|
|
26503
26954
|
);
|
|
@@ -26513,7 +26964,7 @@ var WorkspaceDirectoryService = class {
|
|
|
26513
26964
|
};
|
|
26514
26965
|
label = (path2) => {
|
|
26515
26966
|
const suffix = relative2(homedir2(), path2);
|
|
26516
|
-
return suffix === "" ? "~" : !
|
|
26967
|
+
return suffix === "" ? "~" : !isAbsolute3(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
|
|
26517
26968
|
};
|
|
26518
26969
|
identify = async (bindingId, requestedPath, signal) => {
|
|
26519
26970
|
this.authorizeMachine(bindingId);
|
|
@@ -26541,7 +26992,7 @@ var WorkspaceDirectoryService = class {
|
|
|
26541
26992
|
continue;
|
|
26542
26993
|
}
|
|
26543
26994
|
try {
|
|
26544
|
-
const path2 = await this.resolvePath(
|
|
26995
|
+
const path2 = await this.resolvePath(join10(target, child.name), signal);
|
|
26545
26996
|
entries.push({ directoryId: encodePath(path2), name: child.name });
|
|
26546
26997
|
} catch (cause) {
|
|
26547
26998
|
signal.throwIfAborted();
|