@letta-ai/letta-code 0.34.25 → 0.34.27
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/cursor-worker.js +168 -0
- package/dist/agent-presets.js +5 -68
- package/dist/agent-presets.js.map +2 -2
- package/dist/channels-slack.js +30 -24
- package/dist/channels-slack.js.map +3 -3
- package/dist/mcp-client.js +233 -75
- package/dist/mcp-client.js.map +9 -9
- package/dist/mcp-oauth.js +257 -89
- package/dist/mcp-oauth.js.map +12 -11
- package/dist/memory-confinement.js +109 -51
- package/dist/memory-confinement.js.map +9 -8
- package/dist/types/agent/mcp-originator-authority-file.d.ts +1 -0
- package/dist/types/agent/mcp-originator-authority-file.d.ts.map +1 -1
- package/dist/types/agent/memory-filesystem.d.ts +3 -3
- package/dist/types/agent/memory-filesystem.d.ts.map +1 -1
- package/dist/types/agent/memory-git.d.ts +2 -2
- package/dist/types/agent/memory-git.d.ts.map +1 -1
- package/dist/types/agent/skills.d.ts +3 -3
- package/dist/types/agent/skills.d.ts.map +1 -1
- package/dist/types/agent/subagents/index.d.ts +8 -0
- package/dist/types/agent/subagents/index.d.ts.map +1 -1
- package/dist/types/agent/subagents/manager.d.ts.map +1 -1
- package/dist/types/agent/subagents/memory-worker.d.ts +2 -8
- package/dist/types/agent/subagents/memory-worker.d.ts.map +1 -1
- package/dist/types/agent/subagents/subagent-launcher.d.ts.map +1 -1
- package/dist/types/backend/api/providers.d.ts +8 -2
- package/dist/types/backend/api/providers.d.ts.map +1 -1
- package/dist/types/backend/api/schedules.d.ts +16 -2
- package/dist/types/backend/api/schedules.d.ts.map +1 -1
- package/dist/types/backend/backend.d.ts +5 -2
- package/dist/types/backend/backend.d.ts.map +1 -1
- package/dist/types/backend/dev/fake-headless-backend.d.ts +2 -1
- package/dist/types/backend/dev/fake-headless-backend.d.ts.map +1 -1
- package/dist/types/backend/dev/pi-model-factory.d.ts.map +1 -1
- package/dist/types/backend/local/local-provider-auth-store.d.ts +2 -0
- package/dist/types/backend/local/local-provider-auth-store.d.ts.map +1 -1
- package/dist/types/backend/local/local-transcript-history.d.ts +10 -0
- package/dist/types/backend/local/local-transcript-history.d.ts.map +1 -0
- package/dist/types/backend/local/local-transcript.d.ts +6 -0
- package/dist/types/backend/local/local-transcript.d.ts.map +1 -1
- package/dist/types/channels/slack/attachment-primitives.d.ts +2 -1
- package/dist/types/channels/slack/attachment-primitives.d.ts.map +1 -1
- package/dist/types/channels/types.d.ts +1 -1
- package/dist/types/cli/helpers/chunk-log.d.ts.map +1 -1
- package/dist/types/cli/subcommands/mcp.d.ts +2 -2
- package/dist/types/cli/subcommands/mcp.d.ts.map +1 -1
- package/dist/types/cron/cron-file.d.ts.map +1 -1
- package/dist/types/cron/process-identity.d.ts.map +1 -1
- package/dist/types/cron/run-log.d.ts +1 -0
- package/dist/types/cron/run-log.d.ts.map +1 -1
- package/dist/types/headless-environment-response.d.ts +27 -0
- package/dist/types/headless-environment-response.d.ts.map +1 -1
- package/dist/types/hooks/loader.d.ts.map +1 -1
- package/dist/types/mods/paths.d.ts +3 -3
- package/dist/types/mods/paths.d.ts.map +1 -1
- package/dist/types/permissions/agent-memory-prefixes.d.ts.map +1 -1
- package/dist/types/permissions/analyzer.d.ts +1 -0
- package/dist/types/permissions/analyzer.d.ts.map +1 -1
- package/dist/types/permissions/cross-agent-guard.d.ts.map +1 -1
- package/dist/types/permissions/loader.d.ts +2 -1
- package/dist/types/permissions/loader.d.ts.map +1 -1
- package/dist/types/permissions/sandbox-policy.d.ts +9 -7
- package/dist/types/permissions/sandbox-policy.d.ts.map +1 -1
- package/dist/types/providers/byok-providers.d.ts +14 -0
- package/dist/types/providers/byok-providers.d.ts.map +1 -1
- package/dist/types/sandbox/bwrap.d.ts +2 -2
- package/dist/types/sandbox/bwrap.d.ts.map +1 -1
- package/dist/types/sandbox/policy.d.ts +20 -3
- package/dist/types/sandbox/policy.d.ts.map +1 -1
- package/dist/types/sandbox/seatbelt.d.ts +1 -1
- package/dist/types/sandbox/seatbelt.d.ts.map +1 -1
- package/dist/types/settings-manager.d.ts +4 -12
- package/dist/types/settings-manager.d.ts.map +1 -1
- package/dist/types/tools/commit-trailer.d.ts +27 -0
- package/dist/types/tools/commit-trailer.d.ts.map +1 -0
- package/dist/types/tools/impl/claude-stream-session.d.ts.map +1 -1
- package/dist/types/tools/impl/codex-app-server.d.ts +2 -0
- package/dist/types/tools/impl/codex-app-server.d.ts.map +1 -1
- package/dist/types/tools/impl/cursor-session.d.ts +28 -0
- package/dist/types/tools/impl/cursor-session.d.ts.map +1 -0
- package/dist/types/tools/impl/cursor-worker.d.ts +35 -0
- package/dist/types/tools/impl/cursor-worker.d.ts.map +1 -0
- package/dist/types/tools/impl/external-coding-agent-task.d.ts.map +1 -1
- package/dist/types/tools/impl/external-coding-agent.d.ts +1 -1
- package/dist/types/tools/impl/external-coding-agent.d.ts.map +1 -1
- package/dist/types/tools/impl/memory-task-lifecycle.d.ts +2 -2
- package/dist/types/tools/impl/memory-task-lifecycle.d.ts.map +1 -1
- package/dist/types/tools/impl/overflow.d.ts +1 -1
- package/dist/types/tools/impl/overflow.d.ts.map +1 -1
- package/dist/types/tools/impl/remote-external-coding-agent.d.ts.map +1 -1
- package/dist/types/tools/impl/ripgrep-manager.d.ts.map +1 -1
- package/dist/types/tools/impl/send-agent-message.d.ts.map +1 -1
- package/dist/types/tools/impl/shell-env.d.ts.map +1 -1
- package/dist/types/tools/impl/task.d.ts.map +1 -1
- package/dist/types/tools/impl/wake.d.ts.map +1 -1
- package/dist/types/tools/script-tool-scope.d.ts.map +1 -1
- package/dist/types/tools/tool-definitions.d.ts.map +1 -1
- package/dist/types/tools/workflow/sdk-spawner.d.ts.map +1 -1
- package/dist/types/utils/fs.d.ts +5 -1
- package/dist/types/utils/fs.d.ts.map +1 -1
- package/dist/types/utils/local-backend-paths.d.ts +1 -1
- package/dist/types/utils/local-backend-paths.d.ts.map +1 -1
- package/dist/types/utils/native-cli-env.d.ts +3 -0
- package/dist/types/utils/native-cli-env.d.ts.map +1 -0
- package/dist/types/utils/process-liveness.d.ts +9 -0
- package/dist/types/utils/process-liveness.d.ts.map +1 -1
- package/dist/types/utils/secrets.d.ts +1 -1
- package/dist/types/utils/secrets.d.ts.map +1 -1
- package/dist/types/utils/settings-path.d.ts +14 -0
- package/dist/types/utils/settings-path.d.ts.map +1 -0
- package/dist/types/utils/transcript-paths.d.ts +1 -1
- package/dist/types/websocket/listener/constants.d.ts +6 -0
- package/dist/types/websocket/listener/constants.d.ts.map +1 -1
- package/dist/types/websocket/listener/input-disposition-path.d.ts.map +1 -1
- package/dist/types/websocket/listener/interrupted-turn-storage.d.ts.map +1 -1
- package/dist/types/websocket/listener/org-credentials.d.ts.map +1 -1
- package/dist/types/websocket/listener/remote-settings.d.ts +2 -2
- package/dist/types/websocket/listener/remote-settings.d.ts.map +1 -1
- package/dist/types/websocket/listener/turn-finished-replay.d.ts +1 -0
- package/dist/types/websocket/listener/turn-finished-replay.d.ts.map +1 -1
- package/letta.js +5769 -4506
- package/npm-shrinkwrap.json +293 -115
- package/package.json +6 -3
- package/scripts/agent-watch/verify-pr-identity.test.ts +148 -0
- package/scripts/agent-watch/verify-pr-identity.ts +72 -14
- package/scripts/claude-watch/agent-watch.ts +8 -2
- package/scripts/claude-watch/release-source.test.ts +120 -0
- package/scripts/claude-watch/release-source.ts +79 -9
- package/scripts/codex-watch/agent-watch.ts +2 -2
- package/scripts/codex-watch/release-analysis.test.ts +112 -6
- package/scripts/codex-watch/release-analysis.ts +63 -6
- package/scripts/isolated-unit-tests.json +10 -0
- package/scripts/source-file-size-baseline.json +5 -4
- package/scripts/test-home-preload.ts +1 -0
- package/skills/acquiring-skills/SKILL.md +4 -4
- package/skills/creating-mods/SKILL.md +3 -3
- package/skills/creating-mods/references/analysis-mode.md +7 -5
- package/skills/creating-mods/references/architecture.md +2 -2
- package/skills/creating-mods/references/plan-mode.md +12 -11
- package/skills/creating-mods/references/providers.md +1 -1
- package/skills/creating-skills/scripts/init-skill.ts +4 -2
- package/skills/customizing-commands/SKILL.md +3 -3
- package/skills/customizing-statusline/SKILL.md +3 -3
- package/skills/customizing-statusline/references/api.md +3 -3
- package/skills/customizing-statusline/references/migration.md +2 -2
- package/skills/initializing-memory/SKILL.md +2 -2
- package/skills/managing-agent-webhooks/SKILL.md +23 -3
- package/skills/managing-agent-webhooks/scripts/manage-agent-webhooks.mjs +40 -11
- package/skills/self-configuration/SKILL.md +5 -5
- package/skills/self-configuration/scripts/add_permission.py +26 -5
- package/skills/self-configuration/scripts/show_config.py +17 -2
- package/skills/syncing-memory-filesystem/SKILL.md +2 -10
- package/skills/video-generation/SKILL.md +152 -0
- package/skills/workflow-authoring/SKILL.md +1 -1
- package/dist/types/agent/memory-worktree.d.ts +0 -83
- package/dist/types/agent/memory-worktree.d.ts.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// src/permissions/memory-confinement-launcher.ts
|
|
2
2
|
import { homedir as homedir3 } from "node:os";
|
|
3
|
-
import { basename as basename2, dirname as dirname2, join as
|
|
3
|
+
import { basename as basename2, dirname as dirname2, join as join4, resolve as resolve3 } from "node:path";
|
|
4
4
|
|
|
5
5
|
// src/permissions/sandbox-policy.ts
|
|
6
6
|
import { existsSync, realpathSync } from "node:fs";
|
|
7
7
|
import { homedir as homedir2 } from "node:os";
|
|
8
|
-
import { basename, dirname, isAbsolute, join as
|
|
8
|
+
import { basename, dirname, isAbsolute as isAbsolute2, join as join3, resolve as resolve2 } from "node:path";
|
|
9
9
|
|
|
10
10
|
// src/sandbox/policy.ts
|
|
11
11
|
import { posix, win32 } from "node:path";
|
|
@@ -19,6 +19,32 @@ function buildFsSandboxPolicy(options) {
|
|
|
19
19
|
restrictWrites: options.restrictWrites ?? false
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
|
+
function getOrderedSandboxPathRules(policy) {
|
|
23
|
+
const rules = [];
|
|
24
|
+
const append = (kind, roots) => {
|
|
25
|
+
roots.forEach((root, index) => {
|
|
26
|
+
rules.push({ kind, root, index });
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
append("deny", policy.deniedRoots);
|
|
30
|
+
append("readonly", policy.readonlyRoots);
|
|
31
|
+
append("writable", policy.writableRoots);
|
|
32
|
+
const samePathPriority = {
|
|
33
|
+
readonly: 0,
|
|
34
|
+
writable: 1,
|
|
35
|
+
deny: 2
|
|
36
|
+
};
|
|
37
|
+
const depth = (root) => root.split("/").filter(Boolean).length;
|
|
38
|
+
return rules.sort((a, b) => {
|
|
39
|
+
const depthDifference = depth(a.root) - depth(b.root);
|
|
40
|
+
if (depthDifference !== 0)
|
|
41
|
+
return depthDifference;
|
|
42
|
+
const pathDifference = a.root.localeCompare(b.root);
|
|
43
|
+
if (pathDifference !== 0)
|
|
44
|
+
return pathDifference;
|
|
45
|
+
return samePathPriority[a.kind] - samePathPriority[b.kind];
|
|
46
|
+
});
|
|
47
|
+
}
|
|
22
48
|
function normalizeSandboxPath(path) {
|
|
23
49
|
const trimmed = path.trim();
|
|
24
50
|
const absolute = posix.isAbsolute(trimmed) || win32.isAbsolute(trimmed) ? trimmed : posix.resolve("/", trimmed);
|
|
@@ -36,33 +62,61 @@ function normalizeRoots(roots) {
|
|
|
36
62
|
}
|
|
37
63
|
|
|
38
64
|
// src/utils/local-backend-paths.ts
|
|
65
|
+
import { join as join2 } from "node:path";
|
|
66
|
+
|
|
67
|
+
// src/utils/settings-path.ts
|
|
39
68
|
import { homedir } from "node:os";
|
|
40
|
-
import { join } from "node:path";
|
|
69
|
+
import { isAbsolute, join, normalize, resolve } from "node:path";
|
|
70
|
+
function resolveGlobalConfigDir(env = process.env, fallbackHome = homedir()) {
|
|
71
|
+
const override = env.LETTA_CONFIG_DIR?.trim();
|
|
72
|
+
if (override) {
|
|
73
|
+
if (!isAbsolute(override)) {
|
|
74
|
+
throw new Error("LETTA_CONFIG_DIR must be absolute");
|
|
75
|
+
}
|
|
76
|
+
return normalize(override);
|
|
77
|
+
}
|
|
78
|
+
return join(env.HOME || fallbackHome, ".letta");
|
|
79
|
+
}
|
|
80
|
+
function hasGlobalConfigDirOverride(env = process.env) {
|
|
81
|
+
return Boolean(env.LETTA_CONFIG_DIR?.trim());
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// src/utils/local-backend-paths.ts
|
|
41
85
|
var LOCAL_BACKEND_DIR_ENV = "LETTA_LOCAL_BACKEND_DIR";
|
|
42
|
-
function getLocalBackendStorageDir(homeDir
|
|
43
|
-
|
|
86
|
+
function getLocalBackendStorageDir(homeDir, env = process.env) {
|
|
87
|
+
const configDir = homeDir === undefined || hasGlobalConfigDirOverride(env) ? resolveGlobalConfigDir(env, homeDir) : join2(homeDir, ".letta");
|
|
88
|
+
return env[LOCAL_BACKEND_DIR_ENV] ?? join2(configDir, "lc-local-backend");
|
|
44
89
|
}
|
|
45
90
|
function getLocalBackendCrossAgentTreeRoot(storageDir = getLocalBackendStorageDir()) {
|
|
46
|
-
return
|
|
91
|
+
return join2(storageDir, "memfs");
|
|
47
92
|
}
|
|
48
93
|
|
|
49
94
|
// src/permissions/sandbox-policy.ts
|
|
50
|
-
function getDefaultAgentsTreeRoot(homeDir = homedir2()) {
|
|
51
|
-
return canonicalizeRoot(join2(homeDir, ".letta", "agents"));
|
|
52
|
-
}
|
|
53
95
|
function getCrossBackendAgentsTreeRoots(options = {}) {
|
|
54
|
-
const homeDir = options.homeDir
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
96
|
+
const homeDir = options.homeDir;
|
|
97
|
+
const env = options.env ?? process.env;
|
|
98
|
+
const resolvedHome = homeDir ?? env.HOME ?? homedir2();
|
|
99
|
+
const configRoots = new Set([
|
|
100
|
+
resolveGlobalConfigDir(env, resolvedHome),
|
|
101
|
+
join3(resolvedHome, ".letta")
|
|
102
|
+
]);
|
|
103
|
+
const localBackendStorageDir = options.localBackendStorageDir ?? getLocalBackendStorageDir(homeDir, env);
|
|
104
|
+
const roots = new Set;
|
|
105
|
+
for (const configRoot of configRoots) {
|
|
106
|
+
roots.add(canonicalizeRoot(join3(configRoot, "agents")));
|
|
107
|
+
}
|
|
108
|
+
roots.add(canonicalizeRoot(getLocalBackendCrossAgentTreeRoot(localBackendStorageDir)));
|
|
109
|
+
for (const configRoot of configRoots) {
|
|
110
|
+
roots.add(canonicalizeRoot(getLocalBackendCrossAgentTreeRoot(join3(configRoot, "lc-local-backend"))));
|
|
111
|
+
}
|
|
112
|
+
return [...roots];
|
|
60
113
|
}
|
|
61
|
-
function getLettaHomeRoot(homeDir =
|
|
62
|
-
|
|
114
|
+
function getLettaHomeRoot(homeDir, env = process.env) {
|
|
115
|
+
const configDir = homeDir === undefined || hasGlobalConfigDirOverride(env) ? resolveGlobalConfigDir(env, homeDir) : join3(homeDir, ".letta");
|
|
116
|
+
return canonicalizeRoot(configDir);
|
|
63
117
|
}
|
|
64
118
|
function canonicalizeRoot(input) {
|
|
65
|
-
const abs =
|
|
119
|
+
const abs = isAbsolute2(input) ? input : resolve2(input);
|
|
66
120
|
let dir = abs;
|
|
67
121
|
const tail = [];
|
|
68
122
|
while (!existsSync(dir)) {
|
|
@@ -75,7 +129,7 @@ function canonicalizeRoot(input) {
|
|
|
75
129
|
}
|
|
76
130
|
try {
|
|
77
131
|
const real = realpathSync(dir);
|
|
78
|
-
return normalizeSandboxPath(tail.length ?
|
|
132
|
+
return normalizeSandboxPath(tail.length ? join3(real, ...tail) : real);
|
|
79
133
|
} catch {
|
|
80
134
|
return normalizeSandboxPath(abs);
|
|
81
135
|
}
|
|
@@ -116,7 +170,9 @@ function deriveWritableMemoryRootsForTrees(memoryRoots, agentsTreeRoots) {
|
|
|
116
170
|
const out = new Set;
|
|
117
171
|
for (const root of memoryRoots) {
|
|
118
172
|
const canon = canonicalizeRoot(root);
|
|
119
|
-
|
|
173
|
+
const isExactDeniedTree = canonicalTrees.includes(canon);
|
|
174
|
+
const isInsideDeniedTree = canonicalTrees.some((tree) => canon !== tree && isWithinRoot(canon, tree));
|
|
175
|
+
if (!isExactDeniedTree && (isInsideDeniedTree || !isTreeOrAncestorOfTree(canon, canonicalTrees))) {
|
|
120
176
|
out.add(canon);
|
|
121
177
|
}
|
|
122
178
|
}
|
|
@@ -150,14 +206,18 @@ function buildBwrapArgs(policy) {
|
|
|
150
206
|
for (const root of policy.baseWritableRoots) {
|
|
151
207
|
args.push("--bind-try", root, root);
|
|
152
208
|
}
|
|
153
|
-
for (const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
209
|
+
for (const rule of getOrderedSandboxPathRules(policy)) {
|
|
210
|
+
switch (rule.kind) {
|
|
211
|
+
case "deny":
|
|
212
|
+
args.push("--tmpfs", rule.root);
|
|
213
|
+
break;
|
|
214
|
+
case "readonly":
|
|
215
|
+
args.push("--ro-bind-try", rule.root, rule.root);
|
|
216
|
+
break;
|
|
217
|
+
case "writable":
|
|
218
|
+
args.push("--bind-try", rule.root, rule.root);
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
161
221
|
}
|
|
162
222
|
args.push("--die-with-parent");
|
|
163
223
|
return args;
|
|
@@ -177,22 +237,20 @@ function buildSeatbeltProfile(policy) {
|
|
|
177
237
|
defines.push({ name, value: root });
|
|
178
238
|
lines.push(`(allow file-write* (subpath (param "${name}")))`);
|
|
179
239
|
});
|
|
180
|
-
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
lines.push(`(allow file-read* (subpath (param "${name}")))`);
|
|
195
|
-
});
|
|
240
|
+
for (const rule of getOrderedSandboxPathRules(policy)) {
|
|
241
|
+
const prefix = rule.kind === "deny" ? "DENIED" : rule.kind === "readonly" ? "READONLY" : "WRITABLE";
|
|
242
|
+
const name = `${prefix}_${rule.index}`;
|
|
243
|
+
defines.push({ name, value: rule.root });
|
|
244
|
+
if (rule.kind === "deny") {
|
|
245
|
+
lines.push(`(deny file-read* file-write* (subpath (param "${name}")))`);
|
|
246
|
+
lines.push(`(allow file-read-metadata (literal (param "${name}")))`);
|
|
247
|
+
} else if (rule.kind === "readonly") {
|
|
248
|
+
lines.push(`(deny file-write* (subpath (param "${name}")))`);
|
|
249
|
+
lines.push(`(allow file-read* (subpath (param "${name}")))`);
|
|
250
|
+
} else {
|
|
251
|
+
lines.push(`(allow file-read* file-write* (subpath (param "${name}")))`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
196
254
|
return { profile: `${lines.join(`
|
|
197
255
|
`)}
|
|
198
256
|
`, defines };
|
|
@@ -233,8 +291,8 @@ function wrapLauncher(launcher, policy, options) {
|
|
|
233
291
|
// src/permissions/memory-confinement-launcher.ts
|
|
234
292
|
function normalizeRoot(path) {
|
|
235
293
|
const trimmed = path.trim();
|
|
236
|
-
const expanded = trimmed.startsWith("~/") ?
|
|
237
|
-
return
|
|
294
|
+
const expanded = trimmed.startsWith("~/") ? join4(homedir3(), trimmed.slice(2)) : trimmed.startsWith("$HOME/") ? join4(homedir3(), trimmed.slice(6)) : trimmed;
|
|
295
|
+
return resolve3(expanded);
|
|
238
296
|
}
|
|
239
297
|
function resolveWritableMemoryRoots(env) {
|
|
240
298
|
const roots = new Set;
|
|
@@ -244,7 +302,7 @@ function resolveWritableMemoryRoots(env) {
|
|
|
244
302
|
const root = normalizeRoot(value);
|
|
245
303
|
roots.add(root);
|
|
246
304
|
if (basename2(root) === "memory") {
|
|
247
|
-
roots.add(
|
|
305
|
+
roots.add(join4(dirname2(root), "memory-worktrees"));
|
|
248
306
|
}
|
|
249
307
|
}
|
|
250
308
|
return [...roots];
|
|
@@ -289,7 +347,7 @@ function createMemoryConfinementLauncherWithAvailability(input, availability) {
|
|
|
289
347
|
// src/sandbox/availability.ts
|
|
290
348
|
import { spawnSync } from "node:child_process";
|
|
291
349
|
import { existsSync as existsSync2 } from "node:fs";
|
|
292
|
-
import { delimiter, isAbsolute as
|
|
350
|
+
import { delimiter, isAbsolute as isAbsolute3, join as join5 } from "node:path";
|
|
293
351
|
var cached = null;
|
|
294
352
|
var warnedUnavailableContexts = new Set;
|
|
295
353
|
function detectSandboxBackend(options = {}) {
|
|
@@ -340,12 +398,12 @@ function probeBwrap() {
|
|
|
340
398
|
return { backend: "bwrap", bwrapPath, reason: "bwrap available" };
|
|
341
399
|
}
|
|
342
400
|
function resolveExecutableOnPath(executable, envPath = process.env.PATH) {
|
|
343
|
-
if (
|
|
401
|
+
if (isAbsolute3(executable) && existsSync2(executable))
|
|
344
402
|
return executable;
|
|
345
403
|
for (const dir of (envPath ?? "").split(delimiter)) {
|
|
346
404
|
if (!dir)
|
|
347
405
|
continue;
|
|
348
|
-
const candidate =
|
|
406
|
+
const candidate = join5(dir, executable);
|
|
349
407
|
if (existsSync2(candidate))
|
|
350
408
|
return candidate;
|
|
351
409
|
}
|
|
@@ -360,4 +418,4 @@ export {
|
|
|
360
418
|
createMemoryConfinementLauncher
|
|
361
419
|
};
|
|
362
420
|
|
|
363
|
-
//# debugId=
|
|
421
|
+
//# debugId=8EA4D35C8AB0C06C64756E2164756E21
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/permissions/memory-confinement-launcher.ts", "../src/permissions/sandbox-policy.ts", "../src/sandbox/policy.ts", "../src/utils/local-backend-paths.ts", "../src/sandbox/bwrap.ts", "../src/sandbox/seatbelt.ts", "../src/sandbox/wrap.ts", "../src/sandbox/availability.ts", "../src/memory-confinement.ts"],
|
|
3
|
+
"sources": ["../src/permissions/memory-confinement-launcher.ts", "../src/permissions/sandbox-policy.ts", "../src/sandbox/policy.ts", "../src/utils/local-backend-paths.ts", "../src/utils/settings-path.ts", "../src/sandbox/bwrap.ts", "../src/sandbox/seatbelt.ts", "../src/sandbox/wrap.ts", "../src/sandbox/availability.ts", "../src/memory-confinement.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import { homedir } from \"node:os\";\nimport { basename, dirname, join, resolve } from \"node:path\";\n\nimport {\n buildMemorySubagentSandboxPolicy,\n getCrossBackendAgentsTreeRoots,\n} from \"@/permissions/sandbox-policy\";\nimport type { SandboxAvailability } from \"@/sandbox/availability\";\nimport { SANDBOX_ENV_VAR, type SandboxBackend } from \"@/sandbox/policy\";\nimport { wrapLauncher } from \"@/sandbox/wrap\";\n\nexport interface MemoryConfinementLauncherInput {\n /** Command and arguments for the process that should be confined. */\n launcher: string[];\n /**\n * Environment for the confined process. `MEMORY_DIR` (or\n * `LETTA_MEMORY_DIR`) identifies the memory root that stays writable.\n */\n env: NodeJS.ProcessEnv;\n}\n\nexport interface MemoryConfinementLauncherResult {\n /** Sandbox wrapper followed by the original launcher. */\n launcher: string[];\n /** Original environment plus the nested-sandbox sentinel. */\n env: NodeJS.ProcessEnv;\n backend: SandboxBackend;\n}\n\nfunction normalizeRoot(path: string): string {\n const trimmed = path.trim();\n const expanded = trimmed.startsWith(\"~/\")\n ? join(homedir(), trimmed.slice(2))\n : trimmed.startsWith(\"$HOME/\")\n ? join(homedir(), trimmed.slice(6))\n : trimmed;\n return resolve(expanded);\n}\n\nfunction resolveWritableMemoryRoots(env: NodeJS.ProcessEnv): string[] {\n const roots = new Set<string>();\n for (const value of [env.MEMORY_DIR, env.LETTA_MEMORY_DIR]) {\n if (!value?.trim()) continue;\n const root = normalizeRoot(value);\n roots.add(root);\n if (basename(root) === \"memory\") {\n roots.add(join(dirname(root), \"memory-worktrees\"));\n }\n }\n return [...roots];\n}\n\nfunction customHarnessWritableRoots(env: NodeJS.ProcessEnv): string[] {\n return [env.LETTA_LOCAL_BACKEND_DIR, env.LETTA_TRANSCRIPT_ROOT]\n .filter((value): value is string => Boolean(value?.trim()))\n .map(normalizeRoot);\n}\n\nexport function createMemoryConfinementLauncherWithAvailability(\n input: MemoryConfinementLauncherInput,\n availability: SandboxAvailability,\n): MemoryConfinementLauncherResult {\n if (input.launcher.length === 0) {\n throw new Error(\"Memory confinement requires a non-empty launcher.\");\n }\n\n const memoryRoots = resolveWritableMemoryRoots(input.env);\n if (memoryRoots.length === 0) {\n throw new Error(\n \"Memory confinement requires MEMORY_DIR or LETTA_MEMORY_DIR.\",\n );\n }\n if (!availability.backend) {\n throw new Error(\n `Memory confinement is unavailable: ${availability.reason}.`,\n );\n }\n\n const localBackendStorageDir =\n input.env.LETTA_LOCAL_BACKEND_DIR?.trim() || undefined;\n const policy = buildMemorySubagentSandboxPolicy({\n memoryRoots,\n agentsTreeRoots: getCrossBackendAgentsTreeRoots({\n env: input.env,\n localBackendStorageDir,\n }),\n harnessWritableRoots: customHarnessWritableRoots(input.env),\n });\n const launcher = wrapLauncher(input.launcher, policy, {\n backend: availability.backend,\n bwrapPath: availability.bwrapPath,\n });\n if (!launcher) {\n throw new Error(\"Memory confinement could not wrap the launcher.\");\n }\n\n return {\n launcher,\n env: { ...input.env, [SANDBOX_ENV_VAR]: availability.backend },\n backend: availability.backend,\n };\n}\n",
|
|
6
|
-
"import { existsSync, realpathSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, dirname, isAbsolute, join, resolve } from \"node:path\";\n\nimport {\n buildFsSandboxPolicy,\n type FsSandboxPolicy,\n normalizeSandboxPath,\n} from \"@/sandbox/policy\";\nimport {\n getLocalBackendCrossAgentTreeRoot,\n getLocalBackendStorageDir,\n} from \"@/utils/local-backend-paths\";\n\n/**\n * Builders that translate agent/memory context into a concrete\n * {@link FsSandboxPolicy}. This is the bridge between the domain (agent ids,\n * memory roots) and the pure `@/sandbox` generators — it lives in\n * `permissions/` alongside the static guards it is meant to replace.\n *\n * Every root is canonicalized with realpath before it reaches a backend: both\n * Seatbelt and bwrap match rules against the kernel-resolved path, so a policy\n * built from a lexical path that passes through a symlink would silently match\n * nothing — i.e. a sandbox that allows everything. See `canonicalizeRoot`.\n */\n\n/** The per-agent tree to wall off, e.g. `/Users/me/.letta/agents`. */\nexport function getDefaultAgentsTreeRoot(homeDir: string = homedir()): string {\n return canonicalizeRoot(join(homeDir, \".letta\", \"agents\"));\n}\n\nexport interface CrossBackendAgentsTreeRootsOptions {\n homeDir?: string;\n env?: NodeJS.ProcessEnv;\n /** Explicit local backend storage dir, when already resolved by a caller. */\n localBackendStorageDir?: string | null;\n}\n\n/**\n * Every cross-agent memory tree the kernel sandbox must wall off. API/cloud\n * agents live under `~/.letta/agents`; local-backend agents live under\n * `<storage>/memfs`. A process running in either backend must deny both trees,\n * then carve back only the current/parent agent roots it is allowed to touch.\n */\nexport function getCrossBackendAgentsTreeRoots(\n options: CrossBackendAgentsTreeRootsOptions = {},\n): string[] {\n const homeDir = options.homeDir ?? homedir();\n const localBackendStorageDir =\n options.localBackendStorageDir ??\n getLocalBackendStorageDir(homeDir, options.env ?? process.env);\n\n return [\n getDefaultAgentsTreeRoot(homeDir),\n canonicalizeRoot(getLocalBackendCrossAgentTreeRoot(localBackendStorageDir)),\n ];\n}\n\n/**\n * The harness state directory, e.g. `/Users/me/.letta`. Used as the broad\n * writable base for memory subagents: they may write harness metadata anywhere\n * under it (settings, logs, conversations, transcripts, memory) but not the\n * repo/home/temp — while the cross-agent tree nested inside it stays denied.\n */\nexport function getLettaHomeRoot(homeDir: string = homedir()): string {\n return canonicalizeRoot(join(homeDir, \".letta\"));\n}\n\n/**\n * Resolve a path to the real (symlink-free) path the kernel will see. The leaf\n * may not exist yet (a file about to be created), so we realpath the nearest\n * existing ancestor and re-append the missing tail.\n */\nexport function canonicalizeRoot(input: string): string {\n const abs = isAbsolute(input) ? input : resolve(input);\n\n let dir = abs;\n const tail: string[] = [];\n while (!existsSync(dir)) {\n tail.unshift(basename(dir));\n const parent = dirname(dir);\n if (parent === dir) {\n // Reached the filesystem root without finding an existing ancestor.\n return normalizeSandboxPath(abs);\n }\n dir = parent;\n }\n\n try {\n const real = realpathSync(dir);\n return normalizeSandboxPath(tail.length ? join(real, ...tail) : real);\n } catch {\n return normalizeSandboxPath(abs);\n }\n}\n\n/** Whether a canonical path is the given root or nested inside it. */\nfunction isWithinRoot(path: string, root: string): boolean {\n return path === root || path.startsWith(`${root}/`);\n}\n\nfunction isAncestorOfRoot(path: string, root: string): boolean {\n const prefix = path === \"/\" ? \"/\" : `${path}/`;\n return root.startsWith(prefix);\n}\n\n/**\n * True when a canonical path IS one of the trees or an ancestor of one. Such a\n * path must never be carved back out: re-exposing a whole tree (or an ancestor\n * that contains it) would re-expose the denied roots under bwrap's\n * last-mount-wins semantics, and is too broad under Seatbelt as well.\n */\nfunction isTreeOrAncestorOfTree(\n path: string,\n canonicalTrees: string[],\n): boolean {\n return canonicalTrees.some(\n (tree) => path === tree || isAncestorOfRoot(path, tree),\n );\n}\n\n/**\n * Resolve the caller-supplied agents trees (canonicalizing each), or fall back\n * to both backend trees when none were given. Shared by the policy builders.\n */\nfunction resolveAgentsTreeRootsInput(roots?: string[]): string[] {\n return roots?.length\n ? roots.map(canonicalizeRoot)\n : getCrossBackendAgentsTreeRoots();\n}\n\n/**\n * Map memory roots to the agent directories to carve out of the walled-off\n * agents tree. A memory root under the tree\n * (`~/.letta/agents/<id>/memory[-worktrees]`) yields the whole agent dir\n * (`~/.letta/agents/<id>`); carving the *agent dir* rather than just `/memory`\n * keeps the cwd's immediate parent traversable, so a read-deny on the tree does\n * not empty the child env under Seatbelt. Roots outside the tree (a custom\n * `MEMORY_DIR`) are returned as-is.\n */\nexport function deriveSelfAgentRootsForTrees(\n memoryRoots: string[],\n agentsTreeRoots: string[] = getCrossBackendAgentsTreeRoots(),\n): string[] {\n const canonicalTrees = agentsTreeRoots.map(canonicalizeRoot);\n const out = new Set<string>();\n for (const root of memoryRoots) {\n const canon = canonicalizeRoot(root);\n const containingTree = canonicalTrees.find(\n (tree) => canon !== tree && isWithinRoot(canon, tree),\n );\n if (containingTree) {\n // A memory root nested inside a tree: carve back the whole agent dir so\n // the cwd's immediate parent stays traversable (Seatbelt empty-env bug).\n const leaf = basename(canon);\n const parentLeaf = basename(dirname(canon));\n out.add(\n leaf === \"memory\" || leaf === \"memory-worktrees\"\n ? dirname(canon)\n : parentLeaf === \"memory-worktrees\" ||\n (parentLeaf === \"memory\" && leaf === \".git\")\n ? dirname(dirname(canon))\n : canon,\n );\n continue;\n }\n // Outside every tree: keep as-is, unless it's a tree itself or an ancestor\n // of one (carving those back out would re-expose the denied tree).\n if (!isTreeOrAncestorOfTree(canon, canonicalTrees)) {\n out.add(canon);\n }\n }\n return [...out];\n}\n\nfunction deriveWritableMemoryRootsForTrees(\n memoryRoots: string[],\n agentsTreeRoots: string[],\n): string[] {\n const canonicalTrees = agentsTreeRoots.map(canonicalizeRoot);\n const out = new Set<string>();\n for (const root of memoryRoots) {\n const canon = canonicalizeRoot(root);\n // Never re-carve a whole denied tree, or an ancestor that would re-expose\n // that tree under bwrap's last-mount-wins semantics.\n if (!isTreeOrAncestorOfTree(canon, canonicalTrees)) {\n out.add(canon);\n }\n }\n return [...out];\n}\n\nexport interface MemorySubagentSandboxInput {\n /**\n * Memory roots the child may write to — typically the resolved\n * `MEMORY_DIR` plus its `memory-worktrees` sibling.\n */\n memoryRoots: string[];\n /** Additional roots to carve back read-only after denying agents trees. */\n readonlyRoots?: string[];\n /**\n * Harness state roots configured OUTSIDE `~/.letta` to also make writable —\n * `~/.letta` itself is always the base. The caller passes a custom\n * `LETTA_LOCAL_BACKEND_DIR` / `LETTA_TRANSCRIPT_ROOT` here so the in-process\n * child can still persist conversation/agent-state/transcripts when those are\n * relocated off the default tree. Usually empty (the defaults live under\n * `~/.letta`).\n */\n harnessWritableRoots?: string[];\n /**\n * The agents trees to wall off + carve self out of. Defaults to both\n * `~/.letta/agents` (API/cloud) and `lc-local-backend/memfs` (local). Each\n * agent's memory lives at `<tree>/<id>/memory` on both, so\n * {@link deriveSelfAgentRootsForTrees} carves the same way regardless of\n * backend.\n *\n * Resolved by the caller's layer (`tools/` / `agent/`, which may import\n * `backend/`): `permissions/` sits below `backend/`, so this builder takes the\n * already-resolved path rather than branching on a backend it cannot import.\n */\n agentsTreeRoots?: string[];\n}\n\n/**\n * Policy for the memory-subagent launch profile: it may read the filesystem broadly to do\n * its work, write only under the harness state dir (`~/.letta`), and not read or\n * write *other* agents' memory.\n *\n * The whole subagent process runs under this policy, so it is the sole\n * enforcement for these agents — the static guard is skipped for them. It covers\n * both axes:\n * - writes: `restrictWrites` denies writes everywhere except the base\n * `~/.letta` carve (and self memory). This scopes the agent's\n * non-deterministic work — it can persist memory + harness metadata\n * (settings, logs, conversations, transcripts) but cannot write the repo,\n * home, or temp. Carving the WHOLE `~/.letta` rather than enumerating each\n * harness file is deliberate: the harness writes many paths under it and the\n * set is unbounded, so a per-file carve would silently break as new writers\n * appear. The cross-agent tree nested inside `~/.letta` stays denied.\n * - cross-agent reads: the agents tree is read+write denied, with the agent's\n * own (and inherited parent's) directory carved back out READ-only.\n *\n * Carving the whole agent *directory* readable — not just `/memory` — is what\n * lets us deny the tree without re-triggering the empty-env bug: the subagent's\n * cwd is its memory dir inside the agents tree, and under Seatbelt a child\n * launches with an EMPTY environment if a cwd *ancestor* is read-denied. With\n * the agent dir (the cwd's immediate parent) readable, process init can traverse\n * to the cwd and the env survives.\n *\n * Both backend trees are denied by default so cloud/API agents cannot read local\n * agent memories and local agents cannot read cloud/API memories. Self memory is\n * re-carved writable in `writableRoots` because it is nested inside a denied\n * tree (the base `~/.letta` carve is overridden there by the deny).\n */\nexport function buildMemorySubagentSandboxPolicy(\n input: MemorySubagentSandboxInput,\n): FsSandboxPolicy {\n const agentsTreeRoots = resolveAgentsTreeRootsInput(input.agentsTreeRoots);\n\n // Writes are scoped to the harness state dir. `~/.letta` is the always-on base\n // (covers settings/logs/conversations/transcripts/memory under the defaults);\n // `harnessWritableRoots` adds any harness root relocated OUTSIDE `~/.letta`\n // (custom LETTA_LOCAL_BACKEND_DIR / LETTA_TRANSCRIPT_ROOT). These are emitted\n // BEFORE the cross-agent deny, so the nested tree is still walled off.\n const baseWritableRoots = [\n getLettaHomeRoot(),\n ...(input.harnessWritableRoots ?? []),\n ].map(canonicalizeRoot);\n\n return buildFsSandboxPolicy({\n baseWritableRoots,\n deniedRoots: agentsTreeRoots,\n readonlyRoots: [\n ...deriveSelfAgentRootsForTrees(input.memoryRoots, agentsTreeRoots),\n ...(input.readonlyRoots ?? []).map(canonicalizeRoot),\n ],\n // Self memory is nested inside the denied tree; re-carve it writable so the\n // deny (which overrides the base ~/.letta carve there) is itself overridden.\n writableRoots: deriveWritableMemoryRootsForTrees(\n input.memoryRoots,\n agentsTreeRoots,\n ),\n restrictWrites: true,\n });\n}\n\nexport interface CrossAgentSandboxInput {\n /**\n * Directories the agent may freely read+write inside the walled-off agents\n * tree — typically its own agent directory (`~/.letta/agents/<self-id>`).\n */\n selfRoots: string[];\n /** The agents trees to wall off (read+write). Defaults to both backends. */\n agentsTreeRoots?: string[];\n}\n\n/**\n * Policy for a normal agent that may use the whole filesystem but must not read\n * or write *other* agents' memory. This is the kernel-enforced replacement for\n * the static cross-agent guard.\n *\n * Walls off both backend agents trees (read + write) and carves the agent's own\n * directory back out. Writes elsewhere — the repo, the home dir, temp — stay\n * allowed (`restrictWrites: false`): the only thing this policy removes is\n * access to other agents' memory, exactly like the guard it replaces.\n *\n * Unlike the memory-subagent policy, this one DOES deny reads of the agents tree.\n * That is only safe when the process cwd is outside the tree (the parent\n * agent's cwd is the repo); a cwd inside a read-denied subtree launches with an\n * empty environment under Seatbelt. Callers must enforce that precondition.\n */\nexport function buildCrossAgentSandboxPolicy(\n input: CrossAgentSandboxInput,\n): FsSandboxPolicy {\n const agentsTreeRoots = resolveAgentsTreeRootsInput(input.agentsTreeRoots);\n\n return buildFsSandboxPolicy({\n deniedRoots: agentsTreeRoots,\n writableRoots: input.selfRoots.map(canonicalizeRoot),\n restrictWrites: false,\n });\n}\n",
|
|
7
|
-
"import { posix, win32 } from \"node:path\";\n\n/**\n * A filesystem sandbox policy, expressed entirely in concrete absolute paths.\n *\n * This module is a pure leaf: it knows nothing about agents, launch profiles, or\n * how paths are derived. Callers resolve agent ids / memory roots into paths\n * (via `@/permissions/memory-paths`) and hand the finished policy here. That\n * keeps the OS-specific generators (`seatbelt.ts`, `bwrap.ts`) trivially\n * testable and out of the domain layer graph.\n *\n * Enforcement semantics (both backends implement the same model):\n *\n * - `baseWritableRoots` write re-allowed under these, emitted BEFORE\n * `deniedRoots` so a denied root nested inside still wins.\n * Used to grant a broad harness dir (e.g. all of\n * `~/.letta`) while keeping the cross-agent tree denied —\n * so a memory subagent may write harness state anywhere\n * under `~/.letta` but not the repo/home/temp.\n * - `deniedRoots` read + write denied (e.g. `~/.letta/agents`).\n * - `readonlyRoots` read re-allowed, write stays denied. Overrides denied.\n * - `writableRoots` read + write re-allowed. Overrides denied, the global\n * write-deny, AND `baseWritableRoots` — for a self carve\n * nested inside a denied root (self memory).\n * - `restrictWrites` when true, writes are denied *everywhere* except\n * `baseWritableRoots`/`writableRoots` (write-scoped profile). When\n * false, writes are allowed by default except under\n * `deniedRoots` (cross-agent profile — the normal agent that\n * simply may not touch other agents' memory).\n *\n * Reads are never globally restricted: an agent can read the whole filesystem\n * to do its work, minus the other-agent directories in `deniedRoots`.\n *\n * Specificity is expressed through ordering, not nesting depth. The emitted\n * order is: global write-deny → `baseWritableRoots` →
|
|
8
|
-
"import {
|
|
9
|
-
"import
|
|
10
|
-
"import type
|
|
6
|
+
"import { existsSync, realpathSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, dirname, isAbsolute, join, resolve } from \"node:path\";\n\nimport {\n buildFsSandboxPolicy,\n type FsSandboxPolicy,\n normalizeSandboxPath,\n} from \"@/sandbox/policy\";\nimport {\n getLocalBackendCrossAgentTreeRoot,\n getLocalBackendStorageDir,\n} from \"@/utils/local-backend-paths\";\nimport {\n hasGlobalConfigDirOverride,\n resolveGlobalConfigDir,\n} from \"@/utils/settings-path\";\n\n/**\n * Builders that translate agent/memory context into a concrete\n * {@link FsSandboxPolicy}. This is the bridge between the domain (agent ids,\n * memory roots) and the pure `@/sandbox` generators — it lives in\n * `permissions/` alongside the static guards it is meant to replace.\n *\n * Every root is canonicalized with realpath before it reaches a backend: both\n * Seatbelt and bwrap match rules against the kernel-resolved path, so a policy\n * built from a lexical path that passes through a symlink would silently match\n * nothing — i.e. a sandbox that allows everything. See `canonicalizeRoot`.\n */\n\n/** The per-agent tree to wall off below the active product config root. */\nexport function getDefaultAgentsTreeRoot(\n homeDir?: string,\n env: NodeJS.ProcessEnv = process.env,\n): string {\n const configDir =\n homeDir === undefined || hasGlobalConfigDirOverride(env)\n ? resolveGlobalConfigDir(env, homeDir)\n : join(homeDir, \".letta\");\n return canonicalizeRoot(join(configDir, \"agents\"));\n}\n\nexport interface CrossBackendAgentsTreeRootsOptions {\n homeDir?: string;\n env?: NodeJS.ProcessEnv;\n /** Explicit local backend storage dir, when already resolved by a caller. */\n localBackendStorageDir?: string | null;\n}\n\n/**\n * Every cross-agent memory tree the kernel sandbox must wall off. This includes\n * the active product config root and the legacy HOME-local Letta root when they\n * differ, because Dream and ordinary Letta Code can coexist on one machine.\n * Each config root can contain API/cloud agents under `agents/` and local\n * backend agents under `lc-local-backend/memfs/`; an explicit local-backend\n * storage override is guarded too.\n */\nexport function getCrossBackendAgentsTreeRoots(\n options: CrossBackendAgentsTreeRootsOptions = {},\n): string[] {\n const homeDir = options.homeDir;\n const env = options.env ?? process.env;\n const resolvedHome = homeDir ?? env.HOME ?? homedir();\n const configRoots = new Set([\n resolveGlobalConfigDir(env, resolvedHome),\n join(resolvedHome, \".letta\"),\n ]);\n const localBackendStorageDir =\n options.localBackendStorageDir ?? getLocalBackendStorageDir(homeDir, env);\n const roots = new Set<string>();\n\n for (const configRoot of configRoots) {\n roots.add(canonicalizeRoot(join(configRoot, \"agents\")));\n }\n roots.add(\n canonicalizeRoot(getLocalBackendCrossAgentTreeRoot(localBackendStorageDir)),\n );\n for (const configRoot of configRoots) {\n roots.add(\n canonicalizeRoot(\n getLocalBackendCrossAgentTreeRoot(join(configRoot, \"lc-local-backend\")),\n ),\n );\n }\n\n return [...roots];\n}\n\n/**\n * The harness state directory, e.g. `/Users/me/.letta`. Used as the broad\n * writable base for memory subagents: they may write harness metadata anywhere\n * under it (settings, logs, conversations, transcripts, memory) but not the\n * repo/home/temp — while the cross-agent tree nested inside it stays denied.\n */\nexport function getLettaHomeRoot(\n homeDir?: string,\n env: NodeJS.ProcessEnv = process.env,\n): string {\n const configDir =\n homeDir === undefined || hasGlobalConfigDirOverride(env)\n ? resolveGlobalConfigDir(env, homeDir)\n : join(homeDir, \".letta\");\n return canonicalizeRoot(configDir);\n}\n\n/**\n * Resolve a path to the real (symlink-free) path the kernel will see. The leaf\n * may not exist yet (a file about to be created), so we realpath the nearest\n * existing ancestor and re-append the missing tail.\n */\nexport function canonicalizeRoot(input: string): string {\n const abs = isAbsolute(input) ? input : resolve(input);\n\n let dir = abs;\n const tail: string[] = [];\n while (!existsSync(dir)) {\n tail.unshift(basename(dir));\n const parent = dirname(dir);\n if (parent === dir) {\n // Reached the filesystem root without finding an existing ancestor.\n return normalizeSandboxPath(abs);\n }\n dir = parent;\n }\n\n try {\n const real = realpathSync(dir);\n return normalizeSandboxPath(tail.length ? join(real, ...tail) : real);\n } catch {\n return normalizeSandboxPath(abs);\n }\n}\n\n/** Whether a canonical path is the given root or nested inside it. */\nfunction isWithinRoot(path: string, root: string): boolean {\n return path === root || path.startsWith(`${root}/`);\n}\n\nfunction isAncestorOfRoot(path: string, root: string): boolean {\n const prefix = path === \"/\" ? \"/\" : `${path}/`;\n return root.startsWith(prefix);\n}\n\n/**\n * True when a canonical path IS one of the trees or an ancestor of one. Such a\n * path must never be carved back out: re-exposing a whole tree (or an ancestor\n * that contains it) would re-expose the denied roots under bwrap's\n * last-mount-wins semantics, and is too broad under Seatbelt as well.\n */\nfunction isTreeOrAncestorOfTree(\n path: string,\n canonicalTrees: string[],\n): boolean {\n return canonicalTrees.some(\n (tree) => path === tree || isAncestorOfRoot(path, tree),\n );\n}\n\n/**\n * Resolve the caller-supplied agents trees (canonicalizing each), or fall back\n * to both backend trees when none were given. Shared by the policy builders.\n */\nfunction resolveAgentsTreeRootsInput(roots?: string[]): string[] {\n return roots?.length\n ? roots.map(canonicalizeRoot)\n : getCrossBackendAgentsTreeRoots();\n}\n\n/**\n * Map memory roots to the agent directories to carve out of the walled-off\n * agents tree. A memory root under the tree\n * (`~/.letta/agents/<id>/memory[-worktrees]`) yields the whole agent dir\n * (`~/.letta/agents/<id>`); carving the *agent dir* rather than just `/memory`\n * keeps the cwd's immediate parent traversable, so a read-deny on the tree does\n * not empty the child env under Seatbelt. Roots outside the tree (a custom\n * `MEMORY_DIR`) are returned as-is.\n */\nexport function deriveSelfAgentRootsForTrees(\n memoryRoots: string[],\n agentsTreeRoots: string[] = getCrossBackendAgentsTreeRoots(),\n): string[] {\n const canonicalTrees = agentsTreeRoots.map(canonicalizeRoot);\n const out = new Set<string>();\n for (const root of memoryRoots) {\n const canon = canonicalizeRoot(root);\n const containingTree = canonicalTrees.find(\n (tree) => canon !== tree && isWithinRoot(canon, tree),\n );\n if (containingTree) {\n // A memory root nested inside a tree: carve back the whole agent dir so\n // the cwd's immediate parent stays traversable (Seatbelt empty-env bug).\n const leaf = basename(canon);\n const parentLeaf = basename(dirname(canon));\n out.add(\n leaf === \"memory\" || leaf === \"memory-worktrees\"\n ? dirname(canon)\n : parentLeaf === \"memory-worktrees\" ||\n (parentLeaf === \"memory\" && leaf === \".git\")\n ? dirname(dirname(canon))\n : canon,\n );\n continue;\n }\n // Outside every tree: keep as-is, unless it's a tree itself or an ancestor\n // of one (carving those back out would re-expose the denied tree).\n if (!isTreeOrAncestorOfTree(canon, canonicalTrees)) {\n out.add(canon);\n }\n }\n return [...out];\n}\n\nfunction deriveWritableMemoryRootsForTrees(\n memoryRoots: string[],\n agentsTreeRoots: string[],\n): string[] {\n const canonicalTrees = agentsTreeRoots.map(canonicalizeRoot);\n const out = new Set<string>();\n for (const root of memoryRoots) {\n const canon = canonicalizeRoot(root);\n const isExactDeniedTree = canonicalTrees.includes(canon);\n const isInsideDeniedTree = canonicalTrees.some(\n (tree) => canon !== tree && isWithinRoot(canon, tree),\n );\n\n // A legitimate self-memory root can be both inside the primary agents tree\n // and an ancestor of a second nested denied tree. The sandbox backends now\n // remask nested denies after restores, so keep that self root writable.\n // Continue rejecting a whole denied tree and broad outside ancestors such\n // as HOME or `/`, which are never valid memory-scoped write carves.\n if (\n !isExactDeniedTree &&\n (isInsideDeniedTree || !isTreeOrAncestorOfTree(canon, canonicalTrees))\n ) {\n out.add(canon);\n }\n }\n return [...out];\n}\n\nexport interface MemorySubagentSandboxInput {\n /**\n * Memory roots the child may write to — typically the resolved\n * `MEMORY_DIR` plus its `memory-worktrees` sibling.\n */\n memoryRoots: string[];\n /** Additional roots to carve back read-only after denying agents trees. */\n readonlyRoots?: string[];\n /**\n * Harness state roots configured OUTSIDE `~/.letta` to also make writable —\n * `~/.letta` itself is always the base. The caller passes a custom\n * `LETTA_LOCAL_BACKEND_DIR` / `LETTA_TRANSCRIPT_ROOT` here so the in-process\n * child can still persist conversation/agent-state/transcripts when those are\n * relocated off the default tree. Usually empty (the defaults live under\n * `~/.letta`).\n */\n harnessWritableRoots?: string[];\n /**\n * The agents trees to wall off + carve self out of. Defaults to both\n * `~/.letta/agents` (API/cloud) and `lc-local-backend/memfs` (local). Each\n * agent's memory lives at `<tree>/<id>/memory` on both, so\n * {@link deriveSelfAgentRootsForTrees} carves the same way regardless of\n * backend.\n *\n * Resolved by the caller's layer (`tools/` / `agent/`, which may import\n * `backend/`): `permissions/` sits below `backend/`, so this builder takes the\n * already-resolved path rather than branching on a backend it cannot import.\n */\n agentsTreeRoots?: string[];\n}\n\n/**\n * Policy for the memory-subagent launch profile: it may read the filesystem broadly to do\n * its work, write only under the harness state dir (`~/.letta`), and not read or\n * write *other* agents' memory.\n *\n * The whole subagent process runs under this policy, so it is the sole\n * enforcement for these agents — the static guard is skipped for them. It covers\n * both axes:\n * - writes: `restrictWrites` denies writes everywhere except the base\n * `~/.letta` carve (and self memory). This scopes the agent's\n * non-deterministic work — it can persist memory + harness metadata\n * (settings, logs, conversations, transcripts) but cannot write the repo,\n * home, or temp. Carving the WHOLE `~/.letta` rather than enumerating each\n * harness file is deliberate: the harness writes many paths under it and the\n * set is unbounded, so a per-file carve would silently break as new writers\n * appear. The cross-agent tree nested inside `~/.letta` stays denied.\n * - cross-agent reads: the agents tree is read+write denied, with the agent's\n * own (and inherited parent's) directory carved back out READ-only.\n *\n * Carving the whole agent *directory* readable — not just `/memory` — is what\n * lets us deny the tree without re-triggering the empty-env bug: the subagent's\n * cwd is its memory dir inside the agents tree, and under Seatbelt a child\n * launches with an EMPTY environment if a cwd *ancestor* is read-denied. With\n * the agent dir (the cwd's immediate parent) readable, process init can traverse\n * to the cwd and the env survives.\n *\n * Both backend trees are denied by default so cloud/API agents cannot read local\n * agent memories and local agents cannot read cloud/API memories. Self memory is\n * re-carved writable in `writableRoots` because it is nested inside a denied\n * tree (the base `~/.letta` carve is overridden there by the deny).\n */\nexport function buildMemorySubagentSandboxPolicy(\n input: MemorySubagentSandboxInput,\n): FsSandboxPolicy {\n const agentsTreeRoots = resolveAgentsTreeRootsInput(input.agentsTreeRoots);\n\n // Writes are scoped to the harness state dir. `~/.letta` is the always-on base\n // (covers settings/logs/conversations/transcripts/memory under the defaults);\n // `harnessWritableRoots` adds any harness root relocated OUTSIDE `~/.letta`\n // (custom LETTA_LOCAL_BACKEND_DIR / LETTA_TRANSCRIPT_ROOT). These are emitted\n // BEFORE the cross-agent deny, so the nested tree is still walled off.\n const baseWritableRoots = [\n getLettaHomeRoot(),\n ...(input.harnessWritableRoots ?? []),\n ].map(canonicalizeRoot);\n\n return buildFsSandboxPolicy({\n baseWritableRoots,\n deniedRoots: agentsTreeRoots,\n readonlyRoots: [\n ...deriveSelfAgentRootsForTrees(input.memoryRoots, agentsTreeRoots),\n ...(input.readonlyRoots ?? []).map(canonicalizeRoot),\n ],\n // Self memory is nested inside the denied tree; re-carve it writable so the\n // deny (which overrides the base ~/.letta carve there) is itself overridden.\n writableRoots: deriveWritableMemoryRootsForTrees(\n input.memoryRoots,\n agentsTreeRoots,\n ),\n restrictWrites: true,\n });\n}\n\nexport interface CrossAgentSandboxInput {\n /**\n * Directories the agent may freely read+write inside the walled-off agents\n * tree — typically its own agent directory (`~/.letta/agents/<self-id>`).\n */\n selfRoots: string[];\n /** The agents trees to wall off (read+write). Defaults to both backends. */\n agentsTreeRoots?: string[];\n}\n\n/**\n * Policy for a normal agent that may use the whole filesystem but must not read\n * or write *other* agents' memory. This is the kernel-enforced replacement for\n * the static cross-agent guard.\n *\n * Walls off both backend agents trees (read + write) and carves the agent's own\n * directory back out. Writes elsewhere — the repo, the home dir, temp — stay\n * allowed (`restrictWrites: false`): the only thing this policy removes is\n * access to other agents' memory, exactly like the guard it replaces.\n *\n * Unlike the memory-subagent policy, this one DOES deny reads of the agents tree.\n * That is only safe when the process cwd is outside the tree (the parent\n * agent's cwd is the repo); a cwd inside a read-denied subtree launches with an\n * empty environment under Seatbelt. Callers must enforce that precondition.\n */\nexport function buildCrossAgentSandboxPolicy(\n input: CrossAgentSandboxInput,\n): FsSandboxPolicy {\n const agentsTreeRoots = resolveAgentsTreeRootsInput(input.agentsTreeRoots);\n\n return buildFsSandboxPolicy({\n deniedRoots: agentsTreeRoots,\n writableRoots: input.selfRoots.map(canonicalizeRoot),\n restrictWrites: false,\n });\n}\n",
|
|
7
|
+
"import { posix, win32 } from \"node:path\";\n\n/**\n * A filesystem sandbox policy, expressed entirely in concrete absolute paths.\n *\n * This module is a pure leaf: it knows nothing about agents, launch profiles, or\n * how paths are derived. Callers resolve agent ids / memory roots into paths\n * (via `@/permissions/memory-paths`) and hand the finished policy here. That\n * keeps the OS-specific generators (`seatbelt.ts`, `bwrap.ts`) trivially\n * testable and out of the domain layer graph.\n *\n * Enforcement semantics (both backends implement the same model):\n *\n * - `baseWritableRoots` write re-allowed under these, emitted BEFORE\n * `deniedRoots` so a denied root nested inside still wins.\n * Used to grant a broad harness dir (e.g. all of\n * `~/.letta`) while keeping the cross-agent tree denied —\n * so a memory subagent may write harness state anywhere\n * under `~/.letta` but not the repo/home/temp.\n * - `deniedRoots` read + write denied (e.g. `~/.letta/agents`).\n * - `readonlyRoots` read re-allowed, write stays denied. Overrides denied.\n * - `writableRoots` read + write re-allowed. Overrides denied, the global\n * write-deny, AND `baseWritableRoots` — for a self carve\n * nested inside a denied root (self memory).\n * - `restrictWrites` when true, writes are denied *everywhere* except\n * `baseWritableRoots`/`writableRoots` (write-scoped profile). When\n * false, writes are allowed by default except under\n * `deniedRoots` (cross-agent profile — the normal agent that\n * simply may not touch other agents' memory).\n *\n * Reads are never globally restricted: an agent can read the whole filesystem\n * to do its work, minus the other-agent directories in `deniedRoots`.\n *\n * Specificity is expressed through ordering, not nesting depth. The emitted\n * order is: global write-deny → `baseWritableRoots` → the remaining denied and\n * self-carve rules from broadest path to narrowest path. This permits the\n * required deny → outer self → nested deny → inner self alternation while\n * keeping the most specific path authoritative.\n */\nexport interface FsSandboxPolicy {\n baseWritableRoots: string[];\n deniedRoots: string[];\n readonlyRoots: string[];\n writableRoots: string[];\n restrictWrites: boolean;\n}\n\n/** Backend tag, also the value of the `LETTA_SANDBOX` env sentinel. */\nexport type SandboxBackend = \"seatbelt\" | \"bwrap\";\n\n/**\n * Env var set inside a sandboxed process. Mirrors Codex's `CODEX_SANDBOX`.\n * Tools and nested logic can read it to detect that they are already confined\n * (and, for the re-exec pattern, to avoid wrapping themselves twice).\n */\nexport const SANDBOX_ENV_VAR = \"LETTA_SANDBOX\";\n\nexport interface BuildPolicyOptions {\n /**\n * Broad write carves emitted BEFORE `deniedRoots` (a nested deny still wins).\n * e.g. all of `~/.letta` so a memory subagent can write harness state but not\n * the repo/home/temp.\n */\n baseWritableRoots?: string[];\n /** Roots to wall off (read+write), e.g. `~/.letta/agents`. */\n deniedRoots?: string[];\n /** Paths to re-expose read-only (e.g. a subagent's parent memory dir). */\n readonlyRoots?: string[];\n /** Paths to re-expose read-write (self agent/memory dir, $TMPDIR, /tmp). */\n writableRoots?: string[];\n /** Memory mode: deny writes everywhere except the writable roots. */\n restrictWrites?: boolean;\n}\n\n/**\n * Assemble an {@link FsSandboxPolicy} from plain paths, normalizing and\n * de-duplicating each set. Pure — no filesystem or agent-context access.\n */\nexport function buildFsSandboxPolicy(\n options: BuildPolicyOptions,\n): FsSandboxPolicy {\n return {\n baseWritableRoots: normalizeRoots(options.baseWritableRoots ?? []),\n deniedRoots: normalizeRoots(options.deniedRoots ?? []),\n readonlyRoots: normalizeRoots(options.readonlyRoots ?? []),\n writableRoots: normalizeRoots(options.writableRoots ?? []),\n restrictWrites: options.restrictWrites ?? false,\n };\n}\n\nexport type SandboxPathRuleKind = \"deny\" | \"readonly\" | \"writable\";\n\nexport interface SandboxPathRule {\n kind: SandboxPathRuleKind;\n root: string;\n /** Index in the corresponding policy array, used for stable backend names. */\n index: number;\n}\n\n/**\n * Compile deny/self-carve rules in broad-to-narrow path order.\n *\n * Both sandbox backends use last-rule/mount-wins semantics. Sorting by depth\n * supports alternating overlap shapes such as primary deny → outer self carve\n * → nested backend deny → inner backend self carve. For an exact same path,\n * deny sorts last and therefore fails closed.\n */\nexport function getOrderedSandboxPathRules(\n policy: FsSandboxPolicy,\n): SandboxPathRule[] {\n const rules: SandboxPathRule[] = [];\n const append = (kind: SandboxPathRuleKind, roots: string[]) => {\n roots.forEach((root, index) => {\n rules.push({ kind, root, index });\n });\n };\n\n append(\"deny\", policy.deniedRoots);\n append(\"readonly\", policy.readonlyRoots);\n append(\"writable\", policy.writableRoots);\n\n const samePathPriority: Record<SandboxPathRuleKind, number> = {\n readonly: 0,\n writable: 1,\n deny: 2,\n };\n const depth = (root: string) => root.split(\"/\").filter(Boolean).length;\n\n return rules.sort((a, b) => {\n const depthDifference = depth(a.root) - depth(b.root);\n if (depthDifference !== 0) return depthDifference;\n const pathDifference = a.root.localeCompare(b.root);\n if (pathDifference !== 0) return pathDifference;\n return samePathPriority[a.kind] - samePathPriority[b.kind];\n });\n}\n\n/**\n * Normalize a path for use in a sandbox rule: absolute, forward slashes, no\n * trailing slash. Relative inputs are resolved against `/` so a malformed\n * policy can never silently scope a rule to the current working directory.\n */\nexport function normalizeSandboxPath(path: string): string {\n const trimmed = path.trim();\n const absolute =\n posix.isAbsolute(trimmed) || win32.isAbsolute(trimmed)\n ? trimmed\n : posix.resolve(\"/\", trimmed);\n const forward = absolute.replace(/\\\\/g, \"/\");\n return forward.replace(/\\/+$/, \"\") || \"/\";\n}\n\nfunction normalizeRoots(roots: string[]): string[] {\n const seen = new Set<string>();\n for (const root of roots) {\n if (!root || !root.trim()) continue;\n seen.add(normalizeSandboxPath(root));\n }\n return [...seen];\n}\n",
|
|
8
|
+
"import { join } from \"node:path\";\nimport {\n hasGlobalConfigDirOverride,\n resolveGlobalConfigDir,\n} from \"@/utils/settings-path\";\n\n/**\n * Env override for the local-backend storage dir (defaults to\n * `<product-config>/lc-local-backend`).\n */\nexport const LOCAL_BACKEND_DIR_ENV = \"LETTA_LOCAL_BACKEND_DIR\";\n\n/**\n * Root dir holding all local-backend on-disk state. Pure path resolution (home\n * dir + one env override).\n *\n * Lives in `utils/` (the bottom layer) so it can be shared by both `backend/`\n * — which owns the local store — and the `permissions/` cross-agent guard, which\n * sits below `backend/` and cannot import it but still needs to know where\n * local memory lives to wall off cross-agent access for in-process file tools.\n */\nexport function getLocalBackendStorageDir(\n homeDir?: string,\n env: NodeJS.ProcessEnv = process.env,\n): string {\n const configDir =\n homeDir === undefined || hasGlobalConfigDirOverride(env)\n ? resolveGlobalConfigDir(env, homeDir)\n : join(homeDir, \".letta\");\n return env[LOCAL_BACKEND_DIR_ENV] ?? join(configDir, \"lc-local-backend\");\n}\n\n/**\n * The tree holding every local-backend agent's memory (`<storage>/memfs`) — the\n * cross-agent boundary the filesystem sandbox walls off, analogous to\n * `~/.letta/agents` on the API backend. Each agent's memory lives at\n * `<this>/<agentId>/memory`, so self is carved the same way on both backends.\n */\nexport function getLocalBackendCrossAgentTreeRoot(\n storageDir: string = getLocalBackendStorageDir(),\n): string {\n return join(storageDir, \"memfs\");\n}\n",
|
|
9
|
+
"import { realpathSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join, normalize, resolve } from \"node:path\";\n\n/**\n * Resolve the process-wide config directory. Product hosts may isolate their\n * settings, credentials, and device identity without replacing HOME for every\n * child process.\n */\nexport function resolveGlobalConfigDir(\n env: NodeJS.ProcessEnv = process.env,\n fallbackHome: string = homedir(),\n): string {\n const override = env.LETTA_CONFIG_DIR?.trim();\n if (override) {\n if (!isAbsolute(override)) {\n throw new Error(\"LETTA_CONFIG_DIR must be absolute\");\n }\n return normalize(override);\n }\n return join(env.HOME || fallbackHome, \".letta\");\n}\n\nexport function resolveGlobalSettingsPath(\n env: NodeJS.ProcessEnv = process.env,\n fallbackHome: string = homedir(),\n): string {\n return join(resolveGlobalConfigDir(env, fallbackHome), \"settings.json\");\n}\n\nexport function hasGlobalConfigDirOverride(\n env: NodeJS.ProcessEnv = process.env,\n): boolean {\n return Boolean(env.LETTA_CONFIG_DIR?.trim());\n}\n\n/** Resolve product state while preserving the legacy LETTA_HOME test/cron override. */\nexport function resolveGlobalStateDir(\n env: NodeJS.ProcessEnv = process.env,\n fallbackHome: string = homedir(),\n): string {\n const legacyHome = env.LETTA_HOME?.trim();\n if (!hasGlobalConfigDirOverride(env) && legacyHome)\n return normalize(legacyHome);\n return resolveGlobalConfigDir(env, fallbackHome);\n}\n\nexport function isHomeWorkingDirectory(\n workingDirectory: string,\n env: NodeJS.ProcessEnv = process.env,\n fallbackHome: string = homedir(),\n): boolean {\n const canonicalize = (path: string): string => {\n const absolutePath = resolve(path);\n try {\n return realpathSync.native(absolutePath);\n } catch {\n return absolutePath;\n }\n };\n return (\n canonicalize(workingDirectory) === canonicalize(env.HOME || fallbackHome)\n );\n}\n\nexport function shouldIsolateHomeProjectConfig(\n workingDirectory: string,\n env: NodeJS.ProcessEnv = process.env,\n fallbackHome: string = homedir(),\n): boolean {\n return (\n hasGlobalConfigDirOverride(env) &&\n isHomeWorkingDirectory(workingDirectory, env, fallbackHome)\n );\n}\n\nexport function isProjectSettingsPathGlobal(\n workingDirectory: string,\n env: NodeJS.ProcessEnv = process.env,\n fallbackHome: string = homedir(),\n): boolean {\n return (\n isHomeWorkingDirectory(workingDirectory, env, fallbackHome) ||\n resolve(workingDirectory, \".letta\", \"settings.json\") ===\n resolveGlobalSettingsPath(env, fallbackHome)\n );\n}\n",
|
|
10
|
+
"import { type FsSandboxPolicy, getOrderedSandboxPathRules } from \"./policy.js\";\n\n/**\n * Linux bubblewrap backend.\n *\n * We shell out to `bwrap`, building a mount namespace that mirrors the same\n * policy model as Seatbelt:\n *\n * - The root filesystem is bound `--ro-bind` (write-scoped profile,\n * default-deny writes) or `--bind` (cross-agent profile, default-allow writes). This single\n * choice implements `restrictWrites` for free: under a read-only root, the\n * only writable paths are the explicit `--bind` carveouts.\n * - Each denied root is masked with `--tmpfs`, so other agents' directories\n * are not merely unwritable but *absent* — unreadable and unenumerable,\n * strictly stronger than the static guard.\n * - readonly / writable carveouts are re-bound on top. bwrap creates the\n * mountpoints inside the tmpfs as needed, so a self-memory dir nested in a\n * masked agents tree reappears.\n *\n * No `--unshare-net`: network stays open (out of scope for memory isolation).\n * `--die-with-parent` ensures the sandbox tears down with the agent process,\n * backing up the process-group kill in `shell-runner.ts`.\n *\n * Mount order matters — later operations layer over earlier ones: root → dev →\n * proc → base writable → broad-to-narrow deny/self rules.\n * The base-writable binds come BEFORE the masks so a denied root nested inside a\n * broad base carve (the cross-agent tree under `~/.letta`) is still masked.\n */\n\n/** Default discovery name; availability probing may substitute a bundled path. */\nexport const BWRAP_BIN = \"bwrap\";\n\n/**\n * Build the bwrap flag list (everything between the binary and the `--`\n * separator). The caller prepends the bwrap path and appends\n * `\"--\"` + the inner launcher.\n */\nexport function buildBwrapArgs(policy: FsSandboxPolicy): string[] {\n const args: string[] = [];\n\n // Root view: read-only for write-scoped profiles, writable for cross-agent.\n args.push(policy.restrictWrites ? \"--ro-bind\" : \"--bind\", \"/\", \"/\");\n\n // Minimal writable /dev (gives us /dev/null, /dev/urandom, ptys) and a fresh\n // /proc so the masked root doesn't leak host process state.\n args.push(\"--dev\", \"/dev\");\n args.push(\"--proc\", \"/proc\");\n\n // Base writable roots: re-bind a broad harness dir (~/.letta) read-write on top\n // of the read-only root. Emitted BEFORE the masks below so a denied root nested\n // inside (the cross-agent tree) is still masked — the ancestor-carve hazard is\n // intentional and safe HERE precisely because the mask runs last. `-try` for\n // the same not-yet-created tolerance as the other carves.\n for (const root of policy.baseWritableRoots) {\n args.push(\"--bind-try\", root, root);\n }\n\n // Apply deny and self-carve rules from broadest path to narrowest path. This\n // supports alternating overlap shapes (deny → outer self → nested deny →\n // inner self) without erasing a legitimate inner carve. Use `-try` binds so a\n // lazily-created memory root does not abort the entire spawn.\n for (const rule of getOrderedSandboxPathRules(policy)) {\n switch (rule.kind) {\n case \"deny\":\n args.push(\"--tmpfs\", rule.root);\n break;\n case \"readonly\":\n args.push(\"--ro-bind-try\", rule.root, rule.root);\n break;\n case \"writable\":\n args.push(\"--bind-try\", rule.root, rule.root);\n break;\n }\n }\n\n args.push(\"--die-with-parent\");\n return args;\n}\n",
|
|
11
|
+
"import { type FsSandboxPolicy, getOrderedSandboxPathRules } from \"./policy.js\";\n\n/**\n * macOS Seatbelt backend.\n *\n * We shell out to `/usr/bin/sandbox-exec` with an inline SBPL profile (`-p`).\n * Concrete paths are passed as `-D` parameters and referenced in the profile as\n * `(param \"NAME\")`, so the profile text never needs SBPL string escaping and\n * paths with spaces / quotes are safe (we spawn argv directly, no shell).\n *\n * The profile is `(allow default)` plus targeted denies — deliberately narrower\n * than Codex's Chrome-derived `(deny default)` base. Our threat model is\n * filesystem scoping for memory isolation, not general untrusted-code\n * confinement, so allow-default keeps network, signals, ttys, and arbitrary dev\n * tools working untouched while the FS rules do the isolation. SBPL is\n * last-match-wins, which is why the deny/allow ordering below matters.\n */\n\n/** Hardcoded path — never resolved via PATH, to defend against a planted\n * `sandbox-exec` earlier on PATH (same rationale as Codex). */\nexport const SANDBOX_EXEC_PATH = \"/usr/bin/sandbox-exec\";\n\ninterface SeatbeltDefine {\n name: string;\n value: string;\n}\n\n/**\n * Build the SBPL profile text plus the `-D NAME=value` defines it references.\n * Exposed for snapshot testing; `buildSeatbeltArgs` is what callers use.\n */\nexport function buildSeatbeltProfile(policy: FsSandboxPolicy): {\n profile: string;\n defines: SeatbeltDefine[];\n} {\n const defines: SeatbeltDefine[] = [];\n const lines: string[] = [\"(version 1)\", \"(allow default)\"];\n\n // 1. Memory mode: deny all writes globally. Keep device writes (/dev/null,\n // ttys, pipes) working — countless tools depend on them and they are\n // irrelevant to filesystem isolation.\n if (policy.restrictWrites) {\n lines.push('(deny file-write* (subpath \"/\"))');\n lines.push('(allow file-write* (subpath \"/dev\"))');\n }\n\n // 2. Base writable roots: re-allow writes under a broad harness dir (~/.letta).\n // Emitted AFTER the global write-deny but BEFORE the denied roots, so a\n // cross-agent tree nested inside still gets walled off in step 3.\n policy.baseWritableRoots.forEach((root, i) => {\n const name = `BASEWRITABLE_${i}`;\n defines.push({ name, value: root });\n lines.push(`(allow file-write* (subpath (param \"${name}\")))`);\n });\n\n // 3. Apply deny and self-carve rules from broadest path to narrowest path.\n // Seatbelt is last-match-wins, so an alternating overlap shape remains:\n // primary deny → outer self → nested deny → inner self.\n for (const rule of getOrderedSandboxPathRules(policy)) {\n const prefix =\n rule.kind === \"deny\"\n ? \"DENIED\"\n : rule.kind === \"readonly\"\n ? \"READONLY\"\n : \"WRITABLE\";\n const name = `${prefix}_${rule.index}`;\n defines.push({ name, value: rule.root });\n\n if (rule.kind === \"deny\") {\n lines.push(`(deny file-read* file-write* (subpath (param \"${name}\")))`);\n // Git linked worktrees may stat denied ancestor directories while\n // resolving an allowed worktree path. Metadata does not expose contents.\n lines.push(`(allow file-read-metadata (literal (param \"${name}\")))`);\n } else if (rule.kind === \"readonly\") {\n // Revoke a broader writable ancestor before re-allowing reads. A still\n // narrower writable descendant is emitted later and can opt back in.\n lines.push(`(deny file-write* (subpath (param \"${name}\")))`);\n lines.push(`(allow file-read* (subpath (param \"${name}\")))`);\n } else {\n lines.push(`(allow file-read* file-write* (subpath (param \"${name}\")))`);\n }\n }\n\n return { profile: `${lines.join(\"\\n\")}\\n`, defines };\n}\n\n/**\n * Build the argv tail for `sandbox-exec`: `[\"-p\", <profile>, \"-DNAME=value\",\n * ...]`. The caller prepends {@link SANDBOX_EXEC_PATH} and appends\n * `\"--\"` + the inner launcher.\n */\nexport function buildSeatbeltArgs(policy: FsSandboxPolicy): string[] {\n const { profile, defines } = buildSeatbeltProfile(policy);\n const args = [\"-p\", profile];\n for (const { name, value } of defines) {\n args.push(`-D${name}=${value}`);\n }\n return args;\n}\n",
|
|
11
12
|
"import { BWRAP_BIN, buildBwrapArgs } from \"./bwrap.js\";\nimport type { FsSandboxPolicy, SandboxBackend } from \"./policy.js\";\nimport { buildSeatbeltArgs, SANDBOX_EXEC_PATH } from \"./seatbelt.js\";\n\nexport interface WrapOptions {\n /** Which backend to render for. `null` disables wrapping (returns null). */\n backend: SandboxBackend | null;\n /** Resolved bwrap binary path (system or bundled). Defaults to `bwrap`. */\n bwrapPath?: string;\n}\n\n/**\n * Wrap an inner launcher (e.g. `[\"/bin/zsh\", \"-c\", cmd]`) so it runs under the\n * given sandbox backend with the given policy. Returns the wrapped argv, or\n * `null` when no backend is available — in which case the caller spawns the\n * launcher unchanged (falling back to the static guard tier).\n *\n * Backend selection is the caller's job (see `availability.ts`); this function\n * only renders argv, which keeps it a pure, snapshot-testable transform.\n */\nexport function wrapLauncher(\n launcher: string[],\n policy: FsSandboxPolicy,\n options: WrapOptions,\n): string[] | null {\n if (!options.backend) return null;\n if (launcher.length === 0) return null;\n\n switch (options.backend) {\n case \"seatbelt\":\n return [\n SANDBOX_EXEC_PATH,\n ...buildSeatbeltArgs(policy),\n \"--\",\n ...launcher,\n ];\n case \"bwrap\":\n return [\n options.bwrapPath ?? BWRAP_BIN,\n ...buildBwrapArgs(policy),\n \"--\",\n ...launcher,\n ];\n }\n}\n",
|
|
12
13
|
"import { spawnSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { delimiter, isAbsolute, join } from \"node:path\";\nimport type { SandboxBackend } from \"./policy.js\";\nimport { SANDBOX_EXEC_PATH } from \"./seatbelt.js\";\n\nexport interface SandboxAvailability {\n /** The usable backend, or null when none is available on this host. */\n backend: SandboxBackend | null;\n /** Resolved bwrap binary path, when `backend === \"bwrap\"`. */\n bwrapPath?: string;\n /** Human-readable explanation, primarily for the null case. */\n reason: string;\n}\n\nexport interface DetectOptions {\n /** Override the platform (for tests). Defaults to `process.platform`. */\n platform?: NodeJS.Platform;\n /** Bypass the module-level cache (for tests / re-probing). */\n force?: boolean;\n}\n\nlet cached: SandboxAvailability | null = null;\nconst warnedUnavailableContexts = new Set<string>();\n\n/**\n * Detect which filesystem-sandbox backend works on this host, probing for real\n * (Seatbelt: binary presence; bwrap: an actual user-namespace mount probe).\n * Result is cached for the process since it cannot change mid-run.\n */\nexport function detectSandboxBackend(\n options: DetectOptions = {},\n): SandboxAvailability {\n const platform = options.platform ?? process.platform;\n\n if (!options.force && cached && !options.platform) {\n return cached;\n }\n\n const result = probe(platform);\n\n if (!options.platform) {\n cached = result;\n }\n return result;\n}\n\n/** Clear the cached probe result (tests only). */\nexport function resetSandboxAvailabilityCache(): void {\n cached = null;\n}\n\n/**\n * Whether the memory-subagent filesystem sandbox is enabled. It is **on by\n * default**: memory subagents (reflection, memory, init) run\n * as whole confined processes with a scoped write surface, and there is no\n * interactive approve/deny flow that could stand in for it. Set\n * `LETTA_FS_SANDBOX=0` (or `false`) to opt out entirely. When no backend is\n * available on the host, {@link detectSandboxBackend} returns `{backend:null}`\n * and every sandbox entry point no-ops regardless of this flag.\n *\n * Lives in this leaf so both subagent spawning (agent layer) and parent Bash\n * wrapping (tools layer) gate on the same env var without importing each other.\n */\nexport function isFsSandboxEnabled(\n env: NodeJS.ProcessEnv = process.env,\n): boolean {\n const value = env.LETTA_FS_SANDBOX?.trim().toLowerCase();\n // Default on: only an explicit off-switch disables it.\n return value !== \"0\" && value !== \"false\";\n}\n\n/**\n * Whether the cross-agent shell sandbox (per-shell-command confinement of the\n * agent process's spawned shells) is enabled. It is **off by default**: an\n * interactive agent's own shells walling off other agents' memory broke\n * legitimate workflows (agents inspecting `~/.letta/agents`) with kernel\n * `Operation not permitted` errors that no permission mode could approve\n * through. Set `LETTA_FS_SANDBOX=1` (or `true`) to opt in — recommended for\n * multi-tenant deployments (app server, experiment runners) where one host\n * runs many agents that must not read each other's memory.\n *\n * `LETTA_FS_SANDBOX` semantics across both checks:\n * - unset → memory subagents sandboxed; agent shells unconfined\n * - `1`/`true` → both sandboxed\n * - `0`/`false` → nothing sandboxed\n */\nexport function isShellSandboxEnabled(\n env: NodeJS.ProcessEnv = process.env,\n): boolean {\n const value = env.LETTA_FS_SANDBOX?.trim().toLowerCase();\n // Opt-in only: an explicit on-switch enables it.\n return value === \"1\" || value === \"true\";\n}\n\n/**\n * Emit a loud, once-per-process warning when sandboxing was requested but this\n * host cannot provide a kernel backend. We intentionally continue rather than\n * fail closed: users can still work, but should know filesystem isolation is\n * degraded on this host.\n */\nexport function warnSandboxBackendUnavailable(\n availability: SandboxAvailability,\n context: string,\n): void {\n if (availability.backend) return;\n const key = `${context}:${availability.reason}`;\n if (warnedUnavailableContexts.has(key)) return;\n warnedUnavailableContexts.add(key);\n console.warn(\n `[sandbox] WARNING: ${context} requested filesystem isolation, but no ` +\n `kernel sandbox backend is available (${availability.reason}). ` +\n `Continuing without filesystem sandbox isolation.`,\n );\n}\n\nfunction probe(platform: NodeJS.Platform): SandboxAvailability {\n if (platform === \"darwin\") {\n if (existsSync(SANDBOX_EXEC_PATH)) {\n return { backend: \"seatbelt\", reason: \"sandbox-exec available\" };\n }\n return {\n backend: null,\n reason: `${SANDBOX_EXEC_PATH} not found`,\n };\n }\n\n if (platform === \"linux\") {\n return probeBwrap();\n }\n\n return {\n backend: null,\n reason: `no filesystem sandbox backend for platform \"${platform}\"`,\n };\n}\n\nfunction probeBwrap(): SandboxAvailability {\n // `bwrap` must exist on PATH (a bundled fallback can be wired in later).\n const bwrapPath = resolveExecutableOnPath(\"bwrap\");\n if (!bwrapPath) {\n return { backend: null, reason: \"bwrap not found on PATH\" };\n }\n\n const version = spawnSync(bwrapPath, [\"--version\"], { timeout: 5000 });\n if (version.error || version.status !== 0) {\n return { backend: null, reason: \"bwrap not found on PATH\" };\n }\n\n // Confirm unprivileged user namespaces actually work (they don't in WSL1 or\n // some hardened/container hosts). A read-only root + /bin/true is the\n // cheapest mount that exercises the namespace machinery.\n const userns = spawnSync(\n bwrapPath,\n [\"--ro-bind\", \"/\", \"/\", \"--unshare-user\", \"/bin/true\"],\n { timeout: 5000 },\n );\n if (userns.error || userns.status !== 0) {\n return {\n backend: null,\n reason: \"bwrap present but user namespaces are unavailable\",\n };\n }\n\n return { backend: \"bwrap\", bwrapPath, reason: \"bwrap available\" };\n}\n\nfunction resolveExecutableOnPath(\n executable: string,\n envPath: string | undefined = process.env.PATH,\n): string | null {\n if (isAbsolute(executable) && existsSync(executable)) return executable;\n for (const dir of (envPath ?? \"\").split(delimiter)) {\n if (!dir) continue;\n const candidate = join(dir, executable);\n if (existsSync(candidate)) return candidate;\n }\n return null;\n}\n",
|
|
13
14
|
"import {\n createMemoryConfinementLauncherWithAvailability,\n type MemoryConfinementLauncherInput,\n type MemoryConfinementLauncherResult,\n} from \"@/permissions/memory-confinement-launcher\";\nimport { detectSandboxBackend } from \"@/sandbox/availability\";\n\nexport type {\n MemoryConfinementLauncherInput,\n MemoryConfinementLauncherResult,\n} from \"@/permissions/memory-confinement-launcher\";\n\n/**\n * Wrap a process in the same fail-closed filesystem policy used by Letta\n * Code's unattended memory subagents.\n *\n * The process can read the host broadly, write harness state and its own\n * memory, and cannot read or write other agents' memory. Throws when no\n * supported kernel sandbox is available rather than silently running with a\n * weaker policy.\n */\nexport function createMemoryConfinementLauncher(\n input: MemoryConfinementLauncherInput,\n): MemoryConfinementLauncherResult {\n return createMemoryConfinementLauncherWithAvailability(\n input,\n detectSandboxBackend(),\n );\n}\n"
|
|
14
15
|
],
|
|
15
|
-
"mappings": "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",
|
|
16
|
-
"debugId": "
|
|
16
|
+
"mappings": "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",
|
|
17
|
+
"debugId": "8EA4D35C8AB0C06C64756E2164756E21",
|
|
17
18
|
"names": []
|
|
18
19
|
}
|
|
@@ -39,6 +39,7 @@ export declare function isValidUpdatedAtMs(updatedAtMs: unknown, nowMs: number):
|
|
|
39
39
|
/** Test-only: point persistence at a fixture path (null = in-memory only). */
|
|
40
40
|
export declare function configureAuthorityPersistencePathForTests(path: string | null): void;
|
|
41
41
|
export declare function authorityPersistentPath(): string | null;
|
|
42
|
+
export declare function authorityPersistentPathForServer(serverUrl: string): string;
|
|
42
43
|
export declare const STATE_RANK: Record<McpOriginatorAuthorityState, number>;
|
|
43
44
|
/**
|
|
44
45
|
* Merge a durable retirement intent under the same monotonicity as the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-originator-authority-file.d.ts","sourceRoot":"","sources":["../../../src/agent/mcp-originator-authority-file.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmBH,MAAM,MAAM,2BAA2B,GAAG,MAAM,GAAG,YAAY,GAAG,UAAU,CAAC;AAE7E,uDAAuD;AACvD,MAAM,MAAM,4BAA4B,GAAG,OAAO,CAChD,2BAA2B,EAC3B,MAAM,CACP,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,2BAA2B,CAAC;IACnC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,4BAA4B,CAAC;IAC1C,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,OAAO,GAAG,UAAU,IAAI,MAAM,CAM3E;AAKD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,OAAO,EACpB,KAAK,EAAE,MAAM,GACZ,WAAW,IAAI,MAAM,CAOvB;AASD,8EAA8E;AAC9E,wBAAgB,yCAAyC,CACvD,IAAI,EAAE,MAAM,GAAG,IAAI,GAClB,IAAI,CAEN;AAED,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"mcp-originator-authority-file.d.ts","sourceRoot":"","sources":["../../../src/agent/mcp-originator-authority-file.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmBH,MAAM,MAAM,2BAA2B,GAAG,MAAM,GAAG,YAAY,GAAG,UAAU,CAAC;AAE7E,uDAAuD;AACvD,MAAM,MAAM,4BAA4B,GAAG,OAAO,CAChD,2BAA2B,EAC3B,MAAM,CACP,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,2BAA2B,CAAC;IACnC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,4BAA4B,CAAC;IAC1C,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,OAAO,GAAG,UAAU,IAAI,MAAM,CAM3E;AAKD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,OAAO,EACpB,KAAK,EAAE,MAAM,GACZ,WAAW,IAAI,MAAM,CAOvB;AASD,8EAA8E;AAC9E,wBAAgB,yCAAyC,CACvD,IAAI,EAAE,MAAM,GAAG,IAAI,GAClB,IAAI,CAEN;AAED,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAUvD;AAED,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAW1E;AAED,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,2BAA2B,EAAE,MAAM,CAIlE,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,CAAC,EAAE,4BAA4B,GAAG,SAAS,EAC3C,CAAC,EAAE,4BAA4B,GAAG,SAAS,GAC1C,4BAA4B,GAAG,SAAS,CAI1C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,CAAC,EAAE,eAAe,EAClB,CAAC,EAAE,eAAe,GAAG,SAAS,GAC7B,eAAe,CAcjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG;IAClD,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACtC,QAAQ,EAAE,OAAO,CAAC;CACnB,CAsEA;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,GACpC,IAAI,CAuBN"}
|
|
@@ -21,8 +21,8 @@ export interface MemoryTreeRenderOptions {
|
|
|
21
21
|
maxChars?: number;
|
|
22
22
|
maxChildrenPerDir?: number;
|
|
23
23
|
}
|
|
24
|
-
export declare function getMemoryFilesystemRoot(agentId: string, homeDir?: string): string;
|
|
25
|
-
export declare function getMemorySystemDir(agentId: string, homeDir?: string): string;
|
|
24
|
+
export declare function getMemoryFilesystemRoot(agentId: string, homeDir?: string, env?: NodeJS.ProcessEnv): string;
|
|
25
|
+
export declare function getMemorySystemDir(agentId: string, homeDir?: string, env?: NodeJS.ProcessEnv): string;
|
|
26
26
|
export declare function getScopedMemoryFilesystemRoot(agentId: string, options?: {
|
|
27
27
|
env?: NodeJS.ProcessEnv;
|
|
28
28
|
homeDir?: string;
|
|
@@ -43,7 +43,7 @@ export interface ResolveScopedMemoryDirOptions {
|
|
|
43
43
|
* 4. AGENT_ID env fallback
|
|
44
44
|
*/
|
|
45
45
|
export declare function resolveScopedMemoryDir(options?: ResolveScopedMemoryDirOptions): string | null;
|
|
46
|
-
export declare function ensureMemoryFilesystemDirs(agentId: string, homeDir?: string): void;
|
|
46
|
+
export declare function ensureMemoryFilesystemDirs(agentId: string, homeDir?: string, env?: NodeJS.ProcessEnv): void;
|
|
47
47
|
export interface MemfsCreateBodyLike {
|
|
48
48
|
tags?: string[] | null;
|
|
49
49
|
memory_blocks?: CreateBlock[] | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-filesystem.d.ts","sourceRoot":"","sources":["../../../src/agent/memory-filesystem.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gDAAgD,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gDAAgD,CAAC;AAClF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-filesystem.d.ts","sourceRoot":"","sources":["../../../src/agent/memory-filesystem.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,9 +19,9 @@ export interface CommitMemoryWriteResult {
|
|
|
19
19
|
committed: boolean;
|
|
20
20
|
sha?: string;
|
|
21
21
|
}
|
|
22
|
-
/** Get the agent root directory
|
|
22
|
+
/** Get the agent root directory below the active product config root. */
|
|
23
23
|
export declare function getAgentRootDir(agentId: string): string;
|
|
24
|
-
/** Get the git repo directory for memory
|
|
24
|
+
/** Get the git repo directory for memory. */
|
|
25
25
|
export declare function getMemoryRepoDir(agentId: string): string;
|
|
26
26
|
/**
|
|
27
27
|
* Normalize a configured server URL for use in git credential config keys.
|