@moxt-ai/mobius 0.0.8 → 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 +19 -5
- 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 +625 -178
- package/dist/cli.js.map +4 -4
- package/dist/index.js +616 -171
- 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)
|
|
485
569
|
);
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
"
|
|
490
|
-
"The managed adapter package escaped its private cache"
|
|
570
|
+
if (!isContainedPath(rootPath, packageRoot)) {
|
|
571
|
+
throw new ManagedNpmPackageError(
|
|
572
|
+
"managed_package_verification_failed",
|
|
573
|
+
"The managed npm package escaped its private cache"
|
|
491
574
|
);
|
|
492
575
|
}
|
|
493
|
-
const metadata = await
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
576
|
+
const metadata = await readJsonRecord(
|
|
577
|
+
join3(packageRoot, "package.json"),
|
|
578
|
+
PACKAGE_METADATA_LIMIT_BYTES
|
|
579
|
+
);
|
|
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"
|
|
498
584
|
);
|
|
499
585
|
}
|
|
500
|
-
|
|
586
|
+
if (definition instanceof SriManagedNpmPackageDefinition) {
|
|
587
|
+
verifyPackageLock(
|
|
588
|
+
await readJsonRecord(
|
|
589
|
+
join3(rootPath, "package-lock.json"),
|
|
590
|
+
PACKAGE_LOCK_LIMIT_BYTES
|
|
591
|
+
),
|
|
592
|
+
definition
|
|
593
|
+
);
|
|
594
|
+
}
|
|
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`
|
|
@@ -23909,7 +24270,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23909
24270
|
}
|
|
23910
24271
|
initialize = async (signal, origin) => {
|
|
23911
24272
|
await this.#initializeAgent(signal);
|
|
23912
|
-
|
|
24273
|
+
let stored = origin?.kind === "import" ? new FoundAcpStoredSession(
|
|
23913
24274
|
new AcpStoredSession(
|
|
23914
24275
|
this.#mobiusSessionId,
|
|
23915
24276
|
this.#agentId,
|
|
@@ -23919,6 +24280,10 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23919
24280
|
true
|
|
23920
24281
|
)
|
|
23921
24282
|
) : this.#store.read(this.#mobiusSessionId);
|
|
24283
|
+
if (stored instanceof FoundAcpStoredSession && !stored.session.prompted) {
|
|
24284
|
+
this.#store.remove(this.#mobiusSessionId);
|
|
24285
|
+
stored = this.#store.read(this.#mobiusSessionId);
|
|
24286
|
+
}
|
|
23922
24287
|
if (stored instanceof DeletedAcpStoredSession)
|
|
23923
24288
|
throw new AcpExecutionError(
|
|
23924
24289
|
"The native Agent session was deleted. Start a new chat.",
|
|
@@ -24034,6 +24399,15 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
24034
24399
|
);
|
|
24035
24400
|
this.#nativeSessionId = created.sessionId;
|
|
24036
24401
|
lifecycleResponse = created;
|
|
24402
|
+
}
|
|
24403
|
+
const lifecycleRecord = isRecord6(lifecycleResponse) ? lifecycleResponse : {};
|
|
24404
|
+
this.#configOptions = normalizeConfigOptions(
|
|
24405
|
+
lifecycleRecord["configOptions"],
|
|
24406
|
+
lifecycleRecord["modes"]
|
|
24407
|
+
);
|
|
24408
|
+
await this.#updateTail;
|
|
24409
|
+
signal.throwIfAborted();
|
|
24410
|
+
if (this.#prompted) {
|
|
24037
24411
|
this.#store.write(
|
|
24038
24412
|
new AcpStoredSession(
|
|
24039
24413
|
this.#mobiusSessionId,
|
|
@@ -24041,27 +24415,10 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
24041
24415
|
this.#nativeSessionId,
|
|
24042
24416
|
this.#cwd,
|
|
24043
24417
|
this.#additionalDirectories,
|
|
24044
|
-
|
|
24418
|
+
true
|
|
24045
24419
|
)
|
|
24046
24420
|
);
|
|
24047
24421
|
}
|
|
24048
|
-
const lifecycleRecord = isRecord6(lifecycleResponse) ? lifecycleResponse : {};
|
|
24049
|
-
this.#configOptions = normalizeConfigOptions(
|
|
24050
|
-
lifecycleRecord["configOptions"],
|
|
24051
|
-
lifecycleRecord["modes"]
|
|
24052
|
-
);
|
|
24053
|
-
await this.#updateTail;
|
|
24054
|
-
signal.throwIfAborted();
|
|
24055
|
-
this.#store.write(
|
|
24056
|
-
new AcpStoredSession(
|
|
24057
|
-
this.#mobiusSessionId,
|
|
24058
|
-
this.#agentId,
|
|
24059
|
-
this.#nativeSessionId,
|
|
24060
|
-
this.#cwd,
|
|
24061
|
-
this.#additionalDirectories,
|
|
24062
|
-
this.#prompted
|
|
24063
|
-
)
|
|
24064
|
-
);
|
|
24065
24422
|
};
|
|
24066
24423
|
listNativeSessions = async (cursor, signal) => {
|
|
24067
24424
|
if (!this.#capabilities.listSessions)
|
|
@@ -24941,12 +25298,27 @@ var AcpSessionManager = class {
|
|
|
24941
25298
|
"session_busy"
|
|
24942
25299
|
);
|
|
24943
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
|
+
};
|
|
24944
25316
|
this.#activeSessionIds.add(options.sessionId);
|
|
24945
25317
|
try {
|
|
24946
25318
|
if (this.#cancellationRequests.has(options.sessionId)) {
|
|
24947
25319
|
return { stopReason: "cancelled" };
|
|
24948
25320
|
}
|
|
24949
|
-
const runtime = await this.ensureSession(
|
|
25321
|
+
const runtime = await this.ensureSession(boundedOptions);
|
|
24950
25322
|
if (this.#nativeOperations.has(
|
|
24951
25323
|
`${options.agent.id}:${runtime.nativeSessionId()}`
|
|
24952
25324
|
))
|
|
@@ -24958,7 +25330,7 @@ var AcpSessionManager = class {
|
|
|
24958
25330
|
if (this.#cancellationRequests.has(options.sessionId)) {
|
|
24959
25331
|
return { stopReason: "cancelled" };
|
|
24960
25332
|
}
|
|
24961
|
-
return await runtime.prompt(
|
|
25333
|
+
return await runtime.prompt(boundedOptions);
|
|
24962
25334
|
} catch (error61) {
|
|
24963
25335
|
const failedRuntime = this.#sessions.get(options.sessionId);
|
|
24964
25336
|
if (failedRuntime !== void 0) {
|
|
@@ -24972,6 +25344,7 @@ var AcpSessionManager = class {
|
|
|
24972
25344
|
cause: error61
|
|
24973
25345
|
});
|
|
24974
25346
|
} finally {
|
|
25347
|
+
clearTimeout(deadline);
|
|
24975
25348
|
this.#activeSessionIds.delete(options.sessionId);
|
|
24976
25349
|
this.#cancellationRequests.delete(options.sessionId);
|
|
24977
25350
|
}
|
|
@@ -25781,7 +26154,7 @@ import { resolve as resolve4 } from "node:path";
|
|
|
25781
26154
|
|
|
25782
26155
|
// src/agent-installation/fixed-agent-install-recipes.ts
|
|
25783
26156
|
import { mkdir as mkdir3, mkdtemp as mkdtemp2, rm as rm2 } from "node:fs/promises";
|
|
25784
|
-
import { join as
|
|
26157
|
+
import { join as join9 } from "node:path";
|
|
25785
26158
|
|
|
25786
26159
|
// src/agent-installation/verified-download.ts
|
|
25787
26160
|
import { createHash } from "node:crypto";
|
|
@@ -26005,18 +26378,18 @@ var CodexInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
26005
26378
|
releaseChannel = "latest";
|
|
26006
26379
|
install = async (options) => {
|
|
26007
26380
|
this.assertSupportedPlatform();
|
|
26008
|
-
const root =
|
|
26009
|
-
const temporaryRoot =
|
|
26381
|
+
const root = join9(options.stateDirectory, "agents", this.id);
|
|
26382
|
+
const temporaryRoot = join9(options.stateDirectory, "temporary");
|
|
26010
26383
|
await Promise.all([
|
|
26011
26384
|
mkdir3(root, { mode: 448, recursive: true }),
|
|
26012
26385
|
mkdir3(temporaryRoot, { mode: 448, recursive: true })
|
|
26013
26386
|
]);
|
|
26014
26387
|
const temporaryDirectory = await mkdtemp2(
|
|
26015
|
-
|
|
26388
|
+
join9(temporaryRoot, ".codex-install-")
|
|
26016
26389
|
);
|
|
26017
|
-
const installerPath =
|
|
26018
|
-
const installDirectory =
|
|
26019
|
-
const codexHome =
|
|
26390
|
+
const installerPath = join9(temporaryDirectory, "install.sh");
|
|
26391
|
+
const installDirectory = join9(root, "bin");
|
|
26392
|
+
const codexHome = join9(root, "home");
|
|
26020
26393
|
try {
|
|
26021
26394
|
await Promise.all([
|
|
26022
26395
|
mkdir3(installDirectory, { mode: 448, recursive: true }),
|
|
@@ -26060,7 +26433,7 @@ var CodexInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
26060
26433
|
timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
|
|
26061
26434
|
});
|
|
26062
26435
|
return await this.requireInstalledExecutable(
|
|
26063
|
-
|
|
26436
|
+
join9(installDirectory, "codex")
|
|
26064
26437
|
);
|
|
26065
26438
|
} catch (error61) {
|
|
26066
26439
|
if (options.signal.aborted) {
|
|
@@ -26084,17 +26457,17 @@ var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
26084
26457
|
releaseChannel = "stable";
|
|
26085
26458
|
install = async (options) => {
|
|
26086
26459
|
this.assertSupportedPlatform();
|
|
26087
|
-
const root =
|
|
26088
|
-
const managedHome =
|
|
26089
|
-
const temporaryRoot =
|
|
26460
|
+
const root = join9(options.stateDirectory, "agents", this.id);
|
|
26461
|
+
const managedHome = join9(root, "home");
|
|
26462
|
+
const temporaryRoot = join9(options.stateDirectory, "temporary");
|
|
26090
26463
|
await Promise.all([
|
|
26091
26464
|
mkdir3(managedHome, { mode: 448, recursive: true }),
|
|
26092
26465
|
mkdir3(temporaryRoot, { mode: 448, recursive: true })
|
|
26093
26466
|
]);
|
|
26094
26467
|
const temporaryDirectory = await mkdtemp2(
|
|
26095
|
-
|
|
26468
|
+
join9(temporaryRoot, ".claude-install-")
|
|
26096
26469
|
);
|
|
26097
|
-
const installerPath =
|
|
26470
|
+
const installerPath = join9(temporaryDirectory, "install.sh");
|
|
26098
26471
|
try {
|
|
26099
26472
|
await options.report("downloading");
|
|
26100
26473
|
const download = await downloadVerifiedFile({
|
|
@@ -26131,7 +26504,7 @@ var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
26131
26504
|
timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
|
|
26132
26505
|
});
|
|
26133
26506
|
return await this.requireInstalledExecutable(
|
|
26134
|
-
|
|
26507
|
+
join9(managedHome, ".local", "bin", "claude")
|
|
26135
26508
|
);
|
|
26136
26509
|
} catch (error61) {
|
|
26137
26510
|
if (options.signal.aborted) {
|
|
@@ -26149,10 +26522,82 @@ var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
26149
26522
|
}
|
|
26150
26523
|
};
|
|
26151
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
|
+
};
|
|
26152
26596
|
function fixedAgentInstallRecipes() {
|
|
26153
26597
|
return Object.freeze([
|
|
26154
26598
|
new CodexInstallRecipe(),
|
|
26155
|
-
new ClaudeCodeInstallRecipe()
|
|
26599
|
+
new ClaudeCodeInstallRecipe(),
|
|
26600
|
+
new PiInstallRecipe()
|
|
26156
26601
|
]);
|
|
26157
26602
|
}
|
|
26158
26603
|
|
|
@@ -26282,6 +26727,7 @@ var FixedInstallationExecutor = class {
|
|
|
26282
26727
|
if (agent === null) {
|
|
26283
26728
|
agent = await recipe.install({
|
|
26284
26729
|
audit: this.#audit,
|
|
26730
|
+
environment: this.#environment,
|
|
26285
26731
|
report,
|
|
26286
26732
|
requestId,
|
|
26287
26733
|
signal,
|
|
@@ -26363,6 +26809,7 @@ var FixedInstallationExecutor = class {
|
|
|
26363
26809
|
if (!installedAgent && (requiresAgentReplacement(unavailable.code) || unavailable.code === "acp_incompatible")) {
|
|
26364
26810
|
agent = await recipe.install({
|
|
26365
26811
|
audit: this.#audit,
|
|
26812
|
+
environment: this.#environment,
|
|
26366
26813
|
report,
|
|
26367
26814
|
requestId,
|
|
26368
26815
|
signal,
|
|
@@ -26435,8 +26882,8 @@ import { homedir as homedir2 } from "node:os";
|
|
|
26435
26882
|
import {
|
|
26436
26883
|
basename as basename2,
|
|
26437
26884
|
dirname as dirname4,
|
|
26438
|
-
isAbsolute as
|
|
26439
|
-
join as
|
|
26885
|
+
isAbsolute as isAbsolute3,
|
|
26886
|
+
join as join10,
|
|
26440
26887
|
normalize,
|
|
26441
26888
|
relative as relative2
|
|
26442
26889
|
} from "node:path";
|
|
@@ -26488,20 +26935,20 @@ var WorkspaceDirectoryService = class {
|
|
|
26488
26935
|
if (id === "home") return homedir2();
|
|
26489
26936
|
if (id.startsWith("path-")) {
|
|
26490
26937
|
const path2 = decodePath(id, "path-");
|
|
26491
|
-
if (
|
|
26938
|
+
if (isAbsolute3(path2)) return path2;
|
|
26492
26939
|
}
|
|
26493
26940
|
throw new LocalAuthorizationError("The directory identifier is invalid");
|
|
26494
26941
|
};
|
|
26495
26942
|
resolvePath = async (requested, signal) => {
|
|
26496
26943
|
signal.throwIfAborted();
|
|
26497
|
-
if (!
|
|
26944
|
+
if (!isAbsolute3(requested) || requested.includes("\0") || normalize(requested) !== requested)
|
|
26498
26945
|
throw new LocalAuthorizationError("The local directory path is invalid");
|
|
26499
26946
|
try {
|
|
26500
26947
|
const target = await realpath4(requested);
|
|
26501
26948
|
signal.throwIfAborted();
|
|
26502
26949
|
const metadata = await stat4(target);
|
|
26503
26950
|
signal.throwIfAborted();
|
|
26504
|
-
if (!
|
|
26951
|
+
if (!isAbsolute3(target) || normalize(target) !== target || !metadata.isDirectory())
|
|
26505
26952
|
throw new LocalAuthorizationError(
|
|
26506
26953
|
"The selected location is not a directory"
|
|
26507
26954
|
);
|
|
@@ -26517,7 +26964,7 @@ var WorkspaceDirectoryService = class {
|
|
|
26517
26964
|
};
|
|
26518
26965
|
label = (path2) => {
|
|
26519
26966
|
const suffix = relative2(homedir2(), path2);
|
|
26520
|
-
return suffix === "" ? "~" : !
|
|
26967
|
+
return suffix === "" ? "~" : !isAbsolute3(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
|
|
26521
26968
|
};
|
|
26522
26969
|
identify = async (bindingId, requestedPath, signal) => {
|
|
26523
26970
|
this.authorizeMachine(bindingId);
|
|
@@ -26545,7 +26992,7 @@ var WorkspaceDirectoryService = class {
|
|
|
26545
26992
|
continue;
|
|
26546
26993
|
}
|
|
26547
26994
|
try {
|
|
26548
|
-
const path2 = await this.resolvePath(
|
|
26995
|
+
const path2 = await this.resolvePath(join10(target, child.name), signal);
|
|
26549
26996
|
entries.push({ directoryId: encodePath(path2), name: child.name });
|
|
26550
26997
|
} catch (cause) {
|
|
26551
26998
|
signal.throwIfAborted();
|