@axiom-lattice/core 2.1.53 → 2.1.54
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 +12 -8
- package/dist/index.d.ts +12 -8
- package/dist/index.js +359 -266
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +359 -266
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -3484,13 +3484,15 @@ var import_zod15 = __toESM(require("zod"));
|
|
|
3484
3484
|
|
|
3485
3485
|
// src/deep_agent_new/backends/volumeFilesystem.ts
|
|
3486
3486
|
var VolumeFilesystem = class {
|
|
3487
|
-
constructor(client) {
|
|
3487
|
+
constructor(client, mountPrefix = "") {
|
|
3488
3488
|
this.client = client;
|
|
3489
|
+
this.mountPrefix = mountPrefix;
|
|
3489
3490
|
}
|
|
3490
|
-
async lsInfo(
|
|
3491
|
-
const entries = await this.client.list(
|
|
3491
|
+
async lsInfo(path3) {
|
|
3492
|
+
const entries = await this.client.list(path3);
|
|
3493
|
+
const prefix = this.mountPrefix.endsWith("/") ? this.mountPrefix : this.mountPrefix + "/";
|
|
3492
3494
|
return entries.map((entry) => ({
|
|
3493
|
-
path: entry.path,
|
|
3495
|
+
path: entry.path.startsWith("/") ? entry.path : prefix + entry.path,
|
|
3494
3496
|
is_dir: entry.kind === "directory",
|
|
3495
3497
|
size: entry.size,
|
|
3496
3498
|
modified_at: entry.modified ? new Date(entry.modified).toISOString() : void 0
|
|
@@ -3536,6 +3538,20 @@ var VolumeFilesystem = class {
|
|
|
3536
3538
|
}
|
|
3537
3539
|
};
|
|
3538
3540
|
|
|
3541
|
+
// src/sandbox_lattice/pathUtils.ts
|
|
3542
|
+
function normalizeExternalSandboxPath(inputPath) {
|
|
3543
|
+
if (inputPath === "~" || inputPath === "~/") {
|
|
3544
|
+
return "/";
|
|
3545
|
+
}
|
|
3546
|
+
if (inputPath.startsWith("~/")) {
|
|
3547
|
+
return `/${inputPath.slice(2)}`;
|
|
3548
|
+
}
|
|
3549
|
+
if (inputPath.startsWith("/")) {
|
|
3550
|
+
return inputPath;
|
|
3551
|
+
}
|
|
3552
|
+
return `/${inputPath}`;
|
|
3553
|
+
}
|
|
3554
|
+
|
|
3539
3555
|
// src/sandbox_lattice/utils.ts
|
|
3540
3556
|
var import_node_crypto = require("crypto");
|
|
3541
3557
|
function normalizeSandboxName(name) {
|
|
@@ -3572,6 +3588,20 @@ function buildNamedVolumeName(prefix, ...parts) {
|
|
|
3572
3588
|
}
|
|
3573
3589
|
|
|
3574
3590
|
// src/sandbox_lattice/SandboxLatticeManager.ts
|
|
3591
|
+
function stripPrefixClient(client, prefix) {
|
|
3592
|
+
const strip = (p) => {
|
|
3593
|
+
if (p === prefix || p === prefix + "/") return "";
|
|
3594
|
+
if (p.startsWith(prefix + "/")) return p.slice(prefix.length + 1);
|
|
3595
|
+
return p;
|
|
3596
|
+
};
|
|
3597
|
+
return {
|
|
3598
|
+
read: (p) => client.read(strip(p)),
|
|
3599
|
+
write: (p, c) => client.write(strip(p), c),
|
|
3600
|
+
list: (p) => client.list(strip(p)),
|
|
3601
|
+
readRaw: (p) => client.readRaw(strip(p)),
|
|
3602
|
+
writeRaw: (p, d) => client.writeRaw(strip(p), d)
|
|
3603
|
+
};
|
|
3604
|
+
}
|
|
3575
3605
|
function computeSandboxName(config) {
|
|
3576
3606
|
switch (config.vmIsolation) {
|
|
3577
3607
|
case "global":
|
|
@@ -3643,17 +3673,39 @@ var SandboxLatticeManager = class _SandboxLatticeManager extends BaseLatticeMana
|
|
|
3643
3673
|
return this.createSandbox(name, config);
|
|
3644
3674
|
}
|
|
3645
3675
|
async getVolumeBackend(config) {
|
|
3676
|
+
return this.getVolumeBackendForPath(config, "/project");
|
|
3677
|
+
}
|
|
3678
|
+
async getVolumeBackendForPath(config, filePath) {
|
|
3646
3679
|
const provider = this._requireProvider();
|
|
3647
3680
|
if (!provider.createVolumeFsClient) {
|
|
3648
3681
|
return null;
|
|
3649
3682
|
}
|
|
3650
3683
|
const tenantId = config.tenantId ?? "default";
|
|
3651
|
-
|
|
3652
|
-
|
|
3684
|
+
const mapping = this._resolveVolumeForPath(config, tenantId, filePath);
|
|
3685
|
+
if (!mapping) return null;
|
|
3686
|
+
const client = provider.createVolumeFsClient(mapping.volumeName);
|
|
3687
|
+
return new VolumeFilesystem(stripPrefixClient(client, mapping.pathPrefix), mapping.pathPrefix);
|
|
3688
|
+
}
|
|
3689
|
+
_resolveVolumeForPath(config, tenantId, filePath) {
|
|
3690
|
+
const normalized = normalizeExternalSandboxPath(filePath);
|
|
3691
|
+
if (normalized === "/.agent" || normalized.startsWith("/.agent/")) {
|
|
3692
|
+
return {
|
|
3693
|
+
volumeName: buildNamedVolumeName("s", "skills", tenantId),
|
|
3694
|
+
pathPrefix: "/.agent"
|
|
3695
|
+
};
|
|
3653
3696
|
}
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3697
|
+
if (normalized === "/agent" || normalized.startsWith("/agent/")) {
|
|
3698
|
+
if (!config.assistant_id) return null;
|
|
3699
|
+
return {
|
|
3700
|
+
volumeName: buildNamedVolumeName("a", "agent", tenantId, config.assistant_id),
|
|
3701
|
+
pathPrefix: "/agent"
|
|
3702
|
+
};
|
|
3703
|
+
}
|
|
3704
|
+
if (!config.projectId) return null;
|
|
3705
|
+
return {
|
|
3706
|
+
volumeName: buildNamedVolumeName("p", "project", tenantId, config.workspaceId, config.projectId),
|
|
3707
|
+
pathPrefix: "/project"
|
|
3708
|
+
};
|
|
3657
3709
|
}
|
|
3658
3710
|
async createSandbox(name, config) {
|
|
3659
3711
|
const provider = this._requireProvider();
|
|
@@ -3707,9 +3759,9 @@ var SHELL_EXEC_DESCRIPTION = `Execute a shell command in the sandbox environment
|
|
|
3707
3759
|
|
|
3708
3760
|
Use this to run CLI tools, install packages, inspect files, or perform any operation that requires a shell.
|
|
3709
3761
|
|
|
3710
|
-
To execute a code file, pass the appropriate command (e.g. "python
|
|
3762
|
+
To execute a code file, pass the appropriate command (e.g. "python /project/main.py" or "node /project/app.js"). Only Python (.py) and JavaScript (.js, .mjs) files are supported.
|
|
3711
3763
|
|
|
3712
|
-
Note: the working directory defaults to
|
|
3764
|
+
Note: the working directory defaults to /. Project files are under /project/. Use paths like "/project/file.txt".`;
|
|
3713
3765
|
function formatExecutionResult(data) {
|
|
3714
3766
|
const parts = [];
|
|
3715
3767
|
if (data.output) {
|
|
@@ -5035,13 +5087,13 @@ var createLoadSkillContentTool = () => {
|
|
|
5035
5087
|
async (input, _exe_config) => {
|
|
5036
5088
|
try {
|
|
5037
5089
|
const sandbox = await getSandboxFromExeConfig(_exe_config);
|
|
5038
|
-
const filePath =
|
|
5090
|
+
const filePath = `/.agent/skills/${input.skill_name}/SKILL.md`;
|
|
5039
5091
|
let content;
|
|
5040
5092
|
try {
|
|
5041
5093
|
const result2 = await sandbox.file.readFile(filePath);
|
|
5042
5094
|
content = result2.content;
|
|
5043
5095
|
} catch {
|
|
5044
|
-
const listResult = await sandbox.file.listPath("
|
|
5096
|
+
const listResult = await sandbox.file.listPath("/.agent/skills", { recursive: false });
|
|
5045
5097
|
const available = listResult.files.filter((f) => f.is_dir).map((f) => f.path.split("/").pop()).filter(Boolean).join(", ");
|
|
5046
5098
|
return `Skill "${input.skill_name}" not found. Available skills: ${available}`;
|
|
5047
5099
|
}
|
|
@@ -5049,7 +5101,7 @@ var createLoadSkillContentTool = () => {
|
|
|
5049
5101
|
let result = buildSkillFile(meta, body);
|
|
5050
5102
|
try {
|
|
5051
5103
|
const resourcesResult = await sandbox.file.listPath(
|
|
5052
|
-
|
|
5104
|
+
`/.agent/skills/${input.skill_name}/resources`,
|
|
5053
5105
|
{ recursive: false }
|
|
5054
5106
|
);
|
|
5055
5107
|
const resources = resourcesResult.files.map((f) => f.path.split("/").pop()).filter(Boolean);
|
|
@@ -5102,14 +5154,14 @@ function createSkillMiddleware(params = {}) {
|
|
|
5102
5154
|
projectId: runConfig.projectId,
|
|
5103
5155
|
vmIsolation: "project"
|
|
5104
5156
|
});
|
|
5105
|
-
const result = await sandbox.file.listPath("
|
|
5157
|
+
const result = await sandbox.file.listPath("/.agent/skills", { recursive: false });
|
|
5106
5158
|
const allSkills = [];
|
|
5107
5159
|
for (const entry of result.files) {
|
|
5108
5160
|
if (!entry.is_dir) continue;
|
|
5109
5161
|
const skillName = entry.path.split("/").pop();
|
|
5110
5162
|
if (!skillName) continue;
|
|
5111
5163
|
try {
|
|
5112
|
-
const fileResult = await sandbox.file.readFile(
|
|
5164
|
+
const fileResult = await sandbox.file.readFile(`/.agent/skills/${skillName}/SKILL.md`);
|
|
5113
5165
|
const { meta } = parseSkillFrontmatter(fileResult.content);
|
|
5114
5166
|
allSkills.push({
|
|
5115
5167
|
id: skillName,
|
|
@@ -5273,16 +5325,16 @@ function truncateIfTooLong(result) {
|
|
|
5273
5325
|
}
|
|
5274
5326
|
return result;
|
|
5275
5327
|
}
|
|
5276
|
-
function validatePath(
|
|
5277
|
-
const pathStr =
|
|
5328
|
+
function validatePath(path3) {
|
|
5329
|
+
const pathStr = path3 || "/";
|
|
5278
5330
|
if (!pathStr || pathStr.trim() === "") {
|
|
5279
5331
|
throw new Error("Path cannot be empty");
|
|
5280
5332
|
}
|
|
5281
5333
|
let normalized;
|
|
5282
|
-
if (pathStr === "~") {
|
|
5283
|
-
normalized = "
|
|
5334
|
+
if (pathStr === "~" || pathStr === "~/") {
|
|
5335
|
+
normalized = "/";
|
|
5284
5336
|
} else if (pathStr.startsWith("~/")) {
|
|
5285
|
-
normalized = pathStr
|
|
5337
|
+
normalized = `/${pathStr.slice(2)}`;
|
|
5286
5338
|
} else {
|
|
5287
5339
|
normalized = pathStr.startsWith("/") ? pathStr : "/" + pathStr;
|
|
5288
5340
|
}
|
|
@@ -5291,10 +5343,10 @@ function validatePath(path4) {
|
|
|
5291
5343
|
}
|
|
5292
5344
|
return normalized;
|
|
5293
5345
|
}
|
|
5294
|
-
function globSearchFiles(files, pattern,
|
|
5346
|
+
function globSearchFiles(files, pattern, path3 = "/") {
|
|
5295
5347
|
let normalizedPath;
|
|
5296
5348
|
try {
|
|
5297
|
-
normalizedPath = validatePath(
|
|
5349
|
+
normalizedPath = validatePath(path3);
|
|
5298
5350
|
} catch {
|
|
5299
5351
|
return "No files found";
|
|
5300
5352
|
}
|
|
@@ -5346,7 +5398,7 @@ function formatGrepResults(results, outputMode) {
|
|
|
5346
5398
|
}
|
|
5347
5399
|
return lines.join("\n");
|
|
5348
5400
|
}
|
|
5349
|
-
function grepSearchFiles(files, pattern,
|
|
5401
|
+
function grepSearchFiles(files, pattern, path3 = null, glob = null, outputMode = "files_with_matches") {
|
|
5350
5402
|
let regex;
|
|
5351
5403
|
try {
|
|
5352
5404
|
regex = new RegExp(pattern);
|
|
@@ -5355,7 +5407,7 @@ function grepSearchFiles(files, pattern, path4 = null, glob = null, outputMode =
|
|
|
5355
5407
|
}
|
|
5356
5408
|
let normalizedPath;
|
|
5357
5409
|
try {
|
|
5358
|
-
normalizedPath = validatePath(
|
|
5410
|
+
normalizedPath = validatePath(path3);
|
|
5359
5411
|
} catch {
|
|
5360
5412
|
return "No matches found";
|
|
5361
5413
|
}
|
|
@@ -5387,7 +5439,7 @@ function grepSearchFiles(files, pattern, path4 = null, glob = null, outputMode =
|
|
|
5387
5439
|
}
|
|
5388
5440
|
return formatGrepResults(results, outputMode);
|
|
5389
5441
|
}
|
|
5390
|
-
function grepMatchesFromFiles(files, pattern,
|
|
5442
|
+
function grepMatchesFromFiles(files, pattern, path3 = null, glob = null) {
|
|
5391
5443
|
let regex;
|
|
5392
5444
|
try {
|
|
5393
5445
|
regex = new RegExp(pattern);
|
|
@@ -5396,7 +5448,7 @@ function grepMatchesFromFiles(files, pattern, path4 = null, glob = null) {
|
|
|
5396
5448
|
}
|
|
5397
5449
|
let normalizedPath;
|
|
5398
5450
|
try {
|
|
5399
|
-
normalizedPath = validatePath(
|
|
5451
|
+
normalizedPath = validatePath(path3);
|
|
5400
5452
|
} catch {
|
|
5401
5453
|
return [];
|
|
5402
5454
|
}
|
|
@@ -5457,11 +5509,11 @@ var StateBackend = class {
|
|
|
5457
5509
|
* @returns List of FileInfo objects for files and directories directly in the directory.
|
|
5458
5510
|
* Directories have a trailing / in their path and is_dir=true.
|
|
5459
5511
|
*/
|
|
5460
|
-
lsInfo(
|
|
5512
|
+
lsInfo(path3) {
|
|
5461
5513
|
const files = this.getFiles();
|
|
5462
5514
|
const infos = [];
|
|
5463
5515
|
const subdirs = /* @__PURE__ */ new Set();
|
|
5464
|
-
const normalizedPath =
|
|
5516
|
+
const normalizedPath = path3.endsWith("/") ? path3 : path3 + "/";
|
|
5465
5517
|
for (const [k, fd] of Object.entries(files)) {
|
|
5466
5518
|
if (!k.startsWith(normalizedPath)) {
|
|
5467
5519
|
continue;
|
|
@@ -5567,16 +5619,16 @@ var StateBackend = class {
|
|
|
5567
5619
|
/**
|
|
5568
5620
|
* Structured search results or error string for invalid input.
|
|
5569
5621
|
*/
|
|
5570
|
-
grepRaw(pattern,
|
|
5622
|
+
grepRaw(pattern, path3 = "/", glob = null) {
|
|
5571
5623
|
const files = this.getFiles();
|
|
5572
|
-
return grepMatchesFromFiles(files, pattern,
|
|
5624
|
+
return grepMatchesFromFiles(files, pattern, path3, glob);
|
|
5573
5625
|
}
|
|
5574
5626
|
/**
|
|
5575
5627
|
* Structured glob matching returning FileInfo objects.
|
|
5576
5628
|
*/
|
|
5577
|
-
globInfo(pattern,
|
|
5629
|
+
globInfo(pattern, path3 = "/") {
|
|
5578
5630
|
const files = this.getFiles();
|
|
5579
|
-
const result = globSearchFiles(files, pattern,
|
|
5631
|
+
const result = globSearchFiles(files, pattern, path3);
|
|
5580
5632
|
if (result === "No files found") {
|
|
5581
5633
|
return [];
|
|
5582
5634
|
}
|
|
@@ -5642,16 +5694,16 @@ async function getBackend(backend, stateAndStore) {
|
|
|
5642
5694
|
var FILESYSTEM_SYSTEM_PROMPT = `You have access to a virtual filesystem.
|
|
5643
5695
|
|
|
5644
5696
|
Path conventions:
|
|
5645
|
-
- All paths
|
|
5646
|
-
-
|
|
5647
|
-
-
|
|
5648
|
-
-
|
|
5697
|
+
- All paths are absolute starting with /. Key directories:
|
|
5698
|
+
- /agent/ \u2014 Your private agent directory (identity, memory, preferences). Isolated per agent.
|
|
5699
|
+
- /project/ \u2014 Project workspace. Shared across all agents in the same project. Persisted across sessions.
|
|
5700
|
+
- /.agent/skills/ \u2014 Skill definitions. Read-only for most operations.
|
|
5649
5701
|
|
|
5650
5702
|
- ls: list files in a directory
|
|
5651
5703
|
- read_file: read a file from the filesystem
|
|
5652
5704
|
- write_file: write to a file in the filesystem
|
|
5653
5705
|
- edit_file: edit a file in the filesystem
|
|
5654
|
-
- glob: find files matching a pattern (e.g., "
|
|
5706
|
+
- glob: find files matching a pattern (e.g., "/project/**/*.py")
|
|
5655
5707
|
- grep: search for text within files`;
|
|
5656
5708
|
var LS_TOOL_DESCRIPTION = "List files and directories in a directory";
|
|
5657
5709
|
var READ_FILE_TOOL_DESCRIPTION = "Read the contents of a file";
|
|
@@ -5670,10 +5722,10 @@ function createLsTool(backend, options) {
|
|
|
5670
5722
|
...runConfig
|
|
5671
5723
|
};
|
|
5672
5724
|
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
5673
|
-
const
|
|
5674
|
-
const infos = await resolvedBackend.lsInfo(
|
|
5725
|
+
const path3 = input.path || "/";
|
|
5726
|
+
const infos = await resolvedBackend.lsInfo(path3);
|
|
5675
5727
|
if (infos.length === 0) {
|
|
5676
|
-
return `No files found in ${
|
|
5728
|
+
return `No files found in ${path3}`;
|
|
5677
5729
|
}
|
|
5678
5730
|
const lines = [];
|
|
5679
5731
|
for (const info of infos) {
|
|
@@ -5816,8 +5868,8 @@ function createGlobTool(backend, options) {
|
|
|
5816
5868
|
...runConfig
|
|
5817
5869
|
};
|
|
5818
5870
|
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
5819
|
-
const { pattern, path:
|
|
5820
|
-
const infos = await resolvedBackend.globInfo(pattern,
|
|
5871
|
+
const { pattern, path: path3 = "/" } = input;
|
|
5872
|
+
const infos = await resolvedBackend.globInfo(pattern, path3);
|
|
5821
5873
|
if (infos.length === 0) {
|
|
5822
5874
|
return `No files found matching pattern '${pattern}'`;
|
|
5823
5875
|
}
|
|
@@ -5844,8 +5896,8 @@ function createGrepTool(backend, options) {
|
|
|
5844
5896
|
...runConfig
|
|
5845
5897
|
};
|
|
5846
5898
|
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
5847
|
-
const { pattern, path:
|
|
5848
|
-
const result = await resolvedBackend.grepRaw(pattern,
|
|
5899
|
+
const { pattern, path: path3 = "/", glob = null } = input;
|
|
5900
|
+
const result = await resolvedBackend.grepRaw(pattern, path3, glob);
|
|
5849
5901
|
if (typeof result === "string") {
|
|
5850
5902
|
return result;
|
|
5851
5903
|
}
|
|
@@ -7111,50 +7163,50 @@ var AGENTS_MD = `
|
|
|
7111
7163
|
|
|
7112
7164
|
## First Run
|
|
7113
7165
|
|
|
7114
|
-
If "
|
|
7166
|
+
If "/agent/BOOTSTRAP.md" exists, that's your birth certificate. Follow it, figure out who you are, set up your memory structure, then delete it. You won't need it again. This is the one cleanup exception you can do without asking first.
|
|
7115
7167
|
|
|
7116
7168
|
## Every Session
|
|
7117
7169
|
|
|
7118
7170
|
Before doing anything else, read this startup set in order:
|
|
7119
7171
|
|
|
7120
|
-
1.
|
|
7121
|
-
2.
|
|
7122
|
-
3.
|
|
7123
|
-
4.
|
|
7124
|
-
5.
|
|
7125
|
-
6.
|
|
7126
|
-
7.
|
|
7127
|
-
8.
|
|
7128
|
-
9.
|
|
7172
|
+
1. /agent/SOUL.md
|
|
7173
|
+
2. /agent/AGENTS.md
|
|
7174
|
+
3. /agent/IDENTITY.md
|
|
7175
|
+
4. /agent/USER.md
|
|
7176
|
+
5. /agent/MEMORY.md
|
|
7177
|
+
6. /project/PROJECT.md
|
|
7178
|
+
7. /project/notes/index.md
|
|
7179
|
+
8. /project/notes/wip.md
|
|
7180
|
+
9. /project/notes/pending.md
|
|
7129
7181
|
|
|
7130
7182
|
Don't ask permission. Just do it.
|
|
7131
7183
|
|
|
7132
7184
|
After the startup set, expand only if needed:
|
|
7133
7185
|
|
|
7134
|
-
- If
|
|
7135
|
-
- If the current interruption point still feels underspecified, read the most recent one or two
|
|
7186
|
+
- If /project/notes/wip.md mentions unfamiliar modules, unclear constraints, or prior decisions, read /project/notes/architecture.md and /project/notes/decisions.md.
|
|
7187
|
+
- If the current interruption point still feels underspecified, read the most recent one or two /project/raw/YYYY-MM-DD.md files.
|
|
7136
7188
|
- Do not load every memory file by default. Read deeper only when the current task needs it.
|
|
7137
7189
|
|
|
7138
7190
|
## Memory Model
|
|
7139
7191
|
|
|
7140
7192
|
You wake up fresh each session. Files are your continuity.
|
|
7141
7193
|
|
|
7142
|
-
-
|
|
7143
|
-
-
|
|
7144
|
-
-
|
|
7145
|
-
-
|
|
7146
|
-
-
|
|
7147
|
-
-
|
|
7148
|
-
-
|
|
7149
|
-
-
|
|
7194
|
+
- /agent/ is your private scope.
|
|
7195
|
+
- /agent/MEMORY.md is your memory index.
|
|
7196
|
+
- /agent/memory/*.md stores categorized private memory.
|
|
7197
|
+
- /agent/memory/preferences.md is one example of categorized private memory.
|
|
7198
|
+
- /project/PROJECT.md, /project/raw/, /project/notes/, and /project/artifacts/ belong to the current project.
|
|
7199
|
+
- /project/raw/YYYY-MM-DD.md records what happened.
|
|
7200
|
+
- /project/notes/ records what is worth remembering.
|
|
7201
|
+
- /project/artifacts/ records what was produced.
|
|
7150
7202
|
|
|
7151
7203
|
Use this structure intentionally:
|
|
7152
7204
|
|
|
7153
|
-
- Read
|
|
7154
|
-
- Treat
|
|
7155
|
-
- Write the actual durable private content into
|
|
7156
|
-
- Use
|
|
7157
|
-
- Prefer writing to
|
|
7205
|
+
- Read /agent/MEMORY.md to find the durable private memory that matters now.
|
|
7206
|
+
- Treat /agent/MEMORY.md as an index and navigation file, not as the main place for detailed long-term notes.
|
|
7207
|
+
- Write the actual durable private content into /agent/memory/*.md.
|
|
7208
|
+
- Use /project/PROJECT.md for the current project's operating context, constraints, and stable reference material.
|
|
7209
|
+
- Prefer writing to /project/raw/YYYY-MM-DD.md or /project/notes/wip.md before promoting anything into durable notes or agent memory.
|
|
7158
7210
|
- Not every session needs a write.
|
|
7159
7211
|
- Write only when the session produced something worth preserving for future work.
|
|
7160
7212
|
|
|
@@ -7169,15 +7221,15 @@ Pure one-off questions with no follow-up value usually need no memory update.
|
|
|
7169
7221
|
|
|
7170
7222
|
Promote information upward based on value:
|
|
7171
7223
|
|
|
7172
|
-
- Put immediate observations, action logs, and rough capture in
|
|
7173
|
-
- Put working understanding, partial conclusions, and candidate reminders in
|
|
7224
|
+
- Put immediate observations, action logs, and rough capture in /project/raw/YYYY-MM-DD.md.
|
|
7225
|
+
- Put working understanding, partial conclusions, and candidate reminders in /project/notes/wip.md.
|
|
7174
7226
|
- Put durable project knowledge in project notes once it becomes worth remembering.
|
|
7175
|
-
- Put durable private lessons, preferences, reminders, and long-term context in
|
|
7227
|
+
- Put durable private lessons, preferences, reminders, and long-term context in /agent/MEMORY.md and /agent/memory/*.md.
|
|
7176
7228
|
|
|
7177
7229
|
## Safety
|
|
7178
7230
|
|
|
7179
7231
|
- Don't exfiltrate private data. Ever.
|
|
7180
|
-
- Don't run destructive commands without asking, except deleting
|
|
7232
|
+
- Don't run destructive commands without asking, except deleting /agent/BOOTSTRAP.md after first-run setup is complete.
|
|
7181
7233
|
- When in doubt, ask.
|
|
7182
7234
|
|
|
7183
7235
|
## External vs Internal
|
|
@@ -7209,12 +7261,12 @@ There is no durable memory yet. This is a fresh workspace, so your first job is
|
|
|
7209
7261
|
|
|
7210
7262
|
Before you start shaping identity or style, inspect the memory structure you will use.
|
|
7211
7263
|
|
|
7212
|
-
-
|
|
7213
|
-
-
|
|
7214
|
-
-
|
|
7215
|
-
-
|
|
7216
|
-
-
|
|
7217
|
-
-
|
|
7264
|
+
- /agent/MEMORY.md
|
|
7265
|
+
- /agent/memory/*.md
|
|
7266
|
+
- /project/PROJECT.md
|
|
7267
|
+
- /project/raw/
|
|
7268
|
+
- /project/notes/
|
|
7269
|
+
- /project/artifacts/
|
|
7218
7270
|
|
|
7219
7271
|
You need to understand this structure first, because this is how you will preserve continuity in future work.
|
|
7220
7272
|
|
|
@@ -7237,37 +7289,37 @@ Offer suggestions if they're stuck. Keep it human.
|
|
|
7237
7289
|
|
|
7238
7290
|
Set up and understand this memory structure. This is the memory structure you should use in future work.
|
|
7239
7291
|
|
|
7240
|
-
-
|
|
7241
|
-
-
|
|
7242
|
-
-
|
|
7243
|
-
-
|
|
7244
|
-
-
|
|
7245
|
-
-
|
|
7292
|
+
- /agent/MEMORY.md
|
|
7293
|
+
- /agent/memory/*.md
|
|
7294
|
+
- /project/PROJECT.md
|
|
7295
|
+
- /project/raw/
|
|
7296
|
+
- /project/notes/
|
|
7297
|
+
- /project/artifacts/
|
|
7246
7298
|
|
|
7247
7299
|
Use it like this:
|
|
7248
7300
|
|
|
7249
|
-
-
|
|
7250
|
-
-
|
|
7251
|
-
-
|
|
7252
|
-
-
|
|
7253
|
-
-
|
|
7254
|
-
-
|
|
7301
|
+
- /agent/MEMORY.md is your private memory index.
|
|
7302
|
+
- /agent/memory/*.md holds categorized private memory.
|
|
7303
|
+
- /project/PROJECT.md holds stable project-level context.
|
|
7304
|
+
- /project/raw/ captures what happened.
|
|
7305
|
+
- /project/notes/ captures what is worth remembering.
|
|
7306
|
+
- /project/artifacts/ stores what was produced.
|
|
7255
7307
|
|
|
7256
7308
|
## After You Know Who You Are
|
|
7257
7309
|
|
|
7258
7310
|
Update these files with what you learned:
|
|
7259
7311
|
|
|
7260
|
-
-
|
|
7261
|
-
-
|
|
7262
|
-
-
|
|
7263
|
-
-
|
|
7312
|
+
- /agent/IDENTITY.md for your name, nature, and vibe.
|
|
7313
|
+
- /agent/USER.md for who you're helping and how to work well with them.
|
|
7314
|
+
- /agent/SOUL.md for values, behavior, and boundaries.
|
|
7315
|
+
- /agent/MEMORY.md and /agent/memory/*.md only for durable private memory worth keeping.
|
|
7264
7316
|
|
|
7265
7317
|
Do not keep rewriting these foundational files during ordinary project work.
|
|
7266
7318
|
Update them only when you learn something stable enough to change your long-term identity, user model, or private memory structure.
|
|
7267
7319
|
|
|
7268
7320
|
Prefer rough capture in project memory before creating durable notes:
|
|
7269
7321
|
|
|
7270
|
-
- Start with
|
|
7322
|
+
- Start with /project/raw/YYYY-MM-DD.md or /project/notes/wip.md.
|
|
7271
7323
|
- Promote only the information that should survive into project notes or private agent memory.
|
|
7272
7324
|
|
|
7273
7325
|
## When You're Done
|
|
@@ -12411,8 +12463,52 @@ var SandboxFilesystem = class {
|
|
|
12411
12463
|
}
|
|
12412
12464
|
}
|
|
12413
12465
|
async read(filePath, offset = 0, limit = 1e4) {
|
|
12466
|
+
const ext = filePath.split(".").pop()?.toLowerCase();
|
|
12467
|
+
const binaryExts = /* @__PURE__ */ new Set([
|
|
12468
|
+
"pdf",
|
|
12469
|
+
"png",
|
|
12470
|
+
"jpg",
|
|
12471
|
+
"jpeg",
|
|
12472
|
+
"gif",
|
|
12473
|
+
"svg",
|
|
12474
|
+
"webp",
|
|
12475
|
+
"ico",
|
|
12476
|
+
"bmp",
|
|
12477
|
+
"zip",
|
|
12478
|
+
"gz",
|
|
12479
|
+
"tar",
|
|
12480
|
+
"rar",
|
|
12481
|
+
"7z",
|
|
12482
|
+
"mp3",
|
|
12483
|
+
"mp4",
|
|
12484
|
+
"avi",
|
|
12485
|
+
"mov",
|
|
12486
|
+
"wav",
|
|
12487
|
+
"flac",
|
|
12488
|
+
"exe",
|
|
12489
|
+
"dll",
|
|
12490
|
+
"so",
|
|
12491
|
+
"dylib",
|
|
12492
|
+
"wasm",
|
|
12493
|
+
"ttf",
|
|
12494
|
+
"otf",
|
|
12495
|
+
"woff",
|
|
12496
|
+
"woff2",
|
|
12497
|
+
"doc",
|
|
12498
|
+
"docx",
|
|
12499
|
+
"ppt",
|
|
12500
|
+
"pptx",
|
|
12501
|
+
"xls",
|
|
12502
|
+
"xlsx"
|
|
12503
|
+
]);
|
|
12504
|
+
if (ext && binaryExts.has(ext)) {
|
|
12505
|
+
return `Error: Cannot read binary file '${filePath}': files with .${ext} extension are not supported for text reading. Use shell tools (e.g., 'file' command) to inspect, or download the file directly.`;
|
|
12506
|
+
}
|
|
12414
12507
|
try {
|
|
12415
12508
|
const result = await this.sandbox.file.readFile(filePath);
|
|
12509
|
+
if (result.content.includes("\0")) {
|
|
12510
|
+
return `Error: Cannot read binary file '${filePath}': file contains binary data. Use shell tools to inspect or download the file directly.`;
|
|
12511
|
+
}
|
|
12416
12512
|
return result.content;
|
|
12417
12513
|
} catch (e) {
|
|
12418
12514
|
return `Error: File '${filePath}' not found`;
|
|
@@ -12464,9 +12560,9 @@ var SandboxFilesystem = class {
|
|
|
12464
12560
|
throw new Error(`Error editing file '${filePath}': ${e.message}`);
|
|
12465
12561
|
}
|
|
12466
12562
|
}
|
|
12467
|
-
async grepRaw(pattern, searchPath = "
|
|
12563
|
+
async grepRaw(pattern, searchPath = "/", glob = null) {
|
|
12468
12564
|
try {
|
|
12469
|
-
const result = await this.sandbox.file.findFiles(searchPath || "
|
|
12565
|
+
const result = await this.sandbox.file.findFiles(searchPath || "/", glob || "**/*");
|
|
12470
12566
|
const filePaths = result.files;
|
|
12471
12567
|
const matches = [];
|
|
12472
12568
|
for (const absolutePath of filePaths) {
|
|
@@ -12486,7 +12582,7 @@ var SandboxFilesystem = class {
|
|
|
12486
12582
|
return `Error: ${e.message}`;
|
|
12487
12583
|
}
|
|
12488
12584
|
}
|
|
12489
|
-
async globInfo(pattern, searchPath = "
|
|
12585
|
+
async globInfo(pattern, searchPath = "/") {
|
|
12490
12586
|
const result = await this.sandbox.file.findFiles(searchPath, pattern || "**/*");
|
|
12491
12587
|
return result.files.map((filePath) => ({
|
|
12492
12588
|
path: filePath,
|
|
@@ -13231,13 +13327,13 @@ var StoreBackend = class {
|
|
|
13231
13327
|
* @returns List of FileInfo objects for files and directories directly in the directory.
|
|
13232
13328
|
* Directories have a trailing / in their path and is_dir=true.
|
|
13233
13329
|
*/
|
|
13234
|
-
async lsInfo(
|
|
13330
|
+
async lsInfo(path3) {
|
|
13235
13331
|
const store = this.getStore();
|
|
13236
13332
|
const namespace = this.getNamespace();
|
|
13237
13333
|
const items = await this.searchStorePaginated(store, namespace);
|
|
13238
13334
|
const infos = [];
|
|
13239
13335
|
const subdirs = /* @__PURE__ */ new Set();
|
|
13240
|
-
const normalizedPath =
|
|
13336
|
+
const normalizedPath = path3.endsWith("/") ? path3 : path3 + "/";
|
|
13241
13337
|
for (const item of items) {
|
|
13242
13338
|
const itemKey = String(item.key);
|
|
13243
13339
|
if (!itemKey.startsWith(normalizedPath)) {
|
|
@@ -13355,7 +13451,7 @@ var StoreBackend = class {
|
|
|
13355
13451
|
/**
|
|
13356
13452
|
* Structured search results or error string for invalid input.
|
|
13357
13453
|
*/
|
|
13358
|
-
async grepRaw(pattern,
|
|
13454
|
+
async grepRaw(pattern, path3 = "/", glob = null) {
|
|
13359
13455
|
const store = this.getStore();
|
|
13360
13456
|
const namespace = this.getNamespace();
|
|
13361
13457
|
const items = await this.searchStorePaginated(store, namespace);
|
|
@@ -13367,12 +13463,12 @@ var StoreBackend = class {
|
|
|
13367
13463
|
continue;
|
|
13368
13464
|
}
|
|
13369
13465
|
}
|
|
13370
|
-
return grepMatchesFromFiles(files, pattern,
|
|
13466
|
+
return grepMatchesFromFiles(files, pattern, path3, glob);
|
|
13371
13467
|
}
|
|
13372
13468
|
/**
|
|
13373
13469
|
* Structured glob matching returning FileInfo objects.
|
|
13374
13470
|
*/
|
|
13375
|
-
async globInfo(pattern,
|
|
13471
|
+
async globInfo(pattern, path3 = "/") {
|
|
13376
13472
|
const store = this.getStore();
|
|
13377
13473
|
const namespace = this.getNamespace();
|
|
13378
13474
|
const items = await this.searchStorePaginated(store, namespace);
|
|
@@ -13384,7 +13480,7 @@ var StoreBackend = class {
|
|
|
13384
13480
|
continue;
|
|
13385
13481
|
}
|
|
13386
13482
|
}
|
|
13387
|
-
const result = globSearchFiles(files, pattern,
|
|
13483
|
+
const result = globSearchFiles(files, pattern, path3);
|
|
13388
13484
|
if (result === "No files found") {
|
|
13389
13485
|
return [];
|
|
13390
13486
|
}
|
|
@@ -13433,7 +13529,12 @@ var FilesystemBackend = class {
|
|
|
13433
13529
|
*/
|
|
13434
13530
|
resolvePath(key) {
|
|
13435
13531
|
if (this.virtualMode) {
|
|
13436
|
-
|
|
13532
|
+
let normalizedKey = key;
|
|
13533
|
+
if (normalizedKey === "~" || normalizedKey === "~/") {
|
|
13534
|
+
normalizedKey = "/";
|
|
13535
|
+
} else if (normalizedKey.startsWith("~/")) {
|
|
13536
|
+
normalizedKey = `/${normalizedKey.slice(2)}`;
|
|
13537
|
+
}
|
|
13437
13538
|
const vpath = normalizedKey.startsWith("/") ? normalizedKey : "/" + normalizedKey;
|
|
13438
13539
|
if (vpath.includes("..") || vpath.includes("~")) {
|
|
13439
13540
|
throw new Error("Path traversal not allowed");
|
|
@@ -13445,10 +13546,14 @@ var FilesystemBackend = class {
|
|
|
13445
13546
|
}
|
|
13446
13547
|
return full;
|
|
13447
13548
|
}
|
|
13448
|
-
|
|
13449
|
-
|
|
13549
|
+
let target = key;
|
|
13550
|
+
if (target.startsWith("~/")) {
|
|
13551
|
+
target = `/${target.slice(2)}`;
|
|
13552
|
+
}
|
|
13553
|
+
if (path2.isAbsolute(target)) {
|
|
13554
|
+
return target;
|
|
13450
13555
|
}
|
|
13451
|
-
return path2.resolve(this.cwd,
|
|
13556
|
+
return path2.resolve(this.cwd, target);
|
|
13452
13557
|
}
|
|
13453
13558
|
/**
|
|
13454
13559
|
* List files and directories in the specified directory (non-recursive).
|
|
@@ -13960,10 +14065,10 @@ var CompositeBackend = class {
|
|
|
13960
14065
|
* @returns List of FileInfo objects with route prefixes added, for files and directories
|
|
13961
14066
|
* directly in the directory. Directories have a trailing / in their path and is_dir=true.
|
|
13962
14067
|
*/
|
|
13963
|
-
async lsInfo(
|
|
14068
|
+
async lsInfo(path3) {
|
|
13964
14069
|
for (const [routePrefix, backend] of this.sortedRoutes) {
|
|
13965
|
-
if (
|
|
13966
|
-
const suffix =
|
|
14070
|
+
if (path3.startsWith(routePrefix.replace(/\/$/, ""))) {
|
|
14071
|
+
const suffix = path3.substring(routePrefix.length);
|
|
13967
14072
|
const searchPath = suffix ? "/" + suffix : "/";
|
|
13968
14073
|
const infos = await backend.lsInfo(searchPath);
|
|
13969
14074
|
const prefixed = [];
|
|
@@ -13976,9 +14081,9 @@ var CompositeBackend = class {
|
|
|
13976
14081
|
return prefixed;
|
|
13977
14082
|
}
|
|
13978
14083
|
}
|
|
13979
|
-
if (
|
|
14084
|
+
if (path3 === "/") {
|
|
13980
14085
|
const results = [];
|
|
13981
|
-
const defaultInfos = await this.default.lsInfo(
|
|
14086
|
+
const defaultInfos = await this.default.lsInfo(path3);
|
|
13982
14087
|
results.push(...defaultInfos);
|
|
13983
14088
|
for (const [routePrefix] of this.sortedRoutes) {
|
|
13984
14089
|
results.push({
|
|
@@ -13991,7 +14096,7 @@ var CompositeBackend = class {
|
|
|
13991
14096
|
results.sort((a, b) => a.path.localeCompare(b.path));
|
|
13992
14097
|
return results;
|
|
13993
14098
|
}
|
|
13994
|
-
return await this.default.lsInfo(
|
|
14099
|
+
return await this.default.lsInfo(path3);
|
|
13995
14100
|
}
|
|
13996
14101
|
/**
|
|
13997
14102
|
* Read file content, routing to appropriate backend.
|
|
@@ -14018,10 +14123,10 @@ var CompositeBackend = class {
|
|
|
14018
14123
|
/**
|
|
14019
14124
|
* Structured search results or error string for invalid input.
|
|
14020
14125
|
*/
|
|
14021
|
-
async grepRaw(pattern,
|
|
14126
|
+
async grepRaw(pattern, path3 = "/", glob = null) {
|
|
14022
14127
|
for (const [routePrefix, backend] of this.sortedRoutes) {
|
|
14023
|
-
if (
|
|
14024
|
-
const searchPath =
|
|
14128
|
+
if (path3.startsWith(routePrefix.replace(/\/$/, ""))) {
|
|
14129
|
+
const searchPath = path3.substring(routePrefix.length - 1);
|
|
14025
14130
|
const raw = await backend.grepRaw(pattern, searchPath || "/", glob);
|
|
14026
14131
|
if (typeof raw === "string") {
|
|
14027
14132
|
return raw;
|
|
@@ -14033,7 +14138,7 @@ var CompositeBackend = class {
|
|
|
14033
14138
|
}
|
|
14034
14139
|
}
|
|
14035
14140
|
const allMatches = [];
|
|
14036
|
-
const rawDefault = await this.default.grepRaw(pattern,
|
|
14141
|
+
const rawDefault = await this.default.grepRaw(pattern, path3, glob);
|
|
14037
14142
|
if (typeof rawDefault === "string") {
|
|
14038
14143
|
return rawDefault;
|
|
14039
14144
|
}
|
|
@@ -14055,11 +14160,11 @@ var CompositeBackend = class {
|
|
|
14055
14160
|
/**
|
|
14056
14161
|
* Structured glob matching returning FileInfo objects.
|
|
14057
14162
|
*/
|
|
14058
|
-
async globInfo(pattern,
|
|
14163
|
+
async globInfo(pattern, path3 = "/") {
|
|
14059
14164
|
const results = [];
|
|
14060
14165
|
for (const [routePrefix, backend] of this.sortedRoutes) {
|
|
14061
|
-
if (
|
|
14062
|
-
const searchPath =
|
|
14166
|
+
if (path3.startsWith(routePrefix.replace(/\/$/, ""))) {
|
|
14167
|
+
const searchPath = path3.substring(routePrefix.length - 1);
|
|
14063
14168
|
const infos = await backend.globInfo(pattern, searchPath || "/");
|
|
14064
14169
|
return infos.map((fi) => ({
|
|
14065
14170
|
...fi,
|
|
@@ -14067,7 +14172,7 @@ var CompositeBackend = class {
|
|
|
14067
14172
|
}));
|
|
14068
14173
|
}
|
|
14069
14174
|
}
|
|
14070
|
-
const defaultInfos = await this.default.globInfo(pattern,
|
|
14175
|
+
const defaultInfos = await this.default.globInfo(pattern, path3);
|
|
14071
14176
|
results.push(...defaultInfos);
|
|
14072
14177
|
for (const [routePrefix, backend] of Object.entries(this.routes)) {
|
|
14073
14178
|
const infos = await backend.globInfo(pattern, "/");
|
|
@@ -14115,11 +14220,11 @@ var MemoryBackend = class {
|
|
|
14115
14220
|
getFiles() {
|
|
14116
14221
|
return Object.fromEntries(this.files);
|
|
14117
14222
|
}
|
|
14118
|
-
lsInfo(
|
|
14223
|
+
lsInfo(path3) {
|
|
14119
14224
|
const files = this.getFiles();
|
|
14120
14225
|
const infos = [];
|
|
14121
14226
|
const subdirs = /* @__PURE__ */ new Set();
|
|
14122
|
-
const normalizedPath =
|
|
14227
|
+
const normalizedPath = path3.endsWith("/") ? path3 : path3 + "/";
|
|
14123
14228
|
for (const [k, fd] of Object.entries(files)) {
|
|
14124
14229
|
if (!k.startsWith(normalizedPath)) {
|
|
14125
14230
|
continue;
|
|
@@ -14194,13 +14299,13 @@ var MemoryBackend = class {
|
|
|
14194
14299
|
this.files.set(filePath, newFileData);
|
|
14195
14300
|
return { path: filePath, filesUpdate: null, occurrences };
|
|
14196
14301
|
}
|
|
14197
|
-
grepRaw(pattern,
|
|
14302
|
+
grepRaw(pattern, path3 = "/", glob = null) {
|
|
14198
14303
|
const files = this.getFiles();
|
|
14199
|
-
return grepMatchesFromFiles(files, pattern,
|
|
14304
|
+
return grepMatchesFromFiles(files, pattern, path3, glob);
|
|
14200
14305
|
}
|
|
14201
|
-
globInfo(pattern,
|
|
14306
|
+
globInfo(pattern, path3 = "/") {
|
|
14202
14307
|
const files = this.getFiles();
|
|
14203
|
-
const result = globSearchFiles(files, pattern,
|
|
14308
|
+
const result = globSearchFiles(files, pattern, path3);
|
|
14204
14309
|
if (result === "No files found") {
|
|
14205
14310
|
return [];
|
|
14206
14311
|
}
|
|
@@ -16571,7 +16676,7 @@ var SandboxSkillStore = class {
|
|
|
16571
16676
|
if (name.includes("..") || name.includes("/") || name.includes("\\")) {
|
|
16572
16677
|
throw new Error(`Invalid skill name: ${name} (contains invalid characters)`);
|
|
16573
16678
|
}
|
|
16574
|
-
return
|
|
16679
|
+
return `/.agent/skills/${name}`;
|
|
16575
16680
|
}
|
|
16576
16681
|
/**
|
|
16577
16682
|
* Get skill file path in sandbox (absolute path with ~/ prefix)
|
|
@@ -16638,14 +16743,14 @@ ${body}` : `${frontmatter}
|
|
|
16638
16743
|
async getAllSkills(tenantId, context) {
|
|
16639
16744
|
try {
|
|
16640
16745
|
const sandbox = await this.getSandbox(tenantId, context);
|
|
16641
|
-
const skillsDir = "
|
|
16746
|
+
const skillsDir = "/.agent/skills";
|
|
16642
16747
|
try {
|
|
16643
16748
|
await sandbox.file.listPath(skillsDir, { recursive: false });
|
|
16644
16749
|
} catch (listError) {
|
|
16645
16750
|
console.log(`[SandboxSkillStore] Skills directory not found, creating: ${skillsDir}`);
|
|
16646
16751
|
try {
|
|
16647
16752
|
await sandbox.shell.execCommand({
|
|
16648
|
-
command: `mkdir -p
|
|
16753
|
+
command: `mkdir -p /.agent/skills`
|
|
16649
16754
|
});
|
|
16650
16755
|
} catch (mkdirError) {
|
|
16651
16756
|
console.error(`[SandboxSkillStore] Failed to create skills directory: ${mkdirError.message}`);
|
|
@@ -18258,9 +18363,9 @@ var MicrosandboxInstance = class {
|
|
|
18258
18363
|
const fs3 = this.native.fs();
|
|
18259
18364
|
await fs3.write(file, Buffer.from(content));
|
|
18260
18365
|
},
|
|
18261
|
-
listPath: async (
|
|
18366
|
+
listPath: async (path3, options) => {
|
|
18262
18367
|
const fs3 = this.native.fs();
|
|
18263
|
-
const entries = await fs3.list(
|
|
18368
|
+
const entries = await fs3.list(path3);
|
|
18264
18369
|
const files = (entries || []).map((e) => ({
|
|
18265
18370
|
path: e.path,
|
|
18266
18371
|
is_dir: e.kind === "directory",
|
|
@@ -18269,9 +18374,9 @@ var MicrosandboxInstance = class {
|
|
|
18269
18374
|
}));
|
|
18270
18375
|
return { files };
|
|
18271
18376
|
},
|
|
18272
|
-
findFiles: async (
|
|
18377
|
+
findFiles: async (path3, glob) => {
|
|
18273
18378
|
const output = await exec(this.native, "sh", {
|
|
18274
|
-
args: ["-c", `find "${
|
|
18379
|
+
args: ["-c", `find "${path3}" -name "${glob}" -type f`]
|
|
18275
18380
|
});
|
|
18276
18381
|
const lines = output.stdout().split("\n").filter(Boolean);
|
|
18277
18382
|
return { files: lines };
|
|
@@ -18294,13 +18399,13 @@ var MicrosandboxInstance = class {
|
|
|
18294
18399
|
return { matches, line_numbers };
|
|
18295
18400
|
},
|
|
18296
18401
|
strReplaceEditor: async (params) => {
|
|
18297
|
-
const { path:
|
|
18402
|
+
const { path: path3, old_str, new_str, replace_mode } = params;
|
|
18298
18403
|
const delim = "#";
|
|
18299
18404
|
const escapedOld = old_str.replace(new RegExp(`[\\\\${delim}]`, "g"), "\\$&").replace(/\n/g, "\\n");
|
|
18300
18405
|
const escapedNew = new_str.replace(new RegExp(`[\\\\${delim}]`, "g"), "\\$&").replace(/\n/g, "\\n");
|
|
18301
18406
|
const flag = replace_mode === "ALL" ? "g" : "";
|
|
18302
18407
|
await exec(this.native, "sh", {
|
|
18303
|
-
args: ["-c", `sed -i 's${delim}${escapedOld}${delim}${escapedNew}${delim}${flag}' "${
|
|
18408
|
+
args: ["-c", `sed -i 's${delim}${escapedOld}${delim}${escapedNew}${delim}${flag}' "${path3}"`]
|
|
18304
18409
|
});
|
|
18305
18410
|
},
|
|
18306
18411
|
uploadFile: async (params) => {
|
|
@@ -18392,16 +18497,34 @@ var MicrosandboxProvider = class {
|
|
|
18392
18497
|
native = void 0;
|
|
18393
18498
|
}
|
|
18394
18499
|
if (!native) {
|
|
18395
|
-
|
|
18396
|
-
|
|
18397
|
-
|
|
18398
|
-
|
|
18399
|
-
|
|
18400
|
-
|
|
18401
|
-
|
|
18402
|
-
|
|
18500
|
+
try {
|
|
18501
|
+
native = await import_microsandbox.Sandbox.createDetached({
|
|
18502
|
+
name,
|
|
18503
|
+
image: this.config.image ?? "python:3.11-slim",
|
|
18504
|
+
cpus: this.config.cpus ?? 1,
|
|
18505
|
+
memoryMib: this.config.memoryMib ?? 512,
|
|
18506
|
+
env: {
|
|
18507
|
+
...this.config.env,
|
|
18508
|
+
...buildSandboxMetadataEnv(config)
|
|
18509
|
+
}
|
|
18510
|
+
});
|
|
18511
|
+
} catch (err) {
|
|
18512
|
+
if (err instanceof Error && err.message.includes("already exists")) {
|
|
18513
|
+
await import_microsandbox.Sandbox.remove(name);
|
|
18514
|
+
native = await import_microsandbox.Sandbox.createDetached({
|
|
18515
|
+
name,
|
|
18516
|
+
image: this.config.image ?? "python:3.11-slim",
|
|
18517
|
+
cpus: this.config.cpus ?? 1,
|
|
18518
|
+
memoryMib: this.config.memoryMib ?? 512,
|
|
18519
|
+
env: {
|
|
18520
|
+
...this.config.env,
|
|
18521
|
+
...buildSandboxMetadataEnv(config)
|
|
18522
|
+
}
|
|
18523
|
+
});
|
|
18524
|
+
} else {
|
|
18525
|
+
throw err;
|
|
18403
18526
|
}
|
|
18404
|
-
}
|
|
18527
|
+
}
|
|
18405
18528
|
}
|
|
18406
18529
|
const instance = new MicrosandboxInstance(name, native);
|
|
18407
18530
|
this.instances.set(name, instance);
|
|
@@ -18441,45 +18564,6 @@ var MicrosandboxProvider = class {
|
|
|
18441
18564
|
}
|
|
18442
18565
|
};
|
|
18443
18566
|
|
|
18444
|
-
// src/sandbox_lattice/pathUtils.ts
|
|
18445
|
-
var import_path2 = __toESM(require("path"));
|
|
18446
|
-
var SANDBOX_HOME_DIR = "/home/daytona";
|
|
18447
|
-
function normalizeExternalSandboxPath(inputPath) {
|
|
18448
|
-
if (inputPath === "~") {
|
|
18449
|
-
return "~/";
|
|
18450
|
-
}
|
|
18451
|
-
if (inputPath === SANDBOX_HOME_DIR) {
|
|
18452
|
-
return "~/";
|
|
18453
|
-
}
|
|
18454
|
-
if (inputPath.startsWith(`${SANDBOX_HOME_DIR}/`)) {
|
|
18455
|
-
return `~/${inputPath.slice(SANDBOX_HOME_DIR.length + 1)}`;
|
|
18456
|
-
}
|
|
18457
|
-
if (inputPath.startsWith("~/")) {
|
|
18458
|
-
return inputPath;
|
|
18459
|
-
}
|
|
18460
|
-
if (inputPath.startsWith("/")) {
|
|
18461
|
-
return `~${inputPath}`;
|
|
18462
|
-
}
|
|
18463
|
-
return inputPath;
|
|
18464
|
-
}
|
|
18465
|
-
function toSandboxRelativePath(inputPath) {
|
|
18466
|
-
const canonicalPath = normalizeExternalSandboxPath(inputPath);
|
|
18467
|
-
return canonicalPath === "~/" ? "" : canonicalPath.slice(2);
|
|
18468
|
-
}
|
|
18469
|
-
function toSandboxAbsolutePath(inputPath, homeDir = SANDBOX_HOME_DIR) {
|
|
18470
|
-
const relativePath = toSandboxRelativePath(inputPath);
|
|
18471
|
-
return relativePath ? import_path2.default.posix.join(homeDir, relativePath) : homeDir;
|
|
18472
|
-
}
|
|
18473
|
-
function fromSandboxExecutionPath(inputPath, homeDir = SANDBOX_HOME_DIR) {
|
|
18474
|
-
if (inputPath === homeDir) {
|
|
18475
|
-
return "~/";
|
|
18476
|
-
}
|
|
18477
|
-
if (inputPath.startsWith(`${homeDir}/`)) {
|
|
18478
|
-
return `~/${inputPath.slice(homeDir.length + 1)}`;
|
|
18479
|
-
}
|
|
18480
|
-
return normalizeExternalSandboxPath(inputPath);
|
|
18481
|
-
}
|
|
18482
|
-
|
|
18483
18567
|
// src/sandbox_lattice/MicrosandboxRemoteInstance.ts
|
|
18484
18568
|
var MicrosandboxRemoteInstance = class {
|
|
18485
18569
|
constructor(name, client) {
|
|
@@ -18488,43 +18572,43 @@ var MicrosandboxRemoteInstance = class {
|
|
|
18488
18572
|
readFile: async (file) => {
|
|
18489
18573
|
const result = await this.client.readFile(
|
|
18490
18574
|
this.name,
|
|
18491
|
-
|
|
18575
|
+
normalizeExternalSandboxPath(file)
|
|
18492
18576
|
);
|
|
18493
18577
|
return { content: result.content };
|
|
18494
18578
|
},
|
|
18495
18579
|
writeFile: async (file, content) => {
|
|
18496
18580
|
await this.client.writeFile(
|
|
18497
18581
|
this.name,
|
|
18498
|
-
|
|
18582
|
+
normalizeExternalSandboxPath(file),
|
|
18499
18583
|
content
|
|
18500
18584
|
);
|
|
18501
18585
|
},
|
|
18502
|
-
listPath: async (
|
|
18586
|
+
listPath: async (path3, options) => {
|
|
18503
18587
|
const result = await this.client.listPath(
|
|
18504
18588
|
this.name,
|
|
18505
|
-
|
|
18589
|
+
normalizeExternalSandboxPath(path3),
|
|
18506
18590
|
options?.recursive
|
|
18507
18591
|
);
|
|
18508
18592
|
const files = result.entries.map((entry) => ({
|
|
18509
|
-
path:
|
|
18593
|
+
path: normalizeExternalSandboxPath(entry.path),
|
|
18510
18594
|
is_dir: entry.type === "directory"
|
|
18511
18595
|
}));
|
|
18512
18596
|
return { files };
|
|
18513
18597
|
},
|
|
18514
|
-
findFiles: async (
|
|
18598
|
+
findFiles: async (path3, glob) => {
|
|
18515
18599
|
const result = await this.client.findFiles(
|
|
18516
18600
|
this.name,
|
|
18517
|
-
|
|
18601
|
+
normalizeExternalSandboxPath(path3),
|
|
18518
18602
|
glob
|
|
18519
18603
|
);
|
|
18520
18604
|
return {
|
|
18521
|
-
files: result.files.map((filePath) =>
|
|
18605
|
+
files: result.files.map((filePath) => normalizeExternalSandboxPath(filePath))
|
|
18522
18606
|
};
|
|
18523
18607
|
},
|
|
18524
18608
|
searchInFile: async (file, regex) => {
|
|
18525
18609
|
const result = await this.client.searchInFile(
|
|
18526
18610
|
this.name,
|
|
18527
|
-
|
|
18611
|
+
normalizeExternalSandboxPath(file),
|
|
18528
18612
|
regex
|
|
18529
18613
|
);
|
|
18530
18614
|
return {
|
|
@@ -18534,7 +18618,7 @@ var MicrosandboxRemoteInstance = class {
|
|
|
18534
18618
|
},
|
|
18535
18619
|
strReplaceEditor: async (params) => {
|
|
18536
18620
|
await this.client.replaceInFile(this.name, {
|
|
18537
|
-
path:
|
|
18621
|
+
path: normalizeExternalSandboxPath(params.path),
|
|
18538
18622
|
search: params.old_str,
|
|
18539
18623
|
replace: params.new_str
|
|
18540
18624
|
});
|
|
@@ -18542,14 +18626,14 @@ var MicrosandboxRemoteInstance = class {
|
|
|
18542
18626
|
uploadFile: async (params) => {
|
|
18543
18627
|
await this.client.uploadFile(
|
|
18544
18628
|
this.name,
|
|
18545
|
-
|
|
18629
|
+
normalizeExternalSandboxPath(params.file),
|
|
18546
18630
|
params.data
|
|
18547
18631
|
);
|
|
18548
18632
|
},
|
|
18549
18633
|
downloadFile: async (params) => {
|
|
18550
18634
|
const result = await this.client.downloadFile(
|
|
18551
18635
|
this.name,
|
|
18552
|
-
|
|
18636
|
+
normalizeExternalSandboxPath(params.file)
|
|
18553
18637
|
);
|
|
18554
18638
|
if (result.contentBase64) {
|
|
18555
18639
|
return Buffer.from(result.contentBase64, "base64");
|
|
@@ -18628,34 +18712,34 @@ var MicrosandboxServiceClient = class {
|
|
|
18628
18712
|
method: "GET"
|
|
18629
18713
|
});
|
|
18630
18714
|
}
|
|
18631
|
-
async readFile(sandboxName,
|
|
18715
|
+
async readFile(sandboxName, path3) {
|
|
18632
18716
|
return this.request("/api/files/read", {
|
|
18633
18717
|
method: "POST",
|
|
18634
|
-
body: { sandboxName, path:
|
|
18718
|
+
body: { sandboxName, path: path3 }
|
|
18635
18719
|
});
|
|
18636
18720
|
}
|
|
18637
|
-
async writeFile(sandboxName,
|
|
18721
|
+
async writeFile(sandboxName, path3, content) {
|
|
18638
18722
|
return this.request("/api/files/write", {
|
|
18639
18723
|
method: "POST",
|
|
18640
|
-
body: { sandboxName, path:
|
|
18724
|
+
body: { sandboxName, path: path3, content }
|
|
18641
18725
|
});
|
|
18642
18726
|
}
|
|
18643
|
-
async listPath(sandboxName,
|
|
18727
|
+
async listPath(sandboxName, path3, recursive) {
|
|
18644
18728
|
return this.request("/api/files/list", {
|
|
18645
18729
|
method: "POST",
|
|
18646
|
-
body: { sandboxName, path:
|
|
18730
|
+
body: { sandboxName, path: path3, recursive }
|
|
18647
18731
|
});
|
|
18648
18732
|
}
|
|
18649
|
-
async findFiles(sandboxName,
|
|
18733
|
+
async findFiles(sandboxName, path3, pattern) {
|
|
18650
18734
|
return this.request("/api/files/find", {
|
|
18651
18735
|
method: "POST",
|
|
18652
|
-
body: { sandboxName, path:
|
|
18736
|
+
body: { sandboxName, path: path3, pattern }
|
|
18653
18737
|
});
|
|
18654
18738
|
}
|
|
18655
|
-
async searchInFile(sandboxName,
|
|
18739
|
+
async searchInFile(sandboxName, path3, query) {
|
|
18656
18740
|
return this.request("/api/files/search", {
|
|
18657
18741
|
method: "POST",
|
|
18658
|
-
body: { sandboxName, path:
|
|
18742
|
+
body: { sandboxName, path: path3, query }
|
|
18659
18743
|
});
|
|
18660
18744
|
}
|
|
18661
18745
|
async replaceInFile(sandboxName, input) {
|
|
@@ -18664,14 +18748,14 @@ var MicrosandboxServiceClient = class {
|
|
|
18664
18748
|
body: { sandboxName, ...input }
|
|
18665
18749
|
});
|
|
18666
18750
|
}
|
|
18667
|
-
async uploadFile(sandboxName,
|
|
18751
|
+
async uploadFile(sandboxName, path3, content) {
|
|
18668
18752
|
return this.request("/api/files/upload", {
|
|
18669
18753
|
method: "POST",
|
|
18670
|
-
body: { sandboxName, path:
|
|
18754
|
+
body: { sandboxName, path: path3, contentBase64: content.toString("base64") }
|
|
18671
18755
|
});
|
|
18672
18756
|
}
|
|
18673
|
-
async downloadFile(sandboxName,
|
|
18674
|
-
const query = new URLSearchParams({ sandboxName, path:
|
|
18757
|
+
async downloadFile(sandboxName, path3) {
|
|
18758
|
+
const query = new URLSearchParams({ sandboxName, path: path3 });
|
|
18675
18759
|
return this.request(`/api/files/download?${query.toString()}`, {
|
|
18676
18760
|
method: "GET"
|
|
18677
18761
|
});
|
|
@@ -18682,54 +18766,54 @@ var MicrosandboxServiceClient = class {
|
|
|
18682
18766
|
body: input
|
|
18683
18767
|
});
|
|
18684
18768
|
}
|
|
18685
|
-
async volumeFsRead(volumeName,
|
|
18769
|
+
async volumeFsRead(volumeName, path3) {
|
|
18686
18770
|
const result = await this.request(
|
|
18687
18771
|
`/api/volumes/${encodeURIComponent(volumeName)}/fs/read`,
|
|
18688
18772
|
{
|
|
18689
18773
|
method: "POST",
|
|
18690
|
-
body: { path:
|
|
18774
|
+
body: { path: path3 }
|
|
18691
18775
|
}
|
|
18692
18776
|
);
|
|
18693
18777
|
return result.content;
|
|
18694
18778
|
}
|
|
18695
|
-
async volumeFsWrite(volumeName,
|
|
18779
|
+
async volumeFsWrite(volumeName, path3, content) {
|
|
18696
18780
|
await this.request(
|
|
18697
18781
|
`/api/volumes/${encodeURIComponent(volumeName)}/fs/write`,
|
|
18698
18782
|
{
|
|
18699
18783
|
method: "POST",
|
|
18700
|
-
body: { path:
|
|
18784
|
+
body: { path: path3, content }
|
|
18701
18785
|
}
|
|
18702
18786
|
);
|
|
18703
18787
|
}
|
|
18704
|
-
async volumeFsList(volumeName,
|
|
18788
|
+
async volumeFsList(volumeName, path3) {
|
|
18705
18789
|
const result = await this.request(
|
|
18706
18790
|
`/api/volumes/${encodeURIComponent(volumeName)}/fs/list`,
|
|
18707
18791
|
{
|
|
18708
18792
|
method: "POST",
|
|
18709
|
-
body: { path:
|
|
18793
|
+
body: { path: path3 }
|
|
18710
18794
|
}
|
|
18711
18795
|
);
|
|
18712
18796
|
return result.entries;
|
|
18713
18797
|
}
|
|
18714
|
-
async volumeFsDownload(volumeName,
|
|
18798
|
+
async volumeFsDownload(volumeName, path3) {
|
|
18715
18799
|
const result = await this.request(
|
|
18716
|
-
`/api/volumes/${encodeURIComponent(volumeName)}/fs/download?path=${encodeURIComponent(
|
|
18800
|
+
`/api/volumes/${encodeURIComponent(volumeName)}/fs/download?path=${encodeURIComponent(path3)}`,
|
|
18717
18801
|
{
|
|
18718
18802
|
method: "GET"
|
|
18719
18803
|
}
|
|
18720
18804
|
);
|
|
18721
18805
|
return Buffer.from(result.contentBase64, "base64");
|
|
18722
18806
|
}
|
|
18723
|
-
async volumeFsUpload(volumeName,
|
|
18807
|
+
async volumeFsUpload(volumeName, path3, data) {
|
|
18724
18808
|
await this.request(
|
|
18725
18809
|
`/api/volumes/${encodeURIComponent(volumeName)}/fs/upload`,
|
|
18726
18810
|
{
|
|
18727
18811
|
method: "POST",
|
|
18728
|
-
body: { path:
|
|
18812
|
+
body: { path: path3, contentBase64: data.toString("base64") }
|
|
18729
18813
|
}
|
|
18730
18814
|
);
|
|
18731
18815
|
}
|
|
18732
|
-
async request(
|
|
18816
|
+
async request(path3, init) {
|
|
18733
18817
|
const headers = {};
|
|
18734
18818
|
if (init.body) {
|
|
18735
18819
|
headers["content-type"] = "application/json";
|
|
@@ -18737,7 +18821,7 @@ var MicrosandboxServiceClient = class {
|
|
|
18737
18821
|
if (this.apiKey) {
|
|
18738
18822
|
headers.Authorization = `Bearer ${this.apiKey}`;
|
|
18739
18823
|
}
|
|
18740
|
-
const response = await fetch(`${this.baseURL}${
|
|
18824
|
+
const response = await fetch(`${this.baseURL}${path3}`, {
|
|
18741
18825
|
method: init.method,
|
|
18742
18826
|
headers: Object.keys(headers).length > 0 ? headers : void 0,
|
|
18743
18827
|
body: init.body ? JSON.stringify(init.body) : void 0
|
|
@@ -18770,7 +18854,7 @@ function parseOptionalNumberEnv(name, fallback) {
|
|
|
18770
18854
|
}
|
|
18771
18855
|
function getDefaultMicrosandboxRemoteConfig() {
|
|
18772
18856
|
return {
|
|
18773
|
-
image: process.env.MICROSANDBOX_IMAGE ?? "daytona-cn-shanghai.cr.volces.com/daytona/sandbox:0.0.
|
|
18857
|
+
image: process.env.MICROSANDBOX_IMAGE ?? "daytona-cn-shanghai.cr.volces.com/daytona/sandbox:0.0.4",
|
|
18774
18858
|
//"daytonaio/sandbox:0.6.0",
|
|
18775
18859
|
cpus: parseOptionalNumberEnv("MICROSANDBOX_CPUS", 1),
|
|
18776
18860
|
memoryMib: parseOptionalNumberEnv("MICROSANDBOX_MEMORY", 512),
|
|
@@ -18830,11 +18914,11 @@ var MicrosandboxRemoteProvider = class {
|
|
|
18830
18914
|
}
|
|
18831
18915
|
createVolumeFsClient(volumeName) {
|
|
18832
18916
|
return {
|
|
18833
|
-
read: (
|
|
18834
|
-
write: (
|
|
18835
|
-
list: (
|
|
18836
|
-
readRaw: (
|
|
18837
|
-
writeRaw: (
|
|
18917
|
+
read: (path3) => this.client.volumeFsRead(volumeName, path3),
|
|
18918
|
+
write: (path3, content) => this.client.volumeFsWrite(volumeName, path3, content),
|
|
18919
|
+
list: (path3) => this.client.volumeFsList(volumeName, path3),
|
|
18920
|
+
readRaw: (path3) => this.client.volumeFsDownload(volumeName, path3),
|
|
18921
|
+
writeRaw: (path3, data) => this.client.volumeFsUpload(volumeName, path3, data)
|
|
18838
18922
|
};
|
|
18839
18923
|
}
|
|
18840
18924
|
async listSandboxes() {
|
|
@@ -18856,19 +18940,19 @@ var MicrosandboxRemoteProvider = class {
|
|
|
18856
18940
|
buildDefaultVolumes(config) {
|
|
18857
18941
|
const tenantId = config?.tenantId ?? "default";
|
|
18858
18942
|
const volumes = {
|
|
18859
|
-
"
|
|
18943
|
+
"/.agent": {
|
|
18860
18944
|
type: "named",
|
|
18861
18945
|
name: buildNamedVolumeName("s", "skills", tenantId)
|
|
18862
18946
|
}
|
|
18863
18947
|
};
|
|
18864
18948
|
if (config?.assistant_id) {
|
|
18865
|
-
volumes["/
|
|
18949
|
+
volumes["/agent"] = {
|
|
18866
18950
|
type: "named",
|
|
18867
18951
|
name: buildNamedVolumeName("a", "agent", tenantId, config.assistant_id)
|
|
18868
18952
|
};
|
|
18869
18953
|
}
|
|
18870
18954
|
if (config?.projectId) {
|
|
18871
|
-
volumes["/
|
|
18955
|
+
volumes["/project"] = {
|
|
18872
18956
|
type: "named",
|
|
18873
18957
|
name: buildNamedVolumeName("p", "project", tenantId, config.workspaceId, config.projectId)
|
|
18874
18958
|
};
|
|
@@ -18898,9 +18982,9 @@ var RemoteSandboxInstance = class {
|
|
|
18898
18982
|
throw new Error(String(result.error));
|
|
18899
18983
|
}
|
|
18900
18984
|
},
|
|
18901
|
-
listPath: async (
|
|
18985
|
+
listPath: async (path3, options) => {
|
|
18902
18986
|
const result = await this.client.file.listPath({
|
|
18903
|
-
path:
|
|
18987
|
+
path: path3,
|
|
18904
18988
|
recursive: options?.recursive ?? false
|
|
18905
18989
|
});
|
|
18906
18990
|
if (!result.ok) {
|
|
@@ -18914,8 +18998,8 @@ var RemoteSandboxInstance = class {
|
|
|
18914
18998
|
}));
|
|
18915
18999
|
return { files };
|
|
18916
19000
|
},
|
|
18917
|
-
findFiles: async (
|
|
18918
|
-
const result = await this.client.file.findFiles({ path:
|
|
19001
|
+
findFiles: async (path3, glob) => {
|
|
19002
|
+
const result = await this.client.file.findFiles({ path: path3, glob });
|
|
18919
19003
|
if (!result.ok) {
|
|
18920
19004
|
throw new Error(String(result.error));
|
|
18921
19005
|
}
|
|
@@ -19052,8 +19136,8 @@ var E2BInstance = class {
|
|
|
19052
19136
|
writeFile: async (file, content) => {
|
|
19053
19137
|
await this.native.files.write(file, content);
|
|
19054
19138
|
},
|
|
19055
|
-
listPath: async (
|
|
19056
|
-
const entries = await this.native.files.list(
|
|
19139
|
+
listPath: async (path3, options) => {
|
|
19140
|
+
const entries = await this.native.files.list(path3);
|
|
19057
19141
|
const files = entries.map((e) => ({
|
|
19058
19142
|
path: e.path,
|
|
19059
19143
|
is_dir: e.type === "dir",
|
|
@@ -19062,9 +19146,9 @@ var E2BInstance = class {
|
|
|
19062
19146
|
}));
|
|
19063
19147
|
return { files };
|
|
19064
19148
|
},
|
|
19065
|
-
findFiles: async (
|
|
19149
|
+
findFiles: async (path3, glob) => {
|
|
19066
19150
|
const result = await this.native.commands.run(
|
|
19067
|
-
`find "${
|
|
19151
|
+
`find "${path3}" -name "${glob}" -type f`
|
|
19068
19152
|
);
|
|
19069
19153
|
const lines = result.stdout.split("\n").filter(Boolean);
|
|
19070
19154
|
return { files: lines };
|
|
@@ -19087,13 +19171,13 @@ var E2BInstance = class {
|
|
|
19087
19171
|
return { matches, line_numbers };
|
|
19088
19172
|
},
|
|
19089
19173
|
strReplaceEditor: async (params) => {
|
|
19090
|
-
const { path:
|
|
19174
|
+
const { path: path3, old_str, new_str, replace_mode } = params;
|
|
19091
19175
|
const delim = "#";
|
|
19092
19176
|
const escapedOld = old_str.replace(new RegExp(`[\\\\${delim}]`, "g"), "\\$&").replace(/\n/g, "\\n");
|
|
19093
19177
|
const escapedNew = new_str.replace(new RegExp(`[\\\\${delim}]`, "g"), "\\$&").replace(/\n/g, "\\n");
|
|
19094
19178
|
const flag = replace_mode === "ALL" ? "g" : "";
|
|
19095
19179
|
await this.native.commands.run(
|
|
19096
|
-
`sed -i 's${delim}${escapedOld}${delim}${escapedNew}${delim}${flag}' "${
|
|
19180
|
+
`sed -i 's${delim}${escapedOld}${delim}${escapedNew}${delim}${flag}' "${path3}"`
|
|
19097
19181
|
);
|
|
19098
19182
|
},
|
|
19099
19183
|
uploadFile: async (params) => {
|
|
@@ -19204,23 +19288,27 @@ var E2BProvider = class {
|
|
|
19204
19288
|
var import_sdk = require("@daytonaio/sdk");
|
|
19205
19289
|
|
|
19206
19290
|
// src/sandbox_lattice/DaytonaInstance.ts
|
|
19291
|
+
function toRelativePath(inputPath) {
|
|
19292
|
+
const normalized = normalizeExternalSandboxPath(inputPath);
|
|
19293
|
+
return normalized === "/" ? "" : normalized.slice(1);
|
|
19294
|
+
}
|
|
19207
19295
|
var DaytonaInstance = class {
|
|
19208
19296
|
constructor(name, native) {
|
|
19209
19297
|
this.native = native;
|
|
19210
19298
|
this.file = {
|
|
19211
19299
|
readFile: async (file) => {
|
|
19212
|
-
const buffer2 = await this.native.fs.downloadFile(
|
|
19300
|
+
const buffer2 = await this.native.fs.downloadFile(toRelativePath(file));
|
|
19213
19301
|
return { content: buffer2.toString("utf-8") };
|
|
19214
19302
|
},
|
|
19215
19303
|
writeFile: async (file, content) => {
|
|
19216
|
-
await this.native.fs.uploadFile(Buffer.from(content, "utf-8"),
|
|
19304
|
+
await this.native.fs.uploadFile(Buffer.from(content, "utf-8"), toRelativePath(file));
|
|
19217
19305
|
},
|
|
19218
|
-
listPath: async (
|
|
19219
|
-
const entries = await this.native.fs.listFiles(
|
|
19306
|
+
listPath: async (path3, options) => {
|
|
19307
|
+
const entries = await this.native.fs.listFiles(toRelativePath(path3));
|
|
19220
19308
|
const files = entries.map((e) => {
|
|
19221
19309
|
const rawPath = e.name || "";
|
|
19222
19310
|
return {
|
|
19223
|
-
path:
|
|
19311
|
+
path: normalizeExternalSandboxPath(rawPath),
|
|
19224
19312
|
is_dir: e.isDir ?? false,
|
|
19225
19313
|
size: e.size,
|
|
19226
19314
|
modified_at: e.modTime ? e.modTime : void 0
|
|
@@ -19228,12 +19316,12 @@ var DaytonaInstance = class {
|
|
|
19228
19316
|
});
|
|
19229
19317
|
return { files };
|
|
19230
19318
|
},
|
|
19231
|
-
findFiles: async (
|
|
19232
|
-
const result = await this.native.fs.searchFiles(
|
|
19233
|
-
return { files: (result.files || []).map((filePath) =>
|
|
19319
|
+
findFiles: async (path3, glob) => {
|
|
19320
|
+
const result = await this.native.fs.searchFiles(toRelativePath(path3), glob);
|
|
19321
|
+
return { files: (result.files || []).map((filePath) => normalizeExternalSandboxPath(filePath)) };
|
|
19234
19322
|
},
|
|
19235
19323
|
searchInFile: async (file, regex) => {
|
|
19236
|
-
const matches = await this.native.fs.findFiles(
|
|
19324
|
+
const matches = await this.native.fs.findFiles(toRelativePath(file), regex);
|
|
19237
19325
|
const line_numbers = [];
|
|
19238
19326
|
const matchTexts = [];
|
|
19239
19327
|
for (const match of matches) {
|
|
@@ -19243,8 +19331,8 @@ var DaytonaInstance = class {
|
|
|
19243
19331
|
return { matches: matchTexts, line_numbers };
|
|
19244
19332
|
},
|
|
19245
19333
|
strReplaceEditor: async (params) => {
|
|
19246
|
-
const { path:
|
|
19247
|
-
const relPath =
|
|
19334
|
+
const { path: path3, old_str, new_str, replace_mode } = params;
|
|
19335
|
+
const relPath = toRelativePath(path3);
|
|
19248
19336
|
if (replace_mode === "ALL") {
|
|
19249
19337
|
await this.native.fs.replaceInFiles([relPath], old_str, new_str);
|
|
19250
19338
|
} else {
|
|
@@ -19258,10 +19346,10 @@ var DaytonaInstance = class {
|
|
|
19258
19346
|
}
|
|
19259
19347
|
},
|
|
19260
19348
|
uploadFile: async (params) => {
|
|
19261
|
-
await this.native.fs.uploadFile(params.data,
|
|
19349
|
+
await this.native.fs.uploadFile(params.data, toRelativePath(params.file));
|
|
19262
19350
|
},
|
|
19263
19351
|
downloadFile: async (params) => {
|
|
19264
|
-
const buffer2 = await this.native.fs.downloadFile(
|
|
19352
|
+
const buffer2 = await this.native.fs.downloadFile(toRelativePath(params.file));
|
|
19265
19353
|
return Buffer.isBuffer(buffer2) ? buffer2 : Buffer.from(buffer2);
|
|
19266
19354
|
}
|
|
19267
19355
|
};
|
|
@@ -19377,9 +19465,14 @@ var DaytonaProvider = class {
|
|
|
19377
19465
|
if (volumes.length > 0) {
|
|
19378
19466
|
try {
|
|
19379
19467
|
for (const vol of volumes) {
|
|
19380
|
-
|
|
19381
|
-
|
|
19382
|
-
|
|
19468
|
+
try {
|
|
19469
|
+
await native.fs.listFiles(vol.mountPath);
|
|
19470
|
+
console.log(`[DaytonaProvider] Volume mount verified: ${vol.mountPath}`);
|
|
19471
|
+
} catch {
|
|
19472
|
+
const relPath = vol.mountPath.startsWith("/") ? vol.mountPath.slice(1) : vol.mountPath;
|
|
19473
|
+
await native.fs.listFiles(relPath);
|
|
19474
|
+
console.log(`[DaytonaProvider] Volume mount verified: /${relPath}`);
|
|
19475
|
+
}
|
|
19383
19476
|
}
|
|
19384
19477
|
} catch (verifyErr) {
|
|
19385
19478
|
console.warn(`[DaytonaProvider] Volume mount verification warning: ${verifyErr.message}`);
|
|
@@ -19397,9 +19490,9 @@ var DaytonaProvider = class {
|
|
|
19397
19490
|
/**
|
|
19398
19491
|
* Build volume mounts for a sandbox based on RunSandboxConfig.
|
|
19399
19492
|
* Mounts:
|
|
19400
|
-
*
|
|
19401
|
-
*
|
|
19402
|
-
*
|
|
19493
|
+
* /.agent → tenants/{tenantId}/skills
|
|
19494
|
+
* /agent → tenants/{tenantId}/agents/{assistantId}
|
|
19495
|
+
* /project → tenants/{tenantId}/projects/{projectId}
|
|
19403
19496
|
*/
|
|
19404
19497
|
async buildVolumeMounts(config) {
|
|
19405
19498
|
if (!config || !this.config.volumeName) {
|
|
@@ -19413,20 +19506,20 @@ var DaytonaProvider = class {
|
|
|
19413
19506
|
const mounts = [];
|
|
19414
19507
|
mounts.push({
|
|
19415
19508
|
volumeId: volume.id,
|
|
19416
|
-
mountPath: "
|
|
19509
|
+
mountPath: "/.agent",
|
|
19417
19510
|
subpath: `tenants/${tenantId}/skills`
|
|
19418
19511
|
});
|
|
19419
19512
|
if (config.assistant_id) {
|
|
19420
19513
|
mounts.push({
|
|
19421
19514
|
volumeId: volume.id,
|
|
19422
|
-
mountPath: "/
|
|
19515
|
+
mountPath: "/agent",
|
|
19423
19516
|
subpath: `tenants/${tenantId}/agents/${config.assistant_id}`
|
|
19424
19517
|
});
|
|
19425
19518
|
}
|
|
19426
19519
|
if (config.projectId) {
|
|
19427
19520
|
mounts.push({
|
|
19428
19521
|
volumeId: volume.id,
|
|
19429
|
-
mountPath: "/
|
|
19522
|
+
mountPath: "/project",
|
|
19430
19523
|
subpath: `tenants/${tenantId}/projects/${config.projectId}`
|
|
19431
19524
|
});
|
|
19432
19525
|
}
|