@letta-ai/letta-code 0.27.24 → 0.27.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/types/types/protocol_v2.d.ts +16 -0
- package/dist/types/types/protocol_v2.d.ts.map +1 -1
- package/letta.js +474 -300
- package/package.json +2 -1
- package/scripts/check-skill-frontmatter.js +116 -0
- package/scripts/check.js +1 -0
package/letta.js
CHANGED
|
@@ -4672,7 +4672,7 @@ var package_default;
|
|
|
4672
4672
|
var init_package = __esm(() => {
|
|
4673
4673
|
package_default = {
|
|
4674
4674
|
name: "@letta-ai/letta-code",
|
|
4675
|
-
version: "0.27.
|
|
4675
|
+
version: "0.27.25",
|
|
4676
4676
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
4677
4677
|
type: "module",
|
|
4678
4678
|
packageManager: "bun@1.3.0",
|
|
@@ -4769,6 +4769,7 @@ var init_package = __esm(() => {
|
|
|
4769
4769
|
"check:filename-casing": "node scripts/check-filename-casing.js",
|
|
4770
4770
|
"check:test-mock-isolation": "bun run scripts/check-test-mock-isolation.js",
|
|
4771
4771
|
"check:test-coverage": "node scripts/check-test-coverage.cjs",
|
|
4772
|
+
"check:skill-frontmatter": "node scripts/check-skill-frontmatter.js",
|
|
4772
4773
|
"check:bundled-skill-scripts": "node scripts/check-bundled-skill-scripts.js",
|
|
4773
4774
|
check: "bun run scripts/check.js",
|
|
4774
4775
|
dev: "node scripts/dev.cjs",
|
|
@@ -4909,7 +4910,7 @@ async function forkConversation(conversationId, options = {}) {
|
|
|
4909
4910
|
...options.agentId ? { agent_id: options.agentId } : {},
|
|
4910
4911
|
...options.hidden !== undefined ? { hidden: options.hidden } : {}
|
|
4911
4912
|
};
|
|
4912
|
-
return apiRequest("POST", `/v1/conversations/${encodeURIComponent(conversationId)}/fork`, undefined, { query });
|
|
4913
|
+
return apiRequest("POST", `/v1/conversations/${encodeURIComponent(conversationId)}/fork`, undefined, { query, ...options.headers ? { headers: options.headers } : {} });
|
|
4913
4914
|
}
|
|
4914
4915
|
async function updateConversationDescription(conversationId, body) {
|
|
4915
4916
|
return apiRequest("PATCH", `/v1/conversations/${encodeURIComponent(conversationId)}`, body);
|
|
@@ -441061,6 +441062,15 @@ var init_file_commands = __esm(async () => {
|
|
|
441061
441062
|
ignoreConfigCache = new Map;
|
|
441062
441063
|
});
|
|
441063
441064
|
|
|
441065
|
+
// src/agent/acting-user.ts
|
|
441066
|
+
function actingUserRequestOptions(actingUserId) {
|
|
441067
|
+
if (!actingUserId) {
|
|
441068
|
+
return;
|
|
441069
|
+
}
|
|
441070
|
+
return { headers: { [ACTING_USER_ID_HEADER]: actingUserId } };
|
|
441071
|
+
}
|
|
441072
|
+
var ACTING_USER_ID_HEADER = "X-Letta-Acting-User-Id";
|
|
441073
|
+
|
|
441064
441074
|
// src/agent/max-context.ts
|
|
441065
441075
|
function buildModelHandleFromConfig4(config3) {
|
|
441066
441076
|
if (!config3)
|
|
@@ -441463,10 +441473,15 @@ function buildDoctorMessage(args) {
|
|
|
441463
441473
|
## Memory filesystem
|
|
441464
441474
|
|
|
441465
441475
|
Memory filesystem is enabled. Memory directory: \`${args.memoryDir}\`
|
|
441476
|
+
` : "";
|
|
441477
|
+
const skillRepairSection = args.skillNameFrontmatterRepairReport ? `
|
|
441478
|
+
## Automatic skill metadata repair
|
|
441479
|
+
|
|
441480
|
+
${args.skillNameFrontmatterRepairReport}
|
|
441466
441481
|
` : "";
|
|
441467
441482
|
return `${SYSTEM_REMINDER_OPEN}
|
|
441468
441483
|
The user has requested a memory structure check via /doctor.
|
|
441469
|
-
${memfsSection}
|
|
441484
|
+
${memfsSection}${skillRepairSection}
|
|
441470
441485
|
## 1. Invoke the context-doctor skill
|
|
441471
441486
|
|
|
441472
441487
|
Use the \`Skill\` tool with \`skill: "context-doctor"\` to load guidance for memory structure refinement.
|
|
@@ -441484,6 +441499,150 @@ var init_init_command = __esm(() => {
|
|
|
441484
441499
|
init_git_context();
|
|
441485
441500
|
});
|
|
441486
441501
|
|
|
441502
|
+
// src/cli/helpers/skill-name-frontmatter-repair.ts
|
|
441503
|
+
import { readdir as readdir11, readFile as readFile18, stat as stat13, writeFile as writeFile14 } from "node:fs/promises";
|
|
441504
|
+
import { basename as basename23, dirname as dirname24, join as join48, relative as relative10 } from "node:path";
|
|
441505
|
+
async function pathExists(path36) {
|
|
441506
|
+
try {
|
|
441507
|
+
await stat13(path36);
|
|
441508
|
+
return true;
|
|
441509
|
+
} catch {
|
|
441510
|
+
return false;
|
|
441511
|
+
}
|
|
441512
|
+
}
|
|
441513
|
+
async function findSkillMarkdownFiles(root2) {
|
|
441514
|
+
const entries = await readdir11(root2, { withFileTypes: true });
|
|
441515
|
+
const files = [];
|
|
441516
|
+
for (const entry of entries) {
|
|
441517
|
+
if (entry.name === ".git" || entry.name === "node_modules") {
|
|
441518
|
+
continue;
|
|
441519
|
+
}
|
|
441520
|
+
const fullPath = join48(root2, entry.name);
|
|
441521
|
+
if (entry.isSymbolicLink()) {
|
|
441522
|
+
continue;
|
|
441523
|
+
}
|
|
441524
|
+
if (entry.isDirectory()) {
|
|
441525
|
+
files.push(...await findSkillMarkdownFiles(fullPath));
|
|
441526
|
+
continue;
|
|
441527
|
+
}
|
|
441528
|
+
if (entry.isFile() && entry.name === "SKILL.md") {
|
|
441529
|
+
files.push(fullPath);
|
|
441530
|
+
}
|
|
441531
|
+
}
|
|
441532
|
+
return files;
|
|
441533
|
+
}
|
|
441534
|
+
function formatYamlScalar(value) {
|
|
441535
|
+
if (/^[A-Za-z0-9_-]+$/.test(value)) {
|
|
441536
|
+
return value;
|
|
441537
|
+
}
|
|
441538
|
+
return JSON.stringify(value);
|
|
441539
|
+
}
|
|
441540
|
+
function isNonEmptyNameLine(line) {
|
|
441541
|
+
const match4 = line.match(/^\s*name\s*:\s*(.*?)\s*$/);
|
|
441542
|
+
return !!match4?.[1]?.trim();
|
|
441543
|
+
}
|
|
441544
|
+
function repairSkillNameFrontmatterContent(content, skillName) {
|
|
441545
|
+
if (!skillName.trim()) {
|
|
441546
|
+
return {
|
|
441547
|
+
content,
|
|
441548
|
+
changed: false,
|
|
441549
|
+
reason: "skill directory name is empty"
|
|
441550
|
+
};
|
|
441551
|
+
}
|
|
441552
|
+
const match4 = content.match(FRONTMATTER_REGEX2);
|
|
441553
|
+
if (!match4) {
|
|
441554
|
+
return {
|
|
441555
|
+
content,
|
|
441556
|
+
changed: false,
|
|
441557
|
+
reason: "missing YAML frontmatter"
|
|
441558
|
+
};
|
|
441559
|
+
}
|
|
441560
|
+
const opening2 = match4[1] ?? "";
|
|
441561
|
+
const frontmatter = match4[2] ?? "";
|
|
441562
|
+
const closing2 = match4[3] ?? "";
|
|
441563
|
+
const newline = opening2.includes(`\r
|
|
441564
|
+
`) ? `\r
|
|
441565
|
+
` : `
|
|
441566
|
+
`;
|
|
441567
|
+
const lines = frontmatter.replace(/\r\n/g, `
|
|
441568
|
+
`).split(`
|
|
441569
|
+
`);
|
|
441570
|
+
const nameLineIndex = lines.findIndex((line) => /^\s*name\s*:/.test(line));
|
|
441571
|
+
if (nameLineIndex >= 0 && isNonEmptyNameLine(lines[nameLineIndex] ?? "")) {
|
|
441572
|
+
return { content, changed: false };
|
|
441573
|
+
}
|
|
441574
|
+
const nameLine = `name: ${formatYamlScalar(skillName.trim())}`;
|
|
441575
|
+
if (nameLineIndex >= 0) {
|
|
441576
|
+
lines[nameLineIndex] = nameLine;
|
|
441577
|
+
} else {
|
|
441578
|
+
lines.unshift(nameLine);
|
|
441579
|
+
}
|
|
441580
|
+
const nextContent = `${opening2}${lines.join(newline)}${closing2}${content.slice(match4[0].length)}`;
|
|
441581
|
+
return { content: nextContent, changed: true };
|
|
441582
|
+
}
|
|
441583
|
+
async function repairMissingSkillNameFrontmatter(memoryDir) {
|
|
441584
|
+
const result = {
|
|
441585
|
+
scanned: 0,
|
|
441586
|
+
repaired: [],
|
|
441587
|
+
skipped: []
|
|
441588
|
+
};
|
|
441589
|
+
if (!memoryDir) {
|
|
441590
|
+
return result;
|
|
441591
|
+
}
|
|
441592
|
+
const skillsDir = join48(memoryDir, "skills");
|
|
441593
|
+
if (!await pathExists(skillsDir)) {
|
|
441594
|
+
return result;
|
|
441595
|
+
}
|
|
441596
|
+
let skillFiles;
|
|
441597
|
+
try {
|
|
441598
|
+
skillFiles = await findSkillMarkdownFiles(skillsDir);
|
|
441599
|
+
} catch (error54) {
|
|
441600
|
+
result.skipped.push({
|
|
441601
|
+
path: "skills/",
|
|
441602
|
+
reason: `failed to scan skills directory: ${error54 instanceof Error ? error54.message : String(error54)}`
|
|
441603
|
+
});
|
|
441604
|
+
return result;
|
|
441605
|
+
}
|
|
441606
|
+
for (const skillFile of skillFiles.sort()) {
|
|
441607
|
+
const displayPath = relative10(memoryDir, skillFile).replace(/\\/g, "/");
|
|
441608
|
+
result.scanned++;
|
|
441609
|
+
try {
|
|
441610
|
+
const content = await readFile18(skillFile, "utf8");
|
|
441611
|
+
const repair3 = repairSkillNameFrontmatterContent(content, basename23(dirname24(skillFile)));
|
|
441612
|
+
if (repair3.reason) {
|
|
441613
|
+
result.skipped.push({ path: displayPath, reason: repair3.reason });
|
|
441614
|
+
continue;
|
|
441615
|
+
}
|
|
441616
|
+
if (!repair3.changed) {
|
|
441617
|
+
continue;
|
|
441618
|
+
}
|
|
441619
|
+
await writeFile14(skillFile, repair3.content, "utf8");
|
|
441620
|
+
result.repaired.push(displayPath);
|
|
441621
|
+
} catch (error54) {
|
|
441622
|
+
result.skipped.push({
|
|
441623
|
+
path: displayPath,
|
|
441624
|
+
reason: error54 instanceof Error ? error54.message : String(error54)
|
|
441625
|
+
});
|
|
441626
|
+
}
|
|
441627
|
+
}
|
|
441628
|
+
return result;
|
|
441629
|
+
}
|
|
441630
|
+
function formatSkillNameFrontmatterRepairReport(result) {
|
|
441631
|
+
const sections = [];
|
|
441632
|
+
if (result.repaired.length > 0) {
|
|
441633
|
+
sections.push(`- Added missing \`name:\` frontmatter to ${result.repaired.length} skill${result.repaired.length === 1 ? "" : "s"}: ${result.repaired.map((path36) => `\`${path36}\``).join(", ")}`);
|
|
441634
|
+
}
|
|
441635
|
+
if (result.skipped.length > 0) {
|
|
441636
|
+
sections.push(`- Could not automatically repair ${result.skipped.length} skill${result.skipped.length === 1 ? "" : "s"}: ${result.skipped.map((item) => `\`${item.path}\` (${item.reason})`).join(", ")}`);
|
|
441637
|
+
}
|
|
441638
|
+
return sections.join(`
|
|
441639
|
+
`);
|
|
441640
|
+
}
|
|
441641
|
+
var FRONTMATTER_REGEX2;
|
|
441642
|
+
var init_skill_name_frontmatter_repair = __esm(() => {
|
|
441643
|
+
FRONTMATTER_REGEX2 = /^(---\r?\n)([\s\S]*?)(\r?\n---(?:\r?\n|$))/;
|
|
441644
|
+
});
|
|
441645
|
+
|
|
441487
441646
|
// src/websocket/listener/commands/secrets.ts
|
|
441488
441647
|
function markSecretsReminderRefreshPending(runtime, agentId) {
|
|
441489
441648
|
const prefix = `agent:${agentId}::conversation:`;
|
|
@@ -441588,7 +441747,10 @@ async function handleExecuteCommand(command, socket, conversationRuntime, opts)
|
|
|
441588
441747
|
let output;
|
|
441589
441748
|
switch (command.command_id) {
|
|
441590
441749
|
case "clear":
|
|
441591
|
-
output = await handleClearCommand(socket, conversationRuntime,
|
|
441750
|
+
output = await handleClearCommand(socket, conversationRuntime, {
|
|
441751
|
+
...opts,
|
|
441752
|
+
actingUserId: command.runtime.acting_user_id
|
|
441753
|
+
});
|
|
441592
441754
|
break;
|
|
441593
441755
|
case "doctor":
|
|
441594
441756
|
output = await handleDoctorCommand(socket, conversationRuntime, opts);
|
|
@@ -441875,7 +442037,7 @@ async function handleClearCommand(_socket, conversationRuntime, opts) {
|
|
|
441875
442037
|
}
|
|
441876
442038
|
const conversation = await backend4.createConversation({
|
|
441877
442039
|
agent_id: agentId
|
|
441878
|
-
});
|
|
442040
|
+
}, actingUserRequestOptions(opts.actingUserId));
|
|
441879
442041
|
clearConversationRuntimeState(conversationRuntime);
|
|
441880
442042
|
conversationRuntime.conversationId = conversation.id;
|
|
441881
442043
|
emitListenerStatus(conversationRuntime.listener, opts.onStatusChange, opts.connectionId);
|
|
@@ -441888,7 +442050,13 @@ async function handleDoctorCommand(socket, conversationRuntime, opts) {
|
|
|
441888
442050
|
}
|
|
441889
442051
|
const { context: gitContext } = gatherInitGitContext();
|
|
441890
442052
|
const memoryDir = settingsManager.isMemfsEnabled(agentId) ? getScopedMemoryFilesystemRoot(agentId) : undefined;
|
|
441891
|
-
const
|
|
442053
|
+
const skillNameFrontmatterRepair = await repairMissingSkillNameFrontmatter(memoryDir);
|
|
442054
|
+
const skillNameFrontmatterRepairReport = formatSkillNameFrontmatterRepairReport(skillNameFrontmatterRepair);
|
|
442055
|
+
const doctorMessage = buildDoctorMessage({
|
|
442056
|
+
gitContext,
|
|
442057
|
+
memoryDir,
|
|
442058
|
+
skillNameFrontmatterRepairReport
|
|
442059
|
+
});
|
|
441892
442060
|
await handleIncomingMessage({
|
|
441893
442061
|
type: "message",
|
|
441894
442062
|
agentId,
|
|
@@ -442075,6 +442243,7 @@ var init_commands2 = __esm(async () => {
|
|
|
442075
442243
|
init_error_formatter();
|
|
442076
442244
|
init_init_command();
|
|
442077
442245
|
init_memory_reminder();
|
|
442246
|
+
init_skill_name_frontmatter_repair();
|
|
442078
442247
|
init_command_runtime();
|
|
442079
442248
|
init_constants();
|
|
442080
442249
|
init_hooks2();
|
|
@@ -442265,7 +442434,7 @@ async function handleAgentConversationManagementCommand(parsed, socket, safeSock
|
|
|
442265
442434
|
}
|
|
442266
442435
|
if (parsed.type === "conversation_create") {
|
|
442267
442436
|
try {
|
|
442268
|
-
const conversation = await backend4.createConversation(parsed.body);
|
|
442437
|
+
const conversation = await backend4.createConversation(parsed.body, actingUserRequestOptions(parsed.acting_user_id));
|
|
442269
442438
|
safeSocketSend(socket, {
|
|
442270
442439
|
type: "conversation_create_response",
|
|
442271
442440
|
request_id: parsed.request_id,
|
|
@@ -442327,7 +442496,8 @@ async function handleAgentConversationManagementCommand(parsed, socket, safeSock
|
|
|
442327
442496
|
try {
|
|
442328
442497
|
const conversation = await backend4.forkConversation(parsed.conversation_id, {
|
|
442329
442498
|
...typeof parsed.body?.agent_id === "string" ? { agentId: parsed.body.agent_id } : {},
|
|
442330
|
-
...typeof parsed.body?.hidden === "boolean" ? { hidden: parsed.body.hidden } : {}
|
|
442499
|
+
...typeof parsed.body?.hidden === "boolean" ? { hidden: parsed.body.hidden } : {},
|
|
442500
|
+
...actingUserRequestOptions(parsed.acting_user_id) ?? {}
|
|
442331
442501
|
});
|
|
442332
442502
|
safeSocketSend(socket, {
|
|
442333
442503
|
type: "conversation_fork_response",
|
|
@@ -443783,7 +443953,7 @@ __export(exports_memory_scanner, {
|
|
|
443783
443953
|
getFileNodes: () => getFileNodes
|
|
443784
443954
|
});
|
|
443785
443955
|
import { readdirSync as readdirSync15, readFileSync as readFileSync31, statSync as statSync16 } from "node:fs";
|
|
443786
|
-
import { join as
|
|
443956
|
+
import { join as join49, relative as relative11 } from "node:path";
|
|
443787
443957
|
function scanMemoryFilesystem(memoryRoot) {
|
|
443788
443958
|
const nodes = [];
|
|
443789
443959
|
const scanDir = (dir, depth, parentIsLast) => {
|
|
@@ -443795,8 +443965,8 @@ function scanMemoryFilesystem(memoryRoot) {
|
|
|
443795
443965
|
}
|
|
443796
443966
|
const filtered = entries.filter((name) => !name.startsWith("."));
|
|
443797
443967
|
const sorted = filtered.sort((a2, b3) => {
|
|
443798
|
-
const aPath =
|
|
443799
|
-
const bPath =
|
|
443968
|
+
const aPath = join49(dir, a2);
|
|
443969
|
+
const bPath = join49(dir, b3);
|
|
443800
443970
|
let aIsDir = false;
|
|
443801
443971
|
let bIsDir = false;
|
|
443802
443972
|
try {
|
|
@@ -443816,14 +443986,14 @@ function scanMemoryFilesystem(memoryRoot) {
|
|
|
443816
443986
|
return a2.localeCompare(b3);
|
|
443817
443987
|
});
|
|
443818
443988
|
sorted.forEach((name, index) => {
|
|
443819
|
-
const fullPath =
|
|
443989
|
+
const fullPath = join49(dir, name);
|
|
443820
443990
|
let isDir = false;
|
|
443821
443991
|
try {
|
|
443822
443992
|
isDir = statSync16(fullPath).isDirectory();
|
|
443823
443993
|
} catch {
|
|
443824
443994
|
return;
|
|
443825
443995
|
}
|
|
443826
|
-
const relativePath =
|
|
443996
|
+
const relativePath = relative11(memoryRoot, fullPath).replace(/\\/g, "/");
|
|
443827
443997
|
const isLast = index === sorted.length - 1;
|
|
443828
443998
|
nodes.push({
|
|
443829
443999
|
name: isDir ? `${name}/` : name,
|
|
@@ -443888,9 +444058,9 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
443888
444058
|
const { scanMemoryFilesystem: scanMemoryFilesystem2, getFileNodes: getFileNodes2, readFileContent: readFileContent2 } = await Promise.resolve().then(() => (init_memory_scanner(), exports_memory_scanner));
|
|
443889
444059
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => exports_frontmatter);
|
|
443890
444060
|
const { existsSync: existsSync46, statSync: statSync17 } = await import("node:fs");
|
|
443891
|
-
const { join:
|
|
444061
|
+
const { join: join50, posix: posix4 } = await import("node:path");
|
|
443892
444062
|
const memoryRoot = getMemoryFilesystemRoot2(parsed.agent_id);
|
|
443893
|
-
let memfsInitialized = existsSync46(
|
|
444063
|
+
let memfsInitialized = existsSync46(join50(memoryRoot, ".git"));
|
|
443894
444064
|
const memfsEnabled = memfsInitialized ? true : await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
443895
444065
|
if (!memfsEnabled) {
|
|
443896
444066
|
safeSocketSend(socket, {
|
|
@@ -443908,7 +444078,7 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
443908
444078
|
await ensureLocalMemfsCheckout2(parsed.agent_id, {
|
|
443909
444079
|
pullOnExistingRepo: true
|
|
443910
444080
|
});
|
|
443911
|
-
memfsInitialized = existsSync46(
|
|
444081
|
+
memfsInitialized = existsSync46(join50(memoryRoot, ".git"));
|
|
443912
444082
|
if (!memfsInitialized) {
|
|
443913
444083
|
throw new Error("MemFS is enabled, but the local memory checkout could not be initialized.");
|
|
443914
444084
|
}
|
|
@@ -444207,33 +444377,33 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
444207
444377
|
ensureLocalMemfsCheckout: ensureLocalMemfsCheckout2,
|
|
444208
444378
|
isMemfsEnabledOnServer: isMemfsEnabledOnServer2
|
|
444209
444379
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
444210
|
-
const { readFile:
|
|
444380
|
+
const { readFile: readFile19 } = await import("node:fs/promises");
|
|
444211
444381
|
const { existsSync: existsSync46 } = await import("node:fs");
|
|
444212
|
-
const { isAbsolute: isAbsolute23, join:
|
|
444382
|
+
const { isAbsolute: isAbsolute23, join: join50, normalize: normalize5, relative: relative12, sep: sep5 } = await import("node:path");
|
|
444213
444383
|
if (isAbsolute23(parsed.path) || parsed.path.length === 0) {
|
|
444214
444384
|
sendFailure("path must be a non-empty relative path");
|
|
444215
444385
|
return;
|
|
444216
444386
|
}
|
|
444217
444387
|
const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
|
|
444218
|
-
const absolutePath = normalize5(
|
|
444219
|
-
const rel =
|
|
444388
|
+
const absolutePath = normalize5(join50(memoryRoot, parsed.path));
|
|
444389
|
+
const rel = relative12(memoryRoot, absolutePath);
|
|
444220
444390
|
if (rel.startsWith("..") || rel === "" || isAbsolute23(rel) || rel.split(sep5).includes("..")) {
|
|
444221
444391
|
sendFailure("path must resolve inside the memory root");
|
|
444222
444392
|
return;
|
|
444223
444393
|
}
|
|
444224
|
-
if (!existsSync46(
|
|
444394
|
+
if (!existsSync46(join50(memoryRoot, ".git"))) {
|
|
444225
444395
|
const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
444226
444396
|
if (!enabled) {
|
|
444227
444397
|
sendFailure("memfs is not enabled for this agent");
|
|
444228
444398
|
return;
|
|
444229
444399
|
}
|
|
444230
444400
|
await ensureLocalMemfsCheckout2(parsed.agent_id);
|
|
444231
|
-
if (!existsSync46(
|
|
444401
|
+
if (!existsSync46(join50(memoryRoot, ".git"))) {
|
|
444232
444402
|
sendFailure("failed to initialize local memory checkout");
|
|
444233
444403
|
return;
|
|
444234
444404
|
}
|
|
444235
444405
|
}
|
|
444236
|
-
const buffer = await
|
|
444406
|
+
const buffer = await readFile19(absolutePath);
|
|
444237
444407
|
const content = encoding === "base64" ? buffer.toString("base64") : buffer.toString("utf-8");
|
|
444238
444408
|
const pathspec = rel.split(sep5).join("/");
|
|
444239
444409
|
safeSocketSend(socket, {
|
|
@@ -444273,35 +444443,35 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
444273
444443
|
isMemfsEnabledOnServer: isMemfsEnabledOnServer2
|
|
444274
444444
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
444275
444445
|
const { commitMemoryWrite: commitMemoryWrite2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
444276
|
-
const { writeFile:
|
|
444446
|
+
const { writeFile: writeFile15, mkdir: mkdir12 } = await import("node:fs/promises");
|
|
444277
444447
|
const { existsSync: existsSync46 } = await import("node:fs");
|
|
444278
|
-
const { dirname:
|
|
444448
|
+
const { dirname: dirname25, isAbsolute: isAbsolute23, join: join50, normalize: normalize5, relative: relative12, sep: sep5 } = await import("node:path");
|
|
444279
444449
|
if (isAbsolute23(parsed.path) || parsed.path.length === 0) {
|
|
444280
444450
|
sendFailure("write_memory_file: path must be a non-empty relative path");
|
|
444281
444451
|
return;
|
|
444282
444452
|
}
|
|
444283
444453
|
const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
|
|
444284
|
-
const absolutePath = normalize5(
|
|
444285
|
-
const rel =
|
|
444454
|
+
const absolutePath = normalize5(join50(memoryRoot, parsed.path));
|
|
444455
|
+
const rel = relative12(memoryRoot, absolutePath);
|
|
444286
444456
|
if (rel.startsWith("..") || rel === "" || isAbsolute23(rel) || rel.split(sep5).includes("..")) {
|
|
444287
444457
|
sendFailure("write_memory_file: path must resolve inside the memory root");
|
|
444288
444458
|
return;
|
|
444289
444459
|
}
|
|
444290
|
-
if (!existsSync46(
|
|
444460
|
+
if (!existsSync46(join50(memoryRoot, ".git"))) {
|
|
444291
444461
|
const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
444292
444462
|
if (!enabled) {
|
|
444293
444463
|
sendFailure("write_memory_file: memfs is not enabled for this agent");
|
|
444294
444464
|
return;
|
|
444295
444465
|
}
|
|
444296
444466
|
await ensureLocalMemfsCheckout2(parsed.agent_id);
|
|
444297
|
-
if (!existsSync46(
|
|
444467
|
+
if (!existsSync46(join50(memoryRoot, ".git"))) {
|
|
444298
444468
|
sendFailure("write_memory_file: failed to initialize local memory checkout");
|
|
444299
444469
|
return;
|
|
444300
444470
|
}
|
|
444301
444471
|
}
|
|
444302
444472
|
const buffer = encoding === "base64" ? Buffer.from(parsed.content, "base64") : Buffer.from(parsed.content, "utf-8");
|
|
444303
|
-
await mkdir12(
|
|
444304
|
-
await
|
|
444473
|
+
await mkdir12(dirname25(absolutePath), { recursive: true });
|
|
444474
|
+
await writeFile15(absolutePath, buffer);
|
|
444305
444475
|
const { getBackend: getBackend2 } = await Promise.resolve().then(() => (init_backend2(), exports_backend));
|
|
444306
444476
|
const backend4 = getBackend2();
|
|
444307
444477
|
const memorySyncMode = backend4.capabilities.localMemfs && !backend4.capabilities.remoteMemfs ? "local" : undefined;
|
|
@@ -444378,26 +444548,26 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
444378
444548
|
const { commitMemoryWrite: commitMemoryWrite2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
444379
444549
|
const { unlink: unlink5 } = await import("node:fs/promises");
|
|
444380
444550
|
const { existsSync: existsSync46 } = await import("node:fs");
|
|
444381
|
-
const { isAbsolute: isAbsolute23, join:
|
|
444551
|
+
const { isAbsolute: isAbsolute23, join: join50, normalize: normalize5, relative: relative12, sep: sep5 } = await import("node:path");
|
|
444382
444552
|
if (isAbsolute23(parsed.path) || parsed.path.length === 0) {
|
|
444383
444553
|
sendFailure("delete_memory_file: path must be a non-empty relative path");
|
|
444384
444554
|
return;
|
|
444385
444555
|
}
|
|
444386
444556
|
const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
|
|
444387
|
-
const absolutePath = normalize5(
|
|
444388
|
-
const rel =
|
|
444557
|
+
const absolutePath = normalize5(join50(memoryRoot, parsed.path));
|
|
444558
|
+
const rel = relative12(memoryRoot, absolutePath);
|
|
444389
444559
|
if (rel.startsWith("..") || rel === "" || isAbsolute23(rel) || rel.split(sep5).includes("..")) {
|
|
444390
444560
|
sendFailure("delete_memory_file: path must resolve inside the memory root");
|
|
444391
444561
|
return;
|
|
444392
444562
|
}
|
|
444393
|
-
if (!existsSync46(
|
|
444563
|
+
if (!existsSync46(join50(memoryRoot, ".git"))) {
|
|
444394
444564
|
const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
444395
444565
|
if (!enabled) {
|
|
444396
444566
|
sendFailure("delete_memory_file: memfs is not enabled for this agent");
|
|
444397
444567
|
return;
|
|
444398
444568
|
}
|
|
444399
444569
|
await ensureLocalMemfsCheckout2(parsed.agent_id);
|
|
444400
|
-
if (!existsSync46(
|
|
444570
|
+
if (!existsSync46(join50(memoryRoot, ".git"))) {
|
|
444401
444571
|
sendFailure("delete_memory_file: failed to initialize local memory checkout");
|
|
444402
444572
|
return;
|
|
444403
444573
|
}
|
|
@@ -444817,9 +444987,9 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
444817
444987
|
symlinkSync: symlinkSync2,
|
|
444818
444988
|
unlinkSync: unlinkSync7
|
|
444819
444989
|
} = await import("node:fs");
|
|
444820
|
-
const { basename:
|
|
444821
|
-
const lettaHome = process.env.LETTA_HOME ||
|
|
444822
|
-
const globalSkillsDir =
|
|
444990
|
+
const { basename: basename24, join: join50 } = await import("node:path");
|
|
444991
|
+
const lettaHome = process.env.LETTA_HOME || join50(process.env.HOME || process.env.USERPROFILE || "~", ".letta");
|
|
444992
|
+
const globalSkillsDir = join50(lettaHome, "skills");
|
|
444823
444993
|
if (parsed.type === "skill_enable") {
|
|
444824
444994
|
try {
|
|
444825
444995
|
if (!existsSync46(parsed.skill_path)) {
|
|
@@ -444831,7 +445001,7 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
444831
445001
|
}, "listener_skill_send_failed", "listener_skill_command");
|
|
444832
445002
|
return true;
|
|
444833
445003
|
}
|
|
444834
|
-
const skillMdPath =
|
|
445004
|
+
const skillMdPath = join50(parsed.skill_path, "SKILL.md");
|
|
444835
445005
|
if (!existsSync46(skillMdPath)) {
|
|
444836
445006
|
safeSocketSend(socket, {
|
|
444837
445007
|
type: "skill_enable_response",
|
|
@@ -444841,12 +445011,12 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
444841
445011
|
}, "listener_skill_send_failed", "listener_skill_command");
|
|
444842
445012
|
return true;
|
|
444843
445013
|
}
|
|
444844
|
-
const linkName =
|
|
444845
|
-
const linkPath =
|
|
445014
|
+
const linkName = basename24(parsed.skill_path);
|
|
445015
|
+
const linkPath = join50(globalSkillsDir, linkName);
|
|
444846
445016
|
mkdirSync31(globalSkillsDir, { recursive: true });
|
|
444847
445017
|
if (existsSync46(linkPath)) {
|
|
444848
|
-
const
|
|
444849
|
-
if (
|
|
445018
|
+
const stat14 = lstatSync3(linkPath);
|
|
445019
|
+
if (stat14.isSymbolicLink()) {
|
|
444850
445020
|
if (process.platform === "win32") {
|
|
444851
445021
|
rmdirSync(linkPath);
|
|
444852
445022
|
} else {
|
|
@@ -444885,7 +445055,7 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
444885
445055
|
}
|
|
444886
445056
|
if (parsed.type === "skill_disable") {
|
|
444887
445057
|
try {
|
|
444888
|
-
const linkPath =
|
|
445058
|
+
const linkPath = join50(globalSkillsDir, parsed.name);
|
|
444889
445059
|
if (!existsSync46(linkPath)) {
|
|
444890
445060
|
safeSocketSend(socket, {
|
|
444891
445061
|
type: "skill_disable_response",
|
|
@@ -444895,8 +445065,8 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
444895
445065
|
}, "listener_skill_send_failed", "listener_skill_command");
|
|
444896
445066
|
return true;
|
|
444897
445067
|
}
|
|
444898
|
-
const
|
|
444899
|
-
if (!
|
|
445068
|
+
const stat14 = lstatSync3(linkPath);
|
|
445069
|
+
if (!stat14.isSymbolicLink()) {
|
|
444900
445070
|
safeSocketSend(socket, {
|
|
444901
445071
|
type: "skill_disable_response",
|
|
444902
445072
|
request_id: parsed.request_id,
|
|
@@ -449829,7 +449999,7 @@ var init_listen_client = __esm(async () => {
|
|
|
449829
449999
|
|
|
449830
450000
|
// src/backend/local/transcript-search.ts
|
|
449831
450001
|
import { existsSync as existsSync49, readdirSync as readdirSync18, readFileSync as readFileSync33, statSync as statSync18 } from "node:fs";
|
|
449832
|
-
import { join as
|
|
450002
|
+
import { join as join53 } from "node:path";
|
|
449833
450003
|
function readJsonFile3(path37) {
|
|
449834
450004
|
if (!existsSync49(path37))
|
|
449835
450005
|
return;
|
|
@@ -450050,11 +450220,11 @@ function collectConversationMessages(input) {
|
|
|
450050
450220
|
return [];
|
|
450051
450221
|
if (input.conversationId && conversation.id !== input.conversationId)
|
|
450052
450222
|
return [];
|
|
450053
|
-
const messagesPath =
|
|
450223
|
+
const messagesPath = join53(conversationDir, "messages.jsonl");
|
|
450054
450224
|
const rows = readJsonlFile2(messagesPath);
|
|
450055
450225
|
if (rows.length === 0)
|
|
450056
450226
|
return [];
|
|
450057
|
-
const manifest2 = readJsonFile3(
|
|
450227
|
+
const manifest2 = readJsonFile3(join53(conversationDir, "manifest.json"));
|
|
450058
450228
|
const format5 = transcriptFormat(manifest2, rows);
|
|
450059
450229
|
if (!format5)
|
|
450060
450230
|
return [];
|
|
@@ -450075,11 +450245,11 @@ function collectConversationMessages(input) {
|
|
|
450075
450245
|
});
|
|
450076
450246
|
}
|
|
450077
450247
|
function conversationDirectories(storageDir) {
|
|
450078
|
-
const conversationsDir =
|
|
450248
|
+
const conversationsDir = join53(storageDir, "conversations");
|
|
450079
450249
|
if (!existsSync49(conversationsDir))
|
|
450080
450250
|
return [];
|
|
450081
450251
|
try {
|
|
450082
|
-
return readdirSync18(conversationsDir).map((entry) =>
|
|
450252
|
+
return readdirSync18(conversationsDir).map((entry) => join53(conversationsDir, entry)).filter((entryPath) => statSync18(entryPath).isDirectory());
|
|
450083
450253
|
} catch {
|
|
450084
450254
|
return [];
|
|
450085
450255
|
}
|
|
@@ -450103,7 +450273,7 @@ function searchLocalTranscriptMessages(storageDir, body3) {
|
|
|
450103
450273
|
const endDate = typeof body3.end_date === "string" ? body3.end_date : undefined;
|
|
450104
450274
|
const includeHidden = body3.include_hidden === true;
|
|
450105
450275
|
const records = conversationDirectories(storageDir).flatMap((conversationDir) => {
|
|
450106
|
-
const conversation = conversationSearchRecord(readJsonFile3(
|
|
450276
|
+
const conversation = conversationSearchRecord(readJsonFile3(join53(conversationDir, "conversation.json")));
|
|
450107
450277
|
if (!conversation)
|
|
450108
450278
|
return [];
|
|
450109
450279
|
if (conversation.hidden && !includeHidden)
|
|
@@ -451982,7 +452152,7 @@ import {
|
|
|
451982
452152
|
unlinkSync as unlinkSync8
|
|
451983
452153
|
} from "node:fs";
|
|
451984
452154
|
import { homedir as homedir32 } from "node:os";
|
|
451985
|
-
import { join as
|
|
452155
|
+
import { join as join57 } from "node:path";
|
|
451986
452156
|
import { format as format5 } from "node:util";
|
|
451987
452157
|
function isDebugEnabled2() {
|
|
451988
452158
|
const lettaDebug = process.env.LETTA_DEBUG;
|
|
@@ -452013,8 +452183,8 @@ class DebugLogFile2 {
|
|
|
452013
452183
|
const telem = process.env.LETTA_CODE_TELEM;
|
|
452014
452184
|
if (telem === "0" || telem === "false")
|
|
452015
452185
|
return;
|
|
452016
|
-
this.agentDir =
|
|
452017
|
-
this.logPath =
|
|
452186
|
+
this.agentDir = join57(DEBUG_LOG_DIR2, agentId);
|
|
452187
|
+
this.logPath = join57(this.agentDir, `${sessionId}.log`);
|
|
452018
452188
|
this.dirCreated = false;
|
|
452019
452189
|
this.pruneOldSessions();
|
|
452020
452190
|
}
|
|
@@ -452062,7 +452232,7 @@ class DebugLogFile2 {
|
|
|
452062
452232
|
const toDelete = files.slice(0, files.length - MAX_SESSION_FILES3 + 1);
|
|
452063
452233
|
for (const file3 of toDelete) {
|
|
452064
452234
|
try {
|
|
452065
|
-
unlinkSync8(
|
|
452235
|
+
unlinkSync8(join57(this.agentDir, file3));
|
|
452066
452236
|
} catch {}
|
|
452067
452237
|
}
|
|
452068
452238
|
}
|
|
@@ -452087,7 +452257,7 @@ function debugWarn2(prefix, message, ...args) {
|
|
|
452087
452257
|
}
|
|
452088
452258
|
var DEBUG_LOG_DIR2, MAX_SESSION_FILES3 = 5, DEFAULT_TAIL_LINES2 = 50, debugLogFile2;
|
|
452089
452259
|
var init_debug2 = __esm(() => {
|
|
452090
|
-
DEBUG_LOG_DIR2 =
|
|
452260
|
+
DEBUG_LOG_DIR2 = join57(homedir32(), ".letta", "logs", "debug");
|
|
452091
452261
|
debugLogFile2 = new DebugLogFile2;
|
|
452092
452262
|
});
|
|
452093
452263
|
|
|
@@ -452122,15 +452292,15 @@ __export(exports_skills3, {
|
|
|
452122
452292
|
GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR2
|
|
452123
452293
|
});
|
|
452124
452294
|
import { existsSync as existsSync54 } from "node:fs";
|
|
452125
|
-
import { readdir as
|
|
452126
|
-
import { dirname as
|
|
452295
|
+
import { readdir as readdir14, readFile as readFile19, realpath as realpath5, stat as stat14 } from "node:fs/promises";
|
|
452296
|
+
import { dirname as dirname28, join as join58 } from "node:path";
|
|
452127
452297
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
452128
452298
|
function getBundledSkillsPath2() {
|
|
452129
|
-
const thisDir =
|
|
452299
|
+
const thisDir = dirname28(fileURLToPath8(import.meta.url));
|
|
452130
452300
|
if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
|
|
452131
|
-
return
|
|
452301
|
+
return join58(thisDir, "../skills/builtin");
|
|
452132
452302
|
}
|
|
452133
|
-
return
|
|
452303
|
+
return join58(thisDir, "skills");
|
|
452134
452304
|
}
|
|
452135
452305
|
function compareSkills2(a2, b3) {
|
|
452136
452306
|
return a2.id.localeCompare(b3.id) || a2.source.localeCompare(b3.source) || a2.path.localeCompare(b3.path);
|
|
@@ -452177,7 +452347,7 @@ function isSkillAvailableForAgent2(skill2, agentId) {
|
|
|
452177
452347
|
return true;
|
|
452178
452348
|
}
|
|
452179
452349
|
function getAgentSkillsDir2(agentId) {
|
|
452180
|
-
return
|
|
452350
|
+
return join58(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "memory/skills");
|
|
452181
452351
|
}
|
|
452182
452352
|
async function getBundledSkills2() {
|
|
452183
452353
|
const bundledPath = getBundledSkillsPath2();
|
|
@@ -452200,7 +452370,7 @@ async function discoverSkillsFromDir2(skillsPath, source2) {
|
|
|
452200
452370
|
}
|
|
452201
452371
|
return { skills, errors: errors7 };
|
|
452202
452372
|
}
|
|
452203
|
-
async function discoverSkills2(projectSkillsPath =
|
|
452373
|
+
async function discoverSkills2(projectSkillsPath = join58(process.cwd(), SKILLS_DIR2), agentId, options3) {
|
|
452204
452374
|
const allErrors = [];
|
|
452205
452375
|
const skillsById = new Map;
|
|
452206
452376
|
const sourceSet = new Set(options3?.sources ?? ALL_SKILL_SOURCES);
|
|
@@ -452253,14 +452423,14 @@ async function findSkillFiles2(currentPath, rootPath, skills, errors7, source2,
|
|
|
452253
452423
|
return;
|
|
452254
452424
|
}
|
|
452255
452425
|
try {
|
|
452256
|
-
const entries = await
|
|
452426
|
+
const entries = await readdir14(currentPath, { withFileTypes: true });
|
|
452257
452427
|
for (const entry of entries) {
|
|
452258
|
-
const fullPath =
|
|
452428
|
+
const fullPath = join58(currentPath, entry.name);
|
|
452259
452429
|
try {
|
|
452260
452430
|
let isDirectory = entry.isDirectory();
|
|
452261
452431
|
let isFile = entry.isFile();
|
|
452262
452432
|
if (entry.isSymbolicLink()) {
|
|
452263
|
-
const entryStat = await
|
|
452433
|
+
const entryStat = await stat14(fullPath);
|
|
452264
452434
|
isDirectory = entryStat.isDirectory();
|
|
452265
452435
|
isFile = entryStat.isFile();
|
|
452266
452436
|
}
|
|
@@ -452294,7 +452464,7 @@ async function findSkillFiles2(currentPath, rootPath, skills, errors7, source2,
|
|
|
452294
452464
|
}
|
|
452295
452465
|
}
|
|
452296
452466
|
async function parseSkillFile2(filePath, rootPath, source2) {
|
|
452297
|
-
const content = await
|
|
452467
|
+
const content = await readFile19(filePath, "utf-8");
|
|
452298
452468
|
const { frontmatter, body: body3 } = parseFrontmatter(content);
|
|
452299
452469
|
const normalizedRoot = rootPath.endsWith("/") ? rootPath.slice(0, -1) : rootPath;
|
|
452300
452470
|
const relativePath = filePath.slice(normalizedRoot.length + 1);
|
|
@@ -452346,17 +452516,17 @@ var LOCAL_AGENT_EXCLUDED_BUNDLED_SKILLS2, PROJECT_SKILLS_DIR2, SKILLS_DIR2 = ".s
|
|
|
452346
452516
|
var init_skills4 = __esm(() => {
|
|
452347
452517
|
init_skill_sources();
|
|
452348
452518
|
LOCAL_AGENT_EXCLUDED_BUNDLED_SKILLS2 = new Set(["image-generation"]);
|
|
452349
|
-
PROJECT_SKILLS_DIR2 =
|
|
452350
|
-
GLOBAL_SKILLS_DIR2 =
|
|
452519
|
+
PROJECT_SKILLS_DIR2 = join58(".agents", "skills");
|
|
452520
|
+
GLOBAL_SKILLS_DIR2 = join58(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
|
|
452351
452521
|
});
|
|
452352
452522
|
|
|
452353
452523
|
// src/utils/fs.ts
|
|
452354
452524
|
var exports_fs = {};
|
|
452355
452525
|
__export(exports_fs, {
|
|
452356
452526
|
writeJsonFile: () => writeJsonFile2,
|
|
452357
|
-
writeFile: () =>
|
|
452527
|
+
writeFile: () => writeFile16,
|
|
452358
452528
|
readJsonFile: () => readJsonFile4,
|
|
452359
|
-
readFile: () =>
|
|
452529
|
+
readFile: () => readFile20,
|
|
452360
452530
|
mkdir: () => mkdir13,
|
|
452361
452531
|
exists: () => exists2
|
|
452362
452532
|
});
|
|
@@ -452366,12 +452536,12 @@ import {
|
|
|
452366
452536
|
writeFileSync as fsWriteFileSync2,
|
|
452367
452537
|
mkdirSync as mkdirSync37
|
|
452368
452538
|
} from "node:fs";
|
|
452369
|
-
import { dirname as
|
|
452370
|
-
async function
|
|
452539
|
+
import { dirname as dirname29 } from "node:path";
|
|
452540
|
+
async function readFile20(path39) {
|
|
452371
452541
|
return fsReadFileSync2(path39, { encoding: "utf-8" });
|
|
452372
452542
|
}
|
|
452373
|
-
async function
|
|
452374
|
-
const dir =
|
|
452543
|
+
async function writeFile16(path39, content) {
|
|
452544
|
+
const dir = dirname29(path39);
|
|
452375
452545
|
if (!existsSync55(dir)) {
|
|
452376
452546
|
mkdirSync37(dir, { recursive: true });
|
|
452377
452547
|
}
|
|
@@ -452384,14 +452554,14 @@ async function mkdir13(path39, options3) {
|
|
|
452384
452554
|
mkdirSync37(path39, options3);
|
|
452385
452555
|
}
|
|
452386
452556
|
async function readJsonFile4(path39) {
|
|
452387
|
-
const text2 = await
|
|
452557
|
+
const text2 = await readFile20(path39);
|
|
452388
452558
|
return JSON.parse(text2);
|
|
452389
452559
|
}
|
|
452390
452560
|
async function writeJsonFile2(path39, data, options3) {
|
|
452391
452561
|
const indent = options3?.indent ?? 2;
|
|
452392
452562
|
const content = `${JSON.stringify(data, null, indent)}
|
|
452393
452563
|
`;
|
|
452394
|
-
await
|
|
452564
|
+
await writeFile16(path39, content);
|
|
452395
452565
|
}
|
|
452396
452566
|
var init_fs2 = () => {};
|
|
452397
452567
|
|
|
@@ -452590,8 +452760,8 @@ import {
|
|
|
452590
452760
|
execFile as execFile16
|
|
452591
452761
|
} from "node:child_process";
|
|
452592
452762
|
import { accessSync as accessSync2, constants as constants4, realpathSync as realpathSync6 } from "node:fs";
|
|
452593
|
-
import { readdir as
|
|
452594
|
-
import { dirname as
|
|
452763
|
+
import { readdir as readdir15, rm as rm5 } from "node:fs/promises";
|
|
452764
|
+
import { dirname as dirname30, join as join59 } from "node:path";
|
|
452595
452765
|
import { promisify as promisify14 } from "node:util";
|
|
452596
452766
|
function debugLog4(...args) {
|
|
452597
452767
|
if (DEBUG2) {
|
|
@@ -452666,7 +452836,7 @@ function getResolvedEntrypoint2() {
|
|
|
452666
452836
|
}
|
|
452667
452837
|
}
|
|
452668
452838
|
function findInstalledPackagePath2(resolvedPath) {
|
|
452669
|
-
const marker = `${
|
|
452839
|
+
const marker = `${join59("node_modules", "@letta-ai", "letta-code")}`;
|
|
452670
452840
|
const index = resolvedPath.lastIndexOf(marker);
|
|
452671
452841
|
if (index === -1) {
|
|
452672
452842
|
return null;
|
|
@@ -452705,7 +452875,7 @@ function getSelfUpdateStatus2() {
|
|
|
452705
452875
|
manual_command: manualCommand
|
|
452706
452876
|
};
|
|
452707
452877
|
}
|
|
452708
|
-
const packageParentPath =
|
|
452878
|
+
const packageParentPath = dirname30(installPath);
|
|
452709
452879
|
const writable = canWritePath2(installPath) && canWritePath2(packageParentPath);
|
|
452710
452880
|
return {
|
|
452711
452881
|
supported: true,
|
|
@@ -452815,12 +452985,12 @@ async function getNpmGlobalPath2() {
|
|
|
452815
452985
|
}
|
|
452816
452986
|
}
|
|
452817
452987
|
async function cleanupOrphanedDirs2(globalPath) {
|
|
452818
|
-
const lettaAiDir =
|
|
452988
|
+
const lettaAiDir = join59(globalPath, "lib/node_modules/@letta-ai");
|
|
452819
452989
|
try {
|
|
452820
|
-
const entries = await
|
|
452990
|
+
const entries = await readdir15(lettaAiDir);
|
|
452821
452991
|
for (const entry of entries) {
|
|
452822
452992
|
if (entry.startsWith(".letta-code-")) {
|
|
452823
|
-
const orphanPath =
|
|
452993
|
+
const orphanPath = join59(lettaAiDir, entry);
|
|
452824
452994
|
debugLog4("Cleaning orphaned temp directory:", orphanPath);
|
|
452825
452995
|
await rm5(orphanPath, { recursive: true, force: true });
|
|
452826
452996
|
}
|
|
@@ -453352,7 +453522,7 @@ __export(exports_bootstrap_tools, {
|
|
|
453352
453522
|
});
|
|
453353
453523
|
import { existsSync as existsSync57, mkdirSync as mkdirSync39, writeFileSync as writeFileSync28 } from "node:fs";
|
|
453354
453524
|
import { homedir as homedir34 } from "node:os";
|
|
453355
|
-
import { join as
|
|
453525
|
+
import { join as join61 } from "node:path";
|
|
453356
453526
|
async function bootstrapBaseToolsIfNeeded() {
|
|
453357
453527
|
if (existsSync57(MARKER_PATH))
|
|
453358
453528
|
return;
|
|
@@ -453360,7 +453530,7 @@ async function bootstrapBaseToolsIfNeeded() {
|
|
|
453360
453530
|
try {
|
|
453361
453531
|
const success2 = await addBaseToolsToServer();
|
|
453362
453532
|
if (success2) {
|
|
453363
|
-
mkdirSync39(
|
|
453533
|
+
mkdirSync39(join61(homedir34(), ".letta"), { recursive: true });
|
|
453364
453534
|
writeFileSync28(MARKER_PATH, new Date().toISOString(), "utf-8");
|
|
453365
453535
|
}
|
|
453366
453536
|
} catch (err) {
|
|
@@ -453371,7 +453541,7 @@ var MARKER_PATH;
|
|
|
453371
453541
|
var init_bootstrap_tools = __esm(() => {
|
|
453372
453542
|
init_debug();
|
|
453373
453543
|
init_create6();
|
|
453374
|
-
MARKER_PATH =
|
|
453544
|
+
MARKER_PATH = join61(homedir34(), ".letta", ".bootstrapped");
|
|
453375
453545
|
});
|
|
453376
453546
|
|
|
453377
453547
|
// src/tools/filter.ts
|
|
@@ -453814,7 +453984,7 @@ function validateRegistryHandleOrThrow2(handle2) {
|
|
|
453814
453984
|
}
|
|
453815
453985
|
|
|
453816
453986
|
// src/headless-mod-adapter.ts
|
|
453817
|
-
import { join as
|
|
453987
|
+
import { join as join62 } from "node:path";
|
|
453818
453988
|
function isHeadlessMemfsEnabled(agentId) {
|
|
453819
453989
|
try {
|
|
453820
453990
|
return settingsManager.isMemfsEnabled(agentId);
|
|
@@ -453885,7 +454055,7 @@ function createHeadlessModContext(options3) {
|
|
|
453885
454055
|
};
|
|
453886
454056
|
}
|
|
453887
454057
|
function createHeadlessModAdapter(options3) {
|
|
453888
|
-
const agentModsDirectory = isHeadlessMemfsEnabled(options3.agent.id) ?
|
|
454058
|
+
const agentModsDirectory = isHeadlessMemfsEnabled(options3.agent.id) ? join62(getScopedMemoryFilesystemRoot(options3.agent.id), "mods") : undefined;
|
|
453889
454059
|
return createModAdapter({
|
|
453890
454060
|
...agentModsDirectory ? { agentModsDirectory } : {},
|
|
453891
454061
|
...options3.cacheDirectory ? { cacheDirectory: options3.cacheDirectory } : {},
|
|
@@ -453970,7 +454140,7 @@ async function writeWireMessageAsync(msg) {
|
|
|
453970
454140
|
|
|
453971
454141
|
// src/skills/builtin/creating-skills/scripts/validate-skill.ts
|
|
453972
454142
|
import { existsSync as existsSync58, readFileSync as readFileSync38 } from "node:fs";
|
|
453973
|
-
import { basename as
|
|
454143
|
+
import { basename as basename25, join as join63, resolve as resolve34 } from "node:path";
|
|
453974
454144
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
453975
454145
|
function parseQuotedScalar(value) {
|
|
453976
454146
|
if (value.startsWith('"')) {
|
|
@@ -454067,7 +454237,7 @@ function parseFrontmatter2(source2) {
|
|
|
454067
454237
|
return parseFrontmatterFallback(source2);
|
|
454068
454238
|
}
|
|
454069
454239
|
function validateSkill(skillPath) {
|
|
454070
|
-
const skillMdPath =
|
|
454240
|
+
const skillMdPath = join63(skillPath, "SKILL.md");
|
|
454071
454241
|
if (!existsSync58(skillMdPath)) {
|
|
454072
454242
|
return { valid: false, message: "SKILL.md not found" };
|
|
454073
454243
|
}
|
|
@@ -454130,7 +454300,7 @@ function validateSkill(skillPath) {
|
|
|
454130
454300
|
message: `Name is too long (${trimmedName.length} characters). Maximum is ${MAX_SKILL_NAME_LENGTH} characters.`
|
|
454131
454301
|
};
|
|
454132
454302
|
}
|
|
454133
|
-
const dirName =
|
|
454303
|
+
const dirName = basename25(skillPath);
|
|
454134
454304
|
if (trimmedName !== dirName) {
|
|
454135
454305
|
warnings.push(`Name '${trimmedName}' doesn't match directory name '${dirName}'. For portability, these should match.`);
|
|
454136
454306
|
}
|
|
@@ -454234,8 +454404,8 @@ __export(exports_import, {
|
|
|
454234
454404
|
extractSkillsFromAf: () => extractSkillsFromAf
|
|
454235
454405
|
});
|
|
454236
454406
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
454237
|
-
import { access as access2, chmod, mkdir as mkdir14, readFile as
|
|
454238
|
-
import { dirname as
|
|
454407
|
+
import { access as access2, chmod, mkdir as mkdir14, readFile as readFile21, writeFile as writeFile17 } from "node:fs/promises";
|
|
454408
|
+
import { dirname as dirname31, isAbsolute as isAbsolute24, relative as relative12, resolve as resolve35, sep as sep6, win32 as win325 } from "node:path";
|
|
454239
454409
|
function validateImportedSkillName(name) {
|
|
454240
454410
|
const trimmedName = name.trim();
|
|
454241
454411
|
if (trimmedName !== name || trimmedName.length === 0 || trimmedName.length > MAX_SKILL_NAME_LENGTH || trimmedName === "." || trimmedName === ".." || !IMPORTED_SKILL_NAME_PATTERN.test(trimmedName)) {
|
|
@@ -454246,7 +454416,7 @@ function validateImportedSkillName(name) {
|
|
|
454246
454416
|
function assertPathInside(parent, child) {
|
|
454247
454417
|
const parentPath = resolve35(parent);
|
|
454248
454418
|
const childPath = resolve35(child);
|
|
454249
|
-
const relativePath =
|
|
454419
|
+
const relativePath = relative12(parentPath, childPath);
|
|
454250
454420
|
if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${sep6}`) || isAbsolute24(relativePath)) {
|
|
454251
454421
|
throw new Error(`Imported skill file path escapes skill directory: ${child}`);
|
|
454252
454422
|
}
|
|
@@ -454335,7 +454505,7 @@ async function importAgentFromFile(options3) {
|
|
|
454335
454505
|
}
|
|
454336
454506
|
async function extractSkillsFromAf(afPath, destDir) {
|
|
454337
454507
|
const extracted = [];
|
|
454338
|
-
const content = await
|
|
454508
|
+
const content = await readFile21(afPath, "utf-8");
|
|
454339
454509
|
const afData = JSON.parse(content);
|
|
454340
454510
|
if (!afData.skills || !Array.isArray(afData.skills)) {
|
|
454341
454511
|
return [];
|
|
@@ -454363,8 +454533,8 @@ async function writeSkillFiles(skillDir, files) {
|
|
|
454363
454533
|
}
|
|
454364
454534
|
async function writeSkillFile(skillDir, filePath, content) {
|
|
454365
454535
|
const fullPath = resolveImportedSkillFilePath(skillDir, filePath);
|
|
454366
|
-
await mkdir14(
|
|
454367
|
-
await
|
|
454536
|
+
await mkdir14(dirname31(fullPath), { recursive: true });
|
|
454537
|
+
await writeFile17(fullPath, content, "utf-8");
|
|
454368
454538
|
const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
|
|
454369
454539
|
if (isScript) {
|
|
454370
454540
|
try {
|
|
@@ -454416,8 +454586,8 @@ function parseRegistryHandle(handle2) {
|
|
|
454416
454586
|
}
|
|
454417
454587
|
async function importAgentFromRegistry(options3) {
|
|
454418
454588
|
const { tmpdir: tmpdir10 } = await import("node:os");
|
|
454419
|
-
const { join:
|
|
454420
|
-
const { writeFile:
|
|
454589
|
+
const { join: join64 } = await import("node:path");
|
|
454590
|
+
const { writeFile: writeFile18, unlink: unlink5 } = await import("node:fs/promises");
|
|
454421
454591
|
const { author, name } = parseRegistryHandle(options3.handle);
|
|
454422
454592
|
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER}/${AGENT_REGISTRY_REPO}/refs/heads/${AGENT_REGISTRY_BRANCH}/agents/@${author}/${name}/${name}.af`;
|
|
454423
454593
|
const response = await fetch(rawUrl);
|
|
@@ -454428,8 +454598,8 @@ async function importAgentFromRegistry(options3) {
|
|
|
454428
454598
|
throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
|
|
454429
454599
|
}
|
|
454430
454600
|
const afContent = await response.text();
|
|
454431
|
-
const tempPath =
|
|
454432
|
-
await
|
|
454601
|
+
const tempPath = join64(tmpdir10(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
454602
|
+
await writeFile18(tempPath, afContent, "utf-8");
|
|
454433
454603
|
try {
|
|
454434
454604
|
const result = await importAgentFromFile({
|
|
454435
454605
|
filePath: tempPath,
|
|
@@ -458051,7 +458221,7 @@ var BYTES_PER_TOKEN = 4;
|
|
|
458051
458221
|
|
|
458052
458222
|
// src/cli/helpers/window-title-config.ts
|
|
458053
458223
|
import { homedir as homedir36 } from "node:os";
|
|
458054
|
-
import { basename as
|
|
458224
|
+
import { basename as basename26, resolve as resolve36 } from "node:path";
|
|
458055
458225
|
function isWindowTitleField(value) {
|
|
458056
458226
|
return WINDOW_TITLE_FIELDS.includes(value);
|
|
458057
458227
|
}
|
|
@@ -458210,7 +458380,7 @@ function terminalTitleProjectName(data) {
|
|
|
458210
458380
|
if (!directory)
|
|
458211
458381
|
return null;
|
|
458212
458382
|
const resolved = resolve36(directory);
|
|
458213
|
-
const name =
|
|
458383
|
+
const name = basename26(resolved) || formatDirectoryDisplay(resolved) || resolved;
|
|
458214
458384
|
return truncateTerminalTitlePart(name, 24);
|
|
458215
458385
|
}
|
|
458216
458386
|
function titleDirectory(data) {
|
|
@@ -459485,7 +459655,7 @@ import {
|
|
|
459485
459655
|
writeFileSync as writeFileSync30
|
|
459486
459656
|
} from "node:fs";
|
|
459487
459657
|
import { homedir as homedir37, platform as platform9 } from "node:os";
|
|
459488
|
-
import { dirname as
|
|
459658
|
+
import { dirname as dirname32, join as join65 } from "node:path";
|
|
459489
459659
|
function detectTerminalType() {
|
|
459490
459660
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
459491
459661
|
return "cursor";
|
|
@@ -459517,16 +459687,16 @@ function getKeybindingsPath(terminal) {
|
|
|
459517
459687
|
}[terminal];
|
|
459518
459688
|
const os9 = platform9();
|
|
459519
459689
|
if (os9 === "darwin") {
|
|
459520
|
-
return
|
|
459690
|
+
return join65(homedir37(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
459521
459691
|
}
|
|
459522
459692
|
if (os9 === "win32") {
|
|
459523
459693
|
const appData = process.env.APPDATA;
|
|
459524
459694
|
if (!appData)
|
|
459525
459695
|
return null;
|
|
459526
|
-
return
|
|
459696
|
+
return join65(appData, appName, "User", "keybindings.json");
|
|
459527
459697
|
}
|
|
459528
459698
|
if (os9 === "linux") {
|
|
459529
|
-
return
|
|
459699
|
+
return join65(homedir37(), ".config", appName, "User", "keybindings.json");
|
|
459530
459700
|
}
|
|
459531
459701
|
return null;
|
|
459532
459702
|
}
|
|
@@ -459576,7 +459746,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
459576
459746
|
if (keybindingExists(keybindingsPath)) {
|
|
459577
459747
|
return { success: true, alreadyExists: true };
|
|
459578
459748
|
}
|
|
459579
|
-
const parentDir =
|
|
459749
|
+
const parentDir = dirname32(keybindingsPath);
|
|
459580
459750
|
if (!existsSync60(parentDir)) {
|
|
459581
459751
|
mkdirSync41(parentDir, { recursive: true });
|
|
459582
459752
|
}
|
|
@@ -459679,14 +459849,14 @@ function getWezTermConfigPath() {
|
|
|
459679
459849
|
}
|
|
459680
459850
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
459681
459851
|
if (xdgConfig) {
|
|
459682
|
-
const xdgPath =
|
|
459852
|
+
const xdgPath = join65(xdgConfig, "wezterm", "wezterm.lua");
|
|
459683
459853
|
if (existsSync60(xdgPath))
|
|
459684
459854
|
return xdgPath;
|
|
459685
459855
|
}
|
|
459686
|
-
const configPath =
|
|
459856
|
+
const configPath = join65(homedir37(), ".config", "wezterm", "wezterm.lua");
|
|
459687
459857
|
if (existsSync60(configPath))
|
|
459688
459858
|
return configPath;
|
|
459689
|
-
return
|
|
459859
|
+
return join65(homedir37(), ".wezterm.lua");
|
|
459690
459860
|
}
|
|
459691
459861
|
function stripLuaCommentsFromLine(line, blockCommentEnd) {
|
|
459692
459862
|
let code2 = "";
|
|
@@ -459812,7 +459982,7 @@ function installWezTermDeleteFix() {
|
|
|
459812
459982
|
content = readFileSync40(configPath, { encoding: "utf-8" });
|
|
459813
459983
|
}
|
|
459814
459984
|
content = injectWezTermDeleteFix(content);
|
|
459815
|
-
const parentDir =
|
|
459985
|
+
const parentDir = dirname32(configPath);
|
|
459816
459986
|
if (!existsSync60(parentDir)) {
|
|
459817
459987
|
mkdirSync41(parentDir, { recursive: true });
|
|
459818
459988
|
}
|
|
@@ -459865,9 +460035,9 @@ __export(exports_settings2, {
|
|
|
459865
460035
|
getSetting: () => getSetting
|
|
459866
460036
|
});
|
|
459867
460037
|
import { homedir as homedir38 } from "node:os";
|
|
459868
|
-
import { join as
|
|
460038
|
+
import { join as join66 } from "node:path";
|
|
459869
460039
|
function getSettingsPath() {
|
|
459870
|
-
return
|
|
460040
|
+
return join66(homedir38(), ".letta", "settings.json");
|
|
459871
460041
|
}
|
|
459872
460042
|
async function loadSettings() {
|
|
459873
460043
|
const settingsPath = getSettingsPath();
|
|
@@ -459904,7 +460074,7 @@ async function getSetting(key2) {
|
|
|
459904
460074
|
return settings3[key2];
|
|
459905
460075
|
}
|
|
459906
460076
|
function getProjectSettingsPath() {
|
|
459907
|
-
return
|
|
460077
|
+
return join66(process.cwd(), ".letta", "settings.local.json");
|
|
459908
460078
|
}
|
|
459909
460079
|
async function loadProjectSettings() {
|
|
459910
460080
|
const settingsPath = getProjectSettingsPath();
|
|
@@ -459922,7 +460092,7 @@ async function loadProjectSettings() {
|
|
|
459922
460092
|
}
|
|
459923
460093
|
async function saveProjectSettings(settings3) {
|
|
459924
460094
|
const settingsPath = getProjectSettingsPath();
|
|
459925
|
-
const dirPath =
|
|
460095
|
+
const dirPath = join66(process.cwd(), ".letta");
|
|
459926
460096
|
try {
|
|
459927
460097
|
if (!exists(dirPath)) {
|
|
459928
460098
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -460953,10 +461123,10 @@ var init_InlineBashApproval = __esm(async () => {
|
|
|
460953
461123
|
});
|
|
460954
461124
|
|
|
460955
461125
|
// src/cli/components/DiffRenderer.tsx
|
|
460956
|
-
import { relative as
|
|
461126
|
+
import { relative as relative13 } from "node:path";
|
|
460957
461127
|
function formatDisplayPath4(filePath) {
|
|
460958
461128
|
const cwd2 = process.cwd();
|
|
460959
|
-
const relativePath =
|
|
461129
|
+
const relativePath = relative13(cwd2, filePath);
|
|
460960
461130
|
if (relativePath.startsWith("..")) {
|
|
460961
461131
|
return filePath;
|
|
460962
461132
|
}
|
|
@@ -461315,10 +461485,10 @@ var init_DiffRenderer = __esm(async () => {
|
|
|
461315
461485
|
});
|
|
461316
461486
|
|
|
461317
461487
|
// src/cli/components/AdvancedDiffRenderer.tsx
|
|
461318
|
-
import { relative as
|
|
461488
|
+
import { relative as relative14 } from "node:path";
|
|
461319
461489
|
function formatRelativePath(filePath) {
|
|
461320
461490
|
const cwd2 = process.cwd();
|
|
461321
|
-
const relativePath =
|
|
461491
|
+
const relativePath = relative14(cwd2, filePath);
|
|
461322
461492
|
return relativePath.startsWith("..") ? relativePath : `./${relativePath}`;
|
|
461323
461493
|
}
|
|
461324
461494
|
function padLeft(n, width) {
|
|
@@ -461600,7 +461770,7 @@ function AdvancedDiffRenderer(props) {
|
|
|
461600
461770
|
}
|
|
461601
461771
|
const { hunks } = result;
|
|
461602
461772
|
const filePath = props.filePath;
|
|
461603
|
-
const
|
|
461773
|
+
const relative15 = formatRelativePath(filePath);
|
|
461604
461774
|
const lang41 = languageFromPath(filePath);
|
|
461605
461775
|
const shouldHighlight = lang41 && !exceedsAdvancedDiffHighlightLimits(hunks);
|
|
461606
461776
|
const hunkSyntaxLines = [];
|
|
@@ -461623,7 +461793,7 @@ function AdvancedDiffRenderer(props) {
|
|
|
461623
461793
|
const rows = buildAdvancedDiffRows(hunks, hunkSyntaxLines);
|
|
461624
461794
|
const maxDisplayNo = rows.reduce((m4, r5) => Math.max(m4, r5.displayNo), 1);
|
|
461625
461795
|
const gutterWidth = String(maxDisplayNo).length;
|
|
461626
|
-
const header = props.kind === "write" ? `Wrote changes to ${
|
|
461796
|
+
const header = props.kind === "write" ? `Wrote changes to ${relative15}` : `Updated ${relative15}`;
|
|
461627
461797
|
if (rows.length === 0) {
|
|
461628
461798
|
const noChangesGutter = 4;
|
|
461629
461799
|
return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
|
|
@@ -461674,7 +461844,7 @@ function AdvancedDiffRenderer(props) {
|
|
|
461674
461844
|
"No changes to ",
|
|
461675
461845
|
/* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text2, {
|
|
461676
461846
|
bold: true,
|
|
461677
|
-
children:
|
|
461847
|
+
children: relative15
|
|
461678
461848
|
}, undefined, false, undefined, this),
|
|
461679
461849
|
" (file content identical)"
|
|
461680
461850
|
]
|
|
@@ -461780,9 +461950,9 @@ function getHeaderText(fileEdit) {
|
|
|
461780
461950
|
} else if (operations.length === 1) {
|
|
461781
461951
|
const op = operations[0];
|
|
461782
461952
|
if (op) {
|
|
461783
|
-
const { relative:
|
|
461953
|
+
const { relative: relative16 } = __require("node:path");
|
|
461784
461954
|
const cwd3 = process.cwd();
|
|
461785
|
-
const relPath2 =
|
|
461955
|
+
const relPath2 = relative16(cwd3, op.path);
|
|
461786
461956
|
const displayPath2 = relPath2.startsWith("..") ? op.path : relPath2;
|
|
461787
461957
|
if (op.kind === "add") {
|
|
461788
461958
|
return `Write to ${displayPath2}?`;
|
|
@@ -461796,9 +461966,9 @@ function getHeaderText(fileEdit) {
|
|
|
461796
461966
|
}
|
|
461797
461967
|
return "Apply patch?";
|
|
461798
461968
|
}
|
|
461799
|
-
const { relative:
|
|
461969
|
+
const { relative: relative15 } = __require("node:path");
|
|
461800
461970
|
const cwd2 = process.cwd();
|
|
461801
|
-
const relPath =
|
|
461971
|
+
const relPath = relative15(cwd2, fileEdit.filePath);
|
|
461802
461972
|
const displayPath = relPath.startsWith("..") ? fileEdit.filePath : relPath;
|
|
461803
461973
|
if (t2 === "write" || t2 === "write_file" || t2 === "writefile" || t2 === "write_file_gemini" || t2 === "writefilegemini") {
|
|
461804
461974
|
const { existsSync: existsSync61 } = __require("node:fs");
|
|
@@ -461981,9 +462151,9 @@ var init_InlineFileEditApproval = __esm(async () => {
|
|
|
461981
462151
|
children: fileEdit.patchInput ? /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
|
|
461982
462152
|
flexDirection: "column",
|
|
461983
462153
|
children: parsePatchOperations2(fileEdit.patchInput).map((op, idx) => {
|
|
461984
|
-
const { relative:
|
|
462154
|
+
const { relative: relative15 } = __require("node:path");
|
|
461985
462155
|
const cwd2 = process.cwd();
|
|
461986
|
-
const relPath =
|
|
462156
|
+
const relPath = relative15(cwd2, op.path);
|
|
461987
462157
|
const displayPath = relPath.startsWith("..") ? op.path : relPath;
|
|
461988
462158
|
const diffKey = fileEdit.toolCallId ? `${fileEdit.toolCallId}:${op.path}` : undefined;
|
|
461989
462159
|
const opDiff = diffKey && allDiffs ? allDiffs.get(diffKey) : undefined;
|
|
@@ -469316,7 +469486,7 @@ import {
|
|
|
469316
469486
|
statSync as statSync21
|
|
469317
469487
|
} from "node:fs";
|
|
469318
469488
|
import { arch as arch4, homedir as homedir40, platform as platform10 } from "node:os";
|
|
469319
|
-
import { basename as
|
|
469489
|
+
import { basename as basename27, join as join67 } from "node:path";
|
|
469320
469490
|
function toDisplayPath(value) {
|
|
469321
469491
|
return value.replace(/\\/g, "/");
|
|
469322
469492
|
}
|
|
@@ -469558,7 +469728,7 @@ class FileAutocompleteProvider {
|
|
|
469558
469728
|
}
|
|
469559
469729
|
expandHomePath(path42) {
|
|
469560
469730
|
if (path42.startsWith("~/")) {
|
|
469561
|
-
const expandedPath =
|
|
469731
|
+
const expandedPath = join67(homedir40(), path42.slice(2));
|
|
469562
469732
|
return path42.endsWith("/") && !expandedPath.endsWith("/") ? `${expandedPath}/` : expandedPath;
|
|
469563
469733
|
} else if (path42 === "~") {
|
|
469564
469734
|
return homedir40();
|
|
@@ -469579,7 +469749,7 @@ class FileAutocompleteProvider {
|
|
|
469579
469749
|
} else if (displayBase.startsWith("/")) {
|
|
469580
469750
|
baseDir = displayBase;
|
|
469581
469751
|
} else {
|
|
469582
|
-
baseDir =
|
|
469752
|
+
baseDir = join67(this.basePath, displayBase);
|
|
469583
469753
|
}
|
|
469584
469754
|
try {
|
|
469585
469755
|
if (!statSync21(baseDir).isDirectory()) {
|
|
@@ -469598,7 +469768,7 @@ class FileAutocompleteProvider {
|
|
|
469598
469768
|
return `${toDisplayPath(displayBase)}${normalizedRelativePath}`;
|
|
469599
469769
|
}
|
|
469600
469770
|
scoreEntry(filePath, query2, isDirectory) {
|
|
469601
|
-
const fileName =
|
|
469771
|
+
const fileName = basename27(filePath);
|
|
469602
469772
|
const lowerFileName = fileName.toLowerCase();
|
|
469603
469773
|
const lowerQuery = query2.toLowerCase();
|
|
469604
469774
|
let score = 0;
|
|
@@ -469636,7 +469806,7 @@ class FileAutocompleteProvider {
|
|
|
469636
469806
|
for (const { path: entryPath, isDirectory } of topEntries) {
|
|
469637
469807
|
const pathWithoutSlash = isDirectory ? entryPath.slice(0, -1) : entryPath;
|
|
469638
469808
|
const displayPath2 = scopedQuery ? this.scopedPathForDisplay(scopedQuery.displayBase, pathWithoutSlash) : pathWithoutSlash;
|
|
469639
|
-
const entryName =
|
|
469809
|
+
const entryName = basename27(pathWithoutSlash);
|
|
469640
469810
|
const completionPath = isDirectory ? `${displayPath2}/` : displayPath2;
|
|
469641
469811
|
const value = buildCompletionValue(completionPath, {
|
|
469642
469812
|
isDirectory,
|
|
@@ -469658,9 +469828,9 @@ class FileAutocompleteProvider {
|
|
|
469658
469828
|
var PATH_DELIMITERS2, FD_TOOLS_DIR2, FD_BINARY_NAME2, FD_LOCAL_PATH2;
|
|
469659
469829
|
var init_file_autocomplete = __esm(() => {
|
|
469660
469830
|
PATH_DELIMITERS2 = new Set([" ", "\t", '"', "'", "="]);
|
|
469661
|
-
FD_TOOLS_DIR2 =
|
|
469831
|
+
FD_TOOLS_DIR2 = join67(homedir40(), ".letta", "bin");
|
|
469662
469832
|
FD_BINARY_NAME2 = platform10() === "win32" ? "fd.exe" : "fd";
|
|
469663
|
-
FD_LOCAL_PATH2 =
|
|
469833
|
+
FD_LOCAL_PATH2 = join67(FD_TOOLS_DIR2, FD_BINARY_NAME2);
|
|
469664
469834
|
});
|
|
469665
469835
|
|
|
469666
469836
|
// src/cli/hooks/use-autocomplete-navigation.ts
|
|
@@ -472487,7 +472657,7 @@ import {
|
|
|
472487
472657
|
writeFileSync as writeFileSync31
|
|
472488
472658
|
} from "node:fs";
|
|
472489
472659
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
472490
|
-
import { dirname as
|
|
472660
|
+
import { dirname as dirname33, join as join68 } from "node:path";
|
|
472491
472661
|
function runCommand(command, args, cwd2, input) {
|
|
472492
472662
|
try {
|
|
472493
472663
|
return execFileSync7(command, args, {
|
|
@@ -472708,8 +472878,8 @@ async function createLettaAgent(apiKey, name) {
|
|
|
472708
472878
|
return createMinimalAgent(apiKey, name);
|
|
472709
472879
|
}
|
|
472710
472880
|
function cloneRepoToTemp(repo) {
|
|
472711
|
-
const tempDir = mkdtempSync5(
|
|
472712
|
-
const repoDir =
|
|
472881
|
+
const tempDir = mkdtempSync5(join68(tmpdir10(), "letta-install-github-app-"));
|
|
472882
|
+
const repoDir = join68(tempDir, "repo");
|
|
472713
472883
|
runCommand("gh", ["repo", "clone", repo, repoDir, "--", "--depth=1"]);
|
|
472714
472884
|
return { tempDir, repoDir };
|
|
472715
472885
|
}
|
|
@@ -472720,9 +472890,9 @@ function runGit5(args, cwd2) {
|
|
|
472720
472890
|
return runCommand("git", args, cwd2);
|
|
472721
472891
|
}
|
|
472722
472892
|
function writeWorkflow(repoDir, workflowPath, content) {
|
|
472723
|
-
const absolutePath =
|
|
472724
|
-
if (!existsSync62(
|
|
472725
|
-
mkdirSync43(
|
|
472893
|
+
const absolutePath = join68(repoDir, workflowPath);
|
|
472894
|
+
if (!existsSync62(dirname33(absolutePath))) {
|
|
472895
|
+
mkdirSync43(dirname33(absolutePath), { recursive: true });
|
|
472726
472896
|
}
|
|
472727
472897
|
const next = `${content.trimEnd()}
|
|
472728
472898
|
`;
|
|
@@ -477151,7 +477321,7 @@ __export(exports_generate_memory_viewer, {
|
|
|
477151
477321
|
import { execFile as execFileCb4 } from "node:child_process";
|
|
477152
477322
|
import { chmodSync as chmodSync8, existsSync as existsSync63, mkdirSync as mkdirSync44, writeFileSync as writeFileSync32 } from "node:fs";
|
|
477153
477323
|
import { homedir as homedir41 } from "node:os";
|
|
477154
|
-
import { join as
|
|
477324
|
+
import { join as join69 } from "node:path";
|
|
477155
477325
|
import { promisify as promisify15 } from "node:util";
|
|
477156
477326
|
function messagesFromOverview(overview) {
|
|
477157
477327
|
return overview.messages?.map((message) => ({
|
|
@@ -477460,7 +477630,7 @@ ${m4.body}` : m4.subject;
|
|
|
477460
477630
|
async function generateAndOpenMemoryViewer(agentId, options3) {
|
|
477461
477631
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
477462
477632
|
const repoDir = memoryRoot;
|
|
477463
|
-
if (!existsSync63(
|
|
477633
|
+
if (!existsSync63(join69(repoDir, ".git"))) {
|
|
477464
477634
|
throw new Error("Memory viewer requires memfs. Run /memfs enable first.");
|
|
477465
477635
|
}
|
|
477466
477636
|
const data = await collectMemoryData(agentId, repoDir, memoryRoot, options3?.conversationId);
|
|
@@ -477476,7 +477646,7 @@ async function generateAndOpenMemoryViewer(agentId, options3) {
|
|
|
477476
477646
|
try {
|
|
477477
477647
|
chmodSync8(VIEWERS_DIR, 448);
|
|
477478
477648
|
} catch {}
|
|
477479
|
-
const filePath =
|
|
477649
|
+
const filePath = join69(VIEWERS_DIR, `memory-${encodeURIComponent(agentId)}.html`);
|
|
477480
477650
|
writeFileSync32(filePath, html5);
|
|
477481
477651
|
chmodSync8(filePath, 384);
|
|
477482
477652
|
const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
|
|
@@ -477501,13 +477671,13 @@ var init_generate_memory_viewer = __esm(() => {
|
|
|
477501
477671
|
init_local_memory_context();
|
|
477502
477672
|
init_memory_viewer_template();
|
|
477503
477673
|
execFile17 = promisify15(execFileCb4);
|
|
477504
|
-
VIEWERS_DIR =
|
|
477674
|
+
VIEWERS_DIR = join69(homedir41(), ".letta", "viewers");
|
|
477505
477675
|
REFLECTION_PATTERN = /\(reflection\)|🔮|reflection:/i;
|
|
477506
477676
|
});
|
|
477507
477677
|
|
|
477508
477678
|
// src/cli/components/MemfsTreeViewer.tsx
|
|
477509
477679
|
import { existsSync as existsSync64 } from "node:fs";
|
|
477510
|
-
import { join as
|
|
477680
|
+
import { join as join70 } from "node:path";
|
|
477511
477681
|
function renderTreePrefix(node) {
|
|
477512
477682
|
let prefix = "";
|
|
477513
477683
|
for (let i4 = 0;i4 < node.depth; i4++) {
|
|
@@ -477536,7 +477706,7 @@ function MemfsTreeViewer({
|
|
|
477536
477706
|
const statusTimerRef = import_react90.useRef(null);
|
|
477537
477707
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
477538
477708
|
const memoryExists = existsSync64(memoryRoot);
|
|
477539
|
-
const hasGitRepo = import_react90.useMemo(() => existsSync64(
|
|
477709
|
+
const hasGitRepo = import_react90.useMemo(() => existsSync64(join70(memoryRoot, ".git")), [memoryRoot]);
|
|
477540
477710
|
function showStatus(msg, durationMs) {
|
|
477541
477711
|
if (statusTimerRef.current)
|
|
477542
477712
|
clearTimeout(statusTimerRef.current);
|
|
@@ -479957,19 +480127,19 @@ var init_PersonalitySelector = __esm(async () => {
|
|
|
479957
480127
|
});
|
|
479958
480128
|
|
|
479959
480129
|
// src/utils/aws-credentials.ts
|
|
479960
|
-
import { readFile as
|
|
480130
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
479961
480131
|
import { homedir as homedir42 } from "node:os";
|
|
479962
|
-
import { join as
|
|
480132
|
+
import { join as join71 } from "node:path";
|
|
479963
480133
|
async function parseAwsCredentials() {
|
|
479964
|
-
const credentialsPath =
|
|
479965
|
-
const configPath =
|
|
480134
|
+
const credentialsPath = join71(homedir42(), ".aws", "credentials");
|
|
480135
|
+
const configPath = join71(homedir42(), ".aws", "config");
|
|
479966
480136
|
const profiles = new Map;
|
|
479967
480137
|
try {
|
|
479968
|
-
const content = await
|
|
480138
|
+
const content = await readFile22(credentialsPath, "utf-8");
|
|
479969
480139
|
parseIniFile(content, profiles, false);
|
|
479970
480140
|
} catch {}
|
|
479971
480141
|
try {
|
|
479972
|
-
const content = await
|
|
480142
|
+
const content = await readFile22(configPath, "utf-8");
|
|
479973
480143
|
parseIniFile(content, profiles, true);
|
|
479974
480144
|
} catch {}
|
|
479975
480145
|
return Array.from(profiles.values());
|
|
@@ -481538,8 +481708,8 @@ function SkillsDialog({ onClose, agentId }) {
|
|
|
481538
481708
|
try {
|
|
481539
481709
|
const { discoverSkills: discoverSkills3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
|
|
481540
481710
|
const { getSkillsDirectory: getSkillsDirectory2, getSkillSources: getSkillSources2 } = await Promise.resolve().then(() => (init_context(), exports_context));
|
|
481541
|
-
const { join:
|
|
481542
|
-
const skillsDir = getSkillsDirectory2() ||
|
|
481711
|
+
const { join: join72 } = await import("node:path");
|
|
481712
|
+
const skillsDir = getSkillsDirectory2() || join72(process.cwd(), SKILLS_DIR3);
|
|
481543
481713
|
const result = await discoverSkills3(skillsDir, agentId, {
|
|
481544
481714
|
sources: getSkillSources2()
|
|
481545
481715
|
});
|
|
@@ -485443,9 +485613,9 @@ function getFileEditHeader(toolName, toolArgs) {
|
|
|
485443
485613
|
} else if (operations.length === 1) {
|
|
485444
485614
|
const op = operations[0];
|
|
485445
485615
|
if (op) {
|
|
485446
|
-
const { relative:
|
|
485616
|
+
const { relative: relative16 } = __require("node:path");
|
|
485447
485617
|
const cwd3 = process.cwd();
|
|
485448
|
-
const relPath2 =
|
|
485618
|
+
const relPath2 = relative16(cwd3, op.path);
|
|
485449
485619
|
const displayPath3 = relPath2.startsWith("..") ? op.path : relPath2;
|
|
485450
485620
|
if (op.kind === "add")
|
|
485451
485621
|
return `Write to ${displayPath3}?`;
|
|
@@ -485459,9 +485629,9 @@ function getFileEditHeader(toolName, toolArgs) {
|
|
|
485459
485629
|
return "Apply patch?";
|
|
485460
485630
|
}
|
|
485461
485631
|
const filePath = args.file_path || "";
|
|
485462
|
-
const { relative:
|
|
485632
|
+
const { relative: relative15 } = __require("node:path");
|
|
485463
485633
|
const cwd2 = process.cwd();
|
|
485464
|
-
const relPath =
|
|
485634
|
+
const relPath = relative15(cwd2, filePath);
|
|
485465
485635
|
const displayPath2 = relPath.startsWith("..") ? filePath : relPath;
|
|
485466
485636
|
if (t2 === "write" || t2 === "write_file" || t2 === "writefile" || t2 === "write_file_gemini" || t2 === "writefilegemini") {
|
|
485467
485637
|
const { existsSync: existsSync65 } = __require("node:fs");
|
|
@@ -485549,9 +485719,9 @@ var init_ApprovalPreview = __esm(async () => {
|
|
|
485549
485719
|
/* @__PURE__ */ jsx_dev_runtime89.jsxDEV(Box_default, {
|
|
485550
485720
|
flexDirection: "column",
|
|
485551
485721
|
children: operations.map((op, idx) => {
|
|
485552
|
-
const { relative:
|
|
485722
|
+
const { relative: relative15 } = __require("node:path");
|
|
485553
485723
|
const cwd2 = process.cwd();
|
|
485554
|
-
const relPath =
|
|
485724
|
+
const relPath = relative15(cwd2, op.path);
|
|
485555
485725
|
const displayPath2 = relPath.startsWith("..") ? op.path : relPath;
|
|
485556
485726
|
const diffKey = toolCallId ? `${toolCallId}:${op.path}` : undefined;
|
|
485557
485727
|
const opDiff = diffKey && allDiffs ? allDiffs.get(diffKey) : undefined;
|
|
@@ -500808,7 +500978,7 @@ __export(exports_generate_diff_viewer, {
|
|
|
500808
500978
|
import { execFile as execFileCb5 } from "node:child_process";
|
|
500809
500979
|
import { chmodSync as chmodSync9, existsSync as existsSync65, mkdirSync as mkdirSync45, writeFileSync as writeFileSync33 } from "node:fs";
|
|
500810
500980
|
import { homedir as homedir43 } from "node:os";
|
|
500811
|
-
import { isAbsolute as isAbsolute25, join as
|
|
500981
|
+
import { isAbsolute as isAbsolute25, join as join72, resolve as resolve38 } from "node:path";
|
|
500812
500982
|
import { promisify as promisify16 } from "node:util";
|
|
500813
500983
|
async function runGit6(cwd2, args) {
|
|
500814
500984
|
try {
|
|
@@ -501033,7 +501203,7 @@ async function generateAndOpenDiffViewer(targetPath) {
|
|
|
501033
501203
|
try {
|
|
501034
501204
|
chmodSync9(VIEWERS_DIR2, 448);
|
|
501035
501205
|
} catch {}
|
|
501036
|
-
const filePath =
|
|
501206
|
+
const filePath = join72(VIEWERS_DIR2, `diff-${encodeURIComponent(worktreePath)}.html`);
|
|
501037
501207
|
writeFileSync33(filePath, html5);
|
|
501038
501208
|
chmodSync9(filePath, 384);
|
|
501039
501209
|
const skipOpen = shouldSkipOpen();
|
|
@@ -501104,7 +501274,7 @@ var init_generate_diff_viewer = __esm(() => {
|
|
|
501104
501274
|
init_ssr();
|
|
501105
501275
|
init_diff_viewer_template();
|
|
501106
501276
|
execFile18 = promisify16(execFileCb5);
|
|
501107
|
-
VIEWERS_DIR2 =
|
|
501277
|
+
VIEWERS_DIR2 = join72(homedir43(), ".letta", "viewers");
|
|
501108
501278
|
GIT_MAX_BUFFER = 50 * 1024 * 1024;
|
|
501109
501279
|
});
|
|
501110
501280
|
|
|
@@ -503090,7 +503260,7 @@ __export(exports_shell_aliases, {
|
|
|
503090
503260
|
});
|
|
503091
503261
|
import { existsSync as existsSync66, readFileSync as readFileSync42 } from "node:fs";
|
|
503092
503262
|
import { homedir as homedir44 } from "node:os";
|
|
503093
|
-
import { join as
|
|
503263
|
+
import { join as join73 } from "node:path";
|
|
503094
503264
|
function parseAliasesFromFile(filePath) {
|
|
503095
503265
|
const aliases = new Map;
|
|
503096
503266
|
if (!existsSync66(filePath)) {
|
|
@@ -503162,7 +503332,7 @@ function loadAliases(forceReload = false) {
|
|
|
503162
503332
|
const home = homedir44();
|
|
503163
503333
|
const allAliases = new Map;
|
|
503164
503334
|
for (const file3 of ALIAS_FILES) {
|
|
503165
|
-
const filePath =
|
|
503335
|
+
const filePath = join73(home, file3);
|
|
503166
503336
|
const fileAliases = parseAliasesFromFile(filePath);
|
|
503167
503337
|
for (const [name, value] of fileAliases) {
|
|
503168
503338
|
allAliases.set(name, value);
|
|
@@ -507345,7 +507515,7 @@ The deployment target for this project is CITATION-DOGFOOD-OK.
|
|
|
507345
507515
|
|
|
507346
507516
|
// src/mods/learning-harness.ts
|
|
507347
507517
|
import { spawn as spawn13 } from "node:child_process";
|
|
507348
|
-
import { access as access3, copyFile as copyFile2, mkdir as mkdir15, readFile as
|
|
507518
|
+
import { access as access3, copyFile as copyFile2, mkdir as mkdir15, readFile as readFile23, writeFile as writeFile18 } from "node:fs/promises";
|
|
507349
507519
|
import path42 from "node:path";
|
|
507350
507520
|
function slugify2(value) {
|
|
507351
507521
|
const slug = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -507593,14 +507763,14 @@ async function existingPath(filePath) {
|
|
|
507593
507763
|
return await fileExists(filePath) ? filePath : undefined;
|
|
507594
507764
|
}
|
|
507595
507765
|
async function writeJsonArtifact(filePath, value) {
|
|
507596
|
-
await
|
|
507766
|
+
await writeFile18(filePath, `${JSON.stringify(value, null, 2)}
|
|
507597
507767
|
`, "utf8");
|
|
507598
507768
|
}
|
|
507599
507769
|
async function writeCommandArtifacts(prefix, command, args, result) {
|
|
507600
|
-
await
|
|
507770
|
+
await writeFile18(`${prefix}.command.txt`, `${renderCommand(command, args)}
|
|
507601
507771
|
`, "utf8");
|
|
507602
|
-
await
|
|
507603
|
-
await
|
|
507772
|
+
await writeFile18(`${prefix}.stdout`, result.stdout, "utf8");
|
|
507773
|
+
await writeFile18(`${prefix}.stderr`, result.stderr, "utf8");
|
|
507604
507774
|
await writeJsonArtifact(`${prefix}.result.json`, result);
|
|
507605
507775
|
}
|
|
507606
507776
|
async function prepareMemoryFiles(memoryDir, memoryFiles) {
|
|
@@ -507608,7 +507778,7 @@ async function prepareMemoryFiles(memoryDir, memoryFiles) {
|
|
|
507608
507778
|
for (const [relativePath, content] of Object.entries(memoryFiles ?? {})) {
|
|
507609
507779
|
const filePath = safeJoin(memoryDir, relativePath);
|
|
507610
507780
|
await mkdir15(path42.dirname(filePath), { recursive: true });
|
|
507611
|
-
await
|
|
507781
|
+
await writeFile18(filePath, content, "utf8");
|
|
507612
507782
|
}
|
|
507613
507783
|
}
|
|
507614
507784
|
function renderEvaluationPrompt(prompt, memoryDir) {
|
|
@@ -508271,7 +508441,7 @@ function renderProposerGuide(params) {
|
|
|
508271
508441
|
`;
|
|
508272
508442
|
}
|
|
508273
508443
|
async function writeHistoryArtifacts(params) {
|
|
508274
|
-
await
|
|
508444
|
+
await writeFile18(params.historyPath, renderHistoryIndex({
|
|
508275
508445
|
attempts: params.attempts,
|
|
508276
508446
|
historyManifestPath: params.historyManifestPath,
|
|
508277
508447
|
proposerGuidePath: params.proposerGuidePath,
|
|
@@ -508279,7 +508449,7 @@ async function writeHistoryArtifacts(params) {
|
|
|
508279
508449
|
spec: params.spec
|
|
508280
508450
|
}), "utf8");
|
|
508281
508451
|
await writeJsonArtifact(params.historyManifestPath, buildHistoryManifest(params));
|
|
508282
|
-
await
|
|
508452
|
+
await writeFile18(params.proposerGuidePath, renderProposerGuide(params), "utf8");
|
|
508283
508453
|
}
|
|
508284
508454
|
async function defaultCommandRunner(command, args, options3) {
|
|
508285
508455
|
const startedAt = Date.now();
|
|
@@ -508370,7 +508540,7 @@ function createScenarioSuiteEvaluator(params) {
|
|
|
508370
508540
|
outputFormat
|
|
508371
508541
|
})
|
|
508372
508542
|
];
|
|
508373
|
-
await
|
|
508543
|
+
await writeFile18(hasConfiguredScenarios ? path42.join(scenarioDir, "prompt.md") : path42.join(context3.runDir, "eval-prompt.md"), evalPrompt, "utf8");
|
|
508374
508544
|
const scenarioEvalResult = await context3.runner(context3.cliCommand, evalArgs, {
|
|
508375
508545
|
cwd: context3.repoRoot,
|
|
508376
508546
|
env: {
|
|
@@ -508562,7 +508732,7 @@ async function runModLearningCandidate(params) {
|
|
|
508562
508732
|
outputFormat: "json"
|
|
508563
508733
|
})
|
|
508564
508734
|
];
|
|
508565
|
-
await
|
|
508735
|
+
await writeFile18(path42.join(runDir, "generation-prompt.md"), generationPrompt, "utf8");
|
|
508566
508736
|
generationResult = await params.runner(params.cliCommand, generationArgs, {
|
|
508567
508737
|
cwd: repoRoot,
|
|
508568
508738
|
env: {
|
|
@@ -508641,7 +508811,7 @@ async function runModLearningCandidate(params) {
|
|
|
508641
508811
|
spec: options3.spec
|
|
508642
508812
|
};
|
|
508643
508813
|
await writeJsonArtifact(path42.join(runDir, "report.json"), report);
|
|
508644
|
-
await
|
|
508814
|
+
await writeFile18(reportPath, renderMarkdownReport(report), "utf8");
|
|
508645
508815
|
await writeCandidateManifest(report);
|
|
508646
508816
|
emitProgress("done", params.candidateCount > 1 ? `Optimization iteration ${params.candidateIndex}/${params.candidateCount} complete` : "mod optimization complete", {
|
|
508647
508817
|
attempts: [...params.previousAttempts, summarizeAttempt(report)],
|
|
@@ -508819,7 +508989,7 @@ async function runModLearning(options3) {
|
|
|
508819
508989
|
spec: normalizedOptions.spec
|
|
508820
508990
|
});
|
|
508821
508991
|
await writeJsonArtifact(path42.join(runDir, "report.json"), report);
|
|
508822
|
-
await
|
|
508992
|
+
await writeFile18(reportPath, renderMarkdownReport(report), "utf8");
|
|
508823
508993
|
normalizedOptions.onProgress?.({
|
|
508824
508994
|
candidateCount,
|
|
508825
508995
|
candidateIndex: selectedCandidateIndex,
|
|
@@ -508837,7 +509007,7 @@ async function runModLearning(options3) {
|
|
|
508837
509007
|
return report;
|
|
508838
509008
|
}
|
|
508839
509009
|
async function readModLearningEnv(envPath) {
|
|
508840
|
-
return JSON.parse(await
|
|
509010
|
+
return JSON.parse(await readFile23(envPath, "utf8"));
|
|
508841
509011
|
}
|
|
508842
509012
|
var init_learning_harness = __esm(async () => {
|
|
508843
509013
|
await init_mod_engine();
|
|
@@ -509405,7 +509575,7 @@ var init_mods = __esm(async () => {
|
|
|
509405
509575
|
});
|
|
509406
509576
|
|
|
509407
509577
|
// src/cli/helpers/chdir-command.ts
|
|
509408
|
-
import { realpath as realpath6, stat as
|
|
509578
|
+
import { realpath as realpath6, stat as stat15 } from "node:fs/promises";
|
|
509409
509579
|
import { homedir as homedir45 } from "node:os";
|
|
509410
509580
|
import path44 from "node:path";
|
|
509411
509581
|
function parseChdirCommand(input) {
|
|
@@ -509444,7 +509614,7 @@ async function resolveChdirTarget(pathArg, currentWorkingDirectory) {
|
|
|
509444
509614
|
const expanded = expandHome(pathArg);
|
|
509445
509615
|
const resolved = path44.isAbsolute(expanded) ? expanded : path44.resolve(currentWorkingDirectory, expanded);
|
|
509446
509616
|
const normalized = await realpath6(resolved);
|
|
509447
|
-
const stats = await
|
|
509617
|
+
const stats = await stat15(normalized);
|
|
509448
509618
|
if (!stats.isDirectory()) {
|
|
509449
509619
|
throw new Error(`Not a directory: ${normalized}`);
|
|
509450
509620
|
}
|
|
@@ -511085,7 +511255,7 @@ __export(exports_worktree_diff_list, {
|
|
|
511085
511255
|
listWorktreeDiffOptions: () => listWorktreeDiffOptions
|
|
511086
511256
|
});
|
|
511087
511257
|
import { execFile as execFileCb6 } from "node:child_process";
|
|
511088
|
-
import { basename as
|
|
511258
|
+
import { basename as basename28 } from "node:path";
|
|
511089
511259
|
import { promisify as promisify17 } from "node:util";
|
|
511090
511260
|
async function runGit7(cwd2, args) {
|
|
511091
511261
|
try {
|
|
@@ -511134,7 +511304,7 @@ function parseWorktreeList(output, currentPath) {
|
|
|
511134
511304
|
if (current?.path) {
|
|
511135
511305
|
worktrees.push({
|
|
511136
511306
|
path: current.path,
|
|
511137
|
-
name:
|
|
511307
|
+
name: basename28(current.path),
|
|
511138
511308
|
branch: current.branch ?? "detached",
|
|
511139
511309
|
head: current.head ?? "",
|
|
511140
511310
|
isCurrent: current.path === currentPath,
|
|
@@ -511160,7 +511330,7 @@ function parseWorktreeList(output, currentPath) {
|
|
|
511160
511330
|
if (current?.path) {
|
|
511161
511331
|
worktrees.push({
|
|
511162
511332
|
path: current.path,
|
|
511163
|
-
name:
|
|
511333
|
+
name: basename28(current.path),
|
|
511164
511334
|
branch: current.branch ?? "detached",
|
|
511165
511335
|
head: current.head ?? "",
|
|
511166
511336
|
isCurrent: current.path === currentPath,
|
|
@@ -511229,8 +511399,8 @@ var exports_export = {};
|
|
|
511229
511399
|
__export(exports_export, {
|
|
511230
511400
|
packageSkills: () => packageSkills
|
|
511231
511401
|
});
|
|
511232
|
-
import { readdir as
|
|
511233
|
-
import { relative as
|
|
511402
|
+
import { readdir as readdir16, readFile as readFile24 } from "node:fs/promises";
|
|
511403
|
+
import { relative as relative15, resolve as resolve39 } from "node:path";
|
|
511234
511404
|
async function packageSkills(agentId, skillsDir) {
|
|
511235
511405
|
const skills = [];
|
|
511236
511406
|
const skillNames = new Set;
|
|
@@ -511241,7 +511411,7 @@ async function packageSkills(agentId, skillsDir) {
|
|
|
511241
511411
|
].filter((dir) => Boolean(dir));
|
|
511242
511412
|
for (const baseDir of dirsToCheck) {
|
|
511243
511413
|
try {
|
|
511244
|
-
const entries = await
|
|
511414
|
+
const entries = await readdir16(baseDir, { withFileTypes: true });
|
|
511245
511415
|
for (const entry of entries) {
|
|
511246
511416
|
if (!entry.isDirectory())
|
|
511247
511417
|
continue;
|
|
@@ -511250,7 +511420,7 @@ async function packageSkills(agentId, skillsDir) {
|
|
|
511250
511420
|
const skillDir = resolve39(baseDir, entry.name);
|
|
511251
511421
|
const skillMdPath = resolve39(skillDir, "SKILL.md");
|
|
511252
511422
|
try {
|
|
511253
|
-
await
|
|
511423
|
+
await readFile24(skillMdPath, "utf-8");
|
|
511254
511424
|
} catch {
|
|
511255
511425
|
console.warn(`Skipping invalid skill ${entry.name}: missing SKILL.md`);
|
|
511256
511426
|
continue;
|
|
@@ -511276,14 +511446,14 @@ async function packageSkills(agentId, skillsDir) {
|
|
|
511276
511446
|
async function readSkillFiles(skillDir) {
|
|
511277
511447
|
const files = {};
|
|
511278
511448
|
async function walk(dir) {
|
|
511279
|
-
const entries = await
|
|
511449
|
+
const entries = await readdir16(dir, { withFileTypes: true });
|
|
511280
511450
|
for (const entry of entries) {
|
|
511281
511451
|
const fullPath = resolve39(dir, entry.name);
|
|
511282
511452
|
if (entry.isDirectory()) {
|
|
511283
511453
|
await walk(fullPath);
|
|
511284
511454
|
} else {
|
|
511285
|
-
const content = await
|
|
511286
|
-
const relativePath =
|
|
511455
|
+
const content = await readFile24(fullPath, "utf-8");
|
|
511456
|
+
const relativePath = relative15(skillDir, fullPath).replace(/\\/g, "/");
|
|
511287
511457
|
files[relativePath] = content;
|
|
511288
511458
|
}
|
|
511289
511459
|
}
|
|
@@ -511420,7 +511590,7 @@ var init_conversation_switch_alert = __esm(() => {
|
|
|
511420
511590
|
import { randomUUID as randomUUID33 } from "node:crypto";
|
|
511421
511591
|
import { existsSync as existsSync67, readFileSync as readFileSync43, renameSync as renameSync7, writeFileSync as writeFileSync34 } from "node:fs";
|
|
511422
511592
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
511423
|
-
import { join as
|
|
511593
|
+
import { join as join74 } from "node:path";
|
|
511424
511594
|
async function findCustomCommandByName(commandName) {
|
|
511425
511595
|
const { findCustomCommand: findCustomCommand2 } = await Promise.resolve().then(() => (init_custom(), exports_custom));
|
|
511426
511596
|
return findCustomCommand2(commandName);
|
|
@@ -512021,8 +512191,8 @@ ${SYSTEM_REMINDER_CLOSE}`),
|
|
|
512021
512191
|
try {
|
|
512022
512192
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
512023
512193
|
const personaCandidates = [
|
|
512024
|
-
|
|
512025
|
-
|
|
512194
|
+
join74(memoryRoot, "system", "persona.md"),
|
|
512195
|
+
join74(memoryRoot, "memory", "system", "persona.md")
|
|
512026
512196
|
];
|
|
512027
512197
|
const personaPath = personaCandidates.find((candidate) => existsSync67(candidate));
|
|
512028
512198
|
if (personaPath) {
|
|
@@ -512881,7 +513051,7 @@ Path: ${memoryDir}`, true);
|
|
|
512881
513051
|
updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
|
|
512882
513052
|
return { submitted: true };
|
|
512883
513053
|
}
|
|
512884
|
-
const backupDir =
|
|
513054
|
+
const backupDir = join74(tmpdir11(), `letta-memfs-reset-${agentId}-${Date.now()}`);
|
|
512885
513055
|
renameSync7(memoryDir, backupDir);
|
|
512886
513056
|
if (getBackend().capabilities.localMemfs) {
|
|
512887
513057
|
const { initializeLocalMemoryRepo: initializeLocalMemoryRepo2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
@@ -513320,9 +513490,12 @@ ${SYSTEM_REMINDER_CLOSE}`;
|
|
|
513320
513490
|
cmd.finish("Running memory doctor... I'll ask a few questions to refine memory structure.", true);
|
|
513321
513491
|
const { context: gitContext } = gatherInitGitContext();
|
|
513322
513492
|
const memoryDir = getActiveMemoryDirectory(agentId);
|
|
513493
|
+
const skillNameFrontmatterRepair = await repairMissingSkillNameFrontmatter(memoryDir);
|
|
513494
|
+
const skillNameFrontmatterRepairReport = formatSkillNameFrontmatterRepairReport(skillNameFrontmatterRepair);
|
|
513323
513495
|
const doctorMessage = buildDoctorMessage({
|
|
513324
513496
|
gitContext,
|
|
513325
|
-
memoryDir
|
|
513497
|
+
memoryDir,
|
|
513498
|
+
skillNameFrontmatterRepairReport
|
|
513326
513499
|
});
|
|
513327
513500
|
await processConversationWithQueuedApprovals([
|
|
513328
513501
|
{
|
|
@@ -513699,6 +513872,7 @@ var init_use_submit_handler = __esm(async () => {
|
|
|
513699
513872
|
init_reasoning_tab_toggle();
|
|
513700
513873
|
init_reflection_launcher();
|
|
513701
513874
|
init_reflection_transcript();
|
|
513875
|
+
init_skill_name_frontmatter_repair();
|
|
513702
513876
|
init_system_prompt_warning();
|
|
513703
513877
|
init_thinking_messages();
|
|
513704
513878
|
init_command_runtime();
|
|
@@ -513731,7 +513905,7 @@ var init_use_submit_handler = __esm(async () => {
|
|
|
513731
513905
|
});
|
|
513732
513906
|
|
|
513733
513907
|
// src/cli/app/AppCoordinator.tsx
|
|
513734
|
-
import { join as
|
|
513908
|
+
import { join as join75 } from "node:path";
|
|
513735
513909
|
function buildStartupCommandHints(options3) {
|
|
513736
513910
|
const {
|
|
513737
513911
|
isResumingConversation,
|
|
@@ -515036,7 +515210,7 @@ function App2({
|
|
|
515036
515210
|
agentId: a2.agentId ?? null
|
|
515037
515211
|
}))
|
|
515038
515212
|
});
|
|
515039
|
-
const agentModsDirectory = modContext.memfs.enabled && modContext.memfs.memoryDir ?
|
|
515213
|
+
const agentModsDirectory = modContext.memfs.enabled && modContext.memfs.memoryDir ? join75(modContext.memfs.memoryDir, "mods") : null;
|
|
515040
515214
|
const modAdapter = useLocalModAdapter(modContext, {
|
|
515041
515215
|
agentModsDirectory,
|
|
515042
515216
|
disabled: modsDisabled
|
|
@@ -517063,7 +517237,7 @@ import {
|
|
|
517063
517237
|
writeFileSync as writeFileSync35
|
|
517064
517238
|
} from "node:fs";
|
|
517065
517239
|
import { homedir as homedir46, platform as platform11 } from "node:os";
|
|
517066
|
-
import { dirname as
|
|
517240
|
+
import { dirname as dirname34, join as join76 } from "node:path";
|
|
517067
517241
|
function detectTerminalType2() {
|
|
517068
517242
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
517069
517243
|
return "cursor";
|
|
@@ -517095,16 +517269,16 @@ function getKeybindingsPath2(terminal) {
|
|
|
517095
517269
|
}[terminal];
|
|
517096
517270
|
const os10 = platform11();
|
|
517097
517271
|
if (os10 === "darwin") {
|
|
517098
|
-
return
|
|
517272
|
+
return join76(homedir46(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
517099
517273
|
}
|
|
517100
517274
|
if (os10 === "win32") {
|
|
517101
517275
|
const appData = process.env.APPDATA;
|
|
517102
517276
|
if (!appData)
|
|
517103
517277
|
return null;
|
|
517104
|
-
return
|
|
517278
|
+
return join76(appData, appName, "User", "keybindings.json");
|
|
517105
517279
|
}
|
|
517106
517280
|
if (os10 === "linux") {
|
|
517107
|
-
return
|
|
517281
|
+
return join76(homedir46(), ".config", appName, "User", "keybindings.json");
|
|
517108
517282
|
}
|
|
517109
517283
|
return null;
|
|
517110
517284
|
}
|
|
@@ -517154,7 +517328,7 @@ function installKeybinding2(keybindingsPath) {
|
|
|
517154
517328
|
if (keybindingExists2(keybindingsPath)) {
|
|
517155
517329
|
return { success: true, alreadyExists: true };
|
|
517156
517330
|
}
|
|
517157
|
-
const parentDir =
|
|
517331
|
+
const parentDir = dirname34(keybindingsPath);
|
|
517158
517332
|
if (!existsSync68(parentDir)) {
|
|
517159
517333
|
mkdirSync46(parentDir, { recursive: true });
|
|
517160
517334
|
}
|
|
@@ -517257,14 +517431,14 @@ function getWezTermConfigPath2() {
|
|
|
517257
517431
|
}
|
|
517258
517432
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
517259
517433
|
if (xdgConfig) {
|
|
517260
|
-
const xdgPath =
|
|
517434
|
+
const xdgPath = join76(xdgConfig, "wezterm", "wezterm.lua");
|
|
517261
517435
|
if (existsSync68(xdgPath))
|
|
517262
517436
|
return xdgPath;
|
|
517263
517437
|
}
|
|
517264
|
-
const configPath =
|
|
517438
|
+
const configPath = join76(homedir46(), ".config", "wezterm", "wezterm.lua");
|
|
517265
517439
|
if (existsSync68(configPath))
|
|
517266
517440
|
return configPath;
|
|
517267
|
-
return
|
|
517441
|
+
return join76(homedir46(), ".wezterm.lua");
|
|
517268
517442
|
}
|
|
517269
517443
|
function stripLuaCommentsFromLine2(line, blockCommentEnd) {
|
|
517270
517444
|
let code2 = "";
|
|
@@ -517390,7 +517564,7 @@ function installWezTermDeleteFix2() {
|
|
|
517390
517564
|
content = readFileSync44(configPath, { encoding: "utf-8" });
|
|
517391
517565
|
}
|
|
517392
517566
|
content = injectWezTermDeleteFix2(content);
|
|
517393
|
-
const parentDir =
|
|
517567
|
+
const parentDir = dirname34(configPath);
|
|
517394
517568
|
if (!existsSync68(parentDir)) {
|
|
517395
517569
|
mkdirSync46(parentDir, { recursive: true });
|
|
517396
517570
|
}
|
|
@@ -517443,9 +517617,9 @@ __export(exports_settings3, {
|
|
|
517443
517617
|
getSetting: () => getSetting2
|
|
517444
517618
|
});
|
|
517445
517619
|
import { homedir as homedir47 } from "node:os";
|
|
517446
|
-
import { join as
|
|
517620
|
+
import { join as join77 } from "node:path";
|
|
517447
517621
|
function getSettingsPath2() {
|
|
517448
|
-
return
|
|
517622
|
+
return join77(homedir47(), ".letta", "settings.json");
|
|
517449
517623
|
}
|
|
517450
517624
|
async function loadSettings2() {
|
|
517451
517625
|
const settingsPath = getSettingsPath2();
|
|
@@ -517482,7 +517656,7 @@ async function getSetting2(key2) {
|
|
|
517482
517656
|
return settings3[key2];
|
|
517483
517657
|
}
|
|
517484
517658
|
function getProjectSettingsPath2() {
|
|
517485
|
-
return
|
|
517659
|
+
return join77(process.cwd(), ".letta", "settings.local.json");
|
|
517486
517660
|
}
|
|
517487
517661
|
async function loadProjectSettings2() {
|
|
517488
517662
|
const settingsPath = getProjectSettingsPath2();
|
|
@@ -517500,7 +517674,7 @@ async function loadProjectSettings2() {
|
|
|
517500
517674
|
}
|
|
517501
517675
|
async function saveProjectSettings2(settings3) {
|
|
517502
517676
|
const settingsPath = getProjectSettingsPath2();
|
|
517503
|
-
const dirPath =
|
|
517677
|
+
const dirPath = join77(process.cwd(), ".letta");
|
|
517504
517678
|
try {
|
|
517505
517679
|
if (!exists(dirPath)) {
|
|
517506
517680
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -517991,8 +518165,8 @@ __export(exports_import2, {
|
|
|
517991
518165
|
extractSkillsFromAf: () => extractSkillsFromAf2
|
|
517992
518166
|
});
|
|
517993
518167
|
import { createReadStream as createReadStream3 } from "node:fs";
|
|
517994
|
-
import { access as access4, chmod as chmod2, mkdir as mkdir16, readFile as
|
|
517995
|
-
import { dirname as
|
|
518168
|
+
import { access as access4, chmod as chmod2, mkdir as mkdir16, readFile as readFile25, writeFile as writeFile19 } from "node:fs/promises";
|
|
518169
|
+
import { dirname as dirname35, isAbsolute as isAbsolute26, relative as relative16, resolve as resolve40, sep as sep7, win32 as win326 } from "node:path";
|
|
517996
518170
|
function validateImportedSkillName2(name) {
|
|
517997
518171
|
const trimmedName = name.trim();
|
|
517998
518172
|
if (trimmedName !== name || trimmedName.length === 0 || trimmedName.length > MAX_SKILL_NAME_LENGTH || trimmedName === "." || trimmedName === ".." || !IMPORTED_SKILL_NAME_PATTERN2.test(trimmedName)) {
|
|
@@ -518003,7 +518177,7 @@ function validateImportedSkillName2(name) {
|
|
|
518003
518177
|
function assertPathInside2(parent, child) {
|
|
518004
518178
|
const parentPath = resolve40(parent);
|
|
518005
518179
|
const childPath = resolve40(child);
|
|
518006
|
-
const relativePath =
|
|
518180
|
+
const relativePath = relative16(parentPath, childPath);
|
|
518007
518181
|
if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${sep7}`) || isAbsolute26(relativePath)) {
|
|
518008
518182
|
throw new Error(`Imported skill file path escapes skill directory: ${child}`);
|
|
518009
518183
|
}
|
|
@@ -518092,7 +518266,7 @@ async function importAgentFromFile2(options3) {
|
|
|
518092
518266
|
}
|
|
518093
518267
|
async function extractSkillsFromAf2(afPath, destDir) {
|
|
518094
518268
|
const extracted = [];
|
|
518095
|
-
const content = await
|
|
518269
|
+
const content = await readFile25(afPath, "utf-8");
|
|
518096
518270
|
const afData = JSON.parse(content);
|
|
518097
518271
|
if (!afData.skills || !Array.isArray(afData.skills)) {
|
|
518098
518272
|
return [];
|
|
@@ -518120,8 +518294,8 @@ async function writeSkillFiles2(skillDir, files) {
|
|
|
518120
518294
|
}
|
|
518121
518295
|
async function writeSkillFile2(skillDir, filePath, content) {
|
|
518122
518296
|
const fullPath = resolveImportedSkillFilePath2(skillDir, filePath);
|
|
518123
|
-
await mkdir16(
|
|
518124
|
-
await
|
|
518297
|
+
await mkdir16(dirname35(fullPath), { recursive: true });
|
|
518298
|
+
await writeFile19(fullPath, content, "utf-8");
|
|
518125
518299
|
const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
|
|
518126
518300
|
if (isScript) {
|
|
518127
518301
|
try {
|
|
@@ -518173,8 +518347,8 @@ function parseRegistryHandle2(handle2) {
|
|
|
518173
518347
|
}
|
|
518174
518348
|
async function importAgentFromRegistry2(options3) {
|
|
518175
518349
|
const { tmpdir: tmpdir12 } = await import("node:os");
|
|
518176
|
-
const { join:
|
|
518177
|
-
const { writeFile:
|
|
518350
|
+
const { join: join78 } = await import("node:path");
|
|
518351
|
+
const { writeFile: writeFile20, unlink: unlink5 } = await import("node:fs/promises");
|
|
518178
518352
|
const { author, name } = parseRegistryHandle2(options3.handle);
|
|
518179
518353
|
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER2}/${AGENT_REGISTRY_REPO2}/refs/heads/${AGENT_REGISTRY_BRANCH2}/agents/@${author}/${name}/${name}.af`;
|
|
518180
518354
|
const response = await fetch(rawUrl);
|
|
@@ -518185,8 +518359,8 @@ async function importAgentFromRegistry2(options3) {
|
|
|
518185
518359
|
throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
|
|
518186
518360
|
}
|
|
518187
518361
|
const afContent = await response.text();
|
|
518188
|
-
const tempPath =
|
|
518189
|
-
await
|
|
518362
|
+
const tempPath = join78(tmpdir12(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
518363
|
+
await writeFile20(tempPath, afContent, "utf-8");
|
|
518190
518364
|
try {
|
|
518191
518365
|
const result = await importAgentFromFile2({
|
|
518192
518366
|
filePath: tempPath,
|
|
@@ -518241,12 +518415,12 @@ __export(exports_memory_filesystem2, {
|
|
|
518241
518415
|
});
|
|
518242
518416
|
import { existsSync as existsSync69, mkdirSync as mkdirSync47 } from "node:fs";
|
|
518243
518417
|
import { homedir as homedir48 } from "node:os";
|
|
518244
|
-
import { join as
|
|
518418
|
+
import { join as join78, resolve as resolve41 } from "node:path";
|
|
518245
518419
|
function getMemoryFilesystemRoot2(agentId, homeDir = homedir48()) {
|
|
518246
|
-
return
|
|
518420
|
+
return join78(homeDir, MEMORY_FS_ROOT2, MEMORY_FS_AGENTS_DIR2, agentId, MEMORY_FS_MEMORY_DIR2);
|
|
518247
518421
|
}
|
|
518248
518422
|
function getMemorySystemDir2(agentId, homeDir = homedir48()) {
|
|
518249
|
-
return
|
|
518423
|
+
return join78(getMemoryFilesystemRoot2(agentId, homeDir), MEMORY_SYSTEM_DIR2);
|
|
518250
518424
|
}
|
|
518251
518425
|
function getScopedMemoryFilesystemRoot2(agentId, options3 = {}) {
|
|
518252
518426
|
const env6 = options3.env ?? process.env;
|
|
@@ -518592,7 +518766,7 @@ __export(exports_secrets_store2, {
|
|
|
518592
518766
|
__testOverrideLocalSecretStorage: () => __testOverrideLocalSecretStorage2
|
|
518593
518767
|
});
|
|
518594
518768
|
import { existsSync as existsSync70, mkdirSync as mkdirSync48, readFileSync as readFileSync45, writeFileSync as writeFileSync36 } from "node:fs";
|
|
518595
|
-
import { dirname as
|
|
518769
|
+
import { dirname as dirname36, join as join79 } from "node:path";
|
|
518596
518770
|
function __testOverrideSecretsBackend2(backend4) {
|
|
518597
518771
|
testBackendOverride2 = backend4;
|
|
518598
518772
|
}
|
|
@@ -518603,7 +518777,7 @@ function getSecretsBackend2() {
|
|
|
518603
518777
|
return testBackendOverride2 ?? getBackend();
|
|
518604
518778
|
}
|
|
518605
518779
|
function getFileBackedLocalSecretsPath2() {
|
|
518606
|
-
return
|
|
518780
|
+
return join79(getLocalBackendStorageDir(), FILE_BACKED_LOCAL_SECRETS_PATH2);
|
|
518607
518781
|
}
|
|
518608
518782
|
function readFileBackedLocalSecrets2() {
|
|
518609
518783
|
const filePath = getFileBackedLocalSecretsPath2();
|
|
@@ -518620,7 +518794,7 @@ function readFileBackedLocalSecrets2() {
|
|
|
518620
518794
|
}
|
|
518621
518795
|
function writeFileBackedLocalSecrets2(secrets2) {
|
|
518622
518796
|
const filePath = getFileBackedLocalSecretsPath2();
|
|
518623
|
-
mkdirSync48(
|
|
518797
|
+
mkdirSync48(dirname36(filePath), { mode: 448, recursive: true });
|
|
518624
518798
|
writeFileSync36(filePath, `${JSON.stringify({ secrets: secrets2 }, null, 2)}
|
|
518625
518799
|
`, {
|
|
518626
518800
|
encoding: "utf8",
|
|
@@ -518916,7 +519090,7 @@ var init_secrets_store2 = __esm(() => {
|
|
|
518916
519090
|
init_backend2();
|
|
518917
519091
|
init_paths();
|
|
518918
519092
|
init_secrets();
|
|
518919
|
-
FILE_BACKED_LOCAL_SECRETS_PATH2 =
|
|
519093
|
+
FILE_BACKED_LOCAL_SECRETS_PATH2 = join79("secrets", "local-agent-secrets.json");
|
|
518920
519094
|
SECRETS_CACHE_KEY2 = Symbol.for("@letta/secretsCache");
|
|
518921
519095
|
LOCAL_SECRET_NAME_PATTERN2 = /^[A-Z_][A-Z0-9_]*$/;
|
|
518922
519096
|
});
|
|
@@ -525430,8 +525604,8 @@ import {
|
|
|
525430
525604
|
unlinkSync as unlinkSync7
|
|
525431
525605
|
} from "node:fs";
|
|
525432
525606
|
import { homedir as homedir30 } from "node:os";
|
|
525433
|
-
import { join as
|
|
525434
|
-
var REMOTE_LOG_DIR =
|
|
525607
|
+
import { join as join50 } from "node:path";
|
|
525608
|
+
var REMOTE_LOG_DIR = join50(homedir30(), ".letta", "logs", "remote");
|
|
525435
525609
|
var MAX_LOG_FILES = 10;
|
|
525436
525610
|
function formatTimestamp2() {
|
|
525437
525611
|
const now = new Date;
|
|
@@ -525450,7 +525624,7 @@ function pruneOldLogs() {
|
|
|
525450
525624
|
const toDelete = files.slice(0, files.length - MAX_LOG_FILES + 1);
|
|
525451
525625
|
for (const file3 of toDelete) {
|
|
525452
525626
|
try {
|
|
525453
|
-
unlinkSync7(
|
|
525627
|
+
unlinkSync7(join50(REMOTE_LOG_DIR, file3));
|
|
525454
525628
|
} catch {}
|
|
525455
525629
|
}
|
|
525456
525630
|
}
|
|
@@ -525463,7 +525637,7 @@ class RemoteSessionLog {
|
|
|
525463
525637
|
constructor() {
|
|
525464
525638
|
const now = new Date;
|
|
525465
525639
|
const stamp = now.toISOString().replace(/[:.]/g, "-");
|
|
525466
|
-
this.path =
|
|
525640
|
+
this.path = join50(REMOTE_LOG_DIR, `${stamp}.log`);
|
|
525467
525641
|
}
|
|
525468
525642
|
init() {
|
|
525469
525643
|
this.ensureDir();
|
|
@@ -526092,7 +526266,7 @@ import {
|
|
|
526092
526266
|
readFileSync as readFileSync32,
|
|
526093
526267
|
writeFileSync as writeFileSync23
|
|
526094
526268
|
} from "node:fs";
|
|
526095
|
-
import { join as
|
|
526269
|
+
import { join as join51 } from "node:path";
|
|
526096
526270
|
function readJsonl(path37) {
|
|
526097
526271
|
if (!existsSync47(path37))
|
|
526098
526272
|
return [];
|
|
@@ -526375,7 +526549,7 @@ function convertMessages4(messages, mode, nextId2) {
|
|
|
526375
526549
|
}
|
|
526376
526550
|
function migrateLocalBackendTranscripts(input) {
|
|
526377
526551
|
const storageDir = input.storageDir;
|
|
526378
|
-
const conversationsDir =
|
|
526552
|
+
const conversationsDir = join51(storageDir, "conversations");
|
|
526379
526553
|
const result = {
|
|
526380
526554
|
storageDir,
|
|
526381
526555
|
converted: [],
|
|
@@ -526385,9 +526559,9 @@ function migrateLocalBackendTranscripts(input) {
|
|
|
526385
526559
|
if (!existsSync47(conversationsDir))
|
|
526386
526560
|
return result;
|
|
526387
526561
|
for (const name of readdirSync17(conversationsDir)) {
|
|
526388
|
-
const conversationDir =
|
|
526389
|
-
const messagesPath =
|
|
526390
|
-
const manifestPath =
|
|
526562
|
+
const conversationDir = join51(conversationsDir, name);
|
|
526563
|
+
const messagesPath = join51(conversationDir, "messages.jsonl");
|
|
526564
|
+
const manifestPath = join51(conversationDir, "manifest.json");
|
|
526391
526565
|
const hasManifest = existsSync47(manifestPath);
|
|
526392
526566
|
const existingManifest = hasManifest ? (() => {
|
|
526393
526567
|
try {
|
|
@@ -526430,7 +526604,7 @@ function migrateLocalBackendTranscripts(input) {
|
|
|
526430
526604
|
const backupPath = `${messagesPath}.pre-pi-backup-${timestampSuffix()}`;
|
|
526431
526605
|
if (!input.dryRun) {
|
|
526432
526606
|
copyFileSync2(messagesPath, backupPath);
|
|
526433
|
-
const conversationPath =
|
|
526607
|
+
const conversationPath = join51(conversationDir, "conversation.json");
|
|
526434
526608
|
let conversation;
|
|
526435
526609
|
if (existsSync47(conversationPath)) {
|
|
526436
526610
|
try {
|
|
@@ -526543,8 +526717,8 @@ init_memory_filesystem2();
|
|
|
526543
526717
|
init_memory_git();
|
|
526544
526718
|
init_paths();
|
|
526545
526719
|
import { cpSync, existsSync as existsSync48, mkdirSync as mkdirSync33, rmSync as rmSync10, statSync as statSync17 } from "node:fs";
|
|
526546
|
-
import { readdir as
|
|
526547
|
-
import { dirname as
|
|
526720
|
+
import { readdir as readdir12 } from "node:fs/promises";
|
|
526721
|
+
import { dirname as dirname25, join as join52 } from "node:path";
|
|
526548
526722
|
import { parseArgs as parseArgs9 } from "node:util";
|
|
526549
526723
|
|
|
526550
526724
|
// src/cli/subcommands/memory-tokens.ts
|
|
@@ -526682,7 +526856,7 @@ function getMemoryRoot(agentId) {
|
|
|
526682
526856
|
return getScopedMemoryFilesystemRoot(agentId);
|
|
526683
526857
|
}
|
|
526684
526858
|
function getAgentRoot(agentId) {
|
|
526685
|
-
return
|
|
526859
|
+
return dirname25(getMemoryRoot(agentId));
|
|
526686
526860
|
}
|
|
526687
526861
|
function formatBackupTimestamp(date6 = new Date) {
|
|
526688
526862
|
const pad = (value) => String(value).padStart(2, "0");
|
|
@@ -526699,18 +526873,18 @@ async function listBackups(agentId) {
|
|
|
526699
526873
|
if (!existsSync48(agentRoot)) {
|
|
526700
526874
|
return [];
|
|
526701
526875
|
}
|
|
526702
|
-
const entries = await
|
|
526876
|
+
const entries = await readdir12(agentRoot, { withFileTypes: true });
|
|
526703
526877
|
const backups = [];
|
|
526704
526878
|
for (const entry of entries) {
|
|
526705
526879
|
if (!entry.isDirectory())
|
|
526706
526880
|
continue;
|
|
526707
526881
|
if (!entry.name.startsWith("memory-backup-"))
|
|
526708
526882
|
continue;
|
|
526709
|
-
const path37 =
|
|
526883
|
+
const path37 = join52(agentRoot, entry.name);
|
|
526710
526884
|
let createdAt = null;
|
|
526711
526885
|
try {
|
|
526712
|
-
const
|
|
526713
|
-
createdAt =
|
|
526886
|
+
const stat14 = statSync17(path37);
|
|
526887
|
+
createdAt = stat14.mtime.toISOString();
|
|
526714
526888
|
} catch {
|
|
526715
526889
|
createdAt = null;
|
|
526716
526890
|
}
|
|
@@ -526723,7 +526897,7 @@ function resolveBackupPath(agentId, from) {
|
|
|
526723
526897
|
if (from.startsWith("/") || /^[A-Za-z]:[/\\]/.test(from)) {
|
|
526724
526898
|
return from;
|
|
526725
526899
|
}
|
|
526726
|
-
return
|
|
526900
|
+
return join52(getAgentRoot(agentId), from);
|
|
526727
526901
|
}
|
|
526728
526902
|
async function runMemorySubcommand(argv) {
|
|
526729
526903
|
let parsed;
|
|
@@ -526805,7 +526979,7 @@ async function runMemorySubcommand(argv) {
|
|
|
526805
526979
|
}
|
|
526806
526980
|
const agentRoot = getAgentRoot(agentId);
|
|
526807
526981
|
const backupName = `memory-backup-${formatBackupTimestamp()}`;
|
|
526808
|
-
const backupPath =
|
|
526982
|
+
const backupPath = join52(agentRoot, backupName);
|
|
526809
526983
|
if (existsSync48(backupPath)) {
|
|
526810
526984
|
console.error(`Backup already exists at ${backupPath}`);
|
|
526811
526985
|
return 1;
|
|
@@ -526834,8 +527008,8 @@ async function runMemorySubcommand(argv) {
|
|
|
526834
527008
|
console.error(`Backup not found: ${backupPath}`);
|
|
526835
527009
|
return 1;
|
|
526836
527010
|
}
|
|
526837
|
-
const
|
|
526838
|
-
if (!
|
|
527011
|
+
const stat14 = statSync17(backupPath);
|
|
527012
|
+
if (!stat14.isDirectory()) {
|
|
526839
527013
|
console.error(`Backup path is not a directory: ${backupPath}`);
|
|
526840
527014
|
return 1;
|
|
526841
527015
|
}
|
|
@@ -526857,9 +527031,9 @@ async function runMemorySubcommand(argv) {
|
|
|
526857
527031
|
return 1;
|
|
526858
527032
|
}
|
|
526859
527033
|
if (existsSync48(out)) {
|
|
526860
|
-
const
|
|
526861
|
-
if (
|
|
526862
|
-
const contents = await
|
|
527034
|
+
const stat14 = statSync17(out);
|
|
527035
|
+
if (stat14.isDirectory()) {
|
|
527036
|
+
const contents = await readdir12(out);
|
|
526863
527037
|
if (contents.length > 0) {
|
|
526864
527038
|
console.error(`Export directory not empty: ${out}`);
|
|
526865
527039
|
return 1;
|
|
@@ -526888,7 +527062,7 @@ async function runMemorySubcommand(argv) {
|
|
|
526888
527062
|
init_backend2();
|
|
526889
527063
|
init_message_search();
|
|
526890
527064
|
init_settings_manager();
|
|
526891
|
-
import { writeFile as
|
|
527065
|
+
import { writeFile as writeFile15 } from "node:fs/promises";
|
|
526892
527066
|
import { resolve as resolve30 } from "node:path";
|
|
526893
527067
|
import { parseArgs as parseArgs10 } from "node:util";
|
|
526894
527068
|
function printUsage7() {
|
|
@@ -527233,7 +527407,7 @@ async function runMessagesSubcommand(argv, deps = {}) {
|
|
|
527233
527407
|
`).trim();
|
|
527234
527408
|
if (outputPathRaw && typeof outputPathRaw === "string") {
|
|
527235
527409
|
const outputPath = resolve30(process.cwd(), outputPathRaw);
|
|
527236
|
-
await
|
|
527410
|
+
await writeFile15(outputPath, `${transcript}
|
|
527237
527411
|
`, "utf-8");
|
|
527238
527412
|
console.log(JSON.stringify({
|
|
527239
527413
|
conversation_id: conversationId,
|
|
@@ -527263,7 +527437,7 @@ async function runMessagesSubcommand(argv, deps = {}) {
|
|
|
527263
527437
|
// src/cli/subcommands/mods.ts
|
|
527264
527438
|
init_memory_filesystem2();
|
|
527265
527439
|
await init_mod_engine();
|
|
527266
|
-
import { dirname as
|
|
527440
|
+
import { dirname as dirname26, join as join54 } from "node:path";
|
|
527267
527441
|
import { parseArgs as parseArgs11 } from "node:util";
|
|
527268
527442
|
|
|
527269
527443
|
// src/mods/package-installer.ts
|
|
@@ -527297,8 +527471,8 @@ function isRecord10(value) {
|
|
|
527297
527471
|
function isPathInsideOrEqual2(childPath, parentPath) {
|
|
527298
527472
|
const child = path37.resolve(childPath);
|
|
527299
527473
|
const parent = path37.resolve(parentPath);
|
|
527300
|
-
const
|
|
527301
|
-
return
|
|
527474
|
+
const relative12 = path37.relative(parent, child);
|
|
527475
|
+
return relative12 === "" || !!relative12 && !relative12.startsWith("..") && !path37.isAbsolute(relative12);
|
|
527302
527476
|
}
|
|
527303
527477
|
function readPackageJson(packageJsonPath) {
|
|
527304
527478
|
let parsed;
|
|
@@ -528316,10 +528490,10 @@ function getExplicitAgentId(values2) {
|
|
|
528316
528490
|
return typeof explicitAgent === "string" && explicitAgent.trim() ? explicitAgent.trim() : null;
|
|
528317
528491
|
}
|
|
528318
528492
|
function getAgentModsDirectory(agentId) {
|
|
528319
|
-
return
|
|
528493
|
+
return join54(getScopedMemoryFilesystemRoot(agentId), "mods");
|
|
528320
528494
|
}
|
|
528321
528495
|
function directFilesForSource(source2) {
|
|
528322
|
-
return source2.files.filter((file3) =>
|
|
528496
|
+
return source2.files.filter((file3) => dirname26(file3) === source2.root);
|
|
528323
528497
|
}
|
|
528324
528498
|
function toSection(source2) {
|
|
528325
528499
|
return {
|
|
@@ -528652,9 +528826,9 @@ import {
|
|
|
528652
528826
|
statSync as statSync19,
|
|
528653
528827
|
writeFileSync as writeFileSync26
|
|
528654
528828
|
} from "node:fs";
|
|
528655
|
-
import { mkdir as mkdir12, readdir as
|
|
528829
|
+
import { mkdir as mkdir12, readdir as readdir13 } from "node:fs/promises";
|
|
528656
528830
|
import { tmpdir as tmpdir9 } from "node:os";
|
|
528657
|
-
import { basename as
|
|
528831
|
+
import { basename as basename24, dirname as dirname27, join as join55, normalize as normalize5, resolve as resolve31, sep as sep5 } from "node:path";
|
|
528658
528832
|
import { parseArgs as parseArgs12, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
|
|
528659
528833
|
init_paths2();
|
|
528660
528834
|
var HERMES_REPO_URL = "https://github.com/NousResearch/hermes-agent.git";
|
|
@@ -528829,7 +529003,7 @@ function parseGitHubSpecifier(input) {
|
|
|
528829
529003
|
return {
|
|
528830
529004
|
repoUrl,
|
|
528831
529005
|
branch: null,
|
|
528832
|
-
subdir: marker === "blob" ?
|
|
529006
|
+
subdir: marker === "blob" ? dirname27(treePath) : treePath
|
|
528833
529007
|
};
|
|
528834
529008
|
}
|
|
528835
529009
|
return { repoUrl, branch: null, subdir: null };
|
|
@@ -528862,7 +529036,7 @@ function parseDirectSkillFileUrlSpecifier(input) {
|
|
|
528862
529036
|
if (url2.protocol !== "https:" && !(url2.protocol === "http:" && isLocalhostHostname(url2.hostname))) {
|
|
528863
529037
|
return null;
|
|
528864
529038
|
}
|
|
528865
|
-
if (
|
|
529039
|
+
if (basename24(url2.pathname).toLowerCase() !== "skill.md")
|
|
528866
529040
|
return null;
|
|
528867
529041
|
return { url: url2.toString() };
|
|
528868
529042
|
}
|
|
@@ -528959,14 +529133,14 @@ async function resolveBranchAndSubdir(location) {
|
|
|
528959
529133
|
}
|
|
528960
529134
|
async function cloneSkillSource(location) {
|
|
528961
529135
|
const resolvedLocation = await resolveBranchAndSubdir(location);
|
|
528962
|
-
const tmpDir = mkdtempSync4(
|
|
529136
|
+
const tmpDir = mkdtempSync4(join55(tmpdir9(), "letta-skill-install-"));
|
|
528963
529137
|
const args = ["clone", "--depth", "1"];
|
|
528964
529138
|
if (resolvedLocation.branch) {
|
|
528965
529139
|
args.push("--branch", resolvedLocation.branch);
|
|
528966
529140
|
}
|
|
528967
529141
|
args.push(resolvedLocation.repoUrl, tmpDir);
|
|
528968
529142
|
await execFile15("git", args, { timeout: 120000 });
|
|
528969
|
-
const sourceDir = resolvedLocation.subdir ?
|
|
529143
|
+
const sourceDir = resolvedLocation.subdir ? join55(tmpDir, resolvedLocation.subdir) : tmpDir;
|
|
528970
529144
|
return { tmpDir, sourceDir };
|
|
528971
529145
|
}
|
|
528972
529146
|
function assertDirectSkillFileSize(receivedBytes, maxBytes) {
|
|
@@ -529021,11 +529195,11 @@ async function downloadDirectSkillFileSource(location, options3 = {}) {
|
|
|
529021
529195
|
throw new Error(`Direct skill file download failed for ${location.url}: ${response.status}`);
|
|
529022
529196
|
}
|
|
529023
529197
|
const skillText = await readResponseTextWithLimit(response, MAX_DIRECT_SKILL_FILE_BYTES);
|
|
529024
|
-
const tmpDir = mkdtempSync4(
|
|
529198
|
+
const tmpDir = mkdtempSync4(join55(tmpdir9(), "letta-direct-skill-"));
|
|
529025
529199
|
try {
|
|
529026
|
-
const sourceDir =
|
|
529200
|
+
const sourceDir = join55(tmpDir, "skill");
|
|
529027
529201
|
await mkdir12(sourceDir, { recursive: true });
|
|
529028
|
-
writeFileSync26(
|
|
529202
|
+
writeFileSync26(join55(sourceDir, "SKILL.md"), skillText, "utf8");
|
|
529029
529203
|
return { tmpDir, sourceDir };
|
|
529030
529204
|
} catch (error54) {
|
|
529031
529205
|
rmSync13(tmpDir, { recursive: true, force: true });
|
|
@@ -529066,9 +529240,9 @@ function assertSafeZipMember(name) {
|
|
|
529066
529240
|
}
|
|
529067
529241
|
async function downloadClawHubSkillSource(location) {
|
|
529068
529242
|
const version2 = await resolveClawHubVersion(location);
|
|
529069
|
-
const tmpDir = mkdtempSync4(
|
|
529070
|
-
const zipPath =
|
|
529071
|
-
const sourceDir =
|
|
529243
|
+
const tmpDir = mkdtempSync4(join55(tmpdir9(), "letta-clawhub-skill-"));
|
|
529244
|
+
const zipPath = join55(tmpDir, "skill.zip");
|
|
529245
|
+
const sourceDir = join55(tmpDir, "skill");
|
|
529072
529246
|
await mkdir12(sourceDir, { recursive: true });
|
|
529073
529247
|
const url2 = new URL(`${CLAWHUB_API_BASE_URL}/download`);
|
|
529074
529248
|
url2.searchParams.set("slug", location.slug);
|
|
@@ -529107,16 +529281,16 @@ function sanitizeSkillName(name) {
|
|
|
529107
529281
|
return trimmed;
|
|
529108
529282
|
}
|
|
529109
529283
|
function getSkillName(sourceDir) {
|
|
529110
|
-
const skillMd = readFileSync35(
|
|
529284
|
+
const skillMd = readFileSync35(join55(sourceDir, "SKILL.md"), "utf8");
|
|
529111
529285
|
const { frontmatter } = parseFrontmatter(skillMd);
|
|
529112
529286
|
const frontmatterName = frontmatter.name;
|
|
529113
|
-
const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName :
|
|
529287
|
+
const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName : basename24(sourceDir);
|
|
529114
529288
|
return sanitizeSkillName(name);
|
|
529115
529289
|
}
|
|
529116
529290
|
async function installSkillDirectory(params) {
|
|
529117
529291
|
const sourceDir = resolve31(params.sourceDir);
|
|
529118
529292
|
const memoryDir = resolve31(params.memoryDir);
|
|
529119
|
-
const skillMdPath =
|
|
529293
|
+
const skillMdPath = join55(sourceDir, "SKILL.md");
|
|
529120
529294
|
if (!existsSync52(skillMdPath)) {
|
|
529121
529295
|
throw new Error("No SKILL.md found in the skill directory.");
|
|
529122
529296
|
}
|
|
@@ -529124,8 +529298,8 @@ async function installSkillDirectory(params) {
|
|
|
529124
529298
|
throw new Error(`Skill source is not a directory: ${sourceDir}`);
|
|
529125
529299
|
}
|
|
529126
529300
|
const name = getSkillName(sourceDir);
|
|
529127
|
-
const skillsDir =
|
|
529128
|
-
const targetPath =
|
|
529301
|
+
const skillsDir = join55(memoryDir, "skills");
|
|
529302
|
+
const targetPath = join55(skillsDir, name);
|
|
529129
529303
|
assertInside(skillsDir, targetPath);
|
|
529130
529304
|
if (existsSync52(targetPath)) {
|
|
529131
529305
|
if (!params.force) {
|
|
@@ -529136,22 +529310,22 @@ async function installSkillDirectory(params) {
|
|
|
529136
529310
|
await mkdir12(skillsDir, { recursive: true });
|
|
529137
529311
|
cpSync2(sourceDir, targetPath, {
|
|
529138
529312
|
recursive: true,
|
|
529139
|
-
filter: (source2) =>
|
|
529313
|
+
filter: (source2) => basename24(source2) !== ".git"
|
|
529140
529314
|
});
|
|
529141
529315
|
return { name, path: normalize5(targetPath) };
|
|
529142
529316
|
}
|
|
529143
529317
|
async function listSkillDirectories(params) {
|
|
529144
529318
|
const memoryDir = resolve31(params.memoryDir);
|
|
529145
|
-
const skillsDir =
|
|
529319
|
+
const skillsDir = join55(memoryDir, "skills");
|
|
529146
529320
|
if (!existsSync52(skillsDir))
|
|
529147
529321
|
return [];
|
|
529148
|
-
const entries = await
|
|
529322
|
+
const entries = await readdir13(skillsDir, { withFileTypes: true });
|
|
529149
529323
|
const skills = [];
|
|
529150
529324
|
for (const entry of entries) {
|
|
529151
529325
|
if (!entry.isDirectory())
|
|
529152
529326
|
continue;
|
|
529153
|
-
const skillDir =
|
|
529154
|
-
const skillMdPath =
|
|
529327
|
+
const skillDir = join55(skillsDir, entry.name);
|
|
529328
|
+
const skillMdPath = join55(skillDir, "SKILL.md");
|
|
529155
529329
|
if (!existsSync52(skillMdPath))
|
|
529156
529330
|
continue;
|
|
529157
529331
|
let name = entry.name;
|
|
@@ -529172,9 +529346,9 @@ async function listSkillDirectories(params) {
|
|
|
529172
529346
|
}
|
|
529173
529347
|
async function deleteSkillDirectory(params) {
|
|
529174
529348
|
const memoryDir = resolve31(params.memoryDir);
|
|
529175
|
-
const skillsDir =
|
|
529349
|
+
const skillsDir = join55(memoryDir, "skills");
|
|
529176
529350
|
const name = sanitizeSkillName(params.name);
|
|
529177
|
-
const targetPath =
|
|
529351
|
+
const targetPath = join55(skillsDir, name);
|
|
529178
529352
|
assertInside(skillsDir, targetPath);
|
|
529179
529353
|
if (!existsSync52(targetPath)) {
|
|
529180
529354
|
throw new Error(`Skill "${name}" is not installed at ${targetPath}.`);
|
|
@@ -529671,7 +529845,7 @@ init_secrets();
|
|
|
529671
529845
|
import { randomUUID as randomUUID24 } from "node:crypto";
|
|
529672
529846
|
import { readFileSync as readFileSync36 } from "node:fs";
|
|
529673
529847
|
import { homedir as homedir31 } from "node:os";
|
|
529674
|
-
import { join as
|
|
529848
|
+
import { join as join56, resolve as resolve32 } from "node:path";
|
|
529675
529849
|
var OBSOLETE_SETTINGS_KEYS2 = [
|
|
529676
529850
|
"reflectionBehavior",
|
|
529677
529851
|
"enableSleeptime",
|
|
@@ -530114,7 +530288,7 @@ class SettingsManager2 {
|
|
|
530114
530288
|
return;
|
|
530115
530289
|
const settingsPath = this.getSettingsPath();
|
|
530116
530290
|
const home = process.env.HOME || homedir31();
|
|
530117
|
-
const dirPath =
|
|
530291
|
+
const dirPath = join56(home, ".letta");
|
|
530118
530292
|
try {
|
|
530119
530293
|
if (!exists(dirPath)) {
|
|
530120
530294
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -530155,7 +530329,7 @@ class SettingsManager2 {
|
|
|
530155
530329
|
if (!settings3)
|
|
530156
530330
|
return;
|
|
530157
530331
|
const settingsPath = this.getProjectSettingsPath(workingDirectory);
|
|
530158
|
-
const dirPath =
|
|
530332
|
+
const dirPath = join56(workingDirectory, ".letta");
|
|
530159
530333
|
try {
|
|
530160
530334
|
let existingSettings = {};
|
|
530161
530335
|
if (exists(settingsPath)) {
|
|
@@ -530177,16 +530351,16 @@ class SettingsManager2 {
|
|
|
530177
530351
|
}
|
|
530178
530352
|
getSettingsPath() {
|
|
530179
530353
|
const home = process.env.HOME || homedir31();
|
|
530180
|
-
return
|
|
530354
|
+
return join56(home, ".letta", "settings.json");
|
|
530181
530355
|
}
|
|
530182
530356
|
getProjectSettingsPath(workingDirectory) {
|
|
530183
|
-
return
|
|
530357
|
+
return join56(workingDirectory, ".letta", "settings.json");
|
|
530184
530358
|
}
|
|
530185
530359
|
isProjectSettingsPathCollidingWithGlobal(workingDirectory) {
|
|
530186
530360
|
return resolve32(this.getProjectSettingsPath(workingDirectory)) === resolve32(this.getSettingsPath());
|
|
530187
530361
|
}
|
|
530188
530362
|
getLocalProjectSettingsPath(workingDirectory) {
|
|
530189
|
-
return
|
|
530363
|
+
return join56(workingDirectory, ".letta", "settings.local.json");
|
|
530190
530364
|
}
|
|
530191
530365
|
async loadLocalProjectSettings(workingDirectory = process.cwd()) {
|
|
530192
530366
|
const cached3 = this.localProjectSettings.get(workingDirectory);
|
|
@@ -530247,7 +530421,7 @@ class SettingsManager2 {
|
|
|
530247
530421
|
if (!settings3)
|
|
530248
530422
|
return;
|
|
530249
530423
|
const settingsPath = this.getLocalProjectSettingsPath(workingDirectory);
|
|
530250
|
-
const dirPath =
|
|
530424
|
+
const dirPath = join56(workingDirectory, ".letta");
|
|
530251
530425
|
try {
|
|
530252
530426
|
if (!exists(dirPath)) {
|
|
530253
530427
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -530596,7 +530770,7 @@ class SettingsManager2 {
|
|
|
530596
530770
|
});
|
|
530597
530771
|
}
|
|
530598
530772
|
hasLocalLettaDir(workingDirectory = process.cwd()) {
|
|
530599
|
-
const dirPath =
|
|
530773
|
+
const dirPath = join56(workingDirectory, ".letta");
|
|
530600
530774
|
return exists(dirPath);
|
|
530601
530775
|
}
|
|
530602
530776
|
storeOAuthState(state, codeVerifier, redirectUri, provider) {
|
|
@@ -531229,8 +531403,8 @@ function markMilestone2(name) {
|
|
|
531229
531403
|
firstMilestoneTime2 = now;
|
|
531230
531404
|
}
|
|
531231
531405
|
if (isTimingsEnabled2()) {
|
|
531232
|
-
const
|
|
531233
|
-
console.error(`[timing] MILESTONE ${name} at +${formatDuration3(
|
|
531406
|
+
const relative12 = now - firstMilestoneTime2;
|
|
531407
|
+
console.error(`[timing] MILESTONE ${name} at +${formatDuration3(relative12)} (${formatTimestamp4(new Date)})`);
|
|
531234
531408
|
}
|
|
531235
531409
|
}
|
|
531236
531410
|
|
|
@@ -531367,12 +531541,12 @@ EXAMPLES
|
|
|
531367
531541
|
console.log(usage);
|
|
531368
531542
|
}
|
|
531369
531543
|
async function printInfo() {
|
|
531370
|
-
const { join:
|
|
531544
|
+
const { join: join80 } = await import("path");
|
|
531371
531545
|
const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version2(), exports_version2));
|
|
531372
531546
|
const { SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills4(), exports_skills3));
|
|
531373
531547
|
const { exists: exists3 } = await Promise.resolve().then(() => (init_fs2(), exports_fs));
|
|
531374
531548
|
const cwd2 = process.cwd();
|
|
531375
|
-
const skillsDir =
|
|
531549
|
+
const skillsDir = join80(cwd2, SKILLS_DIR3);
|
|
531376
531550
|
const skillsExist = exists3(skillsDir);
|
|
531377
531551
|
await settingsManager2.loadLocalProjectSettings(cwd2);
|
|
531378
531552
|
const pinned = settingsManager2.getPinnedAgents();
|
|
@@ -532978,4 +533152,4 @@ Error during initialization: ${message}`);
|
|
|
532978
533152
|
}
|
|
532979
533153
|
main2();
|
|
532980
533154
|
|
|
532981
|
-
//# debugId=
|
|
533155
|
+
//# debugId=CD2C04A4505B2DC064756E2164756E21
|