@letta-ai/letta-code 0.21.16 → 0.21.17
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/letta.js +510 -337
- package/package.json +1 -1
- package/skills/working-in-parallel/SKILL.md +25 -10
package/letta.js
CHANGED
|
@@ -3269,7 +3269,7 @@ var package_default;
|
|
|
3269
3269
|
var init_package = __esm(() => {
|
|
3270
3270
|
package_default = {
|
|
3271
3271
|
name: "@letta-ai/letta-code",
|
|
3272
|
-
version: "0.21.
|
|
3272
|
+
version: "0.21.17",
|
|
3273
3273
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3274
3274
|
type: "module",
|
|
3275
3275
|
bin: {
|
|
@@ -9512,11 +9512,24 @@ var init_models2 = __esm(() => {
|
|
|
9512
9512
|
parallel_tool_calls: true
|
|
9513
9513
|
}
|
|
9514
9514
|
},
|
|
9515
|
+
{
|
|
9516
|
+
id: "glm-5.1",
|
|
9517
|
+
handle: "zai/glm-5.1",
|
|
9518
|
+
label: "GLM-5.1",
|
|
9519
|
+
description: "zAI's latest coding model",
|
|
9520
|
+
isFeatured: true,
|
|
9521
|
+
free: true,
|
|
9522
|
+
updateArgs: {
|
|
9523
|
+
context_window: 180000,
|
|
9524
|
+
max_output_tokens: 16000,
|
|
9525
|
+
parallel_tool_calls: true
|
|
9526
|
+
}
|
|
9527
|
+
},
|
|
9515
9528
|
{
|
|
9516
9529
|
id: "glm-5",
|
|
9517
9530
|
handle: "zai/glm-5",
|
|
9518
9531
|
label: "GLM-5",
|
|
9519
|
-
description: "zAI's latest coding model",
|
|
9532
|
+
description: "zAI's latest coding model (legacy)",
|
|
9520
9533
|
isFeatured: true,
|
|
9521
9534
|
free: true,
|
|
9522
9535
|
updateArgs: {
|
|
@@ -37960,13 +37973,17 @@ async function updateAgentLLMConfig2(agentId, modelHandle, updateArgs, options)
|
|
|
37960
37973
|
const finalAgent = await client.agents.retrieve(agentId);
|
|
37961
37974
|
return finalAgent;
|
|
37962
37975
|
}
|
|
37963
|
-
async function updateConversationLLMConfig(conversationId, modelHandle, updateArgs) {
|
|
37976
|
+
async function updateConversationLLMConfig(conversationId, modelHandle, updateArgs, options) {
|
|
37964
37977
|
const client = await getClient();
|
|
37965
37978
|
const modelSettings = buildModelSettings2(modelHandle, updateArgs);
|
|
37979
|
+
const explicitContextWindow = updateArgs?.context_window;
|
|
37980
|
+
const shouldPreserveContextWindow = options?.preserveContextWindow === true;
|
|
37981
|
+
const contextWindow = explicitContextWindow ?? (!shouldPreserveContextWindow ? await getModelContextWindow(modelHandle) : undefined);
|
|
37966
37982
|
const hasModelSettings = Object.keys(modelSettings).length > 0;
|
|
37967
37983
|
const payload = {
|
|
37968
37984
|
model: modelHandle,
|
|
37969
|
-
...hasModelSettings && { model_settings: modelSettings }
|
|
37985
|
+
...hasModelSettings && { model_settings: modelSettings },
|
|
37986
|
+
...contextWindow && { context_window_limit: contextWindow }
|
|
37970
37987
|
};
|
|
37971
37988
|
return client.conversations.update(conversationId, payload);
|
|
37972
37989
|
}
|
|
@@ -38077,7 +38094,8 @@ var init_modify = __esm(async () => {
|
|
|
38077
38094
|
var exports_create = {};
|
|
38078
38095
|
__export(exports_create, {
|
|
38079
38096
|
createAgentWithBaseToolsRecovery: () => createAgentWithBaseToolsRecovery,
|
|
38080
|
-
createAgent: () => createAgent
|
|
38097
|
+
createAgent: () => createAgent,
|
|
38098
|
+
addBaseToolsToServer: () => addBaseToolsToServer
|
|
38081
38099
|
});
|
|
38082
38100
|
function isToolsNotFoundError(err) {
|
|
38083
38101
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -38310,10 +38328,13 @@ __export(exports_memoryGit, {
|
|
|
38310
38328
|
pushMemory: () => pushMemory,
|
|
38311
38329
|
pullMemory: () => pullMemory,
|
|
38312
38330
|
normalizeCredentialBaseUrl: () => normalizeCredentialBaseUrl,
|
|
38331
|
+
maybeUpdateMemoryRemoteOrigin: () => maybeUpdateMemoryRemoteOrigin,
|
|
38313
38332
|
isRetryableGitTransientError: () => isRetryableGitTransientError,
|
|
38333
|
+
isMemfsRemoteUrlForAgent: () => isMemfsRemoteUrlForAgent,
|
|
38314
38334
|
isGitRepo: () => isGitRepo,
|
|
38315
38335
|
getMemoryRepoDir: () => getMemoryRepoDir,
|
|
38316
38336
|
getMemoryGitStatus: () => getMemoryGitStatus,
|
|
38337
|
+
getGitRemoteUrl: () => getGitRemoteUrl,
|
|
38317
38338
|
getAgentRootDir: () => getAgentRootDir,
|
|
38318
38339
|
cloneMemoryRepo: () => cloneMemoryRepo,
|
|
38319
38340
|
addGitMemoryTag: () => addGitMemoryTag,
|
|
@@ -38347,9 +38368,45 @@ function normalizeCredentialBaseUrl(serverUrl) {
|
|
|
38347
38368
|
return trimmed;
|
|
38348
38369
|
}
|
|
38349
38370
|
}
|
|
38350
|
-
function
|
|
38351
|
-
|
|
38352
|
-
|
|
38371
|
+
function normalizeRemoteUrl(url) {
|
|
38372
|
+
return url.trim().replace(/\/+$/, "");
|
|
38373
|
+
}
|
|
38374
|
+
function escapeRegex(value) {
|
|
38375
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
38376
|
+
}
|
|
38377
|
+
function isMemfsRemoteUrlForAgent(remoteUrl, agentId) {
|
|
38378
|
+
const normalized = normalizeRemoteUrl(remoteUrl);
|
|
38379
|
+
const escapedAgentId = escapeRegex(agentId);
|
|
38380
|
+
return new RegExp(`^https?://[^\\s]+/v1/git/${escapedAgentId}/state\\.git$`, "i").test(normalized);
|
|
38381
|
+
}
|
|
38382
|
+
function getGitRemoteUrl(agentId, baseUrl) {
|
|
38383
|
+
const resolvedBaseUrl = (baseUrl ?? getServerUrl()).trim().replace(/\/+$/, "");
|
|
38384
|
+
return `${resolvedBaseUrl}/v1/git/${agentId}/state.git`;
|
|
38385
|
+
}
|
|
38386
|
+
async function maybeUpdateMemoryRemoteOrigin(repoDir, agentId) {
|
|
38387
|
+
let currentOrigin = "";
|
|
38388
|
+
try {
|
|
38389
|
+
const { stdout } = await runGit(repoDir, ["remote", "get-url", "origin"]);
|
|
38390
|
+
currentOrigin = stdout.trim();
|
|
38391
|
+
} catch {
|
|
38392
|
+
return;
|
|
38393
|
+
}
|
|
38394
|
+
if (!currentOrigin) {
|
|
38395
|
+
return;
|
|
38396
|
+
}
|
|
38397
|
+
if (!isMemfsRemoteUrlForAgent(currentOrigin, agentId)) {
|
|
38398
|
+
return;
|
|
38399
|
+
}
|
|
38400
|
+
const expectedOrigin = normalizeRemoteUrl(getGitRemoteUrl(agentId));
|
|
38401
|
+
const normalizedCurrent = normalizeRemoteUrl(currentOrigin);
|
|
38402
|
+
if (normalizedCurrent === expectedOrigin) {
|
|
38403
|
+
return;
|
|
38404
|
+
}
|
|
38405
|
+
await runGit(repoDir, ["remote", "set-url", "origin", expectedOrigin]);
|
|
38406
|
+
debugLog("memfs-git", `Updated origin remote for ${agentId}: ${normalizedCurrent} -> ${expectedOrigin}`);
|
|
38407
|
+
}
|
|
38408
|
+
function getMemoryRemoteUrl(agentId) {
|
|
38409
|
+
return getGitRemoteUrl(agentId);
|
|
38353
38410
|
}
|
|
38354
38411
|
async function getAuthToken() {
|
|
38355
38412
|
const client = await getClient();
|
|
@@ -38431,7 +38488,7 @@ function isGitRepo(agentId) {
|
|
|
38431
38488
|
}
|
|
38432
38489
|
async function cloneMemoryRepo(agentId) {
|
|
38433
38490
|
const token = await getAuthToken();
|
|
38434
|
-
const url =
|
|
38491
|
+
const url = getMemoryRemoteUrl(agentId);
|
|
38435
38492
|
const dir = getMemoryRepoDir(agentId);
|
|
38436
38493
|
debugLog("memfs-git", `Cloning ${url} → ${dir}`);
|
|
38437
38494
|
if (!existsSync8(dir)) {
|
|
@@ -38464,6 +38521,7 @@ async function cloneMemoryRepo(agentId) {
|
|
|
38464
38521
|
async function pullMemory(agentId) {
|
|
38465
38522
|
const token = await getAuthToken();
|
|
38466
38523
|
const dir = getMemoryRepoDir(agentId);
|
|
38524
|
+
await maybeUpdateMemoryRemoteOrigin(dir, agentId);
|
|
38467
38525
|
await configureLocalCredentialHelper(dir, token);
|
|
38468
38526
|
installPreCommitHook(dir);
|
|
38469
38527
|
try {
|
|
@@ -38495,6 +38553,7 @@ Hint: verify remote and auth:
|
|
|
38495
38553
|
async function pushMemory(agentId) {
|
|
38496
38554
|
const token = await getAuthToken();
|
|
38497
38555
|
const dir = getMemoryRepoDir(agentId);
|
|
38556
|
+
await maybeUpdateMemoryRemoteOrigin(dir, agentId);
|
|
38498
38557
|
await configureLocalCredentialHelper(dir, token);
|
|
38499
38558
|
try {
|
|
38500
38559
|
await runGit(dir, ["push"], token);
|
|
@@ -38904,7 +38963,7 @@ async function buildCreateAgentOptionsForPersonality(params) {
|
|
|
38904
38963
|
return {
|
|
38905
38964
|
name: name ?? personality.label,
|
|
38906
38965
|
description: description ?? personality.description,
|
|
38907
|
-
model,
|
|
38966
|
+
model: model ?? personality.defaultModel,
|
|
38908
38967
|
tags,
|
|
38909
38968
|
memoryPromptMode: "memfs",
|
|
38910
38969
|
memoryBlocks: defaultMemoryBlocks.map((block) => {
|
|
@@ -39112,7 +39171,8 @@ var init_personality = __esm(async () => {
|
|
|
39112
39171
|
{
|
|
39113
39172
|
id: "kawaii",
|
|
39114
39173
|
label: "Letta-Chan",
|
|
39115
|
-
description: "sugoi~ (◕‿◕)✨"
|
|
39174
|
+
description: "sugoi~ (◕‿◕)✨",
|
|
39175
|
+
defaultModel: "auto-chat"
|
|
39116
39176
|
},
|
|
39117
39177
|
{
|
|
39118
39178
|
id: "claude",
|
|
@@ -53530,6 +53590,7 @@ class PermissionModeManager {
|
|
|
53530
53590
|
"Edit",
|
|
53531
53591
|
"MultiEdit",
|
|
53532
53592
|
"NotebookEdit",
|
|
53593
|
+
"memory",
|
|
53533
53594
|
"apply_patch",
|
|
53534
53595
|
"ApplyPatch",
|
|
53535
53596
|
"memory_apply_patch",
|
|
@@ -56139,6 +56200,20 @@ __export(exports_Bash, {
|
|
|
56139
56200
|
bash: () => bash
|
|
56140
56201
|
});
|
|
56141
56202
|
import { spawn as spawn3 } from "node:child_process";
|
|
56203
|
+
import { resolve as resolve7 } from "node:path";
|
|
56204
|
+
function validateWorktreePath(command, cwd2) {
|
|
56205
|
+
const match = command.match(/\bgit\s+worktree\s+add\s+(?:-b\s+\S+\s+)?(\S+)/);
|
|
56206
|
+
if (!match?.[1])
|
|
56207
|
+
return null;
|
|
56208
|
+
const targetPath = match[1];
|
|
56209
|
+
const resolved = resolve7(cwd2, targetPath);
|
|
56210
|
+
const requiredPrefix = resolve7(cwd2, ".letta/worktrees");
|
|
56211
|
+
if (!resolved.startsWith(requiredPrefix)) {
|
|
56212
|
+
return `Error: Worktrees must be created under .letta/worktrees/. ` + `Use: git worktree add -b <branch> .letta/worktrees/<name> main
|
|
56213
|
+
` + `Got: ${targetPath}`;
|
|
56214
|
+
}
|
|
56215
|
+
return null;
|
|
56216
|
+
}
|
|
56142
56217
|
function getBackgroundLauncher(command) {
|
|
56143
56218
|
if (cachedWorkingLauncher) {
|
|
56144
56219
|
const [executable, ...launcherArgs] = cachedWorkingLauncher;
|
|
@@ -56224,6 +56299,13 @@ async function bash(args) {
|
|
|
56224
56299
|
onOutput
|
|
56225
56300
|
} = args;
|
|
56226
56301
|
const userCwd = process.env.USER_CWD || process.cwd();
|
|
56302
|
+
const worktreeError = validateWorktreePath(command, userCwd);
|
|
56303
|
+
if (worktreeError) {
|
|
56304
|
+
return {
|
|
56305
|
+
content: [{ type: "text", text: worktreeError }],
|
|
56306
|
+
status: "error"
|
|
56307
|
+
};
|
|
56308
|
+
}
|
|
56227
56309
|
if (command === "/bg") {
|
|
56228
56310
|
const processes = Array.from(backgroundProcesses.entries());
|
|
56229
56311
|
if (processes.length === 0) {
|
|
@@ -56410,7 +56492,7 @@ var init_Bash2 = __esm(async () => {
|
|
|
56410
56492
|
// src/tools/impl/BashOutput.ts
|
|
56411
56493
|
import { readFileSync as readFileSync10, statSync as statSync5 } from "node:fs";
|
|
56412
56494
|
function sleep2(ms) {
|
|
56413
|
-
return new Promise((
|
|
56495
|
+
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
56414
56496
|
}
|
|
56415
56497
|
function readOutputFile(filePath) {
|
|
56416
56498
|
if (!filePath) {
|
|
@@ -57392,12 +57474,12 @@ var init_LS2 = __esm(() => {
|
|
|
57392
57474
|
|
|
57393
57475
|
// src/tools/impl/LS.ts
|
|
57394
57476
|
import { readdir as readdir2, stat } from "node:fs/promises";
|
|
57395
|
-
import { join as join18, resolve as
|
|
57477
|
+
import { join as join18, resolve as resolve12 } from "node:path";
|
|
57396
57478
|
async function ls(args) {
|
|
57397
57479
|
validateRequiredParams(args, ["path"], "LS");
|
|
57398
57480
|
validateParamTypes(args, LS_default2, "LS");
|
|
57399
57481
|
const { path: inputPath, ignore = [] } = args;
|
|
57400
|
-
const dirPath =
|
|
57482
|
+
const dirPath = resolve12(inputPath);
|
|
57401
57483
|
try {
|
|
57402
57484
|
const items = await readdir2(dirPath);
|
|
57403
57485
|
const filteredItems = items.filter((item) => !ignore.some((pattern) => import_picomatch2.default.isMatch(item, pattern)));
|
|
@@ -57830,7 +57912,7 @@ import {
|
|
|
57830
57912
|
writeFile as writeFile2
|
|
57831
57913
|
} from "node:fs/promises";
|
|
57832
57914
|
import { homedir as homedir15 } from "node:os";
|
|
57833
|
-
import { dirname as dirname7, isAbsolute as isAbsolute9, relative as relative5, resolve as
|
|
57915
|
+
import { dirname as dirname7, isAbsolute as isAbsolute9, relative as relative5, resolve as resolve13 } from "node:path";
|
|
57834
57916
|
import { promisify as promisify10 } from "node:util";
|
|
57835
57917
|
async function getAgentIdentity() {
|
|
57836
57918
|
const envAgentId = (process.env.AGENT_ID || process.env.LETTA_AGENT_ID || "").trim();
|
|
@@ -57985,7 +58067,7 @@ async function memory(args) {
|
|
|
57985
58067
|
function resolveMemoryDir() {
|
|
57986
58068
|
const direct = process.env.MEMORY_DIR || process.env.LETTA_MEMORY_DIR;
|
|
57987
58069
|
if (direct && direct.trim().length > 0) {
|
|
57988
|
-
return
|
|
58070
|
+
return resolve13(direct);
|
|
57989
58071
|
}
|
|
57990
58072
|
const contextAgentId = (() => {
|
|
57991
58073
|
try {
|
|
@@ -57996,7 +58078,7 @@ function resolveMemoryDir() {
|
|
|
57996
58078
|
})();
|
|
57997
58079
|
const agentId = contextAgentId || (process.env.AGENT_ID || process.env.LETTA_AGENT_ID || "").trim();
|
|
57998
58080
|
if (agentId && agentId.trim().length > 0) {
|
|
57999
|
-
return
|
|
58081
|
+
return resolve13(homedir15(), ".letta", "agents", agentId, "memory");
|
|
58000
58082
|
}
|
|
58001
58083
|
throw new Error("memory: unable to resolve memory directory. Ensure MEMORY_DIR (or AGENT_ID) is available.");
|
|
58002
58084
|
}
|
|
@@ -58004,7 +58086,7 @@ function ensureMemoryRepo(memoryDir) {
|
|
|
58004
58086
|
if (!existsSync14(memoryDir)) {
|
|
58005
58087
|
throw new Error(`memory: memory directory does not exist: ${memoryDir}`);
|
|
58006
58088
|
}
|
|
58007
|
-
if (!existsSync14(
|
|
58089
|
+
if (!existsSync14(resolve13(memoryDir, ".git"))) {
|
|
58008
58090
|
throw new Error(`memory: ${memoryDir} is not a git repository. This tool requires a git-backed memory filesystem.`);
|
|
58009
58091
|
}
|
|
58010
58092
|
}
|
|
@@ -58018,7 +58100,7 @@ function normalizeMemoryLabel(memoryDir, inputPath, fieldName) {
|
|
|
58018
58100
|
}
|
|
58019
58101
|
const isWindowsAbsolute = /^[a-zA-Z]:[\\/]/.test(raw);
|
|
58020
58102
|
if (isAbsolute9(raw) || isWindowsAbsolute) {
|
|
58021
|
-
const absolutePath =
|
|
58103
|
+
const absolutePath = resolve13(raw);
|
|
58022
58104
|
const relToMemory = relative5(memoryDir, absolutePath);
|
|
58023
58105
|
if (relToMemory && !relToMemory.startsWith("..") && !isAbsolute9(relToMemory)) {
|
|
58024
58106
|
return normalizeRelativeMemoryLabel(relToMemory, fieldName);
|
|
@@ -58064,7 +58146,7 @@ function resolveMemoryFilePath(memoryDir, label) {
|
|
|
58064
58146
|
return absolute;
|
|
58065
58147
|
}
|
|
58066
58148
|
function resolveMemoryPath(memoryDir, path11) {
|
|
58067
|
-
const absolute =
|
|
58149
|
+
const absolute = resolve13(memoryDir, path11);
|
|
58068
58150
|
const rel = relative5(memoryDir, absolute);
|
|
58069
58151
|
if (rel.startsWith("..") || isAbsolute9(rel)) {
|
|
58070
58152
|
throw new Error("memory: resolved path escapes memory directory");
|
|
@@ -58193,6 +58275,7 @@ async function commitAndPush(memoryDir, pathspecs, reason) {
|
|
|
58193
58275
|
]);
|
|
58194
58276
|
const head = await runGit4(memoryDir, ["rev-parse", "HEAD"]);
|
|
58195
58277
|
const sha = head.stdout.trim();
|
|
58278
|
+
await maybeUpdateMemoryRemoteOrigin(memoryDir, agentId);
|
|
58196
58279
|
try {
|
|
58197
58280
|
await runGit4(memoryDir, ["push"]);
|
|
58198
58281
|
} catch (error) {
|
|
@@ -58228,7 +58311,10 @@ function emitMemoryUpdated(affectedPaths) {
|
|
|
58228
58311
|
var execFile10;
|
|
58229
58312
|
var init_Memory2 = __esm(async () => {
|
|
58230
58313
|
init_context();
|
|
58231
|
-
await
|
|
58314
|
+
await __promiseAll([
|
|
58315
|
+
init_client2(),
|
|
58316
|
+
init_memoryGit()
|
|
58317
|
+
]);
|
|
58232
58318
|
execFile10 = promisify10(execFileCb3);
|
|
58233
58319
|
});
|
|
58234
58320
|
|
|
@@ -58245,7 +58331,7 @@ import {
|
|
|
58245
58331
|
writeFile as writeFile3
|
|
58246
58332
|
} from "node:fs/promises";
|
|
58247
58333
|
import { homedir as homedir16 } from "node:os";
|
|
58248
|
-
import { dirname as dirname8, isAbsolute as isAbsolute10, relative as relative6, resolve as
|
|
58334
|
+
import { dirname as dirname8, isAbsolute as isAbsolute10, relative as relative6, resolve as resolve14 } from "node:path";
|
|
58249
58335
|
import { promisify as promisify11 } from "node:util";
|
|
58250
58336
|
async function getAgentIdentity2() {
|
|
58251
58337
|
const envAgentId = (process.env.AGENT_ID || process.env.LETTA_AGENT_ID || "").trim();
|
|
@@ -58521,7 +58607,7 @@ function normalizeAddedContent(label, rawContent) {
|
|
|
58521
58607
|
function resolveMemoryDir2() {
|
|
58522
58608
|
const direct = process.env.MEMORY_DIR || process.env.LETTA_MEMORY_DIR;
|
|
58523
58609
|
if (direct && direct.trim().length > 0) {
|
|
58524
|
-
return
|
|
58610
|
+
return resolve14(direct);
|
|
58525
58611
|
}
|
|
58526
58612
|
const contextAgentId = (() => {
|
|
58527
58613
|
try {
|
|
@@ -58532,7 +58618,7 @@ function resolveMemoryDir2() {
|
|
|
58532
58618
|
})();
|
|
58533
58619
|
const agentId = contextAgentId || (process.env.AGENT_ID || process.env.LETTA_AGENT_ID || "").trim();
|
|
58534
58620
|
if (agentId && agentId.trim().length > 0) {
|
|
58535
|
-
return
|
|
58621
|
+
return resolve14(homedir16(), ".letta", "agents", agentId, "memory");
|
|
58536
58622
|
}
|
|
58537
58623
|
throw new Error("memory_apply_patch: unable to resolve memory directory. Ensure MEMORY_DIR (or AGENT_ID) is available.");
|
|
58538
58624
|
}
|
|
@@ -58540,7 +58626,7 @@ function ensureMemoryRepo2(memoryDir) {
|
|
|
58540
58626
|
if (!existsSync15(memoryDir)) {
|
|
58541
58627
|
throw new Error(`memory_apply_patch: memory directory does not exist: ${memoryDir}`);
|
|
58542
58628
|
}
|
|
58543
|
-
if (!existsSync15(
|
|
58629
|
+
if (!existsSync15(resolve14(memoryDir, ".git"))) {
|
|
58544
58630
|
throw new Error(`memory_apply_patch: ${memoryDir} is not a git repository. This tool requires a git-backed memory filesystem.`);
|
|
58545
58631
|
}
|
|
58546
58632
|
}
|
|
@@ -58554,7 +58640,7 @@ function normalizeMemoryLabel2(memoryDir, inputPath, fieldName) {
|
|
|
58554
58640
|
}
|
|
58555
58641
|
const isWindowsAbsolute = /^[a-zA-Z]:[\\/]/.test(raw);
|
|
58556
58642
|
if (isAbsolute10(raw) || isWindowsAbsolute) {
|
|
58557
|
-
const absolutePath =
|
|
58643
|
+
const absolutePath = resolve14(raw);
|
|
58558
58644
|
const relToMemory = relative6(memoryDir, absolutePath);
|
|
58559
58645
|
if (relToMemory && !relToMemory.startsWith("..") && !isAbsolute10(relToMemory)) {
|
|
58560
58646
|
return normalizeRelativeMemoryLabel2(relToMemory, fieldName);
|
|
@@ -58596,7 +58682,7 @@ function memoryPrefixError2(memoryDir) {
|
|
|
58596
58682
|
return `The memory_apply_patch tool can only be used to modify files in {${memoryDir}} or provided as a relative path`;
|
|
58597
58683
|
}
|
|
58598
58684
|
function resolveMemoryPath2(memoryDir, path11) {
|
|
58599
|
-
const absolute =
|
|
58685
|
+
const absolute = resolve14(memoryDir, path11);
|
|
58600
58686
|
const rel = relative6(memoryDir, absolute);
|
|
58601
58687
|
if (rel.startsWith("..") || isAbsolute10(rel)) {
|
|
58602
58688
|
throw new Error("memory_apply_patch: resolved path escapes memory directory");
|
|
@@ -58728,6 +58814,7 @@ async function commitAndPush2(memoryDir, pathspecs, reason) {
|
|
|
58728
58814
|
]);
|
|
58729
58815
|
const head = await runGit5(memoryDir, ["rev-parse", "HEAD"]);
|
|
58730
58816
|
const sha = head.stdout.trim();
|
|
58817
|
+
await maybeUpdateMemoryRemoteOrigin(memoryDir, agentId);
|
|
58731
58818
|
try {
|
|
58732
58819
|
await runGit5(memoryDir, ["push"]);
|
|
58733
58820
|
} catch (error) {
|
|
@@ -58802,7 +58889,10 @@ function buildOldNewChunks2(lines) {
|
|
|
58802
58889
|
var execFile11;
|
|
58803
58890
|
var init_MemoryApplyPatch2 = __esm(async () => {
|
|
58804
58891
|
init_context();
|
|
58805
|
-
await
|
|
58892
|
+
await __promiseAll([
|
|
58893
|
+
init_client2(),
|
|
58894
|
+
init_memoryGit()
|
|
58895
|
+
]);
|
|
58806
58896
|
execFile11 = promisify11(execFileCb4);
|
|
58807
58897
|
});
|
|
58808
58898
|
|
|
@@ -59368,7 +59458,7 @@ var init_client3 = __esm(() => {
|
|
|
59368
59458
|
this.emit("notification", notification);
|
|
59369
59459
|
}
|
|
59370
59460
|
sendRequest(method, params) {
|
|
59371
|
-
return new Promise((
|
|
59461
|
+
return new Promise((resolve17, reject) => {
|
|
59372
59462
|
const id = ++this.requestId;
|
|
59373
59463
|
const request = {
|
|
59374
59464
|
jsonrpc: "2.0",
|
|
@@ -59377,7 +59467,7 @@ var init_client3 = __esm(() => {
|
|
|
59377
59467
|
params
|
|
59378
59468
|
};
|
|
59379
59469
|
this.pendingRequests.set(id, {
|
|
59380
|
-
resolve:
|
|
59470
|
+
resolve: resolve17,
|
|
59381
59471
|
reject
|
|
59382
59472
|
});
|
|
59383
59473
|
this.sendMessage(request);
|
|
@@ -59497,14 +59587,14 @@ var init_python = __esm(() => {
|
|
|
59497
59587
|
}
|
|
59498
59588
|
console.log("[LSP] Installing pyright...");
|
|
59499
59589
|
const { spawn: spawn4 } = await import("node:child_process");
|
|
59500
|
-
return new Promise((
|
|
59590
|
+
return new Promise((resolve17, reject) => {
|
|
59501
59591
|
const proc = spawn4("npm", ["install", "-g", "pyright"], {
|
|
59502
59592
|
stdio: "inherit"
|
|
59503
59593
|
});
|
|
59504
59594
|
proc.on("exit", (code) => {
|
|
59505
59595
|
if (code === 0) {
|
|
59506
59596
|
console.log("[LSP] Successfully installed pyright");
|
|
59507
|
-
|
|
59597
|
+
resolve17();
|
|
59508
59598
|
} else {
|
|
59509
59599
|
reject(new Error(`npm install failed with code ${code}`));
|
|
59510
59600
|
}
|
|
@@ -59546,14 +59636,14 @@ var init_typescript = __esm(() => {
|
|
|
59546
59636
|
}
|
|
59547
59637
|
console.log("[LSP] Installing typescript-language-server and typescript...");
|
|
59548
59638
|
const { spawn: spawn4 } = await import("node:child_process");
|
|
59549
|
-
return new Promise((
|
|
59639
|
+
return new Promise((resolve17, reject) => {
|
|
59550
59640
|
const proc = spawn4("npm", ["install", "-g", "typescript-language-server", "typescript"], {
|
|
59551
59641
|
stdio: "inherit"
|
|
59552
59642
|
});
|
|
59553
59643
|
proc.on("exit", (code) => {
|
|
59554
59644
|
if (code === 0) {
|
|
59555
59645
|
console.log("[LSP] Successfully installed typescript-language-server");
|
|
59556
|
-
|
|
59646
|
+
resolve17();
|
|
59557
59647
|
} else {
|
|
59558
59648
|
reject(new Error(`npm install failed with code ${code}`));
|
|
59559
59649
|
}
|
|
@@ -59784,7 +59874,7 @@ async function read_lsp(args) {
|
|
|
59784
59874
|
const userCwd = process.env.USER_CWD || process.cwd();
|
|
59785
59875
|
const resolvedPath = path14.default.isAbsolute(args.file_path) ? args.file_path : path14.default.resolve(userCwd, args.file_path);
|
|
59786
59876
|
await lspManager2.touchFile(resolvedPath, false);
|
|
59787
|
-
await new Promise((
|
|
59877
|
+
await new Promise((resolve18) => setTimeout(resolve18, 100));
|
|
59788
59878
|
const diagnostics = lspManager2.getDiagnostics(resolvedPath);
|
|
59789
59879
|
if (diagnostics.length > 0) {
|
|
59790
59880
|
const errors = diagnostics.filter((d) => d.severity === 1);
|
|
@@ -62892,10 +62982,10 @@ var init_esm4 = __esm(() => {
|
|
|
62892
62982
|
return this[ENCODING] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
|
|
62893
62983
|
}
|
|
62894
62984
|
async promise() {
|
|
62895
|
-
return new Promise((
|
|
62985
|
+
return new Promise((resolve18, reject) => {
|
|
62896
62986
|
this.on(DESTROYED, () => reject(new Error("stream destroyed")));
|
|
62897
62987
|
this.on("error", (er) => reject(er));
|
|
62898
|
-
this.on("end", () =>
|
|
62988
|
+
this.on("end", () => resolve18());
|
|
62899
62989
|
});
|
|
62900
62990
|
}
|
|
62901
62991
|
[Symbol.asyncIterator]() {
|
|
@@ -62914,7 +63004,7 @@ var init_esm4 = __esm(() => {
|
|
|
62914
63004
|
return Promise.resolve({ done: false, value: res });
|
|
62915
63005
|
if (this[EOF])
|
|
62916
63006
|
return stop();
|
|
62917
|
-
let
|
|
63007
|
+
let resolve18;
|
|
62918
63008
|
let reject;
|
|
62919
63009
|
const onerr = (er) => {
|
|
62920
63010
|
this.off("data", ondata);
|
|
@@ -62928,19 +63018,19 @@ var init_esm4 = __esm(() => {
|
|
|
62928
63018
|
this.off("end", onend);
|
|
62929
63019
|
this.off(DESTROYED, ondestroy);
|
|
62930
63020
|
this.pause();
|
|
62931
|
-
|
|
63021
|
+
resolve18({ value, done: !!this[EOF] });
|
|
62932
63022
|
};
|
|
62933
63023
|
const onend = () => {
|
|
62934
63024
|
this.off("error", onerr);
|
|
62935
63025
|
this.off("data", ondata);
|
|
62936
63026
|
this.off(DESTROYED, ondestroy);
|
|
62937
63027
|
stop();
|
|
62938
|
-
|
|
63028
|
+
resolve18({ done: true, value: undefined });
|
|
62939
63029
|
};
|
|
62940
63030
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
62941
63031
|
return new Promise((res2, rej) => {
|
|
62942
63032
|
reject = rej;
|
|
62943
|
-
|
|
63033
|
+
resolve18 = res2;
|
|
62944
63034
|
this.once(DESTROYED, ondestroy);
|
|
62945
63035
|
this.once("error", onerr);
|
|
62946
63036
|
this.once("end", onend);
|
|
@@ -63626,8 +63716,8 @@ var init_esm5 = __esm(() => {
|
|
|
63626
63716
|
if (this.#asyncReaddirInFlight) {
|
|
63627
63717
|
await this.#asyncReaddirInFlight;
|
|
63628
63718
|
} else {
|
|
63629
|
-
let
|
|
63630
|
-
this.#asyncReaddirInFlight = new Promise((res) =>
|
|
63719
|
+
let resolve18 = () => {};
|
|
63720
|
+
this.#asyncReaddirInFlight = new Promise((res) => resolve18 = res);
|
|
63631
63721
|
try {
|
|
63632
63722
|
for (const e of await this.#fs.promises.readdir(fullpath, {
|
|
63633
63723
|
withFileTypes: true
|
|
@@ -63640,7 +63730,7 @@ var init_esm5 = __esm(() => {
|
|
|
63640
63730
|
children.provisional = 0;
|
|
63641
63731
|
}
|
|
63642
63732
|
this.#asyncReaddirInFlight = undefined;
|
|
63643
|
-
|
|
63733
|
+
resolve18();
|
|
63644
63734
|
}
|
|
63645
63735
|
return children.slice(0, children.provisional);
|
|
63646
63736
|
}
|
|
@@ -66662,10 +66752,10 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
|
|
|
66662
66752
|
crlfDelay: Number.POSITIVE_INFINITY
|
|
66663
66753
|
});
|
|
66664
66754
|
let rlClosed = false;
|
|
66665
|
-
const rlClosedPromise = new Promise((
|
|
66755
|
+
const rlClosedPromise = new Promise((resolve19) => {
|
|
66666
66756
|
rl.once("close", () => {
|
|
66667
66757
|
rlClosed = true;
|
|
66668
|
-
|
|
66758
|
+
resolve19();
|
|
66669
66759
|
});
|
|
66670
66760
|
});
|
|
66671
66761
|
rl.on("line", (line) => {
|
|
@@ -66676,9 +66766,9 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
|
|
|
66676
66766
|
proc2.stderr.on("data", (data) => {
|
|
66677
66767
|
stderrChunks.push(data);
|
|
66678
66768
|
});
|
|
66679
|
-
const exitCode = await new Promise((
|
|
66680
|
-
proc2.on("close",
|
|
66681
|
-
proc2.on("error", () =>
|
|
66769
|
+
const exitCode = await new Promise((resolve19) => {
|
|
66770
|
+
proc2.on("close", resolve19);
|
|
66771
|
+
proc2.on("error", () => resolve19(null));
|
|
66682
66772
|
});
|
|
66683
66773
|
if (!rlClosed) {
|
|
66684
66774
|
rl.close();
|
|
@@ -66918,6 +67008,14 @@ __export(exports_Task, {
|
|
|
66918
67008
|
task: () => task,
|
|
66919
67009
|
spawnBackgroundSubagentTask: () => spawnBackgroundSubagentTask
|
|
66920
67010
|
});
|
|
67011
|
+
async function resolveCompletionSummary(defaultSummary, completionSummary, result) {
|
|
67012
|
+
if (!completionSummary) {
|
|
67013
|
+
return defaultSummary;
|
|
67014
|
+
}
|
|
67015
|
+
const resolved = typeof completionSummary === "function" ? await completionSummary(result) : completionSummary;
|
|
67016
|
+
const trimmed = resolved.trim();
|
|
67017
|
+
return trimmed.length > 0 ? trimmed : defaultSummary;
|
|
67018
|
+
}
|
|
66921
67019
|
function buildTaskResultHeader(subagentType, subagentId, result, status) {
|
|
66922
67020
|
return [
|
|
66923
67021
|
`subagent_type=${subagentType}`,
|
|
@@ -66951,7 +67049,7 @@ ${result.report}
|
|
|
66951
67049
|
`);
|
|
66952
67050
|
}
|
|
66953
67051
|
function sleep3(ms) {
|
|
66954
|
-
return new Promise((
|
|
67052
|
+
return new Promise((resolve19) => setTimeout(resolve19, ms));
|
|
66955
67053
|
}
|
|
66956
67054
|
function resolveParentScope(parentScope) {
|
|
66957
67055
|
if (parentScope?.agentId) {
|
|
@@ -67005,9 +67103,12 @@ function spawnBackgroundSubagentTask(args) {
|
|
|
67005
67103
|
forkedContext,
|
|
67006
67104
|
parentScope,
|
|
67007
67105
|
silentCompletion,
|
|
67106
|
+
emitCompletionNotification,
|
|
67107
|
+
completionSummary,
|
|
67008
67108
|
onComplete,
|
|
67009
67109
|
deps
|
|
67010
67110
|
} = args;
|
|
67111
|
+
const shouldEmitCompletionNotification = emitCompletionNotification ?? !silentCompletion;
|
|
67011
67112
|
const resolvedParentScope = resolveParentScope(parentScope);
|
|
67012
67113
|
const spawnSubagentFn = deps?.spawnSubagentImpl ?? spawnSubagent;
|
|
67013
67114
|
const addToMessageQueueFn = deps?.addToMessageQueueImpl ?? addToMessageQueue;
|
|
@@ -67057,7 +67158,7 @@ function spawnBackgroundSubagentTask(args) {
|
|
|
67057
67158
|
appendToOutputFile(outputFile, `[onComplete error] ${errorMessage}
|
|
67058
67159
|
`);
|
|
67059
67160
|
}
|
|
67060
|
-
if (
|
|
67161
|
+
if (shouldEmitCompletionNotification) {
|
|
67061
67162
|
const subagentSnapshot = getSubagentSnapshotFn();
|
|
67062
67163
|
const subagentEntry = subagentSnapshot.agents.find((agent) => agent.id === subagentId);
|
|
67063
67164
|
const durationMs = Math.max(0, Date.now() - bgTask.startTime.getTime());
|
|
@@ -67068,10 +67169,12 @@ ${result.report || ""}` : `${header}
|
|
|
67068
67169
|
Error: ${result.error || "Subagent execution failed"}`;
|
|
67069
67170
|
const userCwd = process.env.USER_CWD || process.cwd();
|
|
67070
67171
|
const { content: truncatedResult } = truncateByChars(fullResult, LIMITS.TASK_OUTPUT_CHARS, "Task", { workingDirectory: userCwd, toolName: "Task" });
|
|
67172
|
+
const defaultSummary = `Agent "${description}" ${result.success ? "completed" : "failed"}`;
|
|
67173
|
+
const summary = await resolveCompletionSummary(defaultSummary, completionSummary, { success: result.success, error: result.error });
|
|
67071
67174
|
const notificationXml = formatTaskNotificationFn({
|
|
67072
67175
|
taskId,
|
|
67073
67176
|
status: result.success ? "completed" : "failed",
|
|
67074
|
-
summary
|
|
67177
|
+
summary,
|
|
67075
67178
|
result: truncatedResult,
|
|
67076
67179
|
outputFile,
|
|
67077
67180
|
usage: {
|
|
@@ -67103,7 +67206,7 @@ Error: ${result.error || "Subagent execution failed"}`;
|
|
|
67103
67206
|
appendToOutputFile(outputFile, `[onComplete error] ${callbackMessage}
|
|
67104
67207
|
`);
|
|
67105
67208
|
}
|
|
67106
|
-
if (
|
|
67209
|
+
if (shouldEmitCompletionNotification) {
|
|
67107
67210
|
const subagentSnapshot = getSubagentSnapshotFn();
|
|
67108
67211
|
const subagentEntry = subagentSnapshot.agents.find((agent) => agent.id === subagentId);
|
|
67109
67212
|
const durationMs = Math.max(0, Date.now() - bgTask.startTime.getTime());
|
|
@@ -67111,10 +67214,12 @@ Error: ${result.error || "Subagent execution failed"}`;
|
|
|
67111
67214
|
agentId: existingAgentId ?? "",
|
|
67112
67215
|
conversationId: existingConversationId
|
|
67113
67216
|
}, "error");
|
|
67217
|
+
const defaultSummary = `Agent "${description}" failed`;
|
|
67218
|
+
const summary = await resolveCompletionSummary(defaultSummary, completionSummary, { success: false, error: errorMessage });
|
|
67114
67219
|
const notificationXml = formatTaskNotificationFn({
|
|
67115
67220
|
taskId,
|
|
67116
67221
|
status: "failed",
|
|
67117
|
-
summary
|
|
67222
|
+
summary,
|
|
67118
67223
|
result: `${header}
|
|
67119
67224
|
|
|
67120
67225
|
Error: ${errorMessage}`,
|
|
@@ -70241,7 +70346,7 @@ var init_esm7 = __esm(() => {
|
|
|
70241
70346
|
});
|
|
70242
70347
|
|
|
70243
70348
|
// src/permissions/matcher.ts
|
|
70244
|
-
import { resolve as
|
|
70349
|
+
import { resolve as resolve21 } from "node:path";
|
|
70245
70350
|
function toolForMatch(toolName, options) {
|
|
70246
70351
|
return options?.canonicalizeToolNames === false ? toolName : canonicalToolName(toolName);
|
|
70247
70352
|
}
|
|
@@ -70296,7 +70401,7 @@ function resolveFilePathForMatching(filePath, workingDirectory, windowsContext)
|
|
|
70296
70401
|
if (windowsContext && isWindowsAbsolutePath(filePath)) {
|
|
70297
70402
|
return canonicalizeWindowsAbsolutePath(filePath);
|
|
70298
70403
|
}
|
|
70299
|
-
const resolved = normalizePath(
|
|
70404
|
+
const resolved = normalizePath(resolve21(workingDirectory, filePath));
|
|
70300
70405
|
return windowsContext ? canonicalizeWindowsAbsolutePath(resolved) : resolved;
|
|
70301
70406
|
}
|
|
70302
70407
|
function matchesFilePattern(query, pattern, workingDirectory, options) {
|
|
@@ -70422,7 +70527,7 @@ __export(exports_checker, {
|
|
|
70422
70527
|
checkPermissionWithHooks: () => checkPermissionWithHooks,
|
|
70423
70528
|
checkPermission: () => checkPermission
|
|
70424
70529
|
});
|
|
70425
|
-
import { relative as relative7, resolve as
|
|
70530
|
+
import { relative as relative7, resolve as resolve22 } from "node:path";
|
|
70426
70531
|
function envFlagEnabled(name) {
|
|
70427
70532
|
const value = process.env[name];
|
|
70428
70533
|
if (!value)
|
|
@@ -70712,13 +70817,13 @@ function extractFilePath(toolArgs) {
|
|
|
70712
70817
|
return null;
|
|
70713
70818
|
}
|
|
70714
70819
|
function isWithinAllowedDirectories(filePath, permissions, workingDirectory) {
|
|
70715
|
-
const absolutePath =
|
|
70820
|
+
const absolutePath = resolve22(workingDirectory, filePath);
|
|
70716
70821
|
if (absolutePath.startsWith(workingDirectory)) {
|
|
70717
70822
|
return true;
|
|
70718
70823
|
}
|
|
70719
70824
|
if (permissions.additionalDirectories) {
|
|
70720
70825
|
for (const dir of permissions.additionalDirectories) {
|
|
70721
|
-
const resolvedDir =
|
|
70826
|
+
const resolvedDir = resolve22(workingDirectory, dir);
|
|
70722
70827
|
if (absolutePath.startsWith(resolvedDir)) {
|
|
70723
70828
|
return true;
|
|
70724
70829
|
}
|
|
@@ -70730,7 +70835,7 @@ function getAllowedShellPathRoots(permissions, workingDirectory) {
|
|
|
70730
70835
|
const roots = [workingDirectory];
|
|
70731
70836
|
if (permissions.additionalDirectories) {
|
|
70732
70837
|
for (const dir of permissions.additionalDirectories) {
|
|
70733
|
-
roots.push(
|
|
70838
|
+
roots.push(resolve22(workingDirectory, dir));
|
|
70734
70839
|
}
|
|
70735
70840
|
}
|
|
70736
70841
|
return roots;
|
|
@@ -70832,7 +70937,9 @@ function getDefaultDecision(toolName, toolArgs) {
|
|
|
70832
70937
|
"GlobGemini",
|
|
70833
70938
|
"SearchFileContent",
|
|
70834
70939
|
"WriteTodos",
|
|
70835
|
-
"ReadManyFiles"
|
|
70940
|
+
"ReadManyFiles",
|
|
70941
|
+
"memory",
|
|
70942
|
+
"memory_apply_patch"
|
|
70836
70943
|
];
|
|
70837
70944
|
if (autoAllowTools.includes(toolName)) {
|
|
70838
70945
|
return "allow";
|
|
@@ -71081,7 +71188,7 @@ __export(exports_analyzer, {
|
|
|
71081
71188
|
analyzeApprovalContext: () => analyzeApprovalContext
|
|
71082
71189
|
});
|
|
71083
71190
|
import { homedir as homedir18 } from "node:os";
|
|
71084
|
-
import { dirname as dirname12, relative as relative8, resolve as
|
|
71191
|
+
import { dirname as dirname12, relative as relative8, resolve as resolve23, win32 as win322 } from "node:path";
|
|
71085
71192
|
function normalizeOsPath(path20) {
|
|
71086
71193
|
return path20.replace(/\\/g, "/");
|
|
71087
71194
|
}
|
|
@@ -71090,7 +71197,7 @@ function isWindowsPath(path20) {
|
|
|
71090
71197
|
}
|
|
71091
71198
|
function resolvePathForContext(basePath, targetPath) {
|
|
71092
71199
|
const windows = isWindowsPath(basePath) || isWindowsPath(targetPath);
|
|
71093
|
-
return windows ? win322.resolve(basePath, targetPath) :
|
|
71200
|
+
return windows ? win322.resolve(basePath, targetPath) : resolve23(basePath, targetPath);
|
|
71094
71201
|
}
|
|
71095
71202
|
function relativePathForContext(basePath, targetPath) {
|
|
71096
71203
|
const windows = isWindowsPath(basePath) || isWindowsPath(targetPath);
|
|
@@ -71279,7 +71386,7 @@ function containsDangerousCommand(command) {
|
|
|
71279
71386
|
}
|
|
71280
71387
|
return false;
|
|
71281
71388
|
}
|
|
71282
|
-
function
|
|
71389
|
+
function escapeRegex2(text) {
|
|
71283
71390
|
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
71284
71391
|
}
|
|
71285
71392
|
function normalizePathSeparators(path20) {
|
|
@@ -71324,17 +71431,17 @@ function detectSkillScript(command, workingDir) {
|
|
|
71324
71431
|
}
|
|
71325
71432
|
return null;
|
|
71326
71433
|
};
|
|
71327
|
-
const projectRegex = new RegExp(`^${
|
|
71434
|
+
const projectRegex = new RegExp(`^${escapeRegex2(normalizedWorkingDir)}/\\.skills/(.+?)/scripts/`);
|
|
71328
71435
|
const projectSkill = detect("project", projectRegex);
|
|
71329
71436
|
if (projectSkill) {
|
|
71330
71437
|
return projectSkill;
|
|
71331
71438
|
}
|
|
71332
|
-
const agentRegex = new RegExp(`^${
|
|
71439
|
+
const agentRegex = new RegExp(`^${escapeRegex2(normalizedHomeDir)}/\\.letta/agents/[^/]+/skills/(.+?)/scripts/`);
|
|
71333
71440
|
const agentSkill = detect("agent-scoped", agentRegex);
|
|
71334
71441
|
if (agentSkill) {
|
|
71335
71442
|
return agentSkill;
|
|
71336
71443
|
}
|
|
71337
|
-
const globalRegex = new RegExp(`^${
|
|
71444
|
+
const globalRegex = new RegExp(`^${escapeRegex2(normalizedHomeDir)}/\\.letta/skills/(.+?)/scripts/`);
|
|
71338
71445
|
const globalSkill = detect("global", globalRegex);
|
|
71339
71446
|
if (globalSkill) {
|
|
71340
71447
|
return globalSkill;
|
|
@@ -71763,8 +71870,8 @@ function acquireSwitchLock() {
|
|
|
71763
71870
|
const lock = getSwitchLock();
|
|
71764
71871
|
lock.refCount++;
|
|
71765
71872
|
if (lock.refCount === 1) {
|
|
71766
|
-
lock.promise = new Promise((
|
|
71767
|
-
lock.resolve =
|
|
71873
|
+
lock.promise = new Promise((resolve24) => {
|
|
71874
|
+
lock.resolve = resolve24;
|
|
71768
71875
|
});
|
|
71769
71876
|
}
|
|
71770
71877
|
}
|
|
@@ -76479,11 +76586,11 @@ async function discoverFallbackRunIdWithTimeout(client, ctx) {
|
|
|
76479
76586
|
return withTimeout(discoverFallbackRunIdForResume(client, ctx), FALLBACK_RUN_DISCOVERY_TIMEOUT_MS, `Fallback run discovery timed out after ${FALLBACK_RUN_DISCOVERY_TIMEOUT_MS}ms`);
|
|
76480
76587
|
}
|
|
76481
76588
|
function withTimeout(promise, timeoutMs, timeoutMessage) {
|
|
76482
|
-
return new Promise((
|
|
76589
|
+
return new Promise((resolve24, reject) => {
|
|
76483
76590
|
const timer = setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs);
|
|
76484
76591
|
promise.then((value) => {
|
|
76485
76592
|
clearTimeout(timer);
|
|
76486
|
-
|
|
76593
|
+
resolve24(value);
|
|
76487
76594
|
}, (error) => {
|
|
76488
76595
|
clearTimeout(timer);
|
|
76489
76596
|
reject(error);
|
|
@@ -77750,7 +77857,7 @@ function requestApprovalOverWS(runtime, socket, requestId, controlRequest) {
|
|
|
77750
77857
|
if (isInterrupted()) {
|
|
77751
77858
|
return Promise.reject(new Error("Cancelled by user"));
|
|
77752
77859
|
}
|
|
77753
|
-
return new Promise((
|
|
77860
|
+
return new Promise((resolve24, reject) => {
|
|
77754
77861
|
let settled = false;
|
|
77755
77862
|
const cleanupAbortListener = () => {
|
|
77756
77863
|
abortSignal?.removeEventListener("abort", handleAbort);
|
|
@@ -77761,7 +77868,7 @@ function requestApprovalOverWS(runtime, socket, requestId, controlRequest) {
|
|
|
77761
77868
|
}
|
|
77762
77869
|
settled = true;
|
|
77763
77870
|
cleanupAbortListener();
|
|
77764
|
-
|
|
77871
|
+
resolve24(response);
|
|
77765
77872
|
};
|
|
77766
77873
|
const wrappedReject = (error) => {
|
|
77767
77874
|
if (settled) {
|
|
@@ -80742,7 +80849,7 @@ async function sendMessageStreamWithRetry(conversationId, messages, opts, socket
|
|
|
80742
80849
|
conversationId
|
|
80743
80850
|
});
|
|
80744
80851
|
}
|
|
80745
|
-
await new Promise((
|
|
80852
|
+
await new Promise((resolve24) => setTimeout(resolve24, delayMs));
|
|
80746
80853
|
if (abortSignal?.aborted) {
|
|
80747
80854
|
throw new Error("Cancelled by user");
|
|
80748
80855
|
}
|
|
@@ -80797,7 +80904,7 @@ async function sendMessageStreamWithRetry(conversationId, messages, opts, socket
|
|
|
80797
80904
|
agentId: runtime.agentId ?? undefined,
|
|
80798
80905
|
conversationId
|
|
80799
80906
|
});
|
|
80800
|
-
await new Promise((
|
|
80907
|
+
await new Promise((resolve24) => setTimeout(resolve24, delayMs));
|
|
80801
80908
|
if (abortSignal?.aborted) {
|
|
80802
80909
|
throw new Error("Cancelled by user");
|
|
80803
80910
|
}
|
|
@@ -80872,7 +80979,7 @@ async function sendApprovalContinuationWithRetry(conversationId, messages, opts,
|
|
|
80872
80979
|
retryAfterMs
|
|
80873
80980
|
});
|
|
80874
80981
|
transientRetries = attempt;
|
|
80875
|
-
await new Promise((
|
|
80982
|
+
await new Promise((resolve24) => setTimeout(resolve24, delayMs));
|
|
80876
80983
|
if (abortSignal?.aborted) {
|
|
80877
80984
|
throw new Error("Cancelled by user");
|
|
80878
80985
|
}
|
|
@@ -80917,7 +81024,7 @@ async function sendApprovalContinuationWithRetry(conversationId, messages, opts,
|
|
|
80917
81024
|
category: "conversation_busy",
|
|
80918
81025
|
attempt: conversationBusyRetries
|
|
80919
81026
|
});
|
|
80920
|
-
await new Promise((
|
|
81027
|
+
await new Promise((resolve24) => setTimeout(resolve24, retryDelayMs));
|
|
80921
81028
|
if (abortSignal?.aborted) {
|
|
80922
81029
|
throw new Error("Cancelled by user");
|
|
80923
81030
|
}
|
|
@@ -81380,15 +81487,18 @@ function buildMaybeLaunchReflectionSubagent(params) {
|
|
|
81380
81487
|
parentMemory
|
|
81381
81488
|
});
|
|
81382
81489
|
const { spawnBackgroundSubagentTask: spawnBackgroundSubagentTask2 } = await init_Task2().then(() => exports_Task);
|
|
81490
|
+
const reflectionSuccessSummary = "Reflected on the memory palace, the halls remember more now";
|
|
81383
81491
|
spawnBackgroundSubagentTask2({
|
|
81384
81492
|
subagentType: "reflection",
|
|
81385
81493
|
prompt: reflectionPrompt,
|
|
81386
81494
|
description: AUTO_REFLECTION_DESCRIPTION,
|
|
81387
81495
|
silentCompletion: true,
|
|
81496
|
+
emitCompletionNotification: true,
|
|
81497
|
+
completionSummary: ({ success, error }) => success ? reflectionSuccessSummary : `Tried to reflect, but got lost in the palace: ${error || "Unknown error"}`,
|
|
81388
81498
|
parentScope: { agentId, conversationId },
|
|
81389
81499
|
onComplete: async ({ success, error }) => {
|
|
81390
81500
|
await finalizeAutoReflectionPayload(agentId, conversationId, autoPayload.payloadPath, autoPayload.endSnapshotLine, success);
|
|
81391
|
-
|
|
81501
|
+
await handleMemorySubagentCompletion({
|
|
81392
81502
|
agentId,
|
|
81393
81503
|
conversationId,
|
|
81394
81504
|
subagentType: "reflection",
|
|
@@ -81399,12 +81509,6 @@ function buildMaybeLaunchReflectionSubagent(params) {
|
|
|
81399
81509
|
recompileQueuedByConversation: runtime.listener.queuedSystemPromptRecompileByConversation,
|
|
81400
81510
|
logRecompileFailure: (message) => debugWarn("memory", message)
|
|
81401
81511
|
});
|
|
81402
|
-
addToMessageQueue({
|
|
81403
|
-
kind: "task_notification",
|
|
81404
|
-
text: `<task-notification><summary>${msg}</summary></task-notification>`,
|
|
81405
|
-
agentId,
|
|
81406
|
-
conversationId
|
|
81407
|
-
});
|
|
81408
81512
|
}
|
|
81409
81513
|
});
|
|
81410
81514
|
debugLog("memory", `Auto-launched reflection subagent (${triggerSource})`);
|
|
@@ -81767,7 +81871,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
81767
81871
|
agentId,
|
|
81768
81872
|
conversationId
|
|
81769
81873
|
});
|
|
81770
|
-
await new Promise((
|
|
81874
|
+
await new Promise((resolve24) => setTimeout(resolve24, delayMs));
|
|
81771
81875
|
if (turnAbortSignal.aborted) {
|
|
81772
81876
|
throw new Error("Cancelled by user");
|
|
81773
81877
|
}
|
|
@@ -81812,7 +81916,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
81812
81916
|
agentId,
|
|
81813
81917
|
conversationId
|
|
81814
81918
|
});
|
|
81815
|
-
await new Promise((
|
|
81919
|
+
await new Promise((resolve24) => setTimeout(resolve24, delayMs));
|
|
81816
81920
|
if (turnAbortSignal.aborted) {
|
|
81817
81921
|
throw new Error("Cancelled by user");
|
|
81818
81922
|
}
|
|
@@ -81984,7 +82088,6 @@ var init_turn = __esm(async () => {
|
|
|
81984
82088
|
init_memoryFilesystem();
|
|
81985
82089
|
init_turn_recovery_policy();
|
|
81986
82090
|
init_errorFormatter();
|
|
81987
|
-
init_messageQueueBridge();
|
|
81988
82091
|
init_subagentState();
|
|
81989
82092
|
init_planModeReminder();
|
|
81990
82093
|
init_debug();
|
|
@@ -82203,6 +82306,25 @@ var init_commands = __esm(async () => {
|
|
|
82203
82306
|
|
|
82204
82307
|
// src/websocket/listener/protocol-outbound.ts
|
|
82205
82308
|
import WebSocket2 from "ws";
|
|
82309
|
+
function getCachedDeviceGitContext(cwd2) {
|
|
82310
|
+
const now = Date.now();
|
|
82311
|
+
const cached = gitContextCache.get(cwd2);
|
|
82312
|
+
if (cached && cached.expiresAt > now) {
|
|
82313
|
+
return cached.value;
|
|
82314
|
+
}
|
|
82315
|
+
const value = getGitContext(cwd2);
|
|
82316
|
+
gitContextCache.set(cwd2, {
|
|
82317
|
+
expiresAt: now + GIT_CONTEXT_CACHE_TTL_MS,
|
|
82318
|
+
value
|
|
82319
|
+
});
|
|
82320
|
+
if (gitContextCache.size > MAX_GIT_CONTEXT_CACHE_ENTRIES) {
|
|
82321
|
+
const oldestKey = gitContextCache.keys().next().value;
|
|
82322
|
+
if (oldestKey) {
|
|
82323
|
+
gitContextCache.delete(oldestKey);
|
|
82324
|
+
}
|
|
82325
|
+
}
|
|
82326
|
+
return value;
|
|
82327
|
+
}
|
|
82206
82328
|
function getListenerRuntime(runtime) {
|
|
82207
82329
|
if (!runtime)
|
|
82208
82330
|
return null;
|
|
@@ -82257,7 +82379,7 @@ function buildDeviceStatus(runtime, params) {
|
|
|
82257
82379
|
is_processing: false,
|
|
82258
82380
|
current_permission_mode: permissionMode.getMode(),
|
|
82259
82381
|
current_working_directory: fallbackCwd,
|
|
82260
|
-
git_context:
|
|
82382
|
+
git_context: getCachedDeviceGitContext(fallbackCwd),
|
|
82261
82383
|
letta_code_version: process.env.npm_package_version || null,
|
|
82262
82384
|
current_toolset: null,
|
|
82263
82385
|
current_toolset_preference: "auto",
|
|
@@ -82304,7 +82426,7 @@ function buildDeviceStatus(runtime, params) {
|
|
|
82304
82426
|
is_processing: !!conversationRuntime?.isProcessing,
|
|
82305
82427
|
current_permission_mode: conversationPermissionModeState.mode,
|
|
82306
82428
|
current_working_directory: resolvedCwd,
|
|
82307
|
-
git_context:
|
|
82429
|
+
git_context: getCachedDeviceGitContext(resolvedCwd),
|
|
82308
82430
|
letta_code_version: process.env.npm_package_version || null,
|
|
82309
82431
|
current_toolset: conversationRuntime?.currentToolset ?? (toolsetPreference === "auto" ? null : toolsetPreference),
|
|
82310
82432
|
current_toolset_preference: conversationRuntime?.currentToolsetPreference ?? toolsetPreference,
|
|
@@ -82399,7 +82521,9 @@ function emitProtocolV2Message(socket, runtime, message, scope) {
|
|
|
82399
82521
|
});
|
|
82400
82522
|
return;
|
|
82401
82523
|
}
|
|
82402
|
-
|
|
82524
|
+
if (isDebugEnabled()) {
|
|
82525
|
+
console.log(`[Listen V2] Emitting ${message.type} (seq=${eventSeq})`);
|
|
82526
|
+
}
|
|
82403
82527
|
safeEmitWsEvent("send", "protocol", outbound);
|
|
82404
82528
|
}
|
|
82405
82529
|
function emitDeviceStatusUpdate(socket, runtime, scope) {
|
|
@@ -82620,12 +82744,14 @@ function emitStreamDelta(socket, runtime, delta, scope, subagentId) {
|
|
|
82620
82744
|
};
|
|
82621
82745
|
emitProtocolV2Message(socket, runtime, message, scope);
|
|
82622
82746
|
}
|
|
82747
|
+
var GIT_CONTEXT_CACHE_TTL_MS = 15000, MAX_GIT_CONTEXT_CACHE_ENTRIES = 64, gitContextCache;
|
|
82623
82748
|
var init_protocol_outbound = __esm(async () => {
|
|
82624
82749
|
init_memoryFilesystem();
|
|
82625
82750
|
init_gitContext();
|
|
82626
82751
|
init_subagentState();
|
|
82627
82752
|
init_mode();
|
|
82628
82753
|
init_process_manager();
|
|
82754
|
+
init_debug();
|
|
82629
82755
|
init_constants2();
|
|
82630
82756
|
init_cwd();
|
|
82631
82757
|
init_permissionMode();
|
|
@@ -82635,6 +82761,7 @@ var init_protocol_outbound = __esm(async () => {
|
|
|
82635
82761
|
init_settings_manager(),
|
|
82636
82762
|
init_commands()
|
|
82637
82763
|
]);
|
|
82764
|
+
gitContextCache = new Map;
|
|
82638
82765
|
});
|
|
82639
82766
|
|
|
82640
82767
|
// src/websocket/listener/queue.ts
|
|
@@ -82821,6 +82948,9 @@ function consumeQueuedTurn(runtime) {
|
|
|
82821
82948
|
if (!isCoalescable(item.kind) || !hasSameQueueScope(firstQueuedItem, item)) {
|
|
82822
82949
|
break;
|
|
82823
82950
|
}
|
|
82951
|
+
if (firstQueuedItem.kind === "task_notification" && item.kind !== "task_notification" || firstQueuedItem.kind !== "task_notification" && item.kind === "task_notification") {
|
|
82952
|
+
break;
|
|
82953
|
+
}
|
|
82824
82954
|
queueLen += 1;
|
|
82825
82955
|
if (item.kind === "message") {
|
|
82826
82956
|
hasMessage = true;
|
|
@@ -83953,7 +84083,7 @@ async function applyModelUpdateForRuntime(params) {
|
|
|
83953
84083
|
modelSettings = updatedAgent.model_settings ?? null;
|
|
83954
84084
|
appliedTo = "agent";
|
|
83955
84085
|
} else {
|
|
83956
|
-
const updatedConversation = await updateConversationLLMConfig(conversationId, model.handle, updateArgs);
|
|
84086
|
+
const updatedConversation = await updateConversationLLMConfig(conversationId, model.handle, updateArgs, { preserveContextWindow: false });
|
|
83957
84087
|
modelSettings = updatedConversation.model_settings ?? null;
|
|
83958
84088
|
appliedTo = "conversation";
|
|
83959
84089
|
}
|
|
@@ -84800,8 +84930,8 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
84800
84930
|
const delay = Math.min(INITIAL_RETRY_DELAY_MS * 2 ** (attempt - 1), MAX_RETRY_DELAY_MS);
|
|
84801
84931
|
const maxAttempts = Math.ceil(Math.log2(MAX_RETRY_DURATION_MS / INITIAL_RETRY_DELAY_MS));
|
|
84802
84932
|
opts.onRetrying?.(attempt, maxAttempts, delay, opts.connectionId);
|
|
84803
|
-
await new Promise((
|
|
84804
|
-
runtime.reconnectTimeout = setTimeout(
|
|
84933
|
+
await new Promise((resolve24) => {
|
|
84934
|
+
runtime.reconnectTimeout = setTimeout(resolve24, delay);
|
|
84805
84935
|
});
|
|
84806
84936
|
runtime.reconnectTimeout = null;
|
|
84807
84937
|
if (runtime !== getActiveRuntime() || runtime.intentionallyClosed) {
|
|
@@ -85055,11 +85185,17 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
85055
85185
|
if (isSearchFilesCommand(parsed)) {
|
|
85056
85186
|
runDetachedListenerTask("search_files", async () => {
|
|
85057
85187
|
try {
|
|
85188
|
+
if (parsed.cwd) {
|
|
85189
|
+
const currentRoot = getIndexRoot();
|
|
85190
|
+
if (!parsed.cwd.startsWith(currentRoot + path22.sep) && parsed.cwd !== currentRoot) {
|
|
85191
|
+
setIndexRoot(parsed.cwd);
|
|
85192
|
+
}
|
|
85193
|
+
}
|
|
85058
85194
|
await ensureFileIndex2();
|
|
85059
85195
|
let searchDir = ".";
|
|
85060
85196
|
if (parsed.cwd) {
|
|
85061
85197
|
const rel = path22.relative(getIndexRoot(), parsed.cwd);
|
|
85062
|
-
if (rel && !rel.startsWith("..")) {
|
|
85198
|
+
if (rel && !rel.startsWith("..") && rel !== "") {
|
|
85063
85199
|
searchDir = rel;
|
|
85064
85200
|
}
|
|
85065
85201
|
}
|
|
@@ -86394,7 +86530,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
|
|
|
86394
86530
|
}
|
|
86395
86531
|
const wasRaw = process.stdin.isRaw;
|
|
86396
86532
|
const wasFlowing = process.stdin.readableFlowing;
|
|
86397
|
-
return new Promise((
|
|
86533
|
+
return new Promise((resolve26) => {
|
|
86398
86534
|
let response = "";
|
|
86399
86535
|
let resolved = false;
|
|
86400
86536
|
const cleanup = () => {
|
|
@@ -86411,7 +86547,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
|
|
|
86411
86547
|
};
|
|
86412
86548
|
const timeout = setTimeout(() => {
|
|
86413
86549
|
cleanup();
|
|
86414
|
-
|
|
86550
|
+
resolve26(null);
|
|
86415
86551
|
}, timeoutMs);
|
|
86416
86552
|
const onData = (data) => {
|
|
86417
86553
|
response += data.toString();
|
|
@@ -86421,7 +86557,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
|
|
|
86421
86557
|
if (match3) {
|
|
86422
86558
|
clearTimeout(timeout);
|
|
86423
86559
|
cleanup();
|
|
86424
|
-
|
|
86560
|
+
resolve26({
|
|
86425
86561
|
r: parseHexComponent(match3[1] ?? "0"),
|
|
86426
86562
|
g: parseHexComponent(match3[2] ?? "0"),
|
|
86427
86563
|
b: parseHexComponent(match3[3] ?? "0")
|
|
@@ -86436,7 +86572,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
|
|
|
86436
86572
|
} catch {
|
|
86437
86573
|
clearTimeout(timeout);
|
|
86438
86574
|
cleanup();
|
|
86439
|
-
|
|
86575
|
+
resolve26(null);
|
|
86440
86576
|
}
|
|
86441
86577
|
});
|
|
86442
86578
|
}
|
|
@@ -86487,6 +86623,35 @@ async function initTerminalTheme() {
|
|
|
86487
86623
|
}
|
|
86488
86624
|
var cachedTheme2 = null;
|
|
86489
86625
|
|
|
86626
|
+
// src/agent/bootstrap-tools.ts
|
|
86627
|
+
var exports_bootstrap_tools = {};
|
|
86628
|
+
__export(exports_bootstrap_tools, {
|
|
86629
|
+
bootstrapBaseToolsIfNeeded: () => bootstrapBaseToolsIfNeeded
|
|
86630
|
+
});
|
|
86631
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync18, writeFileSync as writeFileSync12 } from "node:fs";
|
|
86632
|
+
import { homedir as homedir27 } from "node:os";
|
|
86633
|
+
import { join as join32 } from "node:path";
|
|
86634
|
+
async function bootstrapBaseToolsIfNeeded() {
|
|
86635
|
+
if (existsSync25(MARKER_PATH))
|
|
86636
|
+
return;
|
|
86637
|
+
debugLog("bootstrap", "No marker found, bootstrapping base tools...");
|
|
86638
|
+
try {
|
|
86639
|
+
const success = await addBaseToolsToServer();
|
|
86640
|
+
if (success) {
|
|
86641
|
+
mkdirSync18(join32(homedir27(), ".letta"), { recursive: true });
|
|
86642
|
+
writeFileSync12(MARKER_PATH, new Date().toISOString(), "utf-8");
|
|
86643
|
+
}
|
|
86644
|
+
} catch (err) {
|
|
86645
|
+
debugWarn("bootstrap", `Failed to bootstrap base tools: ${err instanceof Error ? err.message : String(err)}`);
|
|
86646
|
+
}
|
|
86647
|
+
}
|
|
86648
|
+
var MARKER_PATH;
|
|
86649
|
+
var init_bootstrap_tools = __esm(async () => {
|
|
86650
|
+
init_debug();
|
|
86651
|
+
await init_create();
|
|
86652
|
+
MARKER_PATH = join32(homedir27(), ".letta", ".bootstrapped");
|
|
86653
|
+
});
|
|
86654
|
+
|
|
86490
86655
|
// src/lsp/manager.ts
|
|
86491
86656
|
var exports_manager2 = {};
|
|
86492
86657
|
__export(exports_manager2, {
|
|
@@ -86679,7 +86844,7 @@ __export(exports_auto_update, {
|
|
|
86679
86844
|
import { execFile as execFile13 } from "node:child_process";
|
|
86680
86845
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
86681
86846
|
import { readdir as readdir8, rm as rm3 } from "node:fs/promises";
|
|
86682
|
-
import { join as
|
|
86847
|
+
import { join as join33 } from "node:path";
|
|
86683
86848
|
import { promisify as promisify13 } from "node:util";
|
|
86684
86849
|
function debugLog3(...args) {
|
|
86685
86850
|
if (DEBUG) {
|
|
@@ -86844,12 +87009,12 @@ async function getNpmGlobalPath() {
|
|
|
86844
87009
|
}
|
|
86845
87010
|
}
|
|
86846
87011
|
async function cleanupOrphanedDirs(globalPath) {
|
|
86847
|
-
const lettaAiDir =
|
|
87012
|
+
const lettaAiDir = join33(globalPath, "lib/node_modules/@letta-ai");
|
|
86848
87013
|
try {
|
|
86849
87014
|
const entries = await readdir8(lettaAiDir);
|
|
86850
87015
|
for (const entry of entries) {
|
|
86851
87016
|
if (entry.startsWith(".letta-code-")) {
|
|
86852
|
-
const orphanPath =
|
|
87017
|
+
const orphanPath = join33(lettaAiDir, entry);
|
|
86853
87018
|
debugLog3("Cleaning orphaned temp directory:", orphanPath);
|
|
86854
87019
|
await rm3(orphanPath, { recursive: true, force: true });
|
|
86855
87020
|
}
|
|
@@ -87642,10 +87807,10 @@ __export(exports_setup, {
|
|
|
87642
87807
|
runSetup: () => runSetup
|
|
87643
87808
|
});
|
|
87644
87809
|
async function runSetup() {
|
|
87645
|
-
return new Promise((
|
|
87810
|
+
return new Promise((resolve27) => {
|
|
87646
87811
|
const { waitUntilExit } = render_default(import_react32.default.createElement(SetupUI, {
|
|
87647
87812
|
onComplete: () => {
|
|
87648
|
-
|
|
87813
|
+
resolve27();
|
|
87649
87814
|
}
|
|
87650
87815
|
}));
|
|
87651
87816
|
waitUntilExit().catch((error) => {
|
|
@@ -88175,10 +88340,10 @@ __export(exports_import, {
|
|
|
88175
88340
|
});
|
|
88176
88341
|
import { createReadStream } from "node:fs";
|
|
88177
88342
|
import { chmod, mkdir as mkdir7, readFile as readFile10, writeFile as writeFile8 } from "node:fs/promises";
|
|
88178
|
-
import { dirname as dirname15, resolve as
|
|
88343
|
+
import { dirname as dirname15, resolve as resolve27 } from "node:path";
|
|
88179
88344
|
async function importAgentFromFile(options) {
|
|
88180
88345
|
const client = await getClient();
|
|
88181
|
-
const resolvedPath =
|
|
88346
|
+
const resolvedPath = resolve27(options.filePath);
|
|
88182
88347
|
const file = createReadStream(resolvedPath);
|
|
88183
88348
|
const importResponse = await client.agents.importFile({
|
|
88184
88349
|
file,
|
|
@@ -88213,7 +88378,7 @@ async function extractSkillsFromAf(afPath, destDir) {
|
|
|
88213
88378
|
return [];
|
|
88214
88379
|
}
|
|
88215
88380
|
for (const skill2 of afData.skills) {
|
|
88216
|
-
const skillDir =
|
|
88381
|
+
const skillDir = resolve27(destDir, skill2.name);
|
|
88217
88382
|
await mkdir7(skillDir, { recursive: true });
|
|
88218
88383
|
if (skill2.files) {
|
|
88219
88384
|
await writeSkillFiles(skillDir, skill2.files);
|
|
@@ -88233,7 +88398,7 @@ async function writeSkillFiles(skillDir, files) {
|
|
|
88233
88398
|
}
|
|
88234
88399
|
}
|
|
88235
88400
|
async function writeSkillFile(skillDir, filePath, content) {
|
|
88236
|
-
const fullPath =
|
|
88401
|
+
const fullPath = resolve27(skillDir, filePath);
|
|
88237
88402
|
await mkdir7(dirname15(fullPath), { recursive: true });
|
|
88238
88403
|
await writeFile8(fullPath, content, "utf-8");
|
|
88239
88404
|
const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
|
|
@@ -88287,7 +88452,7 @@ function parseRegistryHandle(handle) {
|
|
|
88287
88452
|
}
|
|
88288
88453
|
async function importAgentFromRegistry(options) {
|
|
88289
88454
|
const { tmpdir: tmpdir4 } = await import("node:os");
|
|
88290
|
-
const { join:
|
|
88455
|
+
const { join: join35 } = await import("node:path");
|
|
88291
88456
|
const { writeFile: writeFile9, unlink: unlink3 } = await import("node:fs/promises");
|
|
88292
88457
|
const { author, name } = parseRegistryHandle(options.handle);
|
|
88293
88458
|
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER}/${AGENT_REGISTRY_REPO}/refs/heads/${AGENT_REGISTRY_BRANCH}/agents/@${author}/${name}/${name}.af`;
|
|
@@ -88299,7 +88464,7 @@ async function importAgentFromRegistry(options) {
|
|
|
88299
88464
|
throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
|
|
88300
88465
|
}
|
|
88301
88466
|
const afContent = await response.text();
|
|
88302
|
-
const tempPath =
|
|
88467
|
+
const tempPath = join35(tmpdir4(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
88303
88468
|
await writeFile9(tempPath, afContent, "utf-8");
|
|
88304
88469
|
try {
|
|
88305
88470
|
const result = await importAgentFromFile({
|
|
@@ -88540,12 +88705,12 @@ async function prepareHeadlessToolExecutionContext(params) {
|
|
|
88540
88705
|
};
|
|
88541
88706
|
}
|
|
88542
88707
|
async function flushAndExit(code) {
|
|
88543
|
-
const flushWritable = (stream2) => new Promise((
|
|
88708
|
+
const flushWritable = (stream2) => new Promise((resolve28) => {
|
|
88544
88709
|
if (stream2.destroyed || stream2.writableEnded) {
|
|
88545
|
-
|
|
88710
|
+
resolve28();
|
|
88546
88711
|
return;
|
|
88547
88712
|
}
|
|
88548
|
-
stream2.write("", () =>
|
|
88713
|
+
stream2.write("", () => resolve28());
|
|
88549
88714
|
});
|
|
88550
88715
|
await Promise.allSettled([
|
|
88551
88716
|
flushWritable(process.stdout),
|
|
@@ -89493,7 +89658,7 @@ ${loadedContents.join(`
|
|
|
89493
89658
|
} else {
|
|
89494
89659
|
console.error(`Conversation is busy, waiting ${Math.round(retryDelayMs / 1000)}s and retrying...`);
|
|
89495
89660
|
}
|
|
89496
|
-
await new Promise((
|
|
89661
|
+
await new Promise((resolve28) => setTimeout(resolve28, retryDelayMs));
|
|
89497
89662
|
continue;
|
|
89498
89663
|
}
|
|
89499
89664
|
}
|
|
@@ -89542,7 +89707,7 @@ ${loadedContents.join(`
|
|
|
89542
89707
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
89543
89708
|
console.error(`Transient API error before streaming (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
89544
89709
|
}
|
|
89545
|
-
await new Promise((
|
|
89710
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
89546
89711
|
conversationBusyRetries = 0;
|
|
89547
89712
|
continue;
|
|
89548
89713
|
}
|
|
@@ -89781,7 +89946,7 @@ ${loadedContents.join(`
|
|
|
89781
89946
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
89782
89947
|
console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
89783
89948
|
}
|
|
89784
|
-
await new Promise((
|
|
89949
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
89785
89950
|
refreshCurrentInputOtids();
|
|
89786
89951
|
continue;
|
|
89787
89952
|
}
|
|
@@ -89871,7 +90036,7 @@ ${loadedContents.join(`
|
|
|
89871
90036
|
} else {
|
|
89872
90037
|
console.error(`Empty LLM response, retrying (attempt ${attempt} of ${EMPTY_RESPONSE_MAX_RETRIES2})...`);
|
|
89873
90038
|
}
|
|
89874
|
-
await new Promise((
|
|
90039
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
89875
90040
|
refreshCurrentInputOtids();
|
|
89876
90041
|
continue;
|
|
89877
90042
|
}
|
|
@@ -89899,7 +90064,7 @@ ${loadedContents.join(`
|
|
|
89899
90064
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
89900
90065
|
console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
89901
90066
|
}
|
|
89902
|
-
await new Promise((
|
|
90067
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
89903
90068
|
refreshCurrentInputOtids();
|
|
89904
90069
|
continue;
|
|
89905
90070
|
}
|
|
@@ -89929,7 +90094,7 @@ ${loadedContents.join(`
|
|
|
89929
90094
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
89930
90095
|
console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
89931
90096
|
}
|
|
89932
|
-
await new Promise((
|
|
90097
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
89933
90098
|
refreshCurrentInputOtids();
|
|
89934
90099
|
continue;
|
|
89935
90100
|
}
|
|
@@ -90263,9 +90428,9 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
90263
90428
|
const syntheticUserLine = serializeQueuedMessageAsUserLine(queuedMessage);
|
|
90264
90429
|
maybeNotifyBlocked(syntheticUserLine);
|
|
90265
90430
|
if (lineResolver) {
|
|
90266
|
-
const
|
|
90431
|
+
const resolve28 = lineResolver;
|
|
90267
90432
|
lineResolver = null;
|
|
90268
|
-
|
|
90433
|
+
resolve28(syntheticUserLine);
|
|
90269
90434
|
return;
|
|
90270
90435
|
}
|
|
90271
90436
|
lineQueue.push(syntheticUserLine);
|
|
@@ -90273,9 +90438,9 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
90273
90438
|
rl.on("line", (line) => {
|
|
90274
90439
|
maybeNotifyBlocked(line);
|
|
90275
90440
|
if (lineResolver) {
|
|
90276
|
-
const
|
|
90441
|
+
const resolve28 = lineResolver;
|
|
90277
90442
|
lineResolver = null;
|
|
90278
|
-
|
|
90443
|
+
resolve28(line);
|
|
90279
90444
|
} else {
|
|
90280
90445
|
lineQueue.push(line);
|
|
90281
90446
|
}
|
|
@@ -90284,17 +90449,17 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
90284
90449
|
setMessageQueueAdder(null);
|
|
90285
90450
|
msgQueueRuntime.clear("shutdown");
|
|
90286
90451
|
if (lineResolver) {
|
|
90287
|
-
const
|
|
90452
|
+
const resolve28 = lineResolver;
|
|
90288
90453
|
lineResolver = null;
|
|
90289
|
-
|
|
90454
|
+
resolve28(null);
|
|
90290
90455
|
}
|
|
90291
90456
|
});
|
|
90292
90457
|
async function getNextLine() {
|
|
90293
90458
|
if (lineQueue.length > 0) {
|
|
90294
90459
|
return lineQueue.shift() ?? null;
|
|
90295
90460
|
}
|
|
90296
|
-
return new Promise((
|
|
90297
|
-
lineResolver =
|
|
90461
|
+
return new Promise((resolve28) => {
|
|
90462
|
+
lineResolver = resolve28;
|
|
90298
90463
|
});
|
|
90299
90464
|
}
|
|
90300
90465
|
async function requestPermission(toolCallId, toolName, toolInput) {
|
|
@@ -90798,7 +90963,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
90798
90963
|
uuid: `retry-bidir-${randomUUID8()}`
|
|
90799
90964
|
};
|
|
90800
90965
|
console.log(JSON.stringify(retryMsg));
|
|
90801
|
-
await new Promise((
|
|
90966
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
90802
90967
|
continue;
|
|
90803
90968
|
}
|
|
90804
90969
|
throw preStreamError;
|
|
@@ -91094,10 +91259,10 @@ async function detectAndEnableKittyProtocol() {
|
|
|
91094
91259
|
detectionComplete = true;
|
|
91095
91260
|
return;
|
|
91096
91261
|
}
|
|
91097
|
-
return new Promise((
|
|
91262
|
+
return new Promise((resolve28) => {
|
|
91098
91263
|
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
91099
91264
|
detectionComplete = true;
|
|
91100
|
-
|
|
91265
|
+
resolve28();
|
|
91101
91266
|
return;
|
|
91102
91267
|
}
|
|
91103
91268
|
const originalRawMode = process.stdin.isRaw;
|
|
@@ -91130,7 +91295,7 @@ async function detectAndEnableKittyProtocol() {
|
|
|
91130
91295
|
console.error("[kitty] protocol query unsupported; enabled anyway (best-effort)");
|
|
91131
91296
|
}
|
|
91132
91297
|
detectionComplete = true;
|
|
91133
|
-
|
|
91298
|
+
resolve28();
|
|
91134
91299
|
};
|
|
91135
91300
|
const handleData = (data) => {
|
|
91136
91301
|
if (timeoutId === undefined) {
|
|
@@ -91488,10 +91653,10 @@ __export(exports_settings, {
|
|
|
91488
91653
|
loadProjectSettings: () => loadProjectSettings,
|
|
91489
91654
|
getSetting: () => getSetting
|
|
91490
91655
|
});
|
|
91491
|
-
import { homedir as
|
|
91492
|
-
import { join as
|
|
91656
|
+
import { homedir as homedir30 } from "node:os";
|
|
91657
|
+
import { join as join36 } from "node:path";
|
|
91493
91658
|
function getSettingsPath() {
|
|
91494
|
-
return
|
|
91659
|
+
return join36(homedir30(), ".letta", "settings.json");
|
|
91495
91660
|
}
|
|
91496
91661
|
async function loadSettings() {
|
|
91497
91662
|
const settingsPath = getSettingsPath();
|
|
@@ -91528,7 +91693,7 @@ async function getSetting(key) {
|
|
|
91528
91693
|
return settings[key];
|
|
91529
91694
|
}
|
|
91530
91695
|
function getProjectSettingsPath() {
|
|
91531
|
-
return
|
|
91696
|
+
return join36(process.cwd(), ".letta", "settings.local.json");
|
|
91532
91697
|
}
|
|
91533
91698
|
async function loadProjectSettings() {
|
|
91534
91699
|
const settingsPath = getProjectSettingsPath();
|
|
@@ -91546,7 +91711,7 @@ async function loadProjectSettings() {
|
|
|
91546
91711
|
}
|
|
91547
91712
|
async function saveProjectSettings(settings) {
|
|
91548
91713
|
const settingsPath = getProjectSettingsPath();
|
|
91549
|
-
const dirPath =
|
|
91714
|
+
const dirPath = join36(process.cwd(), ".letta");
|
|
91550
91715
|
try {
|
|
91551
91716
|
if (!exists(dirPath)) {
|
|
91552
91717
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -108174,9 +108339,9 @@ function getFileEditHeader(toolName, toolArgs) {
|
|
|
108174
108339
|
const relPath = relative15(cwd2, filePath);
|
|
108175
108340
|
const displayPath = relPath.startsWith("..") ? filePath : relPath;
|
|
108176
108341
|
if (t === "write" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini") {
|
|
108177
|
-
const { existsSync:
|
|
108342
|
+
const { existsSync: existsSync28 } = __require("node:fs");
|
|
108178
108343
|
try {
|
|
108179
|
-
if (
|
|
108344
|
+
if (existsSync28(filePath)) {
|
|
108180
108345
|
return `Overwrite ${displayPath}?`;
|
|
108181
108346
|
}
|
|
108182
108347
|
} catch {}
|
|
@@ -108953,9 +109118,9 @@ function getHeaderText(fileEdit) {
|
|
|
108953
109118
|
const relPath = relative15(cwd2, fileEdit.filePath);
|
|
108954
109119
|
const displayPath = relPath.startsWith("..") ? fileEdit.filePath : relPath;
|
|
108955
109120
|
if (t === "write" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini") {
|
|
108956
|
-
const { existsSync:
|
|
109121
|
+
const { existsSync: existsSync28 } = __require("node:fs");
|
|
108957
109122
|
try {
|
|
108958
|
-
if (
|
|
109123
|
+
if (existsSync28(fileEdit.filePath)) {
|
|
108959
109124
|
return `Overwrite ${displayPath}?`;
|
|
108960
109125
|
}
|
|
108961
109126
|
} catch {}
|
|
@@ -111041,9 +111206,9 @@ html.dark .agent-name { color: var(--text-dim); }
|
|
|
111041
111206
|
var init_plan_viewer_template = () => {};
|
|
111042
111207
|
|
|
111043
111208
|
// src/web/generate-plan-viewer.ts
|
|
111044
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
111045
|
-
import { homedir as
|
|
111046
|
-
import { join as
|
|
111209
|
+
import { chmodSync as chmodSync2, existsSync as existsSync28, mkdirSync as mkdirSync21, writeFileSync as writeFileSync15 } from "node:fs";
|
|
111210
|
+
import { homedir as homedir31 } from "node:os";
|
|
111211
|
+
import { join as join37 } from "node:path";
|
|
111047
111212
|
async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
|
|
111048
111213
|
const data = {
|
|
111049
111214
|
agent: { name: options?.agentName ?? "" },
|
|
@@ -111053,14 +111218,14 @@ async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
|
|
|
111053
111218
|
};
|
|
111054
111219
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
111055
111220
|
const html = plan_viewer_template_default.replace("<!--LETTA_PLAN_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
111056
|
-
if (!
|
|
111057
|
-
|
|
111221
|
+
if (!existsSync28(VIEWERS_DIR)) {
|
|
111222
|
+
mkdirSync21(VIEWERS_DIR, { recursive: true, mode: 448 });
|
|
111058
111223
|
}
|
|
111059
111224
|
try {
|
|
111060
111225
|
chmodSync2(VIEWERS_DIR, 448);
|
|
111061
111226
|
} catch {}
|
|
111062
|
-
const filePath =
|
|
111063
|
-
|
|
111227
|
+
const filePath = join37(VIEWERS_DIR, "plan.html");
|
|
111228
|
+
writeFileSync15(filePath, html);
|
|
111064
111229
|
chmodSync2(filePath, 384);
|
|
111065
111230
|
const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
|
|
111066
111231
|
if (!skipOpen) {
|
|
@@ -111076,7 +111241,7 @@ async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
|
|
|
111076
111241
|
var VIEWERS_DIR;
|
|
111077
111242
|
var init_generate_plan_viewer = __esm(() => {
|
|
111078
111243
|
init_plan_viewer_template();
|
|
111079
|
-
VIEWERS_DIR =
|
|
111244
|
+
VIEWERS_DIR = join37(homedir31(), ".letta", "viewers");
|
|
111080
111245
|
});
|
|
111081
111246
|
|
|
111082
111247
|
// src/cli/components/StaticPlanApproval.tsx
|
|
@@ -113314,9 +113479,9 @@ var init_pasteRegistry = __esm(() => {
|
|
|
113314
113479
|
|
|
113315
113480
|
// src/cli/helpers/clipboard.ts
|
|
113316
113481
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
113317
|
-
import { existsSync as
|
|
113482
|
+
import { existsSync as existsSync29, readFileSync as readFileSync15, statSync as statSync10, unlinkSync as unlinkSync10 } from "node:fs";
|
|
113318
113483
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
113319
|
-
import { basename as basename5, extname as extname5, isAbsolute as isAbsolute19, join as
|
|
113484
|
+
import { basename as basename5, extname as extname5, isAbsolute as isAbsolute19, join as join38, resolve as resolve28 } from "node:path";
|
|
113320
113485
|
function countLines2(text) {
|
|
113321
113486
|
return (text.match(/\r\n|\r|\n/g) || []).length + 1;
|
|
113322
113487
|
}
|
|
@@ -113364,9 +113529,9 @@ function translatePasteForImages(paste) {
|
|
|
113364
113529
|
} catch {}
|
|
113365
113530
|
}
|
|
113366
113531
|
if (!isAbsolute19(filePath))
|
|
113367
|
-
filePath =
|
|
113532
|
+
filePath = resolve28(process.cwd(), filePath);
|
|
113368
113533
|
const ext3 = extname5(filePath || "").toLowerCase();
|
|
113369
|
-
if (IMAGE_EXTS.has(ext3) &&
|
|
113534
|
+
if (IMAGE_EXTS.has(ext3) && existsSync29(filePath) && statSync10(filePath).isFile()) {
|
|
113370
113535
|
const buf = readFileSync15(filePath);
|
|
113371
113536
|
const b64 = buf.toString("base64");
|
|
113372
113537
|
const mt = ext3 === ".png" ? "image/png" : ext3 === ".jpg" || ext3 === ".jpeg" ? "image/jpeg" : ext3 === ".gif" ? "image/gif" : ext3 === ".webp" ? "image/webp" : ext3 === ".bmp" ? "image/bmp" : ext3 === ".svg" ? "image/svg+xml" : ext3 === ".tif" || ext3 === ".tiff" ? "image/tiff" : ext3 === ".heic" ? "image/heic" : ext3 === ".heif" ? "image/heif" : ext3 === ".avif" ? "image/avif" : "application/octet-stream";
|
|
@@ -113384,7 +113549,7 @@ function translatePasteForImages(paste) {
|
|
|
113384
113549
|
function getClipboardImageToTempFile() {
|
|
113385
113550
|
if (process.platform !== "darwin")
|
|
113386
113551
|
return null;
|
|
113387
|
-
const tempPath =
|
|
113552
|
+
const tempPath = join38(tmpdir4(), `letta-clipboard-${Date.now()}.bin`);
|
|
113388
113553
|
try {
|
|
113389
113554
|
const jxa = `
|
|
113390
113555
|
ObjC.import('AppKit');
|
|
@@ -113407,11 +113572,11 @@ function getClipboardImageToTempFile() {
|
|
|
113407
113572
|
encoding: "utf8",
|
|
113408
113573
|
stdio: ["ignore", "pipe", "ignore"]
|
|
113409
113574
|
}).trim();
|
|
113410
|
-
if (!uti || !
|
|
113575
|
+
if (!uti || !existsSync29(tempPath))
|
|
113411
113576
|
return null;
|
|
113412
113577
|
return { tempPath, uti };
|
|
113413
113578
|
} catch {
|
|
113414
|
-
if (
|
|
113579
|
+
if (existsSync29(tempPath)) {
|
|
113415
113580
|
try {
|
|
113416
113581
|
unlinkSync10(tempPath);
|
|
113417
113582
|
} catch {}
|
|
@@ -113444,7 +113609,7 @@ async function tryImportClipboardImageMac() {
|
|
|
113444
113609
|
height: resized.height
|
|
113445
113610
|
};
|
|
113446
113611
|
} catch (err) {
|
|
113447
|
-
if (
|
|
113612
|
+
if (existsSync29(tempPath)) {
|
|
113448
113613
|
try {
|
|
113449
113614
|
unlinkSync10(tempPath);
|
|
113450
113615
|
} catch {}
|
|
@@ -114134,13 +114299,13 @@ __export(exports_terminalKeybindingInstaller, {
|
|
|
114134
114299
|
});
|
|
114135
114300
|
import {
|
|
114136
114301
|
copyFileSync,
|
|
114137
|
-
existsSync as
|
|
114138
|
-
mkdirSync as
|
|
114302
|
+
existsSync as existsSync30,
|
|
114303
|
+
mkdirSync as mkdirSync22,
|
|
114139
114304
|
readFileSync as readFileSync16,
|
|
114140
|
-
writeFileSync as
|
|
114305
|
+
writeFileSync as writeFileSync16
|
|
114141
114306
|
} from "node:fs";
|
|
114142
|
-
import { homedir as
|
|
114143
|
-
import { dirname as dirname16, join as
|
|
114307
|
+
import { homedir as homedir32, platform as platform5 } from "node:os";
|
|
114308
|
+
import { dirname as dirname16, join as join39 } from "node:path";
|
|
114144
114309
|
function detectTerminalType() {
|
|
114145
114310
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
114146
114311
|
return "cursor";
|
|
@@ -114172,16 +114337,16 @@ function getKeybindingsPath(terminal) {
|
|
|
114172
114337
|
}[terminal];
|
|
114173
114338
|
const os7 = platform5();
|
|
114174
114339
|
if (os7 === "darwin") {
|
|
114175
|
-
return
|
|
114340
|
+
return join39(homedir32(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
114176
114341
|
}
|
|
114177
114342
|
if (os7 === "win32") {
|
|
114178
114343
|
const appData = process.env.APPDATA;
|
|
114179
114344
|
if (!appData)
|
|
114180
114345
|
return null;
|
|
114181
|
-
return
|
|
114346
|
+
return join39(appData, appName, "User", "keybindings.json");
|
|
114182
114347
|
}
|
|
114183
114348
|
if (os7 === "linux") {
|
|
114184
|
-
return
|
|
114349
|
+
return join39(homedir32(), ".config", appName, "User", "keybindings.json");
|
|
114185
114350
|
}
|
|
114186
114351
|
return null;
|
|
114187
114352
|
}
|
|
@@ -114203,7 +114368,7 @@ function parseKeybindings(content) {
|
|
|
114203
114368
|
}
|
|
114204
114369
|
}
|
|
114205
114370
|
function keybindingExists(keybindingsPath) {
|
|
114206
|
-
if (!
|
|
114371
|
+
if (!existsSync30(keybindingsPath))
|
|
114207
114372
|
return false;
|
|
114208
114373
|
try {
|
|
114209
114374
|
const content = readFileSync16(keybindingsPath, { encoding: "utf-8" });
|
|
@@ -114216,7 +114381,7 @@ function keybindingExists(keybindingsPath) {
|
|
|
114216
114381
|
}
|
|
114217
114382
|
}
|
|
114218
114383
|
function createBackup(keybindingsPath) {
|
|
114219
|
-
if (!
|
|
114384
|
+
if (!existsSync30(keybindingsPath))
|
|
114220
114385
|
return null;
|
|
114221
114386
|
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
114222
114387
|
try {
|
|
@@ -114232,12 +114397,12 @@ function installKeybinding(keybindingsPath) {
|
|
|
114232
114397
|
return { success: true, alreadyExists: true };
|
|
114233
114398
|
}
|
|
114234
114399
|
const parentDir = dirname16(keybindingsPath);
|
|
114235
|
-
if (!
|
|
114236
|
-
|
|
114400
|
+
if (!existsSync30(parentDir)) {
|
|
114401
|
+
mkdirSync22(parentDir, { recursive: true });
|
|
114237
114402
|
}
|
|
114238
114403
|
let keybindings = [];
|
|
114239
114404
|
let backupPath = null;
|
|
114240
|
-
if (
|
|
114405
|
+
if (existsSync30(keybindingsPath)) {
|
|
114241
114406
|
backupPath = createBackup(keybindingsPath);
|
|
114242
114407
|
const content = readFileSync16(keybindingsPath, { encoding: "utf-8" });
|
|
114243
114408
|
const parsed = parseKeybindings(content);
|
|
@@ -114252,7 +114417,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
114252
114417
|
keybindings.push(SHIFT_ENTER_KEYBINDING);
|
|
114253
114418
|
const newContent = `${JSON.stringify(keybindings, null, 2)}
|
|
114254
114419
|
`;
|
|
114255
|
-
|
|
114420
|
+
writeFileSync16(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
114256
114421
|
return {
|
|
114257
114422
|
success: true,
|
|
114258
114423
|
backupPath: backupPath ?? undefined
|
|
@@ -114267,7 +114432,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
114267
114432
|
}
|
|
114268
114433
|
function removeKeybinding(keybindingsPath) {
|
|
114269
114434
|
try {
|
|
114270
|
-
if (!
|
|
114435
|
+
if (!existsSync30(keybindingsPath)) {
|
|
114271
114436
|
return { success: true };
|
|
114272
114437
|
}
|
|
114273
114438
|
const content = readFileSync16(keybindingsPath, { encoding: "utf-8" });
|
|
@@ -114281,7 +114446,7 @@ function removeKeybinding(keybindingsPath) {
|
|
|
114281
114446
|
const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
|
|
114282
114447
|
const newContent = `${JSON.stringify(filtered, null, 2)}
|
|
114283
114448
|
`;
|
|
114284
|
-
|
|
114449
|
+
writeFileSync16(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
114285
114450
|
return { success: true };
|
|
114286
114451
|
} catch (error) {
|
|
114287
114452
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -114334,17 +114499,17 @@ function getWezTermConfigPath() {
|
|
|
114334
114499
|
}
|
|
114335
114500
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
114336
114501
|
if (xdgConfig) {
|
|
114337
|
-
const xdgPath =
|
|
114338
|
-
if (
|
|
114502
|
+
const xdgPath = join39(xdgConfig, "wezterm", "wezterm.lua");
|
|
114503
|
+
if (existsSync30(xdgPath))
|
|
114339
114504
|
return xdgPath;
|
|
114340
114505
|
}
|
|
114341
|
-
const configPath =
|
|
114342
|
-
if (
|
|
114506
|
+
const configPath = join39(homedir32(), ".config", "wezterm", "wezterm.lua");
|
|
114507
|
+
if (existsSync30(configPath))
|
|
114343
114508
|
return configPath;
|
|
114344
|
-
return
|
|
114509
|
+
return join39(homedir32(), ".wezterm.lua");
|
|
114345
114510
|
}
|
|
114346
114511
|
function wezTermDeleteFixExists(configPath) {
|
|
114347
|
-
if (!
|
|
114512
|
+
if (!existsSync30(configPath))
|
|
114348
114513
|
return false;
|
|
114349
114514
|
try {
|
|
114350
114515
|
const content = readFileSync16(configPath, { encoding: "utf-8" });
|
|
@@ -114361,7 +114526,7 @@ function installWezTermDeleteFix() {
|
|
|
114361
114526
|
}
|
|
114362
114527
|
let content = "";
|
|
114363
114528
|
let backupPath = null;
|
|
114364
|
-
if (
|
|
114529
|
+
if (existsSync30(configPath)) {
|
|
114365
114530
|
backupPath = `${configPath}.letta-backup`;
|
|
114366
114531
|
copyFileSync(configPath, backupPath);
|
|
114367
114532
|
content = readFileSync16(configPath, { encoding: "utf-8" });
|
|
@@ -114391,10 +114556,10 @@ ${WEZTERM_DELETE_FIX}
|
|
|
114391
114556
|
`;
|
|
114392
114557
|
}
|
|
114393
114558
|
const parentDir = dirname16(configPath);
|
|
114394
|
-
if (!
|
|
114395
|
-
|
|
114559
|
+
if (!existsSync30(parentDir)) {
|
|
114560
|
+
mkdirSync22(parentDir, { recursive: true });
|
|
114396
114561
|
}
|
|
114397
|
-
|
|
114562
|
+
writeFileSync16(configPath, content, { encoding: "utf-8" });
|
|
114398
114563
|
return {
|
|
114399
114564
|
success: true,
|
|
114400
114565
|
backupPath: backupPath ?? undefined
|
|
@@ -114971,9 +115136,9 @@ __export(exports_custom, {
|
|
|
114971
115136
|
GLOBAL_COMMANDS_DIR: () => GLOBAL_COMMANDS_DIR,
|
|
114972
115137
|
COMMANDS_DIR: () => COMMANDS_DIR
|
|
114973
115138
|
});
|
|
114974
|
-
import { existsSync as
|
|
115139
|
+
import { existsSync as existsSync31 } from "node:fs";
|
|
114975
115140
|
import { readdir as readdir9, readFile as readFile11 } from "node:fs/promises";
|
|
114976
|
-
import { basename as basename6, dirname as dirname17, join as
|
|
115141
|
+
import { basename as basename6, dirname as dirname17, join as join40 } from "node:path";
|
|
114977
115142
|
async function getCustomCommands() {
|
|
114978
115143
|
if (cachedCommands !== null) {
|
|
114979
115144
|
return cachedCommands;
|
|
@@ -114984,7 +115149,7 @@ async function getCustomCommands() {
|
|
|
114984
115149
|
function refreshCustomCommands() {
|
|
114985
115150
|
cachedCommands = null;
|
|
114986
115151
|
}
|
|
114987
|
-
async function discoverCustomCommands(projectPath =
|
|
115152
|
+
async function discoverCustomCommands(projectPath = join40(process.cwd(), COMMANDS_DIR)) {
|
|
114988
115153
|
const commandsById = new Map;
|
|
114989
115154
|
const userCommands = await discoverFromDirectory(GLOBAL_COMMANDS_DIR, "user");
|
|
114990
115155
|
for (const cmd of userCommands) {
|
|
@@ -115005,7 +115170,7 @@ async function discoverCustomCommands(projectPath = join39(process.cwd(), COMMAN
|
|
|
115005
115170
|
return result;
|
|
115006
115171
|
}
|
|
115007
115172
|
async function discoverFromDirectory(dirPath, source2) {
|
|
115008
|
-
if (!
|
|
115173
|
+
if (!existsSync31(dirPath)) {
|
|
115009
115174
|
return [];
|
|
115010
115175
|
}
|
|
115011
115176
|
const commands2 = [];
|
|
@@ -115016,7 +115181,7 @@ async function findCommandFiles(currentPath, rootPath, commands2, source2) {
|
|
|
115016
115181
|
try {
|
|
115017
115182
|
const entries = await readdir9(currentPath, { withFileTypes: true });
|
|
115018
115183
|
for (const entry of entries) {
|
|
115019
|
-
const fullPath =
|
|
115184
|
+
const fullPath = join40(currentPath, entry.name);
|
|
115020
115185
|
if (entry.isDirectory()) {
|
|
115021
115186
|
await findCommandFiles(fullPath, rootPath, commands2, source2);
|
|
115022
115187
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
@@ -115101,7 +115266,7 @@ async function findCustomCommand(commandName) {
|
|
|
115101
115266
|
}
|
|
115102
115267
|
var COMMANDS_DIR = ".commands", GLOBAL_COMMANDS_DIR, cachedCommands = null;
|
|
115103
115268
|
var init_custom = __esm(() => {
|
|
115104
|
-
GLOBAL_COMMANDS_DIR =
|
|
115269
|
+
GLOBAL_COMMANDS_DIR = join40(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
|
|
115105
115270
|
});
|
|
115106
115271
|
|
|
115107
115272
|
// src/cli/components/HelpDialog.tsx
|
|
@@ -115382,12 +115547,12 @@ var init_HelpDialog = __esm(async () => {
|
|
|
115382
115547
|
});
|
|
115383
115548
|
|
|
115384
115549
|
// src/hooks/writer.ts
|
|
115385
|
-
import { homedir as
|
|
115386
|
-
import { resolve as
|
|
115550
|
+
import { homedir as homedir33 } from "node:os";
|
|
115551
|
+
import { resolve as resolve29 } from "node:path";
|
|
115387
115552
|
function isProjectSettingsPathCollidingWithGlobal2(workingDirectory) {
|
|
115388
|
-
const home = process.env.HOME ||
|
|
115389
|
-
const globalSettingsPath =
|
|
115390
|
-
const projectSettingsPath =
|
|
115553
|
+
const home = process.env.HOME || homedir33();
|
|
115554
|
+
const globalSettingsPath = resolve29(home, ".letta", "settings.json");
|
|
115555
|
+
const projectSettingsPath = resolve29(workingDirectory, ".letta", "settings.json");
|
|
115391
115556
|
return globalSettingsPath === projectSettingsPath;
|
|
115392
115557
|
}
|
|
115393
115558
|
function loadHooksFromLocation(location, workingDirectory = process.cwd()) {
|
|
@@ -118025,7 +118190,7 @@ var init_AgentInfoBar = __esm(async () => {
|
|
|
118025
118190
|
|
|
118026
118191
|
// src/cli/helpers/fileSearch.ts
|
|
118027
118192
|
import { readdirSync as readdirSync12, statSync as statSync11 } from "node:fs";
|
|
118028
|
-
import { join as
|
|
118193
|
+
import { join as join41, relative as relative15, resolve as resolve30 } from "node:path";
|
|
118029
118194
|
function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = [], depth = 0, maxDepth = 10, lowerPattern = pattern.toLowerCase()) {
|
|
118030
118195
|
if (results.length >= maxResults || depth >= maxDepth) {
|
|
118031
118196
|
return results;
|
|
@@ -118034,7 +118199,7 @@ function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = [],
|
|
|
118034
118199
|
const entries = readdirSync12(dir);
|
|
118035
118200
|
for (const entry of entries) {
|
|
118036
118201
|
try {
|
|
118037
|
-
const fullPath =
|
|
118202
|
+
const fullPath = join41(dir, entry);
|
|
118038
118203
|
const relativePath = relative15(getIndexRoot(), fullPath);
|
|
118039
118204
|
if (shouldHardExcludeEntry(entry, getIndexRoot())) {
|
|
118040
118205
|
continue;
|
|
@@ -118068,7 +118233,7 @@ async function searchFiles(query, deep = false) {
|
|
|
118068
118233
|
const dirPart = query.slice(0, lastSlashIndex);
|
|
118069
118234
|
const pattern = query.slice(lastSlashIndex + 1);
|
|
118070
118235
|
try {
|
|
118071
|
-
const resolvedDir =
|
|
118236
|
+
const resolvedDir = resolve30(getIndexRoot(), dirPart);
|
|
118072
118237
|
try {
|
|
118073
118238
|
statSync11(resolvedDir);
|
|
118074
118239
|
searchDir = resolvedDir;
|
|
@@ -118112,7 +118277,7 @@ async function searchFiles(query, deep = false) {
|
|
|
118112
118277
|
const matchingEntries = entries.filter((entry) => !shouldHardExcludeEntry(entry, getIndexRoot()) && (searchPattern.length === 0 || entry.toLowerCase().includes(lowerPattern)));
|
|
118113
118278
|
for (const entry of matchingEntries.slice(0, 50)) {
|
|
118114
118279
|
try {
|
|
118115
|
-
const fullPath =
|
|
118280
|
+
const fullPath = join41(searchDir, entry);
|
|
118116
118281
|
const stats = statSync11(fullPath);
|
|
118117
118282
|
const relativePath = relative15(getIndexRoot(), fullPath);
|
|
118118
118283
|
results.push({
|
|
@@ -120188,15 +120353,15 @@ var init_InputRich = __esm(async () => {
|
|
|
120188
120353
|
// src/cli/commands/install-github-app.ts
|
|
120189
120354
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
120190
120355
|
import {
|
|
120191
|
-
existsSync as
|
|
120192
|
-
mkdirSync as
|
|
120356
|
+
existsSync as existsSync32,
|
|
120357
|
+
mkdirSync as mkdirSync23,
|
|
120193
120358
|
mkdtempSync,
|
|
120194
120359
|
readFileSync as readFileSync17,
|
|
120195
120360
|
rmSync as rmSync4,
|
|
120196
|
-
writeFileSync as
|
|
120361
|
+
writeFileSync as writeFileSync17
|
|
120197
120362
|
} from "node:fs";
|
|
120198
120363
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
120199
|
-
import { dirname as dirname18, join as
|
|
120364
|
+
import { dirname as dirname18, join as join42 } from "node:path";
|
|
120200
120365
|
function runCommand(command, args, cwd2, input) {
|
|
120201
120366
|
try {
|
|
120202
120367
|
return execFileSync4(command, args, {
|
|
@@ -120430,8 +120595,8 @@ async function createLettaAgent(apiKey, name) {
|
|
|
120430
120595
|
return { id: data.id, name: data.name };
|
|
120431
120596
|
}
|
|
120432
120597
|
function cloneRepoToTemp(repo) {
|
|
120433
|
-
const tempDir = mkdtempSync(
|
|
120434
|
-
const repoDir =
|
|
120598
|
+
const tempDir = mkdtempSync(join42(tmpdir5(), "letta-install-github-app-"));
|
|
120599
|
+
const repoDir = join42(tempDir, "repo");
|
|
120435
120600
|
runCommand("gh", ["repo", "clone", repo, repoDir, "--", "--depth=1"]);
|
|
120436
120601
|
return { tempDir, repoDir };
|
|
120437
120602
|
}
|
|
@@ -120442,19 +120607,19 @@ function runGit6(args, cwd2) {
|
|
|
120442
120607
|
return runCommand("git", args, cwd2);
|
|
120443
120608
|
}
|
|
120444
120609
|
function writeWorkflow(repoDir, workflowPath, content) {
|
|
120445
|
-
const absolutePath =
|
|
120446
|
-
if (!
|
|
120447
|
-
|
|
120610
|
+
const absolutePath = join42(repoDir, workflowPath);
|
|
120611
|
+
if (!existsSync32(dirname18(absolutePath))) {
|
|
120612
|
+
mkdirSync23(dirname18(absolutePath), { recursive: true });
|
|
120448
120613
|
}
|
|
120449
120614
|
const next = `${content.trimEnd()}
|
|
120450
120615
|
`;
|
|
120451
|
-
if (
|
|
120616
|
+
if (existsSync32(absolutePath)) {
|
|
120452
120617
|
const previous = readFileSync17(absolutePath, "utf8");
|
|
120453
120618
|
if (previous === next) {
|
|
120454
120619
|
return false;
|
|
120455
120620
|
}
|
|
120456
120621
|
}
|
|
120457
|
-
|
|
120622
|
+
writeFileSync17(absolutePath, next, "utf8");
|
|
120458
120623
|
return true;
|
|
120459
120624
|
}
|
|
120460
120625
|
function getDefaultBaseBranch(repoDir) {
|
|
@@ -124349,9 +124514,9 @@ __export(exports_generate_memory_viewer, {
|
|
|
124349
124514
|
generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
|
|
124350
124515
|
});
|
|
124351
124516
|
import { execFile as execFileCb5 } from "node:child_process";
|
|
124352
|
-
import { chmodSync as chmodSync3, existsSync as
|
|
124353
|
-
import { homedir as
|
|
124354
|
-
import { join as
|
|
124517
|
+
import { chmodSync as chmodSync3, existsSync as existsSync33, mkdirSync as mkdirSync24, writeFileSync as writeFileSync18 } from "node:fs";
|
|
124518
|
+
import { homedir as homedir34 } from "node:os";
|
|
124519
|
+
import { join as join43 } from "node:path";
|
|
124355
124520
|
import { promisify as promisify14 } from "node:util";
|
|
124356
124521
|
async function runGitSafe(cwd2, args) {
|
|
124357
124522
|
try {
|
|
@@ -124634,14 +124799,14 @@ async function generateAndOpenMemoryViewer(agentId, options) {
|
|
|
124634
124799
|
}
|
|
124635
124800
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
124636
124801
|
const html = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
124637
|
-
if (!
|
|
124638
|
-
|
|
124802
|
+
if (!existsSync33(VIEWERS_DIR2)) {
|
|
124803
|
+
mkdirSync24(VIEWERS_DIR2, { recursive: true, mode: 448 });
|
|
124639
124804
|
}
|
|
124640
124805
|
try {
|
|
124641
124806
|
chmodSync3(VIEWERS_DIR2, 448);
|
|
124642
124807
|
} catch {}
|
|
124643
|
-
const filePath =
|
|
124644
|
-
|
|
124808
|
+
const filePath = join43(VIEWERS_DIR2, `memory-${encodeURIComponent(agentId)}.html`);
|
|
124809
|
+
writeFileSync18(filePath, html);
|
|
124645
124810
|
chmodSync3(filePath, 384);
|
|
124646
124811
|
const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
|
|
124647
124812
|
if (!skipOpen) {
|
|
@@ -124664,12 +124829,12 @@ var init_generate_memory_viewer = __esm(async () => {
|
|
|
124664
124829
|
init_memoryGit()
|
|
124665
124830
|
]);
|
|
124666
124831
|
execFile14 = promisify14(execFileCb5);
|
|
124667
|
-
VIEWERS_DIR2 =
|
|
124832
|
+
VIEWERS_DIR2 = join43(homedir34(), ".letta", "viewers");
|
|
124668
124833
|
REFLECTION_PATTERN = /\(reflection\)|🔮|reflection:/i;
|
|
124669
124834
|
});
|
|
124670
124835
|
|
|
124671
124836
|
// src/cli/components/MemfsTreeViewer.tsx
|
|
124672
|
-
import { existsSync as
|
|
124837
|
+
import { existsSync as existsSync34 } from "node:fs";
|
|
124673
124838
|
function renderTreePrefix(node) {
|
|
124674
124839
|
let prefix = "";
|
|
124675
124840
|
for (let i = 0;i < node.depth; i++) {
|
|
@@ -124695,7 +124860,7 @@ function MemfsTreeViewer({
|
|
|
124695
124860
|
const [status, setStatus] = import_react78.useState(null);
|
|
124696
124861
|
const statusTimerRef = import_react78.useRef(null);
|
|
124697
124862
|
const memoryRoot = getMemoryFilesystemRoot(agentId);
|
|
124698
|
-
const memoryExists =
|
|
124863
|
+
const memoryExists = existsSync34(memoryRoot);
|
|
124699
124864
|
const hasGitRepo = import_react78.useMemo(() => isGitRepo(agentId), [agentId]);
|
|
124700
124865
|
function showStatus(msg, durationMs) {
|
|
124701
124866
|
if (statusTimerRef.current)
|
|
@@ -127382,11 +127547,11 @@ var init_PersonalitySelector = __esm(async () => {
|
|
|
127382
127547
|
|
|
127383
127548
|
// src/utils/aws-credentials.ts
|
|
127384
127549
|
import { readFile as readFile12 } from "node:fs/promises";
|
|
127385
|
-
import { homedir as
|
|
127386
|
-
import { join as
|
|
127550
|
+
import { homedir as homedir35 } from "node:os";
|
|
127551
|
+
import { join as join44 } from "node:path";
|
|
127387
127552
|
async function parseAwsCredentials() {
|
|
127388
|
-
const credentialsPath =
|
|
127389
|
-
const configPath =
|
|
127553
|
+
const credentialsPath = join44(homedir35(), ".aws", "credentials");
|
|
127554
|
+
const configPath = join44(homedir35(), ".aws", "config");
|
|
127390
127555
|
const profiles = new Map;
|
|
127391
127556
|
try {
|
|
127392
127557
|
const content = await readFile12(credentialsPath, "utf-8");
|
|
@@ -128494,8 +128659,8 @@ function SkillsDialog({ onClose, agentId }) {
|
|
|
128494
128659
|
try {
|
|
128495
128660
|
const { discoverSkills: discoverSkills3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills(), exports_skills));
|
|
128496
128661
|
const { getSkillsDirectory: getSkillsDirectory2, getSkillSources: getSkillSources2 } = await Promise.resolve().then(() => (init_context(), exports_context));
|
|
128497
|
-
const { join:
|
|
128498
|
-
const skillsDir = getSkillsDirectory2() ||
|
|
128662
|
+
const { join: join45 } = await import("node:path");
|
|
128663
|
+
const skillsDir = getSkillsDirectory2() || join45(process.cwd(), SKILLS_DIR3);
|
|
128499
128664
|
const result = await discoverSkills3(skillsDir, agentId, {
|
|
128500
128665
|
sources: getSkillSources2()
|
|
128501
128666
|
});
|
|
@@ -132486,18 +132651,18 @@ var init_reasoningTabToggle = __esm(() => {
|
|
|
132486
132651
|
});
|
|
132487
132652
|
|
|
132488
132653
|
// src/cli/helpers/startupSystemPromptWarning.ts
|
|
132489
|
-
import { existsSync as
|
|
132490
|
-
import { join as
|
|
132654
|
+
import { existsSync as existsSync35, readdirSync as readdirSync13, readFileSync as readFileSync18 } from "node:fs";
|
|
132655
|
+
import { join as join45 } from "node:path";
|
|
132491
132656
|
function estimateSystemTokens(text) {
|
|
132492
132657
|
return Math.ceil(Buffer.byteLength(text, "utf8") / STARTUP_SYSTEM_PROMPT_ESTIMATED_BYTES_PER_TOKEN);
|
|
132493
132658
|
}
|
|
132494
132659
|
function estimateSystemPromptTokensFromMemoryDir(memoryDir) {
|
|
132495
|
-
const systemDir =
|
|
132496
|
-
if (!
|
|
132660
|
+
const systemDir = join45(memoryDir, "system");
|
|
132661
|
+
if (!existsSync35(systemDir)) {
|
|
132497
132662
|
return 0;
|
|
132498
132663
|
}
|
|
132499
132664
|
const walkMarkdownFiles = (dir) => {
|
|
132500
|
-
if (!
|
|
132665
|
+
if (!existsSync35(dir)) {
|
|
132501
132666
|
return [];
|
|
132502
132667
|
}
|
|
132503
132668
|
const out = [];
|
|
@@ -132506,7 +132671,7 @@ function estimateSystemPromptTokensFromMemoryDir(memoryDir) {
|
|
|
132506
132671
|
if (entry.name.startsWith(".")) {
|
|
132507
132672
|
continue;
|
|
132508
132673
|
}
|
|
132509
|
-
const full =
|
|
132674
|
+
const full = join45(dir, entry.name);
|
|
132510
132675
|
if (entry.isDirectory()) {
|
|
132511
132676
|
if (entry.name === ".git") {
|
|
132512
132677
|
continue;
|
|
@@ -132867,7 +133032,7 @@ async function executeStatusLineCommand(command, payload, options) {
|
|
|
132867
133032
|
};
|
|
132868
133033
|
}
|
|
132869
133034
|
function runWithLauncher(launcher, inputJson, timeout, signal, workingDirectory, startTime) {
|
|
132870
|
-
return new Promise((
|
|
133035
|
+
return new Promise((resolve31, reject) => {
|
|
132871
133036
|
const [executable, ...args] = launcher;
|
|
132872
133037
|
if (!executable) {
|
|
132873
133038
|
reject(new Error("Empty launcher"));
|
|
@@ -132880,7 +133045,7 @@ function runWithLauncher(launcher, inputJson, timeout, signal, workingDirectory,
|
|
|
132880
133045
|
const safeResolve = (result) => {
|
|
132881
133046
|
if (!resolved) {
|
|
132882
133047
|
resolved = true;
|
|
132883
|
-
|
|
133048
|
+
resolve31(result);
|
|
132884
133049
|
}
|
|
132885
133050
|
};
|
|
132886
133051
|
let child;
|
|
@@ -133325,12 +133490,12 @@ __export(exports_shellAliases, {
|
|
|
133325
133490
|
expandAliases: () => expandAliases,
|
|
133326
133491
|
clearAliasCache: () => clearAliasCache
|
|
133327
133492
|
});
|
|
133328
|
-
import { existsSync as
|
|
133329
|
-
import { homedir as
|
|
133330
|
-
import { join as
|
|
133493
|
+
import { existsSync as existsSync36, readFileSync as readFileSync19 } from "node:fs";
|
|
133494
|
+
import { homedir as homedir36 } from "node:os";
|
|
133495
|
+
import { join as join46 } from "node:path";
|
|
133331
133496
|
function parseAliasesFromFile(filePath) {
|
|
133332
133497
|
const aliases = new Map;
|
|
133333
|
-
if (!
|
|
133498
|
+
if (!existsSync36(filePath)) {
|
|
133334
133499
|
return aliases;
|
|
133335
133500
|
}
|
|
133336
133501
|
try {
|
|
@@ -133396,10 +133561,10 @@ function loadAliases(forceReload = false) {
|
|
|
133396
133561
|
if (aliasCache && !forceReload) {
|
|
133397
133562
|
return aliasCache;
|
|
133398
133563
|
}
|
|
133399
|
-
const home =
|
|
133564
|
+
const home = homedir36();
|
|
133400
133565
|
const allAliases = new Map;
|
|
133401
133566
|
for (const file of ALIAS_FILES) {
|
|
133402
|
-
const filePath =
|
|
133567
|
+
const filePath = join46(home, file);
|
|
133403
133568
|
const fileAliases = parseAliasesFromFile(filePath);
|
|
133404
133569
|
for (const [name, value] of fileAliases) {
|
|
133405
133570
|
allAliases.set(name, value);
|
|
@@ -134057,14 +134222,14 @@ __export(exports_export, {
|
|
|
134057
134222
|
packageSkills: () => packageSkills
|
|
134058
134223
|
});
|
|
134059
134224
|
import { readdir as readdir10, readFile as readFile13 } from "node:fs/promises";
|
|
134060
|
-
import { relative as relative16, resolve as
|
|
134225
|
+
import { relative as relative16, resolve as resolve31 } from "node:path";
|
|
134061
134226
|
async function packageSkills(agentId, skillsDir) {
|
|
134062
134227
|
const skills = [];
|
|
134063
134228
|
const skillNames = new Set;
|
|
134064
134229
|
const dirsToCheck = skillsDir ? [skillsDir] : [
|
|
134065
134230
|
agentId && getAgentSkillsDir(agentId),
|
|
134066
|
-
|
|
134067
|
-
|
|
134231
|
+
resolve31(process.cwd(), ".skills"),
|
|
134232
|
+
resolve31(process.env.HOME || "~", ".letta", "skills")
|
|
134068
134233
|
].filter((dir) => Boolean(dir));
|
|
134069
134234
|
for (const baseDir of dirsToCheck) {
|
|
134070
134235
|
try {
|
|
@@ -134074,8 +134239,8 @@ async function packageSkills(agentId, skillsDir) {
|
|
|
134074
134239
|
continue;
|
|
134075
134240
|
if (skillNames.has(entry.name))
|
|
134076
134241
|
continue;
|
|
134077
|
-
const skillDir =
|
|
134078
|
-
const skillMdPath =
|
|
134242
|
+
const skillDir = resolve31(baseDir, entry.name);
|
|
134243
|
+
const skillMdPath = resolve31(skillDir, "SKILL.md");
|
|
134079
134244
|
try {
|
|
134080
134245
|
await readFile13(skillMdPath, "utf-8");
|
|
134081
134246
|
} catch {
|
|
@@ -134105,7 +134270,7 @@ async function readSkillFiles(skillDir) {
|
|
|
134105
134270
|
async function walk(dir) {
|
|
134106
134271
|
const entries = await readdir10(dir, { withFileTypes: true });
|
|
134107
134272
|
for (const entry of entries) {
|
|
134108
|
-
const fullPath =
|
|
134273
|
+
const fullPath = resolve31(dir, entry.name);
|
|
134109
134274
|
if (entry.isDirectory()) {
|
|
134110
134275
|
await walk(fullPath);
|
|
134111
134276
|
} else {
|
|
@@ -134249,9 +134414,9 @@ __export(exports_App, {
|
|
|
134249
134414
|
default: () => App2
|
|
134250
134415
|
});
|
|
134251
134416
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
134252
|
-
import { existsSync as
|
|
134253
|
-
import { homedir as
|
|
134254
|
-
import { join as
|
|
134417
|
+
import { existsSync as existsSync37, readFileSync as readFileSync20, renameSync as renameSync3, writeFileSync as writeFileSync19 } from "node:fs";
|
|
134418
|
+
import { homedir as homedir37, tmpdir as tmpdir6 } from "node:os";
|
|
134419
|
+
import { join as join47, relative as relative17 } from "node:path";
|
|
134255
134420
|
function deriveReasoningEffort(modelSettings, llmConfig) {
|
|
134256
134421
|
if (modelSettings && "provider_type" in modelSettings) {
|
|
134257
134422
|
if (modelSettings.provider_type === "openai" && "reasoning" in modelSettings && modelSettings.reasoning) {
|
|
@@ -134503,14 +134668,14 @@ function saveLastSessionBeforeExit(conversationId) {
|
|
|
134503
134668
|
}
|
|
134504
134669
|
function planFileExists(fallbackPlanFilePath) {
|
|
134505
134670
|
const planFilePath = permissionMode.getPlanFilePath() ?? fallbackPlanFilePath;
|
|
134506
|
-
return !!planFilePath &&
|
|
134671
|
+
return !!planFilePath && existsSync37(planFilePath);
|
|
134507
134672
|
}
|
|
134508
134673
|
function _readPlanFile(fallbackPlanFilePath) {
|
|
134509
134674
|
const planFilePath = permissionMode.getPlanFilePath() ?? fallbackPlanFilePath;
|
|
134510
134675
|
if (!planFilePath) {
|
|
134511
134676
|
return "No plan file path set.";
|
|
134512
134677
|
}
|
|
134513
|
-
if (!
|
|
134678
|
+
if (!existsSync37(planFilePath)) {
|
|
134514
134679
|
return `Plan file not found at ${planFilePath}`;
|
|
134515
134680
|
}
|
|
134516
134681
|
try {
|
|
@@ -135841,8 +136006,8 @@ function App2({
|
|
|
135841
136006
|
if (!planFilePath)
|
|
135842
136007
|
return;
|
|
135843
136008
|
try {
|
|
135844
|
-
const { readFileSync: readFileSync21, existsSync:
|
|
135845
|
-
if (!
|
|
136009
|
+
const { readFileSync: readFileSync21, existsSync: existsSync38 } = __require("node:fs");
|
|
136010
|
+
if (!existsSync38(planFilePath))
|
|
135846
136011
|
return;
|
|
135847
136012
|
const planContent = readFileSync21(planFilePath, "utf-8");
|
|
135848
136013
|
const previewItem = {
|
|
@@ -136160,7 +136325,7 @@ function App2({
|
|
|
136160
136325
|
}
|
|
136161
136326
|
try {
|
|
136162
136327
|
const { updateConversationLLMConfig: updateConversationLLMConfig2 } = await init_modify().then(() => exports_modify);
|
|
136163
|
-
await updateConversationLLMConfig2(targetConversationId, modelHandle, Object.keys(updateArgs).length > 0 ? updateArgs : undefined);
|
|
136328
|
+
await updateConversationLLMConfig2(targetConversationId, modelHandle, Object.keys(updateArgs).length > 0 ? updateArgs : undefined, { preserveContextWindow: true });
|
|
136164
136329
|
} catch (error) {
|
|
136165
136330
|
debugWarn("conversation-model", `Failed to carry over active model to new conversation: ${error instanceof Error ? error.message : String(error)}`);
|
|
136166
136331
|
}
|
|
@@ -136256,9 +136421,9 @@ Memory may be stale. Try running: git -C ~/.letta/agents/${agentId}/memory pull`
|
|
|
136256
136421
|
(async () => {
|
|
136257
136422
|
try {
|
|
136258
136423
|
const { watch } = await import("node:fs");
|
|
136259
|
-
const { existsSync:
|
|
136424
|
+
const { existsSync: existsSync38 } = await import("node:fs");
|
|
136260
136425
|
const memRoot = getMemoryFilesystemRoot(agentId);
|
|
136261
|
-
if (!
|
|
136426
|
+
if (!existsSync38(memRoot))
|
|
136262
136427
|
return;
|
|
136263
136428
|
watcher = watch(memRoot, { recursive: true }, () => {});
|
|
136264
136429
|
memfsWatcherRef.current = watcher;
|
|
@@ -136587,7 +136752,7 @@ ${newState.originalPrompt}`,
|
|
|
136587
136752
|
cancelled = true;
|
|
136588
136753
|
break;
|
|
136589
136754
|
}
|
|
136590
|
-
await new Promise((
|
|
136755
|
+
await new Promise((resolve32) => setTimeout(resolve32, 100));
|
|
136591
136756
|
}
|
|
136592
136757
|
buffersRef.current.byId.delete(statusId);
|
|
136593
136758
|
buffersRef.current.order = buffersRef.current.order.filter((id) => id !== statusId);
|
|
@@ -136651,7 +136816,7 @@ ${newState.originalPrompt}`,
|
|
|
136651
136816
|
cancelled = true;
|
|
136652
136817
|
break;
|
|
136653
136818
|
}
|
|
136654
|
-
await new Promise((
|
|
136819
|
+
await new Promise((resolve32) => setTimeout(resolve32, 100));
|
|
136655
136820
|
}
|
|
136656
136821
|
if (retryStatusId) {
|
|
136657
136822
|
buffersRef.current.byId.delete(retryStatusId);
|
|
@@ -137409,7 +137574,7 @@ ${feedback}
|
|
|
137409
137574
|
});
|
|
137410
137575
|
buffersRef.current.order.push(statusId);
|
|
137411
137576
|
refreshDerived();
|
|
137412
|
-
await new Promise((
|
|
137577
|
+
await new Promise((resolve32) => setTimeout(resolve32, delayMs));
|
|
137413
137578
|
buffersRef.current.byId.delete(statusId);
|
|
137414
137579
|
buffersRef.current.order = buffersRef.current.order.filter((id) => id !== statusId);
|
|
137415
137580
|
refreshDerived();
|
|
@@ -137469,7 +137634,7 @@ ${feedback}
|
|
|
137469
137634
|
cancelled = true;
|
|
137470
137635
|
break;
|
|
137471
137636
|
}
|
|
137472
|
-
await new Promise((
|
|
137637
|
+
await new Promise((resolve32) => setTimeout(resolve32, 100));
|
|
137473
137638
|
}
|
|
137474
137639
|
if (retryStatusId) {
|
|
137475
137640
|
buffersRef.current.byId.delete(retryStatusId);
|
|
@@ -138651,10 +138816,10 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
|
|
|
138651
138816
|
try {
|
|
138652
138817
|
const memoryRoot = getMemoryFilesystemRoot(agentId);
|
|
138653
138818
|
const personaCandidates = [
|
|
138654
|
-
|
|
138655
|
-
|
|
138819
|
+
join47(memoryRoot, "system", "persona.md"),
|
|
138820
|
+
join47(memoryRoot, "memory", "system", "persona.md")
|
|
138656
138821
|
];
|
|
138657
|
-
const personaPath = personaCandidates.find((candidate) =>
|
|
138822
|
+
const personaPath = personaCandidates.find((candidate) => existsSync37(candidate));
|
|
138658
138823
|
if (personaPath) {
|
|
138659
138824
|
const personaContent = readFileSync20(personaPath, "utf-8");
|
|
138660
138825
|
setCurrentPersonalityId(detectPersonalityFromPersonaFile(personaContent));
|
|
@@ -139862,7 +140027,7 @@ Press Enter to continue, or type anything to cancel.`, false, "running");
|
|
|
139862
140027
|
fileContent = await client.agents.exportFile(agentId, exportParams);
|
|
139863
140028
|
}
|
|
139864
140029
|
const fileName = exportParams.conversation_id ? `${exportParams.conversation_id}.af` : `${agentId}.af`;
|
|
139865
|
-
|
|
140030
|
+
writeFileSync19(fileName, JSON.stringify(fileContent, null, 2));
|
|
139866
140031
|
let summary = `AgentFile exported to ${fileName}`;
|
|
139867
140032
|
if (skills.length > 0) {
|
|
139868
140033
|
summary += `
|
|
@@ -139952,11 +140117,11 @@ Path: ${result2.memoryDir}`, true, msg);
|
|
|
139952
140117
|
setCommandRunning(true);
|
|
139953
140118
|
try {
|
|
139954
140119
|
const memoryDir = getMemoryFilesystemRoot(agentId);
|
|
139955
|
-
if (!
|
|
140120
|
+
if (!existsSync37(memoryDir)) {
|
|
139956
140121
|
updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
|
|
139957
140122
|
return { submitted: true };
|
|
139958
140123
|
}
|
|
139959
|
-
const backupDir =
|
|
140124
|
+
const backupDir = join47(tmpdir6(), `letta-memfs-reset-${agentId}-${Date.now()}`);
|
|
139960
140125
|
renameSync3(memoryDir, backupDir);
|
|
139961
140126
|
ensureMemoryFilesystemDirs(agentId);
|
|
139962
140127
|
updateMemorySyncCommand(cmdId, `Memory filesystem reset.
|
|
@@ -139984,8 +140149,8 @@ Run \`/memfs sync\` to repopulate from API.`, true, msg);
|
|
|
139984
140149
|
await removeGitMemoryTag2(agentId);
|
|
139985
140150
|
let backupInfo = "";
|
|
139986
140151
|
const memoryDir = getMemoryFilesystemRoot(agentId);
|
|
139987
|
-
if (
|
|
139988
|
-
const backupDir =
|
|
140152
|
+
if (existsSync37(memoryDir)) {
|
|
140153
|
+
const backupDir = join47(tmpdir6(), `letta-memfs-disable-${agentId}-${Date.now()}`);
|
|
139989
140154
|
renameSync3(memoryDir, backupDir);
|
|
139990
140155
|
backupInfo = `
|
|
139991
140156
|
Local files backed up to ${backupDir}`;
|
|
@@ -141506,7 +141671,7 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
141506
141671
|
conversationModelSettings = updatedAgent?.model_settings;
|
|
141507
141672
|
} else {
|
|
141508
141673
|
const { updateConversationLLMConfig: updateConversationLLMConfig2 } = await init_modify().then(() => exports_modify);
|
|
141509
|
-
const updatedConversation = await updateConversationLLMConfig2(conversationIdRef.current, modelHandle, model.updateArgs);
|
|
141674
|
+
const updatedConversation = await updateConversationLLMConfig2(conversationIdRef.current, modelHandle, model.updateArgs, { preserveContextWindow: false });
|
|
141510
141675
|
conversationModelSettings = updatedConversation.model_settings;
|
|
141511
141676
|
}
|
|
141512
141677
|
const rawEffort = modelUpdateArgs?.reasoning_effort;
|
|
@@ -142142,7 +142307,7 @@ ${guidance}`);
|
|
|
142142
142307
|
const { updateConversationLLMConfig: updateConversationLLMConfig2 } = await init_modify().then(() => exports_modify);
|
|
142143
142308
|
const updatedConversation = await updateConversationLLMConfig2(conversationIdRef.current, desired.modelHandle, {
|
|
142144
142309
|
reasoning_effort: desired.effort
|
|
142145
|
-
});
|
|
142310
|
+
}, { preserveContextWindow: true });
|
|
142146
142311
|
conversationModelSettings = updatedConversation.model_settings;
|
|
142147
142312
|
}
|
|
142148
142313
|
const resolvedReasoningEffort = deriveReasoningEffort(isDefaultConversation ? updatedAgent?.model_settings ?? null : conversationModelSettings, llmConfigRef.current) ?? desired.effort;
|
|
@@ -142386,7 +142551,7 @@ ${guidance}`);
|
|
|
142386
142551
|
}
|
|
142387
142552
|
if (mode === "bypassPermissions") {
|
|
142388
142553
|
const planFilePath = activePlanPath ?? fallbackPlanPath;
|
|
142389
|
-
const plansDir =
|
|
142554
|
+
const plansDir = join47(homedir37(), ".letta", "plans");
|
|
142390
142555
|
handlePlanKeepPlanning(`You must write your plan to a plan file before exiting plan mode.
|
|
142391
142556
|
` + (planFilePath ? `Plan file path: ${planFilePath}
|
|
142392
142557
|
` : "") + `Use a write tool to create your plan in ${plansDir}, then use ExitPlanMode to present the plan to the user.`);
|
|
@@ -142421,7 +142586,7 @@ ${guidance}`);
|
|
|
142421
142586
|
if (!hasUsablePlan) {
|
|
142422
142587
|
lastAutoHandledExitPlanToolCallIdRef.current = approval.toolCallId;
|
|
142423
142588
|
const planFilePath = activePlanPath ?? fallbackPlanPath;
|
|
142424
|
-
const plansDir =
|
|
142589
|
+
const plansDir = join47(homedir37(), ".letta", "plans");
|
|
142425
142590
|
handlePlanKeepPlanning(`You must write your plan to a plan file before exiting plan mode.
|
|
142426
142591
|
` + (planFilePath ? `Plan file path: ${planFilePath}
|
|
142427
142592
|
` : "") + `Use a write tool to create your plan in ${plansDir}, then use ExitPlanMode to present the plan to the user.`);
|
|
@@ -143820,13 +143985,13 @@ __export(exports_terminalKeybindingInstaller2, {
|
|
|
143820
143985
|
});
|
|
143821
143986
|
import {
|
|
143822
143987
|
copyFileSync as copyFileSync2,
|
|
143823
|
-
existsSync as
|
|
143824
|
-
mkdirSync as
|
|
143988
|
+
existsSync as existsSync38,
|
|
143989
|
+
mkdirSync as mkdirSync25,
|
|
143825
143990
|
readFileSync as readFileSync21,
|
|
143826
|
-
writeFileSync as
|
|
143991
|
+
writeFileSync as writeFileSync20
|
|
143827
143992
|
} from "node:fs";
|
|
143828
|
-
import { homedir as
|
|
143829
|
-
import { dirname as dirname19, join as
|
|
143993
|
+
import { homedir as homedir38, platform as platform6 } from "node:os";
|
|
143994
|
+
import { dirname as dirname19, join as join48 } from "node:path";
|
|
143830
143995
|
function detectTerminalType2() {
|
|
143831
143996
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
143832
143997
|
return "cursor";
|
|
@@ -143858,16 +144023,16 @@ function getKeybindingsPath2(terminal) {
|
|
|
143858
144023
|
}[terminal];
|
|
143859
144024
|
const os8 = platform6();
|
|
143860
144025
|
if (os8 === "darwin") {
|
|
143861
|
-
return
|
|
144026
|
+
return join48(homedir38(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
143862
144027
|
}
|
|
143863
144028
|
if (os8 === "win32") {
|
|
143864
144029
|
const appData = process.env.APPDATA;
|
|
143865
144030
|
if (!appData)
|
|
143866
144031
|
return null;
|
|
143867
|
-
return
|
|
144032
|
+
return join48(appData, appName, "User", "keybindings.json");
|
|
143868
144033
|
}
|
|
143869
144034
|
if (os8 === "linux") {
|
|
143870
|
-
return
|
|
144035
|
+
return join48(homedir38(), ".config", appName, "User", "keybindings.json");
|
|
143871
144036
|
}
|
|
143872
144037
|
return null;
|
|
143873
144038
|
}
|
|
@@ -143889,7 +144054,7 @@ function parseKeybindings2(content) {
|
|
|
143889
144054
|
}
|
|
143890
144055
|
}
|
|
143891
144056
|
function keybindingExists2(keybindingsPath) {
|
|
143892
|
-
if (!
|
|
144057
|
+
if (!existsSync38(keybindingsPath))
|
|
143893
144058
|
return false;
|
|
143894
144059
|
try {
|
|
143895
144060
|
const content = readFileSync21(keybindingsPath, { encoding: "utf-8" });
|
|
@@ -143902,7 +144067,7 @@ function keybindingExists2(keybindingsPath) {
|
|
|
143902
144067
|
}
|
|
143903
144068
|
}
|
|
143904
144069
|
function createBackup2(keybindingsPath) {
|
|
143905
|
-
if (!
|
|
144070
|
+
if (!existsSync38(keybindingsPath))
|
|
143906
144071
|
return null;
|
|
143907
144072
|
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
143908
144073
|
try {
|
|
@@ -143918,12 +144083,12 @@ function installKeybinding2(keybindingsPath) {
|
|
|
143918
144083
|
return { success: true, alreadyExists: true };
|
|
143919
144084
|
}
|
|
143920
144085
|
const parentDir = dirname19(keybindingsPath);
|
|
143921
|
-
if (!
|
|
143922
|
-
|
|
144086
|
+
if (!existsSync38(parentDir)) {
|
|
144087
|
+
mkdirSync25(parentDir, { recursive: true });
|
|
143923
144088
|
}
|
|
143924
144089
|
let keybindings = [];
|
|
143925
144090
|
let backupPath = null;
|
|
143926
|
-
if (
|
|
144091
|
+
if (existsSync38(keybindingsPath)) {
|
|
143927
144092
|
backupPath = createBackup2(keybindingsPath);
|
|
143928
144093
|
const content = readFileSync21(keybindingsPath, { encoding: "utf-8" });
|
|
143929
144094
|
const parsed = parseKeybindings2(content);
|
|
@@ -143938,7 +144103,7 @@ function installKeybinding2(keybindingsPath) {
|
|
|
143938
144103
|
keybindings.push(SHIFT_ENTER_KEYBINDING2);
|
|
143939
144104
|
const newContent = `${JSON.stringify(keybindings, null, 2)}
|
|
143940
144105
|
`;
|
|
143941
|
-
|
|
144106
|
+
writeFileSync20(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
143942
144107
|
return {
|
|
143943
144108
|
success: true,
|
|
143944
144109
|
backupPath: backupPath ?? undefined
|
|
@@ -143953,7 +144118,7 @@ function installKeybinding2(keybindingsPath) {
|
|
|
143953
144118
|
}
|
|
143954
144119
|
function removeKeybinding2(keybindingsPath) {
|
|
143955
144120
|
try {
|
|
143956
|
-
if (!
|
|
144121
|
+
if (!existsSync38(keybindingsPath)) {
|
|
143957
144122
|
return { success: true };
|
|
143958
144123
|
}
|
|
143959
144124
|
const content = readFileSync21(keybindingsPath, { encoding: "utf-8" });
|
|
@@ -143967,7 +144132,7 @@ function removeKeybinding2(keybindingsPath) {
|
|
|
143967
144132
|
const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
|
|
143968
144133
|
const newContent = `${JSON.stringify(filtered, null, 2)}
|
|
143969
144134
|
`;
|
|
143970
|
-
|
|
144135
|
+
writeFileSync20(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
143971
144136
|
return { success: true };
|
|
143972
144137
|
} catch (error) {
|
|
143973
144138
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -144020,17 +144185,17 @@ function getWezTermConfigPath2() {
|
|
|
144020
144185
|
}
|
|
144021
144186
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
144022
144187
|
if (xdgConfig) {
|
|
144023
|
-
const xdgPath =
|
|
144024
|
-
if (
|
|
144188
|
+
const xdgPath = join48(xdgConfig, "wezterm", "wezterm.lua");
|
|
144189
|
+
if (existsSync38(xdgPath))
|
|
144025
144190
|
return xdgPath;
|
|
144026
144191
|
}
|
|
144027
|
-
const configPath =
|
|
144028
|
-
if (
|
|
144192
|
+
const configPath = join48(homedir38(), ".config", "wezterm", "wezterm.lua");
|
|
144193
|
+
if (existsSync38(configPath))
|
|
144029
144194
|
return configPath;
|
|
144030
|
-
return
|
|
144195
|
+
return join48(homedir38(), ".wezterm.lua");
|
|
144031
144196
|
}
|
|
144032
144197
|
function wezTermDeleteFixExists2(configPath) {
|
|
144033
|
-
if (!
|
|
144198
|
+
if (!existsSync38(configPath))
|
|
144034
144199
|
return false;
|
|
144035
144200
|
try {
|
|
144036
144201
|
const content = readFileSync21(configPath, { encoding: "utf-8" });
|
|
@@ -144047,7 +144212,7 @@ function installWezTermDeleteFix2() {
|
|
|
144047
144212
|
}
|
|
144048
144213
|
let content = "";
|
|
144049
144214
|
let backupPath = null;
|
|
144050
|
-
if (
|
|
144215
|
+
if (existsSync38(configPath)) {
|
|
144051
144216
|
backupPath = `${configPath}.letta-backup`;
|
|
144052
144217
|
copyFileSync2(configPath, backupPath);
|
|
144053
144218
|
content = readFileSync21(configPath, { encoding: "utf-8" });
|
|
@@ -144077,10 +144242,10 @@ ${WEZTERM_DELETE_FIX2}
|
|
|
144077
144242
|
`;
|
|
144078
144243
|
}
|
|
144079
144244
|
const parentDir = dirname19(configPath);
|
|
144080
|
-
if (!
|
|
144081
|
-
|
|
144245
|
+
if (!existsSync38(parentDir)) {
|
|
144246
|
+
mkdirSync25(parentDir, { recursive: true });
|
|
144082
144247
|
}
|
|
144083
|
-
|
|
144248
|
+
writeFileSync20(configPath, content, { encoding: "utf-8" });
|
|
144084
144249
|
return {
|
|
144085
144250
|
success: true,
|
|
144086
144251
|
backupPath: backupPath ?? undefined
|
|
@@ -144125,10 +144290,10 @@ __export(exports_settings2, {
|
|
|
144125
144290
|
loadProjectSettings: () => loadProjectSettings2,
|
|
144126
144291
|
getSetting: () => getSetting2
|
|
144127
144292
|
});
|
|
144128
|
-
import { homedir as
|
|
144129
|
-
import { join as
|
|
144293
|
+
import { homedir as homedir39 } from "node:os";
|
|
144294
|
+
import { join as join49 } from "node:path";
|
|
144130
144295
|
function getSettingsPath2() {
|
|
144131
|
-
return
|
|
144296
|
+
return join49(homedir39(), ".letta", "settings.json");
|
|
144132
144297
|
}
|
|
144133
144298
|
async function loadSettings2() {
|
|
144134
144299
|
const settingsPath = getSettingsPath2();
|
|
@@ -144165,7 +144330,7 @@ async function getSetting2(key) {
|
|
|
144165
144330
|
return settings[key];
|
|
144166
144331
|
}
|
|
144167
144332
|
function getProjectSettingsPath2() {
|
|
144168
|
-
return
|
|
144333
|
+
return join49(process.cwd(), ".letta", "settings.local.json");
|
|
144169
144334
|
}
|
|
144170
144335
|
async function loadProjectSettings2() {
|
|
144171
144336
|
const settingsPath = getProjectSettingsPath2();
|
|
@@ -144183,7 +144348,7 @@ async function loadProjectSettings2() {
|
|
|
144183
144348
|
}
|
|
144184
144349
|
async function saveProjectSettings2(settings) {
|
|
144185
144350
|
const settingsPath = getProjectSettingsPath2();
|
|
144186
|
-
const dirPath =
|
|
144351
|
+
const dirPath = join49(process.cwd(), ".letta");
|
|
144187
144352
|
try {
|
|
144188
144353
|
if (!exists(dirPath)) {
|
|
144189
144354
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -144415,7 +144580,8 @@ var init_defaults2 = __esm(async () => {
|
|
|
144415
144580
|
var exports_create2 = {};
|
|
144416
144581
|
__export(exports_create2, {
|
|
144417
144582
|
createAgentWithBaseToolsRecovery: () => createAgentWithBaseToolsRecovery2,
|
|
144418
|
-
createAgent: () => createAgent2
|
|
144583
|
+
createAgent: () => createAgent2,
|
|
144584
|
+
addBaseToolsToServer: () => addBaseToolsToServer2
|
|
144419
144585
|
});
|
|
144420
144586
|
function isToolsNotFoundError2(err) {
|
|
144421
144587
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -144650,10 +144816,10 @@ __export(exports_import2, {
|
|
|
144650
144816
|
});
|
|
144651
144817
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
144652
144818
|
import { chmod as chmod2, mkdir as mkdir8, readFile as readFile14, writeFile as writeFile9 } from "node:fs/promises";
|
|
144653
|
-
import { dirname as dirname20, resolve as
|
|
144819
|
+
import { dirname as dirname20, resolve as resolve32 } from "node:path";
|
|
144654
144820
|
async function importAgentFromFile2(options) {
|
|
144655
144821
|
const client = await getClient();
|
|
144656
|
-
const resolvedPath =
|
|
144822
|
+
const resolvedPath = resolve32(options.filePath);
|
|
144657
144823
|
const file = createReadStream2(resolvedPath);
|
|
144658
144824
|
const importResponse = await client.agents.importFile({
|
|
144659
144825
|
file,
|
|
@@ -144688,7 +144854,7 @@ async function extractSkillsFromAf2(afPath, destDir) {
|
|
|
144688
144854
|
return [];
|
|
144689
144855
|
}
|
|
144690
144856
|
for (const skill2 of afData.skills) {
|
|
144691
|
-
const skillDir =
|
|
144857
|
+
const skillDir = resolve32(destDir, skill2.name);
|
|
144692
144858
|
await mkdir8(skillDir, { recursive: true });
|
|
144693
144859
|
if (skill2.files) {
|
|
144694
144860
|
await writeSkillFiles2(skillDir, skill2.files);
|
|
@@ -144708,7 +144874,7 @@ async function writeSkillFiles2(skillDir, files) {
|
|
|
144708
144874
|
}
|
|
144709
144875
|
}
|
|
144710
144876
|
async function writeSkillFile2(skillDir, filePath, content) {
|
|
144711
|
-
const fullPath =
|
|
144877
|
+
const fullPath = resolve32(skillDir, filePath);
|
|
144712
144878
|
await mkdir8(dirname20(fullPath), { recursive: true });
|
|
144713
144879
|
await writeFile9(fullPath, content, "utf-8");
|
|
144714
144880
|
const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
|
|
@@ -144762,7 +144928,7 @@ function parseRegistryHandle2(handle) {
|
|
|
144762
144928
|
}
|
|
144763
144929
|
async function importAgentFromRegistry2(options) {
|
|
144764
144930
|
const { tmpdir: tmpdir7 } = await import("node:os");
|
|
144765
|
-
const { join:
|
|
144931
|
+
const { join: join50 } = await import("node:path");
|
|
144766
144932
|
const { writeFile: writeFile10, unlink: unlink3 } = await import("node:fs/promises");
|
|
144767
144933
|
const { author, name } = parseRegistryHandle2(options.handle);
|
|
144768
144934
|
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER2}/${AGENT_REGISTRY_REPO2}/refs/heads/${AGENT_REGISTRY_BRANCH2}/agents/@${author}/${name}/${name}.af`;
|
|
@@ -144774,7 +144940,7 @@ async function importAgentFromRegistry2(options) {
|
|
|
144774
144940
|
throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
|
|
144775
144941
|
}
|
|
144776
144942
|
const afContent = await response.text();
|
|
144777
|
-
const tempPath =
|
|
144943
|
+
const tempPath = join50(tmpdir7(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
144778
144944
|
await writeFile10(tempPath, afContent, "utf-8");
|
|
144779
144945
|
try {
|
|
144780
144946
|
const result = await importAgentFromFile2({
|
|
@@ -144818,23 +144984,23 @@ __export(exports_memoryFilesystem2, {
|
|
|
144818
144984
|
MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR2,
|
|
144819
144985
|
MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR2
|
|
144820
144986
|
});
|
|
144821
|
-
import { existsSync as
|
|
144822
|
-
import { homedir as
|
|
144823
|
-
import { join as
|
|
144824
|
-
function getMemoryFilesystemRoot2(agentId, homeDir =
|
|
144825
|
-
return
|
|
144987
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync26 } from "node:fs";
|
|
144988
|
+
import { homedir as homedir40 } from "node:os";
|
|
144989
|
+
import { join as join50 } from "node:path";
|
|
144990
|
+
function getMemoryFilesystemRoot2(agentId, homeDir = homedir40()) {
|
|
144991
|
+
return join50(homeDir, MEMORY_FS_ROOT2, MEMORY_FS_AGENTS_DIR2, agentId, MEMORY_FS_MEMORY_DIR2);
|
|
144826
144992
|
}
|
|
144827
|
-
function getMemorySystemDir2(agentId, homeDir =
|
|
144828
|
-
return
|
|
144993
|
+
function getMemorySystemDir2(agentId, homeDir = homedir40()) {
|
|
144994
|
+
return join50(getMemoryFilesystemRoot2(agentId, homeDir), MEMORY_SYSTEM_DIR2);
|
|
144829
144995
|
}
|
|
144830
|
-
function ensureMemoryFilesystemDirs2(agentId, homeDir =
|
|
144996
|
+
function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir40()) {
|
|
144831
144997
|
const root = getMemoryFilesystemRoot2(agentId, homeDir);
|
|
144832
144998
|
const systemDir = getMemorySystemDir2(agentId, homeDir);
|
|
144833
|
-
if (!
|
|
144834
|
-
|
|
144999
|
+
if (!existsSync39(root)) {
|
|
145000
|
+
mkdirSync26(root, { recursive: true });
|
|
144835
145001
|
}
|
|
144836
|
-
if (!
|
|
144837
|
-
|
|
145002
|
+
if (!existsSync39(systemDir)) {
|
|
145003
|
+
mkdirSync26(systemDir, { recursive: true });
|
|
144838
145004
|
}
|
|
144839
145005
|
}
|
|
144840
145006
|
function labelFromRelativePath2(relativePath) {
|
|
@@ -149272,11 +149438,11 @@ async function runListenSubcommand(argv) {
|
|
|
149272
149438
|
connectionName = hostname3();
|
|
149273
149439
|
settingsManager.setListenerEnvName(connectionName);
|
|
149274
149440
|
} else {
|
|
149275
|
-
connectionName = await new Promise((
|
|
149441
|
+
connectionName = await new Promise((resolve24) => {
|
|
149276
149442
|
const { unmount } = render_default(/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(PromptEnvName, {
|
|
149277
149443
|
onSubmit: (name) => {
|
|
149278
149444
|
unmount();
|
|
149279
|
-
|
|
149445
|
+
resolve24(name);
|
|
149280
149446
|
}
|
|
149281
149447
|
}, undefined, false, undefined, this));
|
|
149282
149448
|
});
|
|
@@ -149334,7 +149500,11 @@ async function runListenSubcommand(argv) {
|
|
|
149334
149500
|
sessionLog.log(`Re-registered: connectionId=${result.connectionId}`);
|
|
149335
149501
|
return result;
|
|
149336
149502
|
};
|
|
149503
|
+
const shouldLogWsEvents = debugMode || process.env.LETTA_LOG_WS_EVENTS === "1";
|
|
149337
149504
|
const wsEventLogger = (direction, label, event) => {
|
|
149505
|
+
if (!shouldLogWsEvents) {
|
|
149506
|
+
return;
|
|
149507
|
+
}
|
|
149338
149508
|
sessionLog.wsEvent(direction, label, event);
|
|
149339
149509
|
if (debugMode) {
|
|
149340
149510
|
const arrow = direction === "send" ? "→ send" : "← recv";
|
|
@@ -149350,7 +149520,7 @@ async function runListenSubcommand(argv) {
|
|
|
149350
149520
|
wsUrl: url,
|
|
149351
149521
|
deviceId,
|
|
149352
149522
|
connectionName,
|
|
149353
|
-
onWsEvent: wsEventLogger,
|
|
149523
|
+
onWsEvent: shouldLogWsEvents ? wsEventLogger : undefined,
|
|
149354
149524
|
onStatusChange: (status) => {
|
|
149355
149525
|
sessionLog.log(`status: ${status}`);
|
|
149356
149526
|
console.log(`[${formatTimestamp3()}] status: ${status}`);
|
|
@@ -149409,7 +149579,7 @@ async function runListenSubcommand(argv) {
|
|
|
149409
149579
|
wsUrl: url,
|
|
149410
149580
|
deviceId,
|
|
149411
149581
|
connectionName,
|
|
149412
|
-
onWsEvent: wsEventLogger,
|
|
149582
|
+
onWsEvent: shouldLogWsEvents ? wsEventLogger : undefined,
|
|
149413
149583
|
onStatusChange: (status) => {
|
|
149414
149584
|
sessionLog.log(`status: ${status}`);
|
|
149415
149585
|
clearRetryStatusCallback?.();
|
|
@@ -149711,7 +149881,7 @@ async function runMemfsSubcommand(argv) {
|
|
|
149711
149881
|
// src/cli/subcommands/messages.ts
|
|
149712
149882
|
await init_client2();
|
|
149713
149883
|
import { writeFile as writeFile6 } from "node:fs/promises";
|
|
149714
|
-
import { resolve as
|
|
149884
|
+
import { resolve as resolve24 } from "node:path";
|
|
149715
149885
|
import { parseArgs as parseArgs8 } from "node:util";
|
|
149716
149886
|
function printUsage5() {
|
|
149717
149887
|
console.log(`
|
|
@@ -150015,7 +150185,7 @@ async function runMessagesSubcommand(argv) {
|
|
|
150015
150185
|
|
|
150016
150186
|
`).trim();
|
|
150017
150187
|
if (outputPathRaw && typeof outputPathRaw === "string") {
|
|
150018
|
-
const outputPath =
|
|
150188
|
+
const outputPath = resolve24(process.cwd(), outputPathRaw);
|
|
150019
150189
|
await writeFile6(outputPath, `${transcript}
|
|
150020
150190
|
`, "utf-8");
|
|
150021
150191
|
console.log(JSON.stringify({
|
|
@@ -150241,6 +150411,7 @@ class PermissionModeManager2 {
|
|
|
150241
150411
|
"Edit",
|
|
150242
150412
|
"MultiEdit",
|
|
150243
150413
|
"NotebookEdit",
|
|
150414
|
+
"memory",
|
|
150244
150415
|
"apply_patch",
|
|
150245
150416
|
"ApplyPatch",
|
|
150246
150417
|
"memory_apply_patch",
|
|
@@ -150477,7 +150648,7 @@ await __promiseAll([
|
|
|
150477
150648
|
]);
|
|
150478
150649
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
150479
150650
|
import { homedir as homedir25 } from "node:os";
|
|
150480
|
-
import { join as join29, resolve as
|
|
150651
|
+
import { join as join29, resolve as resolve25 } from "node:path";
|
|
150481
150652
|
var DEFAULT_SETTINGS3 = {
|
|
150482
150653
|
lastAgent: null,
|
|
150483
150654
|
tokenStreaming: false,
|
|
@@ -150931,7 +151102,7 @@ class SettingsManager2 {
|
|
|
150931
151102
|
return join29(workingDirectory, ".letta", "settings.json");
|
|
150932
151103
|
}
|
|
150933
151104
|
isProjectSettingsPathCollidingWithGlobal(workingDirectory) {
|
|
150934
|
-
return
|
|
151105
|
+
return resolve25(this.getProjectSettingsPath(workingDirectory)) === resolve25(this.getSettingsPath());
|
|
150935
151106
|
}
|
|
150936
151107
|
getLocalProjectSettingsPath(workingDirectory) {
|
|
150937
151108
|
return join29(workingDirectory, ".letta", "settings.local.json");
|
|
@@ -151893,8 +152064,8 @@ function acquireSwitchLock2() {
|
|
|
151893
152064
|
const lock = getSwitchLock2();
|
|
151894
152065
|
lock.refCount++;
|
|
151895
152066
|
if (lock.refCount === 1) {
|
|
151896
|
-
lock.promise = new Promise((
|
|
151897
|
-
lock.resolve =
|
|
152067
|
+
lock.promise = new Promise((resolve26) => {
|
|
152068
|
+
lock.resolve = resolve26;
|
|
151898
152069
|
});
|
|
151899
152070
|
}
|
|
151900
152071
|
}
|
|
@@ -152204,12 +152375,12 @@ EXAMPLES
|
|
|
152204
152375
|
console.log(usage);
|
|
152205
152376
|
}
|
|
152206
152377
|
async function printInfo() {
|
|
152207
|
-
const { join:
|
|
152378
|
+
const { join: join51 } = await import("path");
|
|
152208
152379
|
const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version2(), exports_version));
|
|
152209
152380
|
const { SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills2(), exports_skills2));
|
|
152210
152381
|
const { exists: exists3 } = await Promise.resolve().then(() => (init_fs2(), exports_fs));
|
|
152211
152382
|
const cwd2 = process.cwd();
|
|
152212
|
-
const skillsDir =
|
|
152383
|
+
const skillsDir = join51(cwd2, SKILLS_DIR3);
|
|
152213
152384
|
const skillsExist = exists3(skillsDir);
|
|
152214
152385
|
await settingsManager2.loadLocalProjectSettings(cwd2);
|
|
152215
152386
|
const localPinned = settingsManager2.getLocalPinnedAgents(cwd2);
|
|
@@ -152339,6 +152510,8 @@ async function main() {
|
|
|
152339
152510
|
await settingsManager2.initialize();
|
|
152340
152511
|
const settings = await settingsManager2.getSettingsWithSecureTokens();
|
|
152341
152512
|
markMilestone2("SETTINGS_LOADED");
|
|
152513
|
+
const { bootstrapBaseToolsIfNeeded: bootstrapBaseToolsIfNeeded2 } = await init_bootstrap_tools().then(() => exports_bootstrap_tools);
|
|
152514
|
+
await bootstrapBaseToolsIfNeeded2();
|
|
152342
152515
|
const subcommandResult = await runSubcommand(process.argv.slice(2));
|
|
152343
152516
|
if (subcommandResult !== null) {
|
|
152344
152517
|
process.exit(subcommandResult);
|
|
@@ -152379,7 +152552,7 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
152379
152552
|
printHelp();
|
|
152380
152553
|
const helpDelayMs = Number.parseInt(process.env.LETTA_TEST_HELP_EXIT_DELAY_MS ?? "", 10);
|
|
152381
152554
|
if (Number.isFinite(helpDelayMs) && helpDelayMs > 0) {
|
|
152382
|
-
await new Promise((
|
|
152555
|
+
await new Promise((resolve33) => setTimeout(resolve33, helpDelayMs));
|
|
152383
152556
|
}
|
|
152384
152557
|
process.exit(0);
|
|
152385
152558
|
}
|
|
@@ -152601,10 +152774,10 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
152601
152774
|
process.exit(1);
|
|
152602
152775
|
}
|
|
152603
152776
|
} else {
|
|
152604
|
-
const { resolve:
|
|
152605
|
-
const { existsSync:
|
|
152606
|
-
const resolvedPath =
|
|
152607
|
-
if (!
|
|
152777
|
+
const { resolve: resolve33 } = await import("path");
|
|
152778
|
+
const { existsSync: existsSync40 } = await import("fs");
|
|
152779
|
+
const resolvedPath = resolve33(fromAfFile);
|
|
152780
|
+
if (!existsSync40(resolvedPath)) {
|
|
152608
152781
|
console.error(`Error: AgentFile not found: ${resolvedPath}`);
|
|
152609
152782
|
process.exit(1);
|
|
152610
152783
|
}
|
|
@@ -153479,4 +153652,4 @@ Error during initialization: ${message}`);
|
|
|
153479
153652
|
}
|
|
153480
153653
|
main();
|
|
153481
153654
|
|
|
153482
|
-
//# debugId=
|
|
153655
|
+
//# debugId=EB5AD8CB3C0EDF1664756E2164756E21
|