@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/index.js
CHANGED
|
@@ -388,7 +388,11 @@ var LocalAgentDefinition = class {
|
|
|
388
388
|
environment;
|
|
389
389
|
id;
|
|
390
390
|
label;
|
|
391
|
-
|
|
391
|
+
promptTimeoutMilliseconds;
|
|
392
|
+
constructor(id, label, command, arguments_, environment = {}, adapterVersion = "", agentVersion = "", adapterIdentity = readTrustedIdentity(command), agentIdentity = adapterIdentity, promptTimeoutMilliseconds = 30 * 60 * 1e3) {
|
|
393
|
+
if (!Number.isSafeInteger(promptTimeoutMilliseconds) || promptTimeoutMilliseconds < 1) {
|
|
394
|
+
throw new Error("The local Agent prompt deadline is invalid");
|
|
395
|
+
}
|
|
392
396
|
this.adapterIdentity = adapterIdentity;
|
|
393
397
|
this.adapterPath = adapterIdentity.realPath;
|
|
394
398
|
this.adapterVersion = adapterVersion;
|
|
@@ -396,6 +400,7 @@ var LocalAgentDefinition = class {
|
|
|
396
400
|
this.agentVersion = agentVersion;
|
|
397
401
|
this.id = id;
|
|
398
402
|
this.label = label;
|
|
403
|
+
this.promptTimeoutMilliseconds = promptTimeoutMilliseconds;
|
|
399
404
|
this.command = adapterIdentity.realPath;
|
|
400
405
|
this.arguments = Object.freeze([...arguments_]);
|
|
401
406
|
this.environment = Object.freeze({ ...environment });
|
|
@@ -22559,7 +22564,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22559
22564
|
}
|
|
22560
22565
|
initialize = async (signal, origin) => {
|
|
22561
22566
|
await this.#initializeAgent(signal);
|
|
22562
|
-
|
|
22567
|
+
let stored = origin?.kind === "import" ? new FoundAcpStoredSession(
|
|
22563
22568
|
new AcpStoredSession(
|
|
22564
22569
|
this.#mobiusSessionId,
|
|
22565
22570
|
this.#agentId,
|
|
@@ -22569,6 +22574,10 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22569
22574
|
true
|
|
22570
22575
|
)
|
|
22571
22576
|
) : this.#store.read(this.#mobiusSessionId);
|
|
22577
|
+
if (stored instanceof FoundAcpStoredSession && !stored.session.prompted) {
|
|
22578
|
+
this.#store.remove(this.#mobiusSessionId);
|
|
22579
|
+
stored = this.#store.read(this.#mobiusSessionId);
|
|
22580
|
+
}
|
|
22572
22581
|
if (stored instanceof DeletedAcpStoredSession)
|
|
22573
22582
|
throw new AcpExecutionError(
|
|
22574
22583
|
"The native Agent session was deleted. Start a new chat.",
|
|
@@ -22684,6 +22693,15 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22684
22693
|
);
|
|
22685
22694
|
this.#nativeSessionId = created.sessionId;
|
|
22686
22695
|
lifecycleResponse = created;
|
|
22696
|
+
}
|
|
22697
|
+
const lifecycleRecord = isRecord3(lifecycleResponse) ? lifecycleResponse : {};
|
|
22698
|
+
this.#configOptions = normalizeConfigOptions(
|
|
22699
|
+
lifecycleRecord["configOptions"],
|
|
22700
|
+
lifecycleRecord["modes"]
|
|
22701
|
+
);
|
|
22702
|
+
await this.#updateTail;
|
|
22703
|
+
signal.throwIfAborted();
|
|
22704
|
+
if (this.#prompted) {
|
|
22687
22705
|
this.#store.write(
|
|
22688
22706
|
new AcpStoredSession(
|
|
22689
22707
|
this.#mobiusSessionId,
|
|
@@ -22691,27 +22709,10 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22691
22709
|
this.#nativeSessionId,
|
|
22692
22710
|
this.#cwd,
|
|
22693
22711
|
this.#additionalDirectories,
|
|
22694
|
-
|
|
22712
|
+
true
|
|
22695
22713
|
)
|
|
22696
22714
|
);
|
|
22697
22715
|
}
|
|
22698
|
-
const lifecycleRecord = isRecord3(lifecycleResponse) ? lifecycleResponse : {};
|
|
22699
|
-
this.#configOptions = normalizeConfigOptions(
|
|
22700
|
-
lifecycleRecord["configOptions"],
|
|
22701
|
-
lifecycleRecord["modes"]
|
|
22702
|
-
);
|
|
22703
|
-
await this.#updateTail;
|
|
22704
|
-
signal.throwIfAborted();
|
|
22705
|
-
this.#store.write(
|
|
22706
|
-
new AcpStoredSession(
|
|
22707
|
-
this.#mobiusSessionId,
|
|
22708
|
-
this.#agentId,
|
|
22709
|
-
this.#nativeSessionId,
|
|
22710
|
-
this.#cwd,
|
|
22711
|
-
this.#additionalDirectories,
|
|
22712
|
-
this.#prompted
|
|
22713
|
-
)
|
|
22714
|
-
);
|
|
22715
22716
|
};
|
|
22716
22717
|
listNativeSessions = async (cursor, signal) => {
|
|
22717
22718
|
if (!this.#capabilities.listSessions)
|
|
@@ -23591,12 +23592,27 @@ var AcpSessionManager = class {
|
|
|
23591
23592
|
"session_busy"
|
|
23592
23593
|
);
|
|
23593
23594
|
}
|
|
23595
|
+
const deadlineController = new AbortController();
|
|
23596
|
+
const deadlineError = new AcpExecutionError(
|
|
23597
|
+
"The local Agent prompt exceeded its deadline",
|
|
23598
|
+
{},
|
|
23599
|
+
"prompt_timeout"
|
|
23600
|
+
);
|
|
23601
|
+
const deadline = setTimeout(
|
|
23602
|
+
() => deadlineController.abort(deadlineError),
|
|
23603
|
+
options.agent.promptTimeoutMilliseconds
|
|
23604
|
+
);
|
|
23605
|
+
deadline.unref();
|
|
23606
|
+
const boundedOptions = {
|
|
23607
|
+
...options,
|
|
23608
|
+
signal: AbortSignal.any([options.signal, deadlineController.signal])
|
|
23609
|
+
};
|
|
23594
23610
|
this.#activeSessionIds.add(options.sessionId);
|
|
23595
23611
|
try {
|
|
23596
23612
|
if (this.#cancellationRequests.has(options.sessionId)) {
|
|
23597
23613
|
return { stopReason: "cancelled" };
|
|
23598
23614
|
}
|
|
23599
|
-
const runtime = await this.ensureSession(
|
|
23615
|
+
const runtime = await this.ensureSession(boundedOptions);
|
|
23600
23616
|
if (this.#nativeOperations.has(
|
|
23601
23617
|
`${options.agent.id}:${runtime.nativeSessionId()}`
|
|
23602
23618
|
))
|
|
@@ -23608,7 +23624,7 @@ var AcpSessionManager = class {
|
|
|
23608
23624
|
if (this.#cancellationRequests.has(options.sessionId)) {
|
|
23609
23625
|
return { stopReason: "cancelled" };
|
|
23610
23626
|
}
|
|
23611
|
-
return await runtime.prompt(
|
|
23627
|
+
return await runtime.prompt(boundedOptions);
|
|
23612
23628
|
} catch (error61) {
|
|
23613
23629
|
const failedRuntime = this.#sessions.get(options.sessionId);
|
|
23614
23630
|
if (failedRuntime !== void 0) {
|
|
@@ -23622,6 +23638,7 @@ var AcpSessionManager = class {
|
|
|
23622
23638
|
cause: error61
|
|
23623
23639
|
});
|
|
23624
23640
|
} finally {
|
|
23641
|
+
clearTimeout(deadline);
|
|
23625
23642
|
this.#activeSessionIds.delete(options.sessionId);
|
|
23626
23643
|
this.#cancellationRequests.delete(options.sessionId);
|
|
23627
23644
|
}
|
|
@@ -23923,16 +23940,17 @@ import {
|
|
|
23923
23940
|
writeFile
|
|
23924
23941
|
} from "node:fs/promises";
|
|
23925
23942
|
import { hostname as hostname3 } from "node:os";
|
|
23926
|
-
import { basename, join as
|
|
23943
|
+
import { basename, join as join8, resolve as resolve3 } from "node:path";
|
|
23927
23944
|
import { fetch } from "undici";
|
|
23928
23945
|
|
|
23929
23946
|
// src/agent-catalog/discover-local-agents.ts
|
|
23930
23947
|
import { spawn as spawn3 } from "node:child_process";
|
|
23931
|
-
import { isAbsolute, join as
|
|
23948
|
+
import { isAbsolute as isAbsolute2, join as join7 } from "node:path";
|
|
23932
23949
|
import {
|
|
23933
23950
|
methods as methods3,
|
|
23934
23951
|
ndJsonStream as ndJsonStream2,
|
|
23935
|
-
PROTOCOL_VERSION as PROTOCOL_VERSION2
|
|
23952
|
+
PROTOCOL_VERSION as PROTOCOL_VERSION2,
|
|
23953
|
+
RequestError
|
|
23936
23954
|
} from "@agentclientprotocol/sdk";
|
|
23937
23955
|
|
|
23938
23956
|
// src/agent-installation/installation-grants.ts
|
|
@@ -23978,6 +23996,9 @@ async function readGrantedAgents(stateDirectory) {
|
|
|
23978
23996
|
}
|
|
23979
23997
|
|
|
23980
23998
|
// src/agent-installation/managed-adapter-installer.ts
|
|
23999
|
+
import { join as join6 } from "node:path";
|
|
24000
|
+
|
|
24001
|
+
// src/agent-installation/managed-npm-package.ts
|
|
23981
24002
|
import {
|
|
23982
24003
|
mkdir,
|
|
23983
24004
|
mkdtemp,
|
|
@@ -23987,15 +24008,35 @@ import {
|
|
|
23987
24008
|
rm,
|
|
23988
24009
|
stat as stat2
|
|
23989
24010
|
} from "node:fs/promises";
|
|
23990
|
-
import { delimiter, dirname as dirname3, join as join5, relative } from "node:path";
|
|
23991
|
-
var
|
|
24011
|
+
import { delimiter, dirname as dirname3, isAbsolute, join as join5, relative, sep } from "node:path";
|
|
24012
|
+
var INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
|
|
23992
24013
|
var PACKAGE_METADATA_LIMIT_BYTES = 64 * 1024;
|
|
23993
|
-
var
|
|
24014
|
+
var PACKAGE_LOCK_LIMIT_BYTES = 8 * 1024 * 1024;
|
|
24015
|
+
var ManagedNpmPackageDefinition = class {
|
|
24016
|
+
executableName;
|
|
24017
|
+
packageName;
|
|
24018
|
+
version;
|
|
24019
|
+
constructor(packageName, version2, executableName) {
|
|
24020
|
+
this.executableName = executableName;
|
|
24021
|
+
this.packageName = packageName;
|
|
24022
|
+
this.version = version2;
|
|
24023
|
+
}
|
|
24024
|
+
};
|
|
24025
|
+
var SriManagedNpmPackageDefinition = class extends ManagedNpmPackageDefinition {
|
|
24026
|
+
integrity;
|
|
24027
|
+
tarballUrl;
|
|
24028
|
+
constructor(packageName, version2, executableName, integrity, tarballUrl) {
|
|
24029
|
+
super(packageName, version2, executableName);
|
|
24030
|
+
this.integrity = integrity;
|
|
24031
|
+
this.tarballUrl = tarballUrl;
|
|
24032
|
+
}
|
|
24033
|
+
};
|
|
24034
|
+
var ManagedNpmPackageError = class extends Error {
|
|
23994
24035
|
code;
|
|
23995
24036
|
constructor(code, message, options = {}) {
|
|
23996
24037
|
super(message, options);
|
|
23997
24038
|
this.code = code;
|
|
23998
|
-
this.name = "
|
|
24039
|
+
this.name = "ManagedNpmPackageError";
|
|
23999
24040
|
}
|
|
24000
24041
|
};
|
|
24001
24042
|
function isRecord5(value) {
|
|
@@ -24004,28 +24045,43 @@ function isRecord5(value) {
|
|
|
24004
24045
|
function packagePath(root, packageName) {
|
|
24005
24046
|
return join5(root, "node_modules", ...packageName.split("/"));
|
|
24006
24047
|
}
|
|
24007
|
-
|
|
24008
|
-
const
|
|
24048
|
+
function isContainedPath(root, candidate) {
|
|
24049
|
+
const difference = relative(root, candidate);
|
|
24050
|
+
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep}`) && !isAbsolute(difference);
|
|
24051
|
+
}
|
|
24052
|
+
async function readJsonRecord(path2, maximumBytes) {
|
|
24009
24053
|
try {
|
|
24010
|
-
const
|
|
24011
|
-
|
|
24012
|
-
|
|
24013
|
-
|
|
24014
|
-
|
|
24054
|
+
const handle = await open3(path2, "r");
|
|
24055
|
+
try {
|
|
24056
|
+
const metadata = await handle.stat();
|
|
24057
|
+
if (!metadata.isFile() || metadata.size > maximumBytes) {
|
|
24058
|
+
throw new ManagedNpmPackageError(
|
|
24059
|
+
"managed_package_verification_failed",
|
|
24060
|
+
"The managed npm package metadata is invalid"
|
|
24061
|
+
);
|
|
24062
|
+
}
|
|
24063
|
+
const value = JSON.parse(
|
|
24064
|
+
await handle.readFile({ encoding: "utf8" })
|
|
24015
24065
|
);
|
|
24066
|
+
if (!isRecord5(value)) {
|
|
24067
|
+
throw new ManagedNpmPackageError(
|
|
24068
|
+
"managed_package_verification_failed",
|
|
24069
|
+
"The managed npm package metadata is invalid"
|
|
24070
|
+
);
|
|
24071
|
+
}
|
|
24072
|
+
return value;
|
|
24073
|
+
} finally {
|
|
24074
|
+
await handle.close();
|
|
24016
24075
|
}
|
|
24017
|
-
|
|
24018
|
-
|
|
24019
|
-
|
|
24020
|
-
if (!isRecord5(value)) {
|
|
24021
|
-
throw new ManagedAdapterInstallError(
|
|
24022
|
-
"adapter_verification_failed",
|
|
24023
|
-
"The managed adapter package metadata is invalid"
|
|
24024
|
-
);
|
|
24076
|
+
} catch (error61) {
|
|
24077
|
+
if (error61 instanceof ManagedNpmPackageError) {
|
|
24078
|
+
throw error61;
|
|
24025
24079
|
}
|
|
24026
|
-
|
|
24027
|
-
|
|
24028
|
-
|
|
24080
|
+
throw new ManagedNpmPackageError(
|
|
24081
|
+
"managed_package_verification_failed",
|
|
24082
|
+
"The managed npm package metadata is invalid",
|
|
24083
|
+
{ cause: error61 }
|
|
24084
|
+
);
|
|
24029
24085
|
}
|
|
24030
24086
|
}
|
|
24031
24087
|
function readBinPath(packageMetadata, executableName) {
|
|
@@ -24036,83 +24092,125 @@ function readBinPath(packageMetadata, executableName) {
|
|
|
24036
24092
|
if (isRecord5(bin) && typeof bin[executableName] === "string") {
|
|
24037
24093
|
return bin[executableName];
|
|
24038
24094
|
}
|
|
24039
|
-
throw new
|
|
24040
|
-
"
|
|
24041
|
-
"The managed
|
|
24095
|
+
throw new ManagedNpmPackageError(
|
|
24096
|
+
"managed_package_verification_failed",
|
|
24097
|
+
"The managed npm package executable declaration is invalid"
|
|
24042
24098
|
);
|
|
24043
24099
|
}
|
|
24044
|
-
|
|
24100
|
+
function verifyPackageLock(lock, definition) {
|
|
24101
|
+
if (lock["lockfileVersion"] !== 3) {
|
|
24102
|
+
throw new ManagedNpmPackageError(
|
|
24103
|
+
"managed_package_verification_failed",
|
|
24104
|
+
"The managed npm package lockfile is invalid"
|
|
24105
|
+
);
|
|
24106
|
+
}
|
|
24107
|
+
const packages = lock["packages"];
|
|
24108
|
+
if (!isRecord5(packages)) {
|
|
24109
|
+
throw new ManagedNpmPackageError(
|
|
24110
|
+
"managed_package_verification_failed",
|
|
24111
|
+
"The managed npm package lockfile is invalid"
|
|
24112
|
+
);
|
|
24113
|
+
}
|
|
24114
|
+
const suffix = `node_modules/${definition.packageName}`;
|
|
24115
|
+
let entry;
|
|
24116
|
+
let matches = 0;
|
|
24117
|
+
for (const [key, candidate] of Object.entries(packages)) {
|
|
24118
|
+
const normalizedKey = key.replaceAll("\\", "/");
|
|
24119
|
+
if (normalizedKey === suffix || normalizedKey.endsWith(`/${suffix}`)) {
|
|
24120
|
+
entry = candidate;
|
|
24121
|
+
matches += 1;
|
|
24122
|
+
}
|
|
24123
|
+
}
|
|
24124
|
+
if (matches !== 1 || !isRecord5(entry) || entry["integrity"] !== definition.integrity || entry["resolved"] !== definition.tarballUrl || entry["version"] !== definition.version) {
|
|
24125
|
+
throw new ManagedNpmPackageError(
|
|
24126
|
+
"managed_package_verification_failed",
|
|
24127
|
+
"The managed npm package lockfile does not match the pinned artifact"
|
|
24128
|
+
);
|
|
24129
|
+
}
|
|
24130
|
+
}
|
|
24131
|
+
async function validateManagedNpmPackage(root, definition) {
|
|
24132
|
+
try {
|
|
24133
|
+
return await validateManagedNpmPackageContents(root, definition);
|
|
24134
|
+
} catch (error61) {
|
|
24135
|
+
if (error61 instanceof ManagedNpmPackageError) {
|
|
24136
|
+
throw error61;
|
|
24137
|
+
}
|
|
24138
|
+
throw new ManagedNpmPackageError(
|
|
24139
|
+
"managed_package_verification_failed",
|
|
24140
|
+
"The managed npm package is invalid",
|
|
24141
|
+
{ cause: error61 }
|
|
24142
|
+
);
|
|
24143
|
+
}
|
|
24144
|
+
}
|
|
24145
|
+
async function validateManagedNpmPackageContents(root, definition) {
|
|
24045
24146
|
const rootPath = await realpath2(root);
|
|
24046
24147
|
const packageRoot = await realpath2(
|
|
24047
|
-
packagePath(rootPath,
|
|
24148
|
+
packagePath(rootPath, definition.packageName)
|
|
24149
|
+
);
|
|
24150
|
+
if (!isContainedPath(rootPath, packageRoot)) {
|
|
24151
|
+
throw new ManagedNpmPackageError(
|
|
24152
|
+
"managed_package_verification_failed",
|
|
24153
|
+
"The managed npm package escaped its private cache"
|
|
24154
|
+
);
|
|
24155
|
+
}
|
|
24156
|
+
const metadata = await readJsonRecord(
|
|
24157
|
+
join5(packageRoot, "package.json"),
|
|
24158
|
+
PACKAGE_METADATA_LIMIT_BYTES
|
|
24048
24159
|
);
|
|
24049
|
-
|
|
24050
|
-
|
|
24051
|
-
|
|
24052
|
-
"
|
|
24053
|
-
"The managed adapter package escaped its private cache"
|
|
24160
|
+
if (metadata["name"] !== definition.packageName || metadata["version"] !== definition.version) {
|
|
24161
|
+
throw new ManagedNpmPackageError(
|
|
24162
|
+
"managed_package_verification_failed",
|
|
24163
|
+
"The managed npm package identity is invalid"
|
|
24054
24164
|
);
|
|
24055
24165
|
}
|
|
24056
|
-
|
|
24057
|
-
|
|
24058
|
-
|
|
24059
|
-
|
|
24060
|
-
|
|
24166
|
+
if (definition instanceof SriManagedNpmPackageDefinition) {
|
|
24167
|
+
verifyPackageLock(
|
|
24168
|
+
await readJsonRecord(
|
|
24169
|
+
join5(rootPath, "package-lock.json"),
|
|
24170
|
+
PACKAGE_LOCK_LIMIT_BYTES
|
|
24171
|
+
),
|
|
24172
|
+
definition
|
|
24061
24173
|
);
|
|
24062
24174
|
}
|
|
24063
|
-
const declaredBin = readBinPath(metadata,
|
|
24175
|
+
const declaredBin = readBinPath(metadata, definition.executableName);
|
|
24064
24176
|
const executable = await resolveExecutablePath(
|
|
24065
24177
|
join5(packageRoot, declaredBin)
|
|
24066
24178
|
);
|
|
24067
|
-
if (executable === null) {
|
|
24068
|
-
throw new
|
|
24069
|
-
"
|
|
24070
|
-
"The managed
|
|
24071
|
-
);
|
|
24072
|
-
}
|
|
24073
|
-
const executableDifference = relative(rootPath, executable.path);
|
|
24074
|
-
if (executableDifference.startsWith("..") || executableDifference.length === 0) {
|
|
24075
|
-
throw new ManagedAdapterInstallError(
|
|
24076
|
-
"adapter_verification_failed",
|
|
24077
|
-
"The managed adapter executable escaped its private cache"
|
|
24179
|
+
if (executable === null || !isContainedPath(rootPath, executable.path)) {
|
|
24180
|
+
throw new ManagedNpmPackageError(
|
|
24181
|
+
"managed_package_verification_failed",
|
|
24182
|
+
"The managed npm package executable is invalid"
|
|
24078
24183
|
);
|
|
24079
24184
|
}
|
|
24080
24185
|
return executable;
|
|
24081
24186
|
}
|
|
24082
|
-
var
|
|
24083
|
-
|
|
24084
|
-
#stateDirectory;
|
|
24085
|
-
constructor(options) {
|
|
24086
|
-
this.#environment = options.environment;
|
|
24087
|
-
this.#stateDirectory = options.stateDirectory;
|
|
24088
|
-
}
|
|
24089
|
-
install = async (specification, signal) => {
|
|
24187
|
+
var ManagedNpmPackageInstaller = class {
|
|
24188
|
+
install = async (root, definition, environment, signal) => {
|
|
24090
24189
|
signal.throwIfAborted();
|
|
24091
|
-
const agentCache = join5(this.#stateDirectory, "adapters", specification.id);
|
|
24092
|
-
const published = join5(agentCache, specification.adapterVersion);
|
|
24093
24190
|
try {
|
|
24094
|
-
const metadata = await stat2(
|
|
24191
|
+
const metadata = await stat2(root);
|
|
24095
24192
|
if (metadata.isDirectory()) {
|
|
24096
|
-
return await
|
|
24193
|
+
return await validateManagedNpmPackage(root, definition);
|
|
24097
24194
|
}
|
|
24098
24195
|
} catch (error61) {
|
|
24099
24196
|
if (!(error61 instanceof Error) || !("code" in error61) || error61.code !== "ENOENT") {
|
|
24100
24197
|
throw error61;
|
|
24101
24198
|
}
|
|
24102
24199
|
}
|
|
24103
|
-
|
|
24200
|
+
const parent = dirname3(root);
|
|
24201
|
+
await mkdir(parent, { mode: 448, recursive: true });
|
|
24104
24202
|
const staging = await mkdtemp(
|
|
24105
|
-
join5(
|
|
24203
|
+
join5(parent, `.${definition.version}.staging-`)
|
|
24106
24204
|
);
|
|
24107
24205
|
try {
|
|
24108
24206
|
const npm = await findExecutableOnPath(
|
|
24109
24207
|
process.platform === "win32" ? "npm.cmd" : "npm",
|
|
24110
|
-
|
|
24208
|
+
environment
|
|
24111
24209
|
);
|
|
24112
24210
|
if (npm === null) {
|
|
24113
|
-
throw new
|
|
24211
|
+
throw new ManagedNpmPackageError(
|
|
24114
24212
|
"package_manager_not_found",
|
|
24115
|
-
"A supported npm executable is required to install the
|
|
24213
|
+
"A supported npm executable is required to install the managed package"
|
|
24116
24214
|
);
|
|
24117
24215
|
}
|
|
24118
24216
|
await runBoundedProcess({
|
|
@@ -24124,51 +24222,57 @@ var ManagedAdapterInstaller = class {
|
|
|
24124
24222
|
"--ignore-scripts",
|
|
24125
24223
|
"--no-audit",
|
|
24126
24224
|
"--no-fund",
|
|
24127
|
-
"--package-lock=
|
|
24128
|
-
"--save
|
|
24225
|
+
"--package-lock=true",
|
|
24226
|
+
"--save-exact",
|
|
24129
24227
|
"--registry=https://registry.npmjs.org/",
|
|
24130
|
-
`${
|
|
24228
|
+
`${definition.packageName}@${definition.version}`
|
|
24131
24229
|
],
|
|
24132
24230
|
command: npm.path,
|
|
24133
24231
|
cwd: staging,
|
|
24134
24232
|
environment: {
|
|
24135
24233
|
HOME: join5(staging, "home"),
|
|
24136
24234
|
NPM_CONFIG_AUDIT: "false",
|
|
24235
|
+
NPM_CONFIG_CACHE: join5(staging, ".npm-cache"),
|
|
24137
24236
|
NPM_CONFIG_FUND: "false",
|
|
24138
24237
|
NPM_CONFIG_IGNORE_SCRIPTS: "true",
|
|
24139
24238
|
NPM_CONFIG_OMIT: "optional",
|
|
24239
|
+
NPM_CONFIG_PACKAGE_LOCK: "true",
|
|
24140
24240
|
NPM_CONFIG_REGISTRY: "https://registry.npmjs.org/",
|
|
24141
24241
|
PATH: `${dirname3(process.execPath)}${delimiter}/usr/bin${delimiter}/bin`
|
|
24142
24242
|
},
|
|
24143
24243
|
outputLimitBytes: 64 * 1024,
|
|
24144
24244
|
signal,
|
|
24145
|
-
timeoutMilliseconds:
|
|
24245
|
+
timeoutMilliseconds: INSTALL_TIMEOUT_MILLISECONDS
|
|
24146
24246
|
});
|
|
24147
|
-
await
|
|
24247
|
+
await Promise.all([
|
|
24248
|
+
rm(join5(staging, ".npm-cache"), { force: true, recursive: true }),
|
|
24249
|
+
rm(join5(staging, "home"), { force: true, recursive: true })
|
|
24250
|
+
]);
|
|
24251
|
+
await validateManagedNpmPackage(staging, definition);
|
|
24148
24252
|
try {
|
|
24149
|
-
await rename(staging,
|
|
24253
|
+
await rename(staging, root);
|
|
24150
24254
|
} catch (error61) {
|
|
24151
24255
|
try {
|
|
24152
|
-
return await
|
|
24256
|
+
return await validateManagedNpmPackage(root, definition);
|
|
24153
24257
|
} catch {
|
|
24154
|
-
throw new
|
|
24155
|
-
"
|
|
24156
|
-
"The managed
|
|
24258
|
+
throw new ManagedNpmPackageError(
|
|
24259
|
+
"managed_package_publish_failed",
|
|
24260
|
+
"The managed npm package could not be published",
|
|
24157
24261
|
{ cause: error61 }
|
|
24158
24262
|
);
|
|
24159
24263
|
}
|
|
24160
24264
|
}
|
|
24161
|
-
return await
|
|
24265
|
+
return await validateManagedNpmPackage(root, definition);
|
|
24162
24266
|
} catch (error61) {
|
|
24163
24267
|
if (signal.aborted) {
|
|
24164
24268
|
signal.throwIfAborted();
|
|
24165
24269
|
}
|
|
24166
|
-
if (error61 instanceof
|
|
24270
|
+
if (error61 instanceof ManagedNpmPackageError) {
|
|
24167
24271
|
throw error61;
|
|
24168
24272
|
}
|
|
24169
|
-
throw new
|
|
24170
|
-
"
|
|
24171
|
-
"The pinned
|
|
24273
|
+
throw new ManagedNpmPackageError(
|
|
24274
|
+
"managed_package_install_failed",
|
|
24275
|
+
"The pinned npm package could not be installed",
|
|
24172
24276
|
{ cause: error61 }
|
|
24173
24277
|
);
|
|
24174
24278
|
} finally {
|
|
@@ -24177,20 +24281,152 @@ var ManagedAdapterInstaller = class {
|
|
|
24177
24281
|
};
|
|
24178
24282
|
};
|
|
24179
24283
|
|
|
24284
|
+
// src/agent-installation/managed-adapter-installer.ts
|
|
24285
|
+
var ManagedAdapterInstallError = class extends Error {
|
|
24286
|
+
code;
|
|
24287
|
+
constructor(code, message, options = {}) {
|
|
24288
|
+
super(message, options);
|
|
24289
|
+
this.code = code;
|
|
24290
|
+
this.name = "ManagedAdapterInstallError";
|
|
24291
|
+
}
|
|
24292
|
+
};
|
|
24293
|
+
function translateError(error61) {
|
|
24294
|
+
if (error61 instanceof ManagedAdapterInstallError) {
|
|
24295
|
+
return error61;
|
|
24296
|
+
}
|
|
24297
|
+
if (error61 instanceof ManagedNpmPackageError) {
|
|
24298
|
+
if (error61.code === "package_manager_not_found") {
|
|
24299
|
+
return new ManagedAdapterInstallError(
|
|
24300
|
+
error61.code,
|
|
24301
|
+
"A supported npm executable is required to install the ACP adapter",
|
|
24302
|
+
{ cause: error61 }
|
|
24303
|
+
);
|
|
24304
|
+
}
|
|
24305
|
+
if (error61.code === "managed_package_verification_failed") {
|
|
24306
|
+
return new ManagedAdapterInstallError(
|
|
24307
|
+
"adapter_verification_failed",
|
|
24308
|
+
"The managed adapter did not match its pinned artifact",
|
|
24309
|
+
{ cause: error61 }
|
|
24310
|
+
);
|
|
24311
|
+
}
|
|
24312
|
+
if (error61.code === "managed_package_publish_failed") {
|
|
24313
|
+
return new ManagedAdapterInstallError(
|
|
24314
|
+
"adapter_publish_failed",
|
|
24315
|
+
"The managed adapter could not be published",
|
|
24316
|
+
{ cause: error61 }
|
|
24317
|
+
);
|
|
24318
|
+
}
|
|
24319
|
+
}
|
|
24320
|
+
return new ManagedAdapterInstallError(
|
|
24321
|
+
"adapter_install_failed",
|
|
24322
|
+
"The pinned ACP adapter could not be installed",
|
|
24323
|
+
{ cause: error61 }
|
|
24324
|
+
);
|
|
24325
|
+
}
|
|
24326
|
+
async function validateManagedAdapter(root, specification) {
|
|
24327
|
+
try {
|
|
24328
|
+
return await validateManagedNpmPackage(
|
|
24329
|
+
root,
|
|
24330
|
+
specification.adapterPackageDefinition
|
|
24331
|
+
);
|
|
24332
|
+
} catch (error61) {
|
|
24333
|
+
throw translateError(error61);
|
|
24334
|
+
}
|
|
24335
|
+
}
|
|
24336
|
+
var ManagedAdapterInstaller = class {
|
|
24337
|
+
#environment;
|
|
24338
|
+
#npmInstaller;
|
|
24339
|
+
#stateDirectory;
|
|
24340
|
+
constructor(options, npmInstaller = new ManagedNpmPackageInstaller()) {
|
|
24341
|
+
this.#environment = options.environment;
|
|
24342
|
+
this.#npmInstaller = npmInstaller;
|
|
24343
|
+
this.#stateDirectory = options.stateDirectory;
|
|
24344
|
+
}
|
|
24345
|
+
install = async (specification, signal) => {
|
|
24346
|
+
const root = join6(
|
|
24347
|
+
this.#stateDirectory,
|
|
24348
|
+
"adapters",
|
|
24349
|
+
specification.id,
|
|
24350
|
+
specification.adapterVersion
|
|
24351
|
+
);
|
|
24352
|
+
try {
|
|
24353
|
+
return await this.#npmInstaller.install(
|
|
24354
|
+
root,
|
|
24355
|
+
specification.adapterPackageDefinition,
|
|
24356
|
+
this.#environment,
|
|
24357
|
+
signal
|
|
24358
|
+
);
|
|
24359
|
+
} catch (error61) {
|
|
24360
|
+
if (signal.aborted) {
|
|
24361
|
+
signal.throwIfAborted();
|
|
24362
|
+
}
|
|
24363
|
+
throw translateError(error61);
|
|
24364
|
+
}
|
|
24365
|
+
};
|
|
24366
|
+
};
|
|
24367
|
+
|
|
24368
|
+
// src/agent-installation/pi-managed-packages.ts
|
|
24369
|
+
var PI_ACP_PACKAGE = new SriManagedNpmPackageDefinition(
|
|
24370
|
+
"pi-acp",
|
|
24371
|
+
"0.0.33",
|
|
24372
|
+
"pi-acp",
|
|
24373
|
+
"sha512-vX9kY1tK14E72G4dBAx+RGCk/k7XPjTHls6dLUxA8WSkBav6B6JHuSBv3eusp50LCR/GTRsR2kIKsG0Z5jANzw==",
|
|
24374
|
+
"https://registry.npmjs.org/pi-acp/-/pi-acp-0.0.33.tgz"
|
|
24375
|
+
);
|
|
24376
|
+
var PI_AGENT_PACKAGE = new SriManagedNpmPackageDefinition(
|
|
24377
|
+
"@earendil-works/pi-coding-agent",
|
|
24378
|
+
"0.85.0",
|
|
24379
|
+
"pi",
|
|
24380
|
+
"sha512-INxVkLAVfAMju5MojJpmyu/0bMP+r+ffZuS7UqVv32E2JwHBRbcHfELDfmFNvapEbgYfKN2r9OYO1p3TqDBR+g==",
|
|
24381
|
+
"https://registry.npmjs.org/@earendil-works/pi-coding-agent/-/pi-coding-agent-0.85.0.tgz"
|
|
24382
|
+
);
|
|
24383
|
+
|
|
24180
24384
|
// src/agent-catalog/discover-local-agents.ts
|
|
24181
24385
|
var VERSION_PROBE_TIMEOUT_MILLISECONDS = 3e3;
|
|
24182
24386
|
var ACP_PROBE_TIMEOUT_MILLISECONDS = 5e3;
|
|
24183
24387
|
var ACP_OUTPUT_LIMIT_BYTES = 1024 * 1024;
|
|
24388
|
+
var DEFAULT_PROMPT_TIMEOUT_MILLISECONDS = 30 * 60 * 1e3;
|
|
24389
|
+
var PI_ACP_PROBE_TIMEOUT_MILLISECONDS = 3e4;
|
|
24390
|
+
var PI_PROMPT_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
|
|
24184
24391
|
var LocalAgentSpecification = class {
|
|
24392
|
+
acpProbeTimeoutMilliseconds = ACP_PROBE_TIMEOUT_MILLISECONDS;
|
|
24393
|
+
authenticationCommand = () => "";
|
|
24394
|
+
adapterVersionArguments = ["--version"];
|
|
24395
|
+
agentVersionArguments = ["--version"];
|
|
24396
|
+
promptTimeoutMilliseconds = DEFAULT_PROMPT_TIMEOUT_MILLISECONDS;
|
|
24397
|
+
get adapterExecutable() {
|
|
24398
|
+
return this.adapterPackageDefinition.executableName;
|
|
24399
|
+
}
|
|
24400
|
+
get adapterPackage() {
|
|
24401
|
+
return this.adapterPackageDefinition.packageName;
|
|
24402
|
+
}
|
|
24403
|
+
get adapterVersion() {
|
|
24404
|
+
return this.adapterPackageDefinition.version;
|
|
24405
|
+
}
|
|
24406
|
+
resolveManagedAgent = async (stateDirectory, platform) => {
|
|
24407
|
+
const executable = await resolveExecutablePath(
|
|
24408
|
+
join7(stateDirectory, ...this.managedAgentExecutablePath),
|
|
24409
|
+
platform
|
|
24410
|
+
);
|
|
24411
|
+
if (executable === null) {
|
|
24412
|
+
throw new Error("The managed Agent executable is unavailable");
|
|
24413
|
+
}
|
|
24414
|
+
return executable;
|
|
24415
|
+
};
|
|
24185
24416
|
recoveryCommand = () => `npm install -g --omit=optional ${this.adapterPackage}@${this.adapterVersion}`;
|
|
24186
24417
|
supportsInstallation = (platform, architecture) => (platform === "darwin" || platform === "linux") && (architecture === "arm64" || architecture === "x64");
|
|
24418
|
+
verifyAcp = (_connection, _initialized, _defaultWorkspace, _signal) => Promise.resolve();
|
|
24419
|
+
};
|
|
24420
|
+
var BridgedAcpAgentDefinition = class extends LocalAgentSpecification {
|
|
24187
24421
|
};
|
|
24188
|
-
var CodexAgentSpecification = class extends
|
|
24422
|
+
var CodexAgentSpecification = class extends BridgedAcpAgentDefinition {
|
|
24189
24423
|
adapterEnvironmentVariable = "CODEX_PATH";
|
|
24190
|
-
adapterExecutable = "codex-acp";
|
|
24191
24424
|
adapterOverrideVariable = "MOBIUS_CODEX_ACP_PATH";
|
|
24192
|
-
|
|
24193
|
-
|
|
24425
|
+
adapterPackageDefinition = new ManagedNpmPackageDefinition(
|
|
24426
|
+
"@agentclientprotocol/codex-acp",
|
|
24427
|
+
"1.8.0",
|
|
24428
|
+
"codex-acp"
|
|
24429
|
+
);
|
|
24194
24430
|
agentExecutable = "codex";
|
|
24195
24431
|
agentOverrideVariable = "MOBIUS_CODEX_PATH";
|
|
24196
24432
|
id = "codex";
|
|
@@ -24207,12 +24443,14 @@ var CodexAgentSpecification = class extends LocalAgentSpecification {
|
|
|
24207
24443
|
];
|
|
24208
24444
|
managedAgentExecutablePath = ["agents", "codex", "bin", "codex"];
|
|
24209
24445
|
};
|
|
24210
|
-
var ClaudeCodeAgentSpecification = class extends
|
|
24446
|
+
var ClaudeCodeAgentSpecification = class extends BridgedAcpAgentDefinition {
|
|
24211
24447
|
adapterEnvironmentVariable = "CLAUDE_CODE_EXECUTABLE";
|
|
24212
|
-
adapterExecutable = "claude-agent-acp";
|
|
24213
24448
|
adapterOverrideVariable = "MOBIUS_CLAUDE_ACP_PATH";
|
|
24214
|
-
|
|
24215
|
-
|
|
24449
|
+
adapterPackageDefinition = new ManagedNpmPackageDefinition(
|
|
24450
|
+
"@agentclientprotocol/claude-agent-acp",
|
|
24451
|
+
"0.73.0",
|
|
24452
|
+
"claude-agent-acp"
|
|
24453
|
+
);
|
|
24216
24454
|
agentExecutable = "claude";
|
|
24217
24455
|
agentOverrideVariable = "MOBIUS_CLAUDE_PATH";
|
|
24218
24456
|
id = "claude";
|
|
@@ -24236,10 +24474,86 @@ var ClaudeCodeAgentSpecification = class extends LocalAgentSpecification {
|
|
|
24236
24474
|
"claude"
|
|
24237
24475
|
];
|
|
24238
24476
|
};
|
|
24477
|
+
var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
|
|
24478
|
+
acpProbeTimeoutMilliseconds = PI_ACP_PROBE_TIMEOUT_MILLISECONDS;
|
|
24479
|
+
adapterEnvironmentVariable = "PI_ACP_PI_COMMAND";
|
|
24480
|
+
adapterOverrideVariable = "MOBIUS_PI_ACP_PATH";
|
|
24481
|
+
adapterPackageDefinition = PI_ACP_PACKAGE;
|
|
24482
|
+
adapterVersionArguments = [];
|
|
24483
|
+
authenticationCommand = () => "pi-acp --terminal-login";
|
|
24484
|
+
agentExecutable = "pi";
|
|
24485
|
+
agentOverrideVariable = "MOBIUS_PI_PATH";
|
|
24486
|
+
id = "pi";
|
|
24487
|
+
label = "Pi";
|
|
24488
|
+
managedAdapterExecutablePath = [
|
|
24489
|
+
"adapters",
|
|
24490
|
+
"pi",
|
|
24491
|
+
PI_ACP_PACKAGE.version,
|
|
24492
|
+
"node_modules",
|
|
24493
|
+
"pi-acp",
|
|
24494
|
+
"dist",
|
|
24495
|
+
"index.js"
|
|
24496
|
+
];
|
|
24497
|
+
managedAgentExecutablePath = [
|
|
24498
|
+
"agents",
|
|
24499
|
+
"pi",
|
|
24500
|
+
PI_AGENT_PACKAGE.version,
|
|
24501
|
+
"node_modules",
|
|
24502
|
+
"@earendil-works",
|
|
24503
|
+
"pi-coding-agent",
|
|
24504
|
+
"dist",
|
|
24505
|
+
"bundle",
|
|
24506
|
+
"cli.js"
|
|
24507
|
+
];
|
|
24508
|
+
promptTimeoutMilliseconds = PI_PROMPT_TIMEOUT_MILLISECONDS;
|
|
24509
|
+
resolveManagedAgent = async (stateDirectory, _platform) => await validateManagedNpmPackage(
|
|
24510
|
+
join7(stateDirectory, "agents", this.id, PI_AGENT_PACKAGE.version),
|
|
24511
|
+
PI_AGENT_PACKAGE
|
|
24512
|
+
);
|
|
24513
|
+
verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
|
|
24514
|
+
const capabilities = initialized.agentCapabilities ?? {};
|
|
24515
|
+
if (capabilities.loadSession !== true) {
|
|
24516
|
+
throw new AgentProbeError(
|
|
24517
|
+
"acp_incompatible",
|
|
24518
|
+
"Pi ACP adapter does not support session recovery"
|
|
24519
|
+
);
|
|
24520
|
+
}
|
|
24521
|
+
const session = await connection.agent.request(
|
|
24522
|
+
methods3.agent.session.new,
|
|
24523
|
+
{
|
|
24524
|
+
additionalDirectories: [],
|
|
24525
|
+
cwd: defaultWorkspace,
|
|
24526
|
+
mcpServers: []
|
|
24527
|
+
},
|
|
24528
|
+
{ cancellationSignal: signal }
|
|
24529
|
+
);
|
|
24530
|
+
if (session.sessionId.length === 0) {
|
|
24531
|
+
throw new AgentProbeError(
|
|
24532
|
+
"acp_incompatible",
|
|
24533
|
+
"Pi ACP adapter returned an invalid session"
|
|
24534
|
+
);
|
|
24535
|
+
}
|
|
24536
|
+
const prompt = await connection.agent.request(
|
|
24537
|
+
methods3.agent.session.prompt,
|
|
24538
|
+
{
|
|
24539
|
+
prompt: [{ text: "/session", type: "text" }],
|
|
24540
|
+
sessionId: session.sessionId
|
|
24541
|
+
},
|
|
24542
|
+
{ cancellationSignal: signal }
|
|
24543
|
+
);
|
|
24544
|
+
if (prompt.stopReason !== "end_turn") {
|
|
24545
|
+
throw new AgentProbeError(
|
|
24546
|
+
"acp_incompatible",
|
|
24547
|
+
"Pi ACP adapter did not complete its conformance prompt"
|
|
24548
|
+
);
|
|
24549
|
+
}
|
|
24550
|
+
};
|
|
24551
|
+
};
|
|
24239
24552
|
function supportedLocalAgentSpecifications() {
|
|
24240
24553
|
return Object.freeze([
|
|
24241
24554
|
new CodexAgentSpecification(),
|
|
24242
|
-
new ClaudeCodeAgentSpecification()
|
|
24555
|
+
new ClaudeCodeAgentSpecification(),
|
|
24556
|
+
new PiAgentSpecification()
|
|
24243
24557
|
]);
|
|
24244
24558
|
}
|
|
24245
24559
|
var AgentDiscovery = class {
|
|
@@ -24292,6 +24606,14 @@ var IncompatibleAdapter = class extends UnavailableAgent {
|
|
|
24292
24606
|
super(specification);
|
|
24293
24607
|
}
|
|
24294
24608
|
};
|
|
24609
|
+
var AuthenticationRequiredAgent = class extends UnavailableAgent {
|
|
24610
|
+
code = "authentication_required";
|
|
24611
|
+
message = "Agent authentication is required";
|
|
24612
|
+
status = "authentication_required";
|
|
24613
|
+
constructor(specification) {
|
|
24614
|
+
super(specification);
|
|
24615
|
+
}
|
|
24616
|
+
};
|
|
24295
24617
|
var LocalAgentInventory = class {
|
|
24296
24618
|
available;
|
|
24297
24619
|
discoveries;
|
|
@@ -24313,7 +24635,10 @@ var LocalAgentInventory = class {
|
|
|
24313
24635
|
this.discoveries = Object.freeze([...discoveries]);
|
|
24314
24636
|
this.installable = Object.freeze(
|
|
24315
24637
|
unavailable.filter(
|
|
24316
|
-
(discovery) => discovery.specification.supportsInstallation(
|
|
24638
|
+
(discovery) => !(discovery instanceof AuthenticationRequiredAgent) && discovery.specification.supportsInstallation(
|
|
24639
|
+
platform,
|
|
24640
|
+
architecture
|
|
24641
|
+
)
|
|
24317
24642
|
).map(
|
|
24318
24643
|
(discovery) => new InstallableAgentDefinition(
|
|
24319
24644
|
discovery.specification.id,
|
|
@@ -24340,17 +24665,21 @@ var DiscoveryAcpHandler = class {
|
|
|
24340
24665
|
onPermission = (_request, _signal) => Promise.reject(new Error("ACP probe does not grant permissions"));
|
|
24341
24666
|
onUpdate = (_notification) => Promise.resolve();
|
|
24342
24667
|
};
|
|
24343
|
-
async function resolveManagedExecutable(
|
|
24344
|
-
|
|
24345
|
-
|
|
24346
|
-
|
|
24347
|
-
|
|
24668
|
+
async function resolveManagedExecutable(specification, options) {
|
|
24669
|
+
try {
|
|
24670
|
+
return await specification.resolveManagedAgent(
|
|
24671
|
+
readStateDirectory(options.environment),
|
|
24672
|
+
options.platform ?? process.platform
|
|
24673
|
+
);
|
|
24674
|
+
} catch {
|
|
24675
|
+
return null;
|
|
24676
|
+
}
|
|
24348
24677
|
}
|
|
24349
24678
|
async function resolveManagedAdapterExecutable(specification, options) {
|
|
24350
24679
|
let managed;
|
|
24351
24680
|
try {
|
|
24352
24681
|
managed = await validateManagedAdapter(
|
|
24353
|
-
|
|
24682
|
+
join7(
|
|
24354
24683
|
readStateDirectory(options.environment),
|
|
24355
24684
|
"adapters",
|
|
24356
24685
|
specification.id,
|
|
@@ -24366,7 +24695,7 @@ async function resolveManagedAdapterExecutable(specification, options) {
|
|
|
24366
24695
|
async function resolveSpecificationExecutables(executableName, overrideVariable, resolveManaged, options) {
|
|
24367
24696
|
const override = options.environment[overrideVariable];
|
|
24368
24697
|
if (override !== void 0) {
|
|
24369
|
-
if (override.length === 0 || !
|
|
24698
|
+
if (override.length === 0 || !isAbsolute2(override)) {
|
|
24370
24699
|
return [];
|
|
24371
24700
|
}
|
|
24372
24701
|
const executable = await resolveExecutablePath(override, options.platform);
|
|
@@ -24390,10 +24719,7 @@ async function resolveAgentExecutables(specification, options) {
|
|
|
24390
24719
|
return await resolveSpecificationExecutables(
|
|
24391
24720
|
specification.agentExecutable,
|
|
24392
24721
|
specification.agentOverrideVariable,
|
|
24393
|
-
async () => await resolveManagedExecutable(
|
|
24394
|
-
specification.managedAgentExecutablePath,
|
|
24395
|
-
options
|
|
24396
|
-
),
|
|
24722
|
+
async () => await resolveManagedExecutable(specification, options),
|
|
24397
24723
|
options
|
|
24398
24724
|
);
|
|
24399
24725
|
}
|
|
@@ -24416,9 +24742,9 @@ async function resolveAdapterExecutable(specification, options) {
|
|
|
24416
24742
|
function normalizedVersion(output2) {
|
|
24417
24743
|
return output2.trim().split(/\r?\n/, 1)[0]?.trim().slice(0, 128) ?? "";
|
|
24418
24744
|
}
|
|
24419
|
-
async function probeVersion(executable, environment, defaultWorkspace, signal) {
|
|
24745
|
+
async function probeVersion(executable, arguments_, environment, defaultWorkspace, signal) {
|
|
24420
24746
|
const result = await runBoundedProcess({
|
|
24421
|
-
arguments:
|
|
24747
|
+
arguments: arguments_,
|
|
24422
24748
|
command: executable.path,
|
|
24423
24749
|
cwd: defaultWorkspace,
|
|
24424
24750
|
environment,
|
|
@@ -24448,6 +24774,7 @@ async function findVerifiedAgentExecutable(specification, options) {
|
|
|
24448
24774
|
try {
|
|
24449
24775
|
const version2 = await probeVersion(
|
|
24450
24776
|
executable,
|
|
24777
|
+
specification.agentVersionArguments,
|
|
24451
24778
|
options.environment,
|
|
24452
24779
|
options.defaultWorkspace,
|
|
24453
24780
|
options.signal
|
|
@@ -24516,14 +24843,14 @@ function writableAcpStream(output2) {
|
|
|
24516
24843
|
}
|
|
24517
24844
|
});
|
|
24518
24845
|
}
|
|
24519
|
-
async function probeAcp(agent, environment, defaultWorkspace, signal) {
|
|
24846
|
+
async function probeAcp(specification, agent, environment, defaultWorkspace, signal) {
|
|
24520
24847
|
signal.throwIfAborted();
|
|
24521
24848
|
const controller = new AbortController();
|
|
24522
24849
|
let timedOut = false;
|
|
24523
24850
|
const timeout = setTimeout(() => {
|
|
24524
24851
|
timedOut = true;
|
|
24525
24852
|
controller.abort(new Error("ACP probe timed out"));
|
|
24526
|
-
},
|
|
24853
|
+
}, specification.acpProbeTimeoutMilliseconds);
|
|
24527
24854
|
const abort = () => controller.abort(signal.reason);
|
|
24528
24855
|
signal.addEventListener("abort", abort, { once: true });
|
|
24529
24856
|
if (signal.aborted) {
|
|
@@ -24582,6 +24909,13 @@ async function probeAcp(agent, environment, defaultWorkspace, signal) {
|
|
|
24582
24909
|
"ACP adapter selected an unsupported protocol version"
|
|
24583
24910
|
);
|
|
24584
24911
|
}
|
|
24912
|
+
await specification.verifyAcp(
|
|
24913
|
+
connection,
|
|
24914
|
+
initialized,
|
|
24915
|
+
defaultWorkspace,
|
|
24916
|
+
controller.signal
|
|
24917
|
+
);
|
|
24918
|
+
return normalizedVersion(initialized.agentInfo?.version ?? "");
|
|
24585
24919
|
} catch (error61) {
|
|
24586
24920
|
if (signal.aborted) {
|
|
24587
24921
|
signal.throwIfAborted();
|
|
@@ -24596,6 +24930,13 @@ async function probeAcp(agent, environment, defaultWorkspace, signal) {
|
|
|
24596
24930
|
if (error61 instanceof AgentProbeError) {
|
|
24597
24931
|
throw error61;
|
|
24598
24932
|
}
|
|
24933
|
+
if (error61 instanceof RequestError && error61.code === -32e3 && specification.authenticationCommand().length > 0) {
|
|
24934
|
+
throw new AgentProbeError(
|
|
24935
|
+
"authentication_required",
|
|
24936
|
+
"Agent authentication is required",
|
|
24937
|
+
{ cause: error61 }
|
|
24938
|
+
);
|
|
24939
|
+
}
|
|
24599
24940
|
throw new AgentProbeError(
|
|
24600
24941
|
"acp_incompatible",
|
|
24601
24942
|
"ACP adapter initialization failed",
|
|
@@ -24612,6 +24953,9 @@ async function probeAcp(agent, environment, defaultWorkspace, signal) {
|
|
|
24612
24953
|
}
|
|
24613
24954
|
function probeFailure(specification, executableKind, error61) {
|
|
24614
24955
|
if (error61 instanceof AgentProbeError) {
|
|
24956
|
+
if (error61.code === "authentication_required") {
|
|
24957
|
+
return new AuthenticationRequiredAgent(specification);
|
|
24958
|
+
}
|
|
24615
24959
|
return error61.code === "acp_incompatible" ? new IncompatibleAdapter(specification) : new ProbeFailed(specification, error61.code, error61.message);
|
|
24616
24960
|
}
|
|
24617
24961
|
if (error61 instanceof ProcessExecutionError) {
|
|
@@ -24646,6 +24990,7 @@ async function discoverSpecification(specification, options) {
|
|
|
24646
24990
|
try {
|
|
24647
24991
|
agentVersion = await probeVersion(
|
|
24648
24992
|
agent,
|
|
24993
|
+
specification.agentVersionArguments,
|
|
24649
24994
|
options.environment,
|
|
24650
24995
|
options.defaultWorkspace,
|
|
24651
24996
|
options.signal
|
|
@@ -24660,15 +25005,18 @@ async function discoverSpecification(specification, options) {
|
|
|
24660
25005
|
for (const adapter of adapters) {
|
|
24661
25006
|
let adapterVersion = "";
|
|
24662
25007
|
try {
|
|
24663
|
-
|
|
24664
|
-
|
|
24665
|
-
|
|
24666
|
-
|
|
24667
|
-
|
|
24668
|
-
|
|
24669
|
-
|
|
24670
|
-
|
|
24671
|
-
|
|
25008
|
+
if (specification.adapterVersionArguments.length > 0) {
|
|
25009
|
+
adapterVersion = await probeVersion(
|
|
25010
|
+
adapter,
|
|
25011
|
+
specification.adapterVersionArguments,
|
|
25012
|
+
{
|
|
25013
|
+
...options.environment,
|
|
25014
|
+
[specification.adapterEnvironmentVariable]: agent.path
|
|
25015
|
+
},
|
|
25016
|
+
options.defaultWorkspace,
|
|
25017
|
+
options.signal
|
|
25018
|
+
);
|
|
25019
|
+
}
|
|
24672
25020
|
} catch (error61) {
|
|
24673
25021
|
if (options.signal.aborted) {
|
|
24674
25022
|
options.signal.throwIfAborted();
|
|
@@ -24685,16 +25033,39 @@ async function discoverSpecification(specification, options) {
|
|
|
24685
25033
|
adapterVersion,
|
|
24686
25034
|
agentVersion,
|
|
24687
25035
|
adapter.identity,
|
|
24688
|
-
agent.identity
|
|
25036
|
+
agent.identity,
|
|
25037
|
+
specification.promptTimeoutMilliseconds
|
|
24689
25038
|
);
|
|
24690
25039
|
try {
|
|
24691
|
-
await probeAcp(
|
|
25040
|
+
const acpVersion = await probeAcp(
|
|
25041
|
+
specification,
|
|
24692
25042
|
definition,
|
|
24693
25043
|
options.environment,
|
|
24694
25044
|
options.defaultWorkspace,
|
|
24695
25045
|
options.signal
|
|
24696
25046
|
);
|
|
24697
|
-
|
|
25047
|
+
const verifiedAdapterVersion = adapterVersion.length > 0 ? adapterVersion : acpVersion;
|
|
25048
|
+
if (verifiedAdapterVersion.length === 0) {
|
|
25049
|
+
throw new AgentProbeError(
|
|
25050
|
+
"acp_incompatible",
|
|
25051
|
+
"ACP adapter did not report a version"
|
|
25052
|
+
);
|
|
25053
|
+
}
|
|
25054
|
+
return new AvailableAgent(
|
|
25055
|
+
specification,
|
|
25056
|
+
new LocalAgentDefinition(
|
|
25057
|
+
specification.id,
|
|
25058
|
+
specification.label,
|
|
25059
|
+
adapter.path,
|
|
25060
|
+
[],
|
|
25061
|
+
{ [specification.adapterEnvironmentVariable]: agent.path },
|
|
25062
|
+
verifiedAdapterVersion,
|
|
25063
|
+
agentVersion,
|
|
25064
|
+
adapter.identity,
|
|
25065
|
+
agent.identity,
|
|
25066
|
+
specification.promptTimeoutMilliseconds
|
|
25067
|
+
)
|
|
25068
|
+
);
|
|
24698
25069
|
} catch (error61) {
|
|
24699
25070
|
if (options.signal.aborted) {
|
|
24700
25071
|
options.signal.throwIfAborted();
|
|
@@ -24984,10 +25355,10 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
|
|
|
24984
25355
|
return decodeClaimResponse(value);
|
|
24985
25356
|
}
|
|
24986
25357
|
async function persistConnection(channelId, relayOrigin, daemonToken, defaultWorkspace) {
|
|
24987
|
-
const connectionsDirectory =
|
|
25358
|
+
const connectionsDirectory = join8(readStateDirectory(), "connections");
|
|
24988
25359
|
await mkdir2(connectionsDirectory, { mode: 448, recursive: true });
|
|
24989
|
-
const connectionPath =
|
|
24990
|
-
const temporaryPath =
|
|
25360
|
+
const connectionPath = join8(connectionsDirectory, `${channelId}.json`);
|
|
25361
|
+
const temporaryPath = join8(
|
|
24991
25362
|
connectionsDirectory,
|
|
24992
25363
|
`.${channelId}.${randomUUID()}.tmp`
|
|
24993
25364
|
);
|
|
@@ -25034,7 +25405,7 @@ function decodeSavedConnection(value, expectedChannelId) {
|
|
|
25034
25405
|
};
|
|
25035
25406
|
}
|
|
25036
25407
|
async function readSavedConnection(channelId) {
|
|
25037
|
-
const connectionPath =
|
|
25408
|
+
const connectionPath = join8(
|
|
25038
25409
|
readStateDirectory(),
|
|
25039
25410
|
"connections",
|
|
25040
25411
|
`${channelId}.json`
|
|
@@ -25089,7 +25460,7 @@ function buildPairedDaemon(connection, connectionPath, inventory) {
|
|
|
25089
25460
|
);
|
|
25090
25461
|
relayUrl.protocol = relayUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
25091
25462
|
relayUrl.searchParams.set("token", connection.daemonToken);
|
|
25092
|
-
const auditDatabasePath =
|
|
25463
|
+
const auditDatabasePath = join8(
|
|
25093
25464
|
readStateDirectory(),
|
|
25094
25465
|
"audit",
|
|
25095
25466
|
`${connection.channelId}.sqlite`
|
|
@@ -25148,7 +25519,7 @@ async function pairLocalMachine(arguments_, signal = new AbortController().signa
|
|
|
25148
25519
|
}
|
|
25149
25520
|
async function resumeLocalMachine(arguments_, signal = new AbortController().signal) {
|
|
25150
25521
|
const channelId = parseChannelArgument(arguments_);
|
|
25151
|
-
const connectionPath =
|
|
25522
|
+
const connectionPath = join8(
|
|
25152
25523
|
readStateDirectory(),
|
|
25153
25524
|
"connections",
|
|
25154
25525
|
`${channelId}.json`
|
|
@@ -25771,7 +26142,7 @@ import { resolve as resolve4 } from "node:path";
|
|
|
25771
26142
|
|
|
25772
26143
|
// src/agent-installation/fixed-agent-install-recipes.ts
|
|
25773
26144
|
import { mkdir as mkdir3, mkdtemp as mkdtemp2, rm as rm2 } from "node:fs/promises";
|
|
25774
|
-
import { join as
|
|
26145
|
+
import { join as join9 } from "node:path";
|
|
25775
26146
|
|
|
25776
26147
|
// src/agent-installation/verified-download.ts
|
|
25777
26148
|
import { createHash } from "node:crypto";
|
|
@@ -25995,18 +26366,18 @@ var CodexInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
25995
26366
|
releaseChannel = "latest";
|
|
25996
26367
|
install = async (options) => {
|
|
25997
26368
|
this.assertSupportedPlatform();
|
|
25998
|
-
const root =
|
|
25999
|
-
const temporaryRoot =
|
|
26369
|
+
const root = join9(options.stateDirectory, "agents", this.id);
|
|
26370
|
+
const temporaryRoot = join9(options.stateDirectory, "temporary");
|
|
26000
26371
|
await Promise.all([
|
|
26001
26372
|
mkdir3(root, { mode: 448, recursive: true }),
|
|
26002
26373
|
mkdir3(temporaryRoot, { mode: 448, recursive: true })
|
|
26003
26374
|
]);
|
|
26004
26375
|
const temporaryDirectory = await mkdtemp2(
|
|
26005
|
-
|
|
26376
|
+
join9(temporaryRoot, ".codex-install-")
|
|
26006
26377
|
);
|
|
26007
|
-
const installerPath =
|
|
26008
|
-
const installDirectory =
|
|
26009
|
-
const codexHome =
|
|
26378
|
+
const installerPath = join9(temporaryDirectory, "install.sh");
|
|
26379
|
+
const installDirectory = join9(root, "bin");
|
|
26380
|
+
const codexHome = join9(root, "home");
|
|
26010
26381
|
try {
|
|
26011
26382
|
await Promise.all([
|
|
26012
26383
|
mkdir3(installDirectory, { mode: 448, recursive: true }),
|
|
@@ -26050,7 +26421,7 @@ var CodexInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
26050
26421
|
timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
|
|
26051
26422
|
});
|
|
26052
26423
|
return await this.requireInstalledExecutable(
|
|
26053
|
-
|
|
26424
|
+
join9(installDirectory, "codex")
|
|
26054
26425
|
);
|
|
26055
26426
|
} catch (error61) {
|
|
26056
26427
|
if (options.signal.aborted) {
|
|
@@ -26074,17 +26445,17 @@ var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
26074
26445
|
releaseChannel = "stable";
|
|
26075
26446
|
install = async (options) => {
|
|
26076
26447
|
this.assertSupportedPlatform();
|
|
26077
|
-
const root =
|
|
26078
|
-
const managedHome =
|
|
26079
|
-
const temporaryRoot =
|
|
26448
|
+
const root = join9(options.stateDirectory, "agents", this.id);
|
|
26449
|
+
const managedHome = join9(root, "home");
|
|
26450
|
+
const temporaryRoot = join9(options.stateDirectory, "temporary");
|
|
26080
26451
|
await Promise.all([
|
|
26081
26452
|
mkdir3(managedHome, { mode: 448, recursive: true }),
|
|
26082
26453
|
mkdir3(temporaryRoot, { mode: 448, recursive: true })
|
|
26083
26454
|
]);
|
|
26084
26455
|
const temporaryDirectory = await mkdtemp2(
|
|
26085
|
-
|
|
26456
|
+
join9(temporaryRoot, ".claude-install-")
|
|
26086
26457
|
);
|
|
26087
|
-
const installerPath =
|
|
26458
|
+
const installerPath = join9(temporaryDirectory, "install.sh");
|
|
26088
26459
|
try {
|
|
26089
26460
|
await options.report("downloading");
|
|
26090
26461
|
const download = await downloadVerifiedFile({
|
|
@@ -26121,7 +26492,7 @@ var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
26121
26492
|
timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
|
|
26122
26493
|
});
|
|
26123
26494
|
return await this.requireInstalledExecutable(
|
|
26124
|
-
|
|
26495
|
+
join9(managedHome, ".local", "bin", "claude")
|
|
26125
26496
|
);
|
|
26126
26497
|
} catch (error61) {
|
|
26127
26498
|
if (options.signal.aborted) {
|
|
@@ -26139,10 +26510,82 @@ var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
|
26139
26510
|
}
|
|
26140
26511
|
};
|
|
26141
26512
|
};
|
|
26513
|
+
var PiInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
26514
|
+
#npmInstaller;
|
|
26515
|
+
id = "pi";
|
|
26516
|
+
label = "Pi";
|
|
26517
|
+
releaseChannel = PI_AGENT_PACKAGE.version;
|
|
26518
|
+
constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
|
|
26519
|
+
super();
|
|
26520
|
+
this.#npmInstaller = npmInstaller;
|
|
26521
|
+
}
|
|
26522
|
+
install = async (options) => {
|
|
26523
|
+
this.assertSupportedPlatform();
|
|
26524
|
+
try {
|
|
26525
|
+
await options.report("downloading");
|
|
26526
|
+
await options.report("verifying");
|
|
26527
|
+
await options.report("installing_agent");
|
|
26528
|
+
const executable = await this.#npmInstaller.install(
|
|
26529
|
+
join9(
|
|
26530
|
+
options.stateDirectory,
|
|
26531
|
+
"agents",
|
|
26532
|
+
this.id,
|
|
26533
|
+
PI_AGENT_PACKAGE.version
|
|
26534
|
+
),
|
|
26535
|
+
PI_AGENT_PACKAGE,
|
|
26536
|
+
options.environment,
|
|
26537
|
+
options.signal
|
|
26538
|
+
);
|
|
26539
|
+
options.audit.record(
|
|
26540
|
+
"agent_npm_package_verified",
|
|
26541
|
+
options.requestId,
|
|
26542
|
+
this.id,
|
|
26543
|
+
{
|
|
26544
|
+
integrity: PI_AGENT_PACKAGE.integrity,
|
|
26545
|
+
package: PI_AGENT_PACKAGE.packageName,
|
|
26546
|
+
version: PI_AGENT_PACKAGE.version
|
|
26547
|
+
}
|
|
26548
|
+
);
|
|
26549
|
+
return executable;
|
|
26550
|
+
} catch (error61) {
|
|
26551
|
+
if (options.signal.aborted) {
|
|
26552
|
+
options.signal.throwIfAborted();
|
|
26553
|
+
}
|
|
26554
|
+
if (error61 instanceof ManagedNpmPackageError) {
|
|
26555
|
+
if (error61.code === "managed_package_verification_failed") {
|
|
26556
|
+
throw new InstallationManagerError(
|
|
26557
|
+
"agent_verification_failed",
|
|
26558
|
+
"The managed Pi package did not match its pinned artifact",
|
|
26559
|
+
{ cause: error61 }
|
|
26560
|
+
);
|
|
26561
|
+
}
|
|
26562
|
+
if (error61.code === "managed_package_publish_failed") {
|
|
26563
|
+
throw new InstallationManagerError(
|
|
26564
|
+
"agent_publish_failed",
|
|
26565
|
+
"The managed Pi package could not be published",
|
|
26566
|
+
{ cause: error61 }
|
|
26567
|
+
);
|
|
26568
|
+
}
|
|
26569
|
+
throw new InstallationManagerError(error61.code, error61.message, {
|
|
26570
|
+
cause: error61
|
|
26571
|
+
});
|
|
26572
|
+
}
|
|
26573
|
+
if (error61 instanceof InstallationManagerError) {
|
|
26574
|
+
throw error61;
|
|
26575
|
+
}
|
|
26576
|
+
throw new InstallationManagerError(
|
|
26577
|
+
"agent_install_failed",
|
|
26578
|
+
"The fixed Pi installation recipe failed",
|
|
26579
|
+
{ cause: error61 }
|
|
26580
|
+
);
|
|
26581
|
+
}
|
|
26582
|
+
};
|
|
26583
|
+
};
|
|
26142
26584
|
function fixedAgentInstallRecipes() {
|
|
26143
26585
|
return Object.freeze([
|
|
26144
26586
|
new CodexInstallRecipe(),
|
|
26145
|
-
new ClaudeCodeInstallRecipe()
|
|
26587
|
+
new ClaudeCodeInstallRecipe(),
|
|
26588
|
+
new PiInstallRecipe()
|
|
26146
26589
|
]);
|
|
26147
26590
|
}
|
|
26148
26591
|
|
|
@@ -26272,6 +26715,7 @@ var FixedInstallationExecutor = class {
|
|
|
26272
26715
|
if (agent === null) {
|
|
26273
26716
|
agent = await recipe.install({
|
|
26274
26717
|
audit: this.#audit,
|
|
26718
|
+
environment: this.#environment,
|
|
26275
26719
|
report,
|
|
26276
26720
|
requestId,
|
|
26277
26721
|
signal,
|
|
@@ -26353,6 +26797,7 @@ var FixedInstallationExecutor = class {
|
|
|
26353
26797
|
if (!installedAgent && (requiresAgentReplacement(unavailable.code) || unavailable.code === "acp_incompatible")) {
|
|
26354
26798
|
agent = await recipe.install({
|
|
26355
26799
|
audit: this.#audit,
|
|
26800
|
+
environment: this.#environment,
|
|
26356
26801
|
report,
|
|
26357
26802
|
requestId,
|
|
26358
26803
|
signal,
|
|
@@ -26416,8 +26861,8 @@ import { homedir as homedir2 } from "node:os";
|
|
|
26416
26861
|
import {
|
|
26417
26862
|
basename as basename2,
|
|
26418
26863
|
dirname as dirname4,
|
|
26419
|
-
isAbsolute as
|
|
26420
|
-
join as
|
|
26864
|
+
isAbsolute as isAbsolute3,
|
|
26865
|
+
join as join10,
|
|
26421
26866
|
normalize,
|
|
26422
26867
|
relative as relative2
|
|
26423
26868
|
} from "node:path";
|
|
@@ -26469,20 +26914,20 @@ var WorkspaceDirectoryService = class {
|
|
|
26469
26914
|
if (id === "home") return homedir2();
|
|
26470
26915
|
if (id.startsWith("path-")) {
|
|
26471
26916
|
const path2 = decodePath(id, "path-");
|
|
26472
|
-
if (
|
|
26917
|
+
if (isAbsolute3(path2)) return path2;
|
|
26473
26918
|
}
|
|
26474
26919
|
throw new LocalAuthorizationError("The directory identifier is invalid");
|
|
26475
26920
|
};
|
|
26476
26921
|
resolvePath = async (requested, signal) => {
|
|
26477
26922
|
signal.throwIfAborted();
|
|
26478
|
-
if (!
|
|
26923
|
+
if (!isAbsolute3(requested) || requested.includes("\0") || normalize(requested) !== requested)
|
|
26479
26924
|
throw new LocalAuthorizationError("The local directory path is invalid");
|
|
26480
26925
|
try {
|
|
26481
26926
|
const target = await realpath4(requested);
|
|
26482
26927
|
signal.throwIfAborted();
|
|
26483
26928
|
const metadata = await stat4(target);
|
|
26484
26929
|
signal.throwIfAborted();
|
|
26485
|
-
if (!
|
|
26930
|
+
if (!isAbsolute3(target) || normalize(target) !== target || !metadata.isDirectory())
|
|
26486
26931
|
throw new LocalAuthorizationError(
|
|
26487
26932
|
"The selected location is not a directory"
|
|
26488
26933
|
);
|
|
@@ -26498,7 +26943,7 @@ var WorkspaceDirectoryService = class {
|
|
|
26498
26943
|
};
|
|
26499
26944
|
label = (path2) => {
|
|
26500
26945
|
const suffix = relative2(homedir2(), path2);
|
|
26501
|
-
return suffix === "" ? "~" : !
|
|
26946
|
+
return suffix === "" ? "~" : !isAbsolute3(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
|
|
26502
26947
|
};
|
|
26503
26948
|
identify = async (bindingId, requestedPath, signal) => {
|
|
26504
26949
|
this.authorizeMachine(bindingId);
|
|
@@ -26526,7 +26971,7 @@ var WorkspaceDirectoryService = class {
|
|
|
26526
26971
|
continue;
|
|
26527
26972
|
}
|
|
26528
26973
|
try {
|
|
26529
|
-
const path2 = await this.resolvePath(
|
|
26974
|
+
const path2 = await this.resolvePath(join10(target, child.name), signal);
|
|
26530
26975
|
entries.push({ directoryId: encodePath(path2), name: child.name });
|
|
26531
26976
|
} catch (cause) {
|
|
26532
26977
|
signal.throwIfAborted();
|