@axiom-lattice/core 2.1.50 → 2.1.51
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/index.d.mts +5 -11
- package/dist/index.d.ts +5 -11
- package/dist/index.js +212 -136
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +212 -136
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -5212,21 +5212,28 @@ function truncateIfTooLong(result) {
|
|
|
5212
5212
|
}
|
|
5213
5213
|
return result;
|
|
5214
5214
|
}
|
|
5215
|
-
function validatePath(
|
|
5216
|
-
const pathStr =
|
|
5215
|
+
function validatePath(path4) {
|
|
5216
|
+
const pathStr = path4 || "/";
|
|
5217
5217
|
if (!pathStr || pathStr.trim() === "") {
|
|
5218
5218
|
throw new Error("Path cannot be empty");
|
|
5219
5219
|
}
|
|
5220
|
-
let normalized
|
|
5220
|
+
let normalized;
|
|
5221
|
+
if (pathStr === "~") {
|
|
5222
|
+
normalized = "~/";
|
|
5223
|
+
} else if (pathStr.startsWith("~/")) {
|
|
5224
|
+
normalized = pathStr;
|
|
5225
|
+
} else {
|
|
5226
|
+
normalized = pathStr.startsWith("/") ? pathStr : "/" + pathStr;
|
|
5227
|
+
}
|
|
5221
5228
|
if (!normalized.endsWith("/")) {
|
|
5222
5229
|
normalized += "/";
|
|
5223
5230
|
}
|
|
5224
5231
|
return normalized;
|
|
5225
5232
|
}
|
|
5226
|
-
function globSearchFiles(files, pattern,
|
|
5233
|
+
function globSearchFiles(files, pattern, path4 = "/") {
|
|
5227
5234
|
let normalizedPath;
|
|
5228
5235
|
try {
|
|
5229
|
-
normalizedPath = validatePath(
|
|
5236
|
+
normalizedPath = validatePath(path4);
|
|
5230
5237
|
} catch {
|
|
5231
5238
|
return "No files found";
|
|
5232
5239
|
}
|
|
@@ -5278,7 +5285,7 @@ function formatGrepResults(results, outputMode) {
|
|
|
5278
5285
|
}
|
|
5279
5286
|
return lines.join("\n");
|
|
5280
5287
|
}
|
|
5281
|
-
function grepSearchFiles(files, pattern,
|
|
5288
|
+
function grepSearchFiles(files, pattern, path4 = null, glob = null, outputMode = "files_with_matches") {
|
|
5282
5289
|
let regex;
|
|
5283
5290
|
try {
|
|
5284
5291
|
regex = new RegExp(pattern);
|
|
@@ -5287,7 +5294,7 @@ function grepSearchFiles(files, pattern, path3 = null, glob = null, outputMode =
|
|
|
5287
5294
|
}
|
|
5288
5295
|
let normalizedPath;
|
|
5289
5296
|
try {
|
|
5290
|
-
normalizedPath = validatePath(
|
|
5297
|
+
normalizedPath = validatePath(path4);
|
|
5291
5298
|
} catch {
|
|
5292
5299
|
return "No matches found";
|
|
5293
5300
|
}
|
|
@@ -5319,7 +5326,7 @@ function grepSearchFiles(files, pattern, path3 = null, glob = null, outputMode =
|
|
|
5319
5326
|
}
|
|
5320
5327
|
return formatGrepResults(results, outputMode);
|
|
5321
5328
|
}
|
|
5322
|
-
function grepMatchesFromFiles(files, pattern,
|
|
5329
|
+
function grepMatchesFromFiles(files, pattern, path4 = null, glob = null) {
|
|
5323
5330
|
let regex;
|
|
5324
5331
|
try {
|
|
5325
5332
|
regex = new RegExp(pattern);
|
|
@@ -5328,7 +5335,7 @@ function grepMatchesFromFiles(files, pattern, path3 = null, glob = null) {
|
|
|
5328
5335
|
}
|
|
5329
5336
|
let normalizedPath;
|
|
5330
5337
|
try {
|
|
5331
|
-
normalizedPath = validatePath(
|
|
5338
|
+
normalizedPath = validatePath(path4);
|
|
5332
5339
|
} catch {
|
|
5333
5340
|
return [];
|
|
5334
5341
|
}
|
|
@@ -5389,11 +5396,11 @@ var StateBackend = class {
|
|
|
5389
5396
|
* @returns List of FileInfo objects for files and directories directly in the directory.
|
|
5390
5397
|
* Directories have a trailing / in their path and is_dir=true.
|
|
5391
5398
|
*/
|
|
5392
|
-
lsInfo(
|
|
5399
|
+
lsInfo(path4) {
|
|
5393
5400
|
const files = this.getFiles();
|
|
5394
5401
|
const infos = [];
|
|
5395
5402
|
const subdirs = /* @__PURE__ */ new Set();
|
|
5396
|
-
const normalizedPath =
|
|
5403
|
+
const normalizedPath = path4.endsWith("/") ? path4 : path4 + "/";
|
|
5397
5404
|
for (const [k, fd] of Object.entries(files)) {
|
|
5398
5405
|
if (!k.startsWith(normalizedPath)) {
|
|
5399
5406
|
continue;
|
|
@@ -5499,16 +5506,16 @@ var StateBackend = class {
|
|
|
5499
5506
|
/**
|
|
5500
5507
|
* Structured search results or error string for invalid input.
|
|
5501
5508
|
*/
|
|
5502
|
-
grepRaw(pattern,
|
|
5509
|
+
grepRaw(pattern, path4 = "/", glob = null) {
|
|
5503
5510
|
const files = this.getFiles();
|
|
5504
|
-
return grepMatchesFromFiles(files, pattern,
|
|
5511
|
+
return grepMatchesFromFiles(files, pattern, path4, glob);
|
|
5505
5512
|
}
|
|
5506
5513
|
/**
|
|
5507
5514
|
* Structured glob matching returning FileInfo objects.
|
|
5508
5515
|
*/
|
|
5509
|
-
globInfo(pattern,
|
|
5516
|
+
globInfo(pattern, path4 = "/") {
|
|
5510
5517
|
const files = this.getFiles();
|
|
5511
|
-
const result = globSearchFiles(files, pattern,
|
|
5518
|
+
const result = globSearchFiles(files, pattern, path4);
|
|
5512
5519
|
if (result === "No files found") {
|
|
5513
5520
|
return [];
|
|
5514
5521
|
}
|
|
@@ -5602,10 +5609,10 @@ function createLsTool(backend, options) {
|
|
|
5602
5609
|
...runConfig
|
|
5603
5610
|
};
|
|
5604
5611
|
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
5605
|
-
const
|
|
5606
|
-
const infos = await resolvedBackend.lsInfo(
|
|
5612
|
+
const path4 = input.path || "/";
|
|
5613
|
+
const infos = await resolvedBackend.lsInfo(path4);
|
|
5607
5614
|
if (infos.length === 0) {
|
|
5608
|
-
return `No files found in ${
|
|
5615
|
+
return `No files found in ${path4}`;
|
|
5609
5616
|
}
|
|
5610
5617
|
const lines = [];
|
|
5611
5618
|
for (const info of infos) {
|
|
@@ -5748,8 +5755,8 @@ function createGlobTool(backend, options) {
|
|
|
5748
5755
|
...runConfig
|
|
5749
5756
|
};
|
|
5750
5757
|
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
5751
|
-
const { pattern, path:
|
|
5752
|
-
const infos = await resolvedBackend.globInfo(pattern,
|
|
5758
|
+
const { pattern, path: path4 = "/" } = input;
|
|
5759
|
+
const infos = await resolvedBackend.globInfo(pattern, path4);
|
|
5753
5760
|
if (infos.length === 0) {
|
|
5754
5761
|
return `No files found matching pattern '${pattern}'`;
|
|
5755
5762
|
}
|
|
@@ -5776,8 +5783,8 @@ function createGrepTool(backend, options) {
|
|
|
5776
5783
|
...runConfig
|
|
5777
5784
|
};
|
|
5778
5785
|
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
5779
|
-
const { pattern, path:
|
|
5780
|
-
const result = await resolvedBackend.grepRaw(pattern,
|
|
5786
|
+
const { pattern, path: path4 = "/", glob = null } = input;
|
|
5787
|
+
const result = await resolvedBackend.grepRaw(pattern, path4, glob);
|
|
5781
5788
|
if (typeof result === "string") {
|
|
5782
5789
|
return result;
|
|
5783
5790
|
}
|
|
@@ -13163,13 +13170,13 @@ var StoreBackend = class {
|
|
|
13163
13170
|
* @returns List of FileInfo objects for files and directories directly in the directory.
|
|
13164
13171
|
* Directories have a trailing / in their path and is_dir=true.
|
|
13165
13172
|
*/
|
|
13166
|
-
async lsInfo(
|
|
13173
|
+
async lsInfo(path4) {
|
|
13167
13174
|
const store = this.getStore();
|
|
13168
13175
|
const namespace = this.getNamespace();
|
|
13169
13176
|
const items = await this.searchStorePaginated(store, namespace);
|
|
13170
13177
|
const infos = [];
|
|
13171
13178
|
const subdirs = /* @__PURE__ */ new Set();
|
|
13172
|
-
const normalizedPath =
|
|
13179
|
+
const normalizedPath = path4.endsWith("/") ? path4 : path4 + "/";
|
|
13173
13180
|
for (const item of items) {
|
|
13174
13181
|
const itemKey = String(item.key);
|
|
13175
13182
|
if (!itemKey.startsWith(normalizedPath)) {
|
|
@@ -13287,7 +13294,7 @@ var StoreBackend = class {
|
|
|
13287
13294
|
/**
|
|
13288
13295
|
* Structured search results or error string for invalid input.
|
|
13289
13296
|
*/
|
|
13290
|
-
async grepRaw(pattern,
|
|
13297
|
+
async grepRaw(pattern, path4 = "/", glob = null) {
|
|
13291
13298
|
const store = this.getStore();
|
|
13292
13299
|
const namespace = this.getNamespace();
|
|
13293
13300
|
const items = await this.searchStorePaginated(store, namespace);
|
|
@@ -13299,12 +13306,12 @@ var StoreBackend = class {
|
|
|
13299
13306
|
continue;
|
|
13300
13307
|
}
|
|
13301
13308
|
}
|
|
13302
|
-
return grepMatchesFromFiles(files, pattern,
|
|
13309
|
+
return grepMatchesFromFiles(files, pattern, path4, glob);
|
|
13303
13310
|
}
|
|
13304
13311
|
/**
|
|
13305
13312
|
* Structured glob matching returning FileInfo objects.
|
|
13306
13313
|
*/
|
|
13307
|
-
async globInfo(pattern,
|
|
13314
|
+
async globInfo(pattern, path4 = "/") {
|
|
13308
13315
|
const store = this.getStore();
|
|
13309
13316
|
const namespace = this.getNamespace();
|
|
13310
13317
|
const items = await this.searchStorePaginated(store, namespace);
|
|
@@ -13316,7 +13323,7 @@ var StoreBackend = class {
|
|
|
13316
13323
|
continue;
|
|
13317
13324
|
}
|
|
13318
13325
|
}
|
|
13319
|
-
const result = globSearchFiles(files, pattern,
|
|
13326
|
+
const result = globSearchFiles(files, pattern, path4);
|
|
13320
13327
|
if (result === "No files found") {
|
|
13321
13328
|
return [];
|
|
13322
13329
|
}
|
|
@@ -13365,8 +13372,9 @@ var FilesystemBackend = class {
|
|
|
13365
13372
|
*/
|
|
13366
13373
|
resolvePath(key) {
|
|
13367
13374
|
if (this.virtualMode) {
|
|
13368
|
-
const
|
|
13369
|
-
|
|
13375
|
+
const normalizedKey = key === "~" ? "/" : key.startsWith("~/") ? `/${key.slice(2)}` : key;
|
|
13376
|
+
const vpath = normalizedKey.startsWith("/") ? normalizedKey : "/" + normalizedKey;
|
|
13377
|
+
if (vpath.includes("..") || vpath.includes("~")) {
|
|
13370
13378
|
throw new Error("Path traversal not allowed");
|
|
13371
13379
|
}
|
|
13372
13380
|
const full = path2.resolve(this.cwd, vpath.substring(1));
|
|
@@ -13891,10 +13899,10 @@ var CompositeBackend = class {
|
|
|
13891
13899
|
* @returns List of FileInfo objects with route prefixes added, for files and directories
|
|
13892
13900
|
* directly in the directory. Directories have a trailing / in their path and is_dir=true.
|
|
13893
13901
|
*/
|
|
13894
|
-
async lsInfo(
|
|
13902
|
+
async lsInfo(path4) {
|
|
13895
13903
|
for (const [routePrefix, backend] of this.sortedRoutes) {
|
|
13896
|
-
if (
|
|
13897
|
-
const suffix =
|
|
13904
|
+
if (path4.startsWith(routePrefix.replace(/\/$/, ""))) {
|
|
13905
|
+
const suffix = path4.substring(routePrefix.length);
|
|
13898
13906
|
const searchPath = suffix ? "/" + suffix : "/";
|
|
13899
13907
|
const infos = await backend.lsInfo(searchPath);
|
|
13900
13908
|
const prefixed = [];
|
|
@@ -13907,9 +13915,9 @@ var CompositeBackend = class {
|
|
|
13907
13915
|
return prefixed;
|
|
13908
13916
|
}
|
|
13909
13917
|
}
|
|
13910
|
-
if (
|
|
13918
|
+
if (path4 === "/") {
|
|
13911
13919
|
const results = [];
|
|
13912
|
-
const defaultInfos = await this.default.lsInfo(
|
|
13920
|
+
const defaultInfos = await this.default.lsInfo(path4);
|
|
13913
13921
|
results.push(...defaultInfos);
|
|
13914
13922
|
for (const [routePrefix] of this.sortedRoutes) {
|
|
13915
13923
|
results.push({
|
|
@@ -13922,7 +13930,7 @@ var CompositeBackend = class {
|
|
|
13922
13930
|
results.sort((a, b) => a.path.localeCompare(b.path));
|
|
13923
13931
|
return results;
|
|
13924
13932
|
}
|
|
13925
|
-
return await this.default.lsInfo(
|
|
13933
|
+
return await this.default.lsInfo(path4);
|
|
13926
13934
|
}
|
|
13927
13935
|
/**
|
|
13928
13936
|
* Read file content, routing to appropriate backend.
|
|
@@ -13949,10 +13957,10 @@ var CompositeBackend = class {
|
|
|
13949
13957
|
/**
|
|
13950
13958
|
* Structured search results or error string for invalid input.
|
|
13951
13959
|
*/
|
|
13952
|
-
async grepRaw(pattern,
|
|
13960
|
+
async grepRaw(pattern, path4 = "/", glob = null) {
|
|
13953
13961
|
for (const [routePrefix, backend] of this.sortedRoutes) {
|
|
13954
|
-
if (
|
|
13955
|
-
const searchPath =
|
|
13962
|
+
if (path4.startsWith(routePrefix.replace(/\/$/, ""))) {
|
|
13963
|
+
const searchPath = path4.substring(routePrefix.length - 1);
|
|
13956
13964
|
const raw = await backend.grepRaw(pattern, searchPath || "/", glob);
|
|
13957
13965
|
if (typeof raw === "string") {
|
|
13958
13966
|
return raw;
|
|
@@ -13964,7 +13972,7 @@ var CompositeBackend = class {
|
|
|
13964
13972
|
}
|
|
13965
13973
|
}
|
|
13966
13974
|
const allMatches = [];
|
|
13967
|
-
const rawDefault = await this.default.grepRaw(pattern,
|
|
13975
|
+
const rawDefault = await this.default.grepRaw(pattern, path4, glob);
|
|
13968
13976
|
if (typeof rawDefault === "string") {
|
|
13969
13977
|
return rawDefault;
|
|
13970
13978
|
}
|
|
@@ -13986,11 +13994,11 @@ var CompositeBackend = class {
|
|
|
13986
13994
|
/**
|
|
13987
13995
|
* Structured glob matching returning FileInfo objects.
|
|
13988
13996
|
*/
|
|
13989
|
-
async globInfo(pattern,
|
|
13997
|
+
async globInfo(pattern, path4 = "/") {
|
|
13990
13998
|
const results = [];
|
|
13991
13999
|
for (const [routePrefix, backend] of this.sortedRoutes) {
|
|
13992
|
-
if (
|
|
13993
|
-
const searchPath =
|
|
14000
|
+
if (path4.startsWith(routePrefix.replace(/\/$/, ""))) {
|
|
14001
|
+
const searchPath = path4.substring(routePrefix.length - 1);
|
|
13994
14002
|
const infos = await backend.globInfo(pattern, searchPath || "/");
|
|
13995
14003
|
return infos.map((fi) => ({
|
|
13996
14004
|
...fi,
|
|
@@ -13998,7 +14006,7 @@ var CompositeBackend = class {
|
|
|
13998
14006
|
}));
|
|
13999
14007
|
}
|
|
14000
14008
|
}
|
|
14001
|
-
const defaultInfos = await this.default.globInfo(pattern,
|
|
14009
|
+
const defaultInfos = await this.default.globInfo(pattern, path4);
|
|
14002
14010
|
results.push(...defaultInfos);
|
|
14003
14011
|
for (const [routePrefix, backend] of Object.entries(this.routes)) {
|
|
14004
14012
|
const infos = await backend.globInfo(pattern, "/");
|
|
@@ -14046,11 +14054,11 @@ var MemoryBackend = class {
|
|
|
14046
14054
|
getFiles() {
|
|
14047
14055
|
return Object.fromEntries(this.files);
|
|
14048
14056
|
}
|
|
14049
|
-
lsInfo(
|
|
14057
|
+
lsInfo(path4) {
|
|
14050
14058
|
const files = this.getFiles();
|
|
14051
14059
|
const infos = [];
|
|
14052
14060
|
const subdirs = /* @__PURE__ */ new Set();
|
|
14053
|
-
const normalizedPath =
|
|
14061
|
+
const normalizedPath = path4.endsWith("/") ? path4 : path4 + "/";
|
|
14054
14062
|
for (const [k, fd] of Object.entries(files)) {
|
|
14055
14063
|
if (!k.startsWith(normalizedPath)) {
|
|
14056
14064
|
continue;
|
|
@@ -14125,13 +14133,13 @@ var MemoryBackend = class {
|
|
|
14125
14133
|
this.files.set(filePath, newFileData);
|
|
14126
14134
|
return { path: filePath, filesUpdate: null, occurrences };
|
|
14127
14135
|
}
|
|
14128
|
-
grepRaw(pattern,
|
|
14136
|
+
grepRaw(pattern, path4 = "/", glob = null) {
|
|
14129
14137
|
const files = this.getFiles();
|
|
14130
|
-
return grepMatchesFromFiles(files, pattern,
|
|
14138
|
+
return grepMatchesFromFiles(files, pattern, path4, glob);
|
|
14131
14139
|
}
|
|
14132
|
-
globInfo(pattern,
|
|
14140
|
+
globInfo(pattern, path4 = "/") {
|
|
14133
14141
|
const files = this.getFiles();
|
|
14134
|
-
const result = globSearchFiles(files, pattern,
|
|
14142
|
+
const result = globSearchFiles(files, pattern, path4);
|
|
14135
14143
|
if (result === "No files found") {
|
|
14136
14144
|
return [];
|
|
14137
14145
|
}
|
|
@@ -18186,9 +18194,9 @@ var MicrosandboxInstance = class {
|
|
|
18186
18194
|
const fs3 = this.native.fs();
|
|
18187
18195
|
await fs3.write(file, Buffer.from(content));
|
|
18188
18196
|
},
|
|
18189
|
-
listPath: async (
|
|
18197
|
+
listPath: async (path4, options) => {
|
|
18190
18198
|
const fs3 = this.native.fs();
|
|
18191
|
-
const entries = await fs3.list(
|
|
18199
|
+
const entries = await fs3.list(path4);
|
|
18192
18200
|
const files = (entries || []).map((e) => ({
|
|
18193
18201
|
path: e.path,
|
|
18194
18202
|
is_dir: e.kind === "directory",
|
|
@@ -18197,10 +18205,10 @@ var MicrosandboxInstance = class {
|
|
|
18197
18205
|
}));
|
|
18198
18206
|
return { files };
|
|
18199
18207
|
},
|
|
18200
|
-
findFiles: async (
|
|
18208
|
+
findFiles: async (path4, glob) => {
|
|
18201
18209
|
const output = await this.native.execWithConfig({
|
|
18202
18210
|
cmd: "sh",
|
|
18203
|
-
args: ["-c", `find "${
|
|
18211
|
+
args: ["-c", `find "${path4}" -name "${glob}" -type f`]
|
|
18204
18212
|
});
|
|
18205
18213
|
const lines = output.stdout().split("\n").filter(Boolean);
|
|
18206
18214
|
return { files: lines };
|
|
@@ -18224,14 +18232,14 @@ var MicrosandboxInstance = class {
|
|
|
18224
18232
|
return { matches, line_numbers };
|
|
18225
18233
|
},
|
|
18226
18234
|
strReplaceEditor: async (params) => {
|
|
18227
|
-
const { path:
|
|
18235
|
+
const { path: path4, old_str, new_str, replace_mode } = params;
|
|
18228
18236
|
const delim = "#";
|
|
18229
18237
|
const escapedOld = old_str.replace(new RegExp(`[\\\\${delim}]`, "g"), "\\$&").replace(/\n/g, "\\n");
|
|
18230
18238
|
const escapedNew = new_str.replace(new RegExp(`[\\\\${delim}]`, "g"), "\\$&").replace(/\n/g, "\\n");
|
|
18231
18239
|
const flag = replace_mode === "ALL" ? "g" : "";
|
|
18232
18240
|
await this.native.execWithConfig({
|
|
18233
18241
|
cmd: "sh",
|
|
18234
|
-
args: ["-c", `sed -i 's${delim}${escapedOld}${delim}${escapedNew}${delim}${flag}' "${
|
|
18242
|
+
args: ["-c", `sed -i 's${delim}${escapedOld}${delim}${escapedNew}${delim}${flag}' "${path4}"`]
|
|
18235
18243
|
});
|
|
18236
18244
|
},
|
|
18237
18245
|
uploadFile: async (params) => {
|
|
@@ -18370,31 +18378,77 @@ var MicrosandboxProvider = class {
|
|
|
18370
18378
|
}
|
|
18371
18379
|
};
|
|
18372
18380
|
|
|
18381
|
+
// src/sandbox_lattice/pathUtils.ts
|
|
18382
|
+
var import_path2 = __toESM(require("path"));
|
|
18383
|
+
function isVirtualSandboxPath(inputPath) {
|
|
18384
|
+
return inputPath === "~" || inputPath.startsWith("~/") || inputPath.startsWith("/");
|
|
18385
|
+
}
|
|
18386
|
+
function toSandboxHomePath(inputPath, options = {}) {
|
|
18387
|
+
const { homeDir = "/home/daytona", absolute = false } = options;
|
|
18388
|
+
if (!isVirtualSandboxPath(inputPath)) {
|
|
18389
|
+
return inputPath;
|
|
18390
|
+
}
|
|
18391
|
+
let relativePath = inputPath;
|
|
18392
|
+
while (relativePath.startsWith("~/") || relativePath.startsWith("/")) {
|
|
18393
|
+
if (relativePath.startsWith("~/")) {
|
|
18394
|
+
relativePath = relativePath.slice(2);
|
|
18395
|
+
} else {
|
|
18396
|
+
relativePath = relativePath.slice(1);
|
|
18397
|
+
}
|
|
18398
|
+
}
|
|
18399
|
+
if (relativePath === "~") {
|
|
18400
|
+
relativePath = "";
|
|
18401
|
+
}
|
|
18402
|
+
if (!absolute) {
|
|
18403
|
+
return relativePath;
|
|
18404
|
+
}
|
|
18405
|
+
return relativePath ? import_path2.default.posix.join(homeDir, relativePath) : homeDir;
|
|
18406
|
+
}
|
|
18407
|
+
|
|
18373
18408
|
// src/sandbox_lattice/MicrosandboxRemoteInstance.ts
|
|
18374
18409
|
var MicrosandboxRemoteInstance = class {
|
|
18375
18410
|
constructor(name, client) {
|
|
18376
18411
|
this.client = client;
|
|
18377
18412
|
this.file = {
|
|
18378
18413
|
readFile: async (file) => {
|
|
18379
|
-
const result = await this.client.readFile(
|
|
18414
|
+
const result = await this.client.readFile(
|
|
18415
|
+
this.name,
|
|
18416
|
+
toSandboxHomePath(file, { absolute: true, homeDir: "/home/daytona" })
|
|
18417
|
+
);
|
|
18380
18418
|
return { content: result.content };
|
|
18381
18419
|
},
|
|
18382
18420
|
writeFile: async (file, content) => {
|
|
18383
|
-
await this.client.writeFile(
|
|
18421
|
+
await this.client.writeFile(
|
|
18422
|
+
this.name,
|
|
18423
|
+
toSandboxHomePath(file, { absolute: true, homeDir: "/home/daytona" }),
|
|
18424
|
+
content
|
|
18425
|
+
);
|
|
18384
18426
|
},
|
|
18385
|
-
listPath: async (
|
|
18386
|
-
const result = await this.client.listPath(
|
|
18427
|
+
listPath: async (path4, options) => {
|
|
18428
|
+
const result = await this.client.listPath(
|
|
18429
|
+
this.name,
|
|
18430
|
+
toSandboxHomePath(path4, { absolute: true, homeDir: "/home/daytona" }),
|
|
18431
|
+
options?.recursive
|
|
18432
|
+
);
|
|
18387
18433
|
const files = result.entries.map((entry) => ({
|
|
18388
18434
|
path: entry.path,
|
|
18389
18435
|
is_dir: entry.type === "dir"
|
|
18390
18436
|
}));
|
|
18391
18437
|
return { files };
|
|
18392
18438
|
},
|
|
18393
|
-
findFiles: async (
|
|
18394
|
-
return this.client.findFiles(
|
|
18439
|
+
findFiles: async (path4, glob) => {
|
|
18440
|
+
return this.client.findFiles(
|
|
18441
|
+
this.name,
|
|
18442
|
+
toSandboxHomePath(path4, { absolute: true, homeDir: "/home/daytona" }),
|
|
18443
|
+
glob
|
|
18444
|
+
);
|
|
18395
18445
|
},
|
|
18396
18446
|
searchInFile: async (file, regex) => {
|
|
18397
|
-
const result = await this.client.searchInFile(
|
|
18447
|
+
const result = await this.client.searchInFile(
|
|
18448
|
+
this.name,
|
|
18449
|
+
toSandboxHomePath(file, { absolute: true, homeDir: "/home/daytona" }),
|
|
18450
|
+
regex
|
|
18451
|
+
);
|
|
18398
18452
|
return {
|
|
18399
18453
|
matches: result.matches.map((match) => match.content),
|
|
18400
18454
|
line_numbers: result.matches.map((match) => match.line)
|
|
@@ -18402,16 +18456,23 @@ var MicrosandboxRemoteInstance = class {
|
|
|
18402
18456
|
},
|
|
18403
18457
|
strReplaceEditor: async (params) => {
|
|
18404
18458
|
await this.client.replaceInFile(this.name, {
|
|
18405
|
-
path: params.path,
|
|
18459
|
+
path: toSandboxHomePath(params.path, { absolute: true, homeDir: "/home/daytona" }),
|
|
18406
18460
|
search: params.old_str,
|
|
18407
18461
|
replace: params.new_str
|
|
18408
18462
|
});
|
|
18409
18463
|
},
|
|
18410
18464
|
uploadFile: async (params) => {
|
|
18411
|
-
await this.client.uploadFile(
|
|
18465
|
+
await this.client.uploadFile(
|
|
18466
|
+
this.name,
|
|
18467
|
+
toSandboxHomePath(params.file, { absolute: true, homeDir: "/home/daytona" }),
|
|
18468
|
+
params.data
|
|
18469
|
+
);
|
|
18412
18470
|
},
|
|
18413
18471
|
downloadFile: async (params) => {
|
|
18414
|
-
const result = await this.client.downloadFile(
|
|
18472
|
+
const result = await this.client.downloadFile(
|
|
18473
|
+
this.name,
|
|
18474
|
+
toSandboxHomePath(params.file, { absolute: true, homeDir: "/home/daytona" })
|
|
18475
|
+
);
|
|
18415
18476
|
if (result.contentBase64) {
|
|
18416
18477
|
return Buffer.from(result.contentBase64, "base64");
|
|
18417
18478
|
}
|
|
@@ -18456,6 +18517,7 @@ var MicrosandboxRemoteInstance = class {
|
|
|
18456
18517
|
var MicrosandboxServiceClient = class {
|
|
18457
18518
|
constructor(config) {
|
|
18458
18519
|
this.baseURL = config.baseURL.replace(/\/$/, "");
|
|
18520
|
+
this.apiKey = config.apiKey;
|
|
18459
18521
|
}
|
|
18460
18522
|
async ensureSandbox(name, input) {
|
|
18461
18523
|
return this.request(`/api/sandboxes/${encodeURIComponent(name)}`, {
|
|
@@ -18488,34 +18550,34 @@ var MicrosandboxServiceClient = class {
|
|
|
18488
18550
|
method: "GET"
|
|
18489
18551
|
});
|
|
18490
18552
|
}
|
|
18491
|
-
async readFile(sandboxName,
|
|
18553
|
+
async readFile(sandboxName, path4) {
|
|
18492
18554
|
return this.request("/api/files/read", {
|
|
18493
18555
|
method: "POST",
|
|
18494
|
-
body: { sandboxName, path:
|
|
18556
|
+
body: { sandboxName, path: path4 }
|
|
18495
18557
|
});
|
|
18496
18558
|
}
|
|
18497
|
-
async writeFile(sandboxName,
|
|
18559
|
+
async writeFile(sandboxName, path4, content) {
|
|
18498
18560
|
return this.request("/api/files/write", {
|
|
18499
18561
|
method: "POST",
|
|
18500
|
-
body: { sandboxName, path:
|
|
18562
|
+
body: { sandboxName, path: path4, content }
|
|
18501
18563
|
});
|
|
18502
18564
|
}
|
|
18503
|
-
async listPath(sandboxName,
|
|
18565
|
+
async listPath(sandboxName, path4, recursive) {
|
|
18504
18566
|
return this.request("/api/files/list", {
|
|
18505
18567
|
method: "POST",
|
|
18506
|
-
body: { sandboxName, path:
|
|
18568
|
+
body: { sandboxName, path: path4, recursive }
|
|
18507
18569
|
});
|
|
18508
18570
|
}
|
|
18509
|
-
async findFiles(sandboxName,
|
|
18571
|
+
async findFiles(sandboxName, path4, pattern) {
|
|
18510
18572
|
return this.request("/api/files/find", {
|
|
18511
18573
|
method: "POST",
|
|
18512
|
-
body: { sandboxName, path:
|
|
18574
|
+
body: { sandboxName, path: path4, pattern }
|
|
18513
18575
|
});
|
|
18514
18576
|
}
|
|
18515
|
-
async searchInFile(sandboxName,
|
|
18577
|
+
async searchInFile(sandboxName, path4, query) {
|
|
18516
18578
|
return this.request("/api/files/search", {
|
|
18517
18579
|
method: "POST",
|
|
18518
|
-
body: { sandboxName, path:
|
|
18580
|
+
body: { sandboxName, path: path4, query }
|
|
18519
18581
|
});
|
|
18520
18582
|
}
|
|
18521
18583
|
async replaceInFile(sandboxName, input) {
|
|
@@ -18524,14 +18586,14 @@ var MicrosandboxServiceClient = class {
|
|
|
18524
18586
|
body: { sandboxName, ...input }
|
|
18525
18587
|
});
|
|
18526
18588
|
}
|
|
18527
|
-
async uploadFile(sandboxName,
|
|
18589
|
+
async uploadFile(sandboxName, path4, content) {
|
|
18528
18590
|
return this.request("/api/files/upload", {
|
|
18529
18591
|
method: "POST",
|
|
18530
|
-
body: { sandboxName, path:
|
|
18592
|
+
body: { sandboxName, path: path4, contentBase64: content.toString("base64") }
|
|
18531
18593
|
});
|
|
18532
18594
|
}
|
|
18533
|
-
async downloadFile(sandboxName,
|
|
18534
|
-
const query = new URLSearchParams({ sandboxName, path:
|
|
18595
|
+
async downloadFile(sandboxName, path4) {
|
|
18596
|
+
const query = new URLSearchParams({ sandboxName, path: path4 });
|
|
18535
18597
|
return this.request(`/api/files/download?${query.toString()}`, {
|
|
18536
18598
|
method: "GET"
|
|
18537
18599
|
});
|
|
@@ -18542,33 +18604,60 @@ var MicrosandboxServiceClient = class {
|
|
|
18542
18604
|
body: input
|
|
18543
18605
|
});
|
|
18544
18606
|
}
|
|
18545
|
-
async request(
|
|
18546
|
-
const
|
|
18607
|
+
async request(path4, init) {
|
|
18608
|
+
const headers = {};
|
|
18609
|
+
if (init.body) {
|
|
18610
|
+
headers["content-type"] = "application/json";
|
|
18611
|
+
}
|
|
18612
|
+
if (this.apiKey) {
|
|
18613
|
+
headers.Authorization = `Bearer ${this.apiKey}`;
|
|
18614
|
+
}
|
|
18615
|
+
const response = await fetch(`${this.baseURL}${path4}`, {
|
|
18547
18616
|
method: init.method,
|
|
18548
|
-
headers:
|
|
18617
|
+
headers: Object.keys(headers).length > 0 ? headers : void 0,
|
|
18549
18618
|
body: init.body ? JSON.stringify(init.body) : void 0
|
|
18550
18619
|
});
|
|
18551
18620
|
if (!response.ok) {
|
|
18552
18621
|
throw new Error(`Microsandbox service request failed: ${response.status} ${response.statusText}`);
|
|
18553
18622
|
}
|
|
18554
18623
|
const payload = await response.json();
|
|
18624
|
+
if (payload?.success === false) {
|
|
18625
|
+
throw new Error(`Microsandbox service request failed: ${payload.error ?? "unsuccessful response envelope"}`);
|
|
18626
|
+
}
|
|
18627
|
+
if (payload?.success !== true || !("data" in payload)) {
|
|
18628
|
+
throw new Error("Microsandbox service returned an invalid success envelope");
|
|
18629
|
+
}
|
|
18555
18630
|
return payload.data;
|
|
18556
18631
|
}
|
|
18557
18632
|
};
|
|
18558
18633
|
|
|
18559
18634
|
// src/sandbox_lattice/providers/MicrosandboxRemoteProvider.ts
|
|
18560
|
-
|
|
18561
|
-
|
|
18562
|
-
|
|
18563
|
-
|
|
18564
|
-
}
|
|
18635
|
+
function parseOptionalNumberEnv(name, fallback) {
|
|
18636
|
+
const rawValue = process.env[name];
|
|
18637
|
+
if (rawValue === void 0) {
|
|
18638
|
+
return fallback;
|
|
18639
|
+
}
|
|
18640
|
+
const parsedValue = Number(rawValue);
|
|
18641
|
+
if (!Number.isFinite(parsedValue)) {
|
|
18642
|
+
throw new Error(`Invalid ${name} environment value: ${rawValue}`);
|
|
18643
|
+
}
|
|
18644
|
+
return parsedValue;
|
|
18645
|
+
}
|
|
18646
|
+
function getDefaultMicrosandboxRemoteConfig() {
|
|
18647
|
+
return {
|
|
18648
|
+
image: process.env.MICROSANDBOX_IMAGE ?? "daytonaio/sandbox:0.6.0",
|
|
18649
|
+
cpus: parseOptionalNumberEnv("MICROSANDBOX_CPUS", 1),
|
|
18650
|
+
memoryMib: parseOptionalNumberEnv("MICROSANDBOX_MEMORY", 512)
|
|
18651
|
+
};
|
|
18652
|
+
}
|
|
18565
18653
|
var MicrosandboxRemoteProvider = class {
|
|
18566
18654
|
constructor(config) {
|
|
18567
18655
|
this.config = config;
|
|
18568
18656
|
this.instances = /* @__PURE__ */ new Map();
|
|
18569
18657
|
this.creating = /* @__PURE__ */ new Map();
|
|
18570
18658
|
this.client = config.client ?? new MicrosandboxServiceClient({
|
|
18571
|
-
baseURL: config.baseURL
|
|
18659
|
+
baseURL: config.baseURL,
|
|
18660
|
+
apiKey: config.apiKey ?? process.env.MICROSANDBOX_API_KEY
|
|
18572
18661
|
});
|
|
18573
18662
|
}
|
|
18574
18663
|
async createSandbox(name, config) {
|
|
@@ -18587,9 +18676,14 @@ var MicrosandboxRemoteProvider = class {
|
|
|
18587
18676
|
return instance;
|
|
18588
18677
|
})();
|
|
18589
18678
|
this.creating.set(name, creation);
|
|
18590
|
-
creation.
|
|
18591
|
-
|
|
18592
|
-
|
|
18679
|
+
creation.then(
|
|
18680
|
+
() => {
|
|
18681
|
+
this.creating.delete(name);
|
|
18682
|
+
},
|
|
18683
|
+
() => {
|
|
18684
|
+
this.creating.delete(name);
|
|
18685
|
+
}
|
|
18686
|
+
);
|
|
18593
18687
|
return creation;
|
|
18594
18688
|
}
|
|
18595
18689
|
async getSandbox(name) {
|
|
@@ -18611,6 +18705,7 @@ var MicrosandboxRemoteProvider = class {
|
|
|
18611
18705
|
return Array.from(this.instances.values());
|
|
18612
18706
|
}
|
|
18613
18707
|
buildEnsureInput(config) {
|
|
18708
|
+
const defaultMicrosandboxRemoteConfig = getDefaultMicrosandboxRemoteConfig();
|
|
18614
18709
|
return {
|
|
18615
18710
|
image: this.config.image ?? defaultMicrosandboxRemoteConfig.image,
|
|
18616
18711
|
cpus: this.config.cpus ?? defaultMicrosandboxRemoteConfig.cpus,
|
|
@@ -18622,20 +18717,20 @@ var MicrosandboxRemoteProvider = class {
|
|
|
18622
18717
|
buildDefaultVolumes(config) {
|
|
18623
18718
|
const tenantId = config?.tenantId ?? "default";
|
|
18624
18719
|
const volumes = {
|
|
18625
|
-
"/home/
|
|
18720
|
+
"/home/daytona/.agents/skills": {
|
|
18626
18721
|
type: "named",
|
|
18627
18722
|
name: `${tenantId}-skills`
|
|
18628
18723
|
}
|
|
18629
18724
|
};
|
|
18630
18725
|
if (config?.assistant_id) {
|
|
18631
|
-
volumes["/home/
|
|
18726
|
+
volumes["/home/daytona/agent"] = {
|
|
18632
18727
|
type: "named",
|
|
18633
18728
|
name: `${tenantId}-agent-${config.assistant_id}`
|
|
18634
18729
|
};
|
|
18635
18730
|
}
|
|
18636
18731
|
if (config?.projectId) {
|
|
18637
18732
|
const projectVolumeName = config.workspaceId ? `${tenantId}-workspace-${config.workspaceId}-project-${config.projectId}` : `${tenantId}-project-${config.projectId}`;
|
|
18638
|
-
volumes["/home/
|
|
18733
|
+
volumes["/home/daytona/project"] = {
|
|
18639
18734
|
type: "named",
|
|
18640
18735
|
name: projectVolumeName
|
|
18641
18736
|
};
|
|
@@ -18665,9 +18760,9 @@ var RemoteSandboxInstance = class {
|
|
|
18665
18760
|
throw new Error(String(result.error));
|
|
18666
18761
|
}
|
|
18667
18762
|
},
|
|
18668
|
-
listPath: async (
|
|
18763
|
+
listPath: async (path4, options) => {
|
|
18669
18764
|
const result = await this.client.file.listPath({
|
|
18670
|
-
path:
|
|
18765
|
+
path: path4,
|
|
18671
18766
|
recursive: options?.recursive ?? false
|
|
18672
18767
|
});
|
|
18673
18768
|
if (!result.ok) {
|
|
@@ -18681,8 +18776,8 @@ var RemoteSandboxInstance = class {
|
|
|
18681
18776
|
}));
|
|
18682
18777
|
return { files };
|
|
18683
18778
|
},
|
|
18684
|
-
findFiles: async (
|
|
18685
|
-
const result = await this.client.file.findFiles({ path:
|
|
18779
|
+
findFiles: async (path4, glob) => {
|
|
18780
|
+
const result = await this.client.file.findFiles({ path: path4, glob });
|
|
18686
18781
|
if (!result.ok) {
|
|
18687
18782
|
throw new Error(String(result.error));
|
|
18688
18783
|
}
|
|
@@ -18819,8 +18914,8 @@ var E2BInstance = class {
|
|
|
18819
18914
|
writeFile: async (file, content) => {
|
|
18820
18915
|
await this.native.files.write(file, content);
|
|
18821
18916
|
},
|
|
18822
|
-
listPath: async (
|
|
18823
|
-
const entries = await this.native.files.list(
|
|
18917
|
+
listPath: async (path4, options) => {
|
|
18918
|
+
const entries = await this.native.files.list(path4);
|
|
18824
18919
|
const files = entries.map((e) => ({
|
|
18825
18920
|
path: e.path,
|
|
18826
18921
|
is_dir: e.type === "dir",
|
|
@@ -18829,9 +18924,9 @@ var E2BInstance = class {
|
|
|
18829
18924
|
}));
|
|
18830
18925
|
return { files };
|
|
18831
18926
|
},
|
|
18832
|
-
findFiles: async (
|
|
18927
|
+
findFiles: async (path4, glob) => {
|
|
18833
18928
|
const result = await this.native.commands.run(
|
|
18834
|
-
`find "${
|
|
18929
|
+
`find "${path4}" -name "${glob}" -type f`
|
|
18835
18930
|
);
|
|
18836
18931
|
const lines = result.stdout.split("\n").filter(Boolean);
|
|
18837
18932
|
return { files: lines };
|
|
@@ -18854,13 +18949,13 @@ var E2BInstance = class {
|
|
|
18854
18949
|
return { matches, line_numbers };
|
|
18855
18950
|
},
|
|
18856
18951
|
strReplaceEditor: async (params) => {
|
|
18857
|
-
const { path:
|
|
18952
|
+
const { path: path4, old_str, new_str, replace_mode } = params;
|
|
18858
18953
|
const delim = "#";
|
|
18859
18954
|
const escapedOld = old_str.replace(new RegExp(`[\\\\${delim}]`, "g"), "\\$&").replace(/\n/g, "\\n");
|
|
18860
18955
|
const escapedNew = new_str.replace(new RegExp(`[\\\\${delim}]`, "g"), "\\$&").replace(/\n/g, "\\n");
|
|
18861
18956
|
const flag = replace_mode === "ALL" ? "g" : "";
|
|
18862
18957
|
await this.native.commands.run(
|
|
18863
|
-
`sed -i 's${delim}${escapedOld}${delim}${escapedNew}${delim}${flag}' "${
|
|
18958
|
+
`sed -i 's${delim}${escapedOld}${delim}${escapedNew}${delim}${flag}' "${path4}"`
|
|
18864
18959
|
);
|
|
18865
18960
|
},
|
|
18866
18961
|
uploadFile: async (params) => {
|
|
@@ -18976,14 +19071,14 @@ var DaytonaInstance = class {
|
|
|
18976
19071
|
this.native = native;
|
|
18977
19072
|
this.file = {
|
|
18978
19073
|
readFile: async (file) => {
|
|
18979
|
-
const buffer2 = await this.native.fs.downloadFile(
|
|
19074
|
+
const buffer2 = await this.native.fs.downloadFile(toSandboxHomePath(file));
|
|
18980
19075
|
return { content: buffer2.toString("utf-8") };
|
|
18981
19076
|
},
|
|
18982
19077
|
writeFile: async (file, content) => {
|
|
18983
|
-
await this.native.fs.uploadFile(Buffer.from(content, "utf-8"),
|
|
19078
|
+
await this.native.fs.uploadFile(Buffer.from(content, "utf-8"), toSandboxHomePath(file));
|
|
18984
19079
|
},
|
|
18985
|
-
listPath: async (
|
|
18986
|
-
const entries = await this.native.fs.listFiles(
|
|
19080
|
+
listPath: async (path4, options) => {
|
|
19081
|
+
const entries = await this.native.fs.listFiles(toSandboxHomePath(path4));
|
|
18987
19082
|
const files = entries.map((e) => {
|
|
18988
19083
|
let name = e.name || "";
|
|
18989
19084
|
while (name.startsWith("~/") || name.startsWith("/")) {
|
|
@@ -18993,7 +19088,7 @@ var DaytonaInstance = class {
|
|
|
18993
19088
|
name = name.slice(1);
|
|
18994
19089
|
}
|
|
18995
19090
|
}
|
|
18996
|
-
const fullPath = name ? `${
|
|
19091
|
+
const fullPath = name ? `${path4}/${name}`.replace(/\/+/g, "/") : path4;
|
|
18997
19092
|
return {
|
|
18998
19093
|
path: fullPath,
|
|
18999
19094
|
is_dir: e.isDir ?? false,
|
|
@@ -19003,12 +19098,12 @@ var DaytonaInstance = class {
|
|
|
19003
19098
|
});
|
|
19004
19099
|
return { files };
|
|
19005
19100
|
},
|
|
19006
|
-
findFiles: async (
|
|
19007
|
-
const result = await this.native.fs.searchFiles(
|
|
19101
|
+
findFiles: async (path4, glob) => {
|
|
19102
|
+
const result = await this.native.fs.searchFiles(toSandboxHomePath(path4), glob);
|
|
19008
19103
|
return { files: result.files || [] };
|
|
19009
19104
|
},
|
|
19010
19105
|
searchInFile: async (file, regex) => {
|
|
19011
|
-
const matches = await this.native.fs.findFiles(
|
|
19106
|
+
const matches = await this.native.fs.findFiles(toSandboxHomePath(file), regex);
|
|
19012
19107
|
const line_numbers = [];
|
|
19013
19108
|
const matchTexts = [];
|
|
19014
19109
|
for (const match of matches) {
|
|
@@ -19018,8 +19113,8 @@ var DaytonaInstance = class {
|
|
|
19018
19113
|
return { matches: matchTexts, line_numbers };
|
|
19019
19114
|
},
|
|
19020
19115
|
strReplaceEditor: async (params) => {
|
|
19021
|
-
const { path:
|
|
19022
|
-
const relPath =
|
|
19116
|
+
const { path: path4, old_str, new_str, replace_mode } = params;
|
|
19117
|
+
const relPath = toSandboxHomePath(path4);
|
|
19023
19118
|
if (replace_mode === "ALL") {
|
|
19024
19119
|
await this.native.fs.replaceInFiles([relPath], old_str, new_str);
|
|
19025
19120
|
} else {
|
|
@@ -19033,10 +19128,10 @@ var DaytonaInstance = class {
|
|
|
19033
19128
|
}
|
|
19034
19129
|
},
|
|
19035
19130
|
uploadFile: async (params) => {
|
|
19036
|
-
await this.native.fs.uploadFile(params.data,
|
|
19131
|
+
await this.native.fs.uploadFile(params.data, toSandboxHomePath(params.file));
|
|
19037
19132
|
},
|
|
19038
19133
|
downloadFile: async (params) => {
|
|
19039
|
-
const buffer2 = await this.native.fs.downloadFile(
|
|
19134
|
+
const buffer2 = await this.native.fs.downloadFile(toSandboxHomePath(params.file));
|
|
19040
19135
|
return Buffer.isBuffer(buffer2) ? buffer2 : Buffer.from(buffer2);
|
|
19041
19136
|
}
|
|
19042
19137
|
};
|
|
@@ -19057,25 +19152,6 @@ var DaytonaInstance = class {
|
|
|
19057
19152
|
};
|
|
19058
19153
|
this.name = name;
|
|
19059
19154
|
}
|
|
19060
|
-
/**
|
|
19061
|
-
* All sandbox file operations live under the user's home directory (~).
|
|
19062
|
-
* The AI uses virtual paths like "~/agent/file.txt". Daytona SDK expects
|
|
19063
|
-
* relative paths for file operations (they are resolved against ~ automatically),
|
|
19064
|
-
* so we strip the leading "~/" or "/" here.
|
|
19065
|
-
*
|
|
19066
|
-
* Handles edge cases like "~/~/agent/file.txt" by repeatedly stripping prefixes.
|
|
19067
|
-
*/
|
|
19068
|
-
toSandboxHomePath(path3) {
|
|
19069
|
-
let result = path3;
|
|
19070
|
-
while (result.startsWith("~/") || result.startsWith("/")) {
|
|
19071
|
-
if (result.startsWith("~/")) {
|
|
19072
|
-
result = result.slice(2);
|
|
19073
|
-
} else if (result.startsWith("/")) {
|
|
19074
|
-
result = result.slice(1);
|
|
19075
|
-
}
|
|
19076
|
-
}
|
|
19077
|
-
return result;
|
|
19078
|
-
}
|
|
19079
19155
|
async start() {
|
|
19080
19156
|
await this.native.start();
|
|
19081
19157
|
}
|