@letta-ai/letta-code 0.21.12 → 0.21.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/letta.js +128 -15
- package/package.json +1 -1
package/letta.js
CHANGED
|
@@ -3269,7 +3269,7 @@ var package_default;
|
|
|
3269
3269
|
var init_package = __esm(() => {
|
|
3270
3270
|
package_default = {
|
|
3271
3271
|
name: "@letta-ai/letta-code",
|
|
3272
|
-
version: "0.21.
|
|
3272
|
+
version: "0.21.13",
|
|
3273
3273
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3274
3274
|
type: "module",
|
|
3275
3275
|
bin: {
|
|
@@ -40508,7 +40508,7 @@ import {
|
|
|
40508
40508
|
mkdirSync as mkdirSync8,
|
|
40509
40509
|
readFileSync as readFileSync7,
|
|
40510
40510
|
renameSync as renameSync2,
|
|
40511
|
-
|
|
40511
|
+
rmSync as rmSync2,
|
|
40512
40512
|
statSync as statSync2,
|
|
40513
40513
|
writeFileSync as writeFileSync6
|
|
40514
40514
|
} from "node:fs";
|
|
@@ -40586,7 +40586,7 @@ function isLockStale(lockDir) {
|
|
|
40586
40586
|
}
|
|
40587
40587
|
function stealLock(lockDir) {
|
|
40588
40588
|
try {
|
|
40589
|
-
|
|
40589
|
+
rmSync2(lockDir, { recursive: true, force: true });
|
|
40590
40590
|
} catch {}
|
|
40591
40591
|
}
|
|
40592
40592
|
function acquireLock() {
|
|
@@ -40607,7 +40607,7 @@ function acquireLock() {
|
|
|
40607
40607
|
try {
|
|
40608
40608
|
const current = readLockOwner(lockDir);
|
|
40609
40609
|
if (current && current.token === token) {
|
|
40610
|
-
|
|
40610
|
+
rmSync2(lockDir, { recursive: true, force: true });
|
|
40611
40611
|
}
|
|
40612
40612
|
} catch {}
|
|
40613
40613
|
}
|
|
@@ -65411,7 +65411,7 @@ async function runProcess(context3) {
|
|
|
65411
65411
|
}
|
|
65412
65412
|
async function shell(args) {
|
|
65413
65413
|
validateRequiredParams(args, ["command"], "shell");
|
|
65414
|
-
const { command, workdir, timeout_ms, signal, onOutput } = args;
|
|
65414
|
+
const { command, workdir, timeout_ms, env_overrides, signal, onOutput } = args;
|
|
65415
65415
|
if (!Array.isArray(command) || command.length === 0) {
|
|
65416
65416
|
throw new Error("command must be a non-empty array of strings");
|
|
65417
65417
|
}
|
|
@@ -65422,7 +65422,10 @@ async function shell(args) {
|
|
|
65422
65422
|
const context3 = {
|
|
65423
65423
|
command,
|
|
65424
65424
|
cwd: cwd2,
|
|
65425
|
-
env:
|
|
65425
|
+
env: {
|
|
65426
|
+
...getShellEnv(),
|
|
65427
|
+
...env_overrides ?? {}
|
|
65428
|
+
},
|
|
65426
65429
|
timeout,
|
|
65427
65430
|
signal,
|
|
65428
65431
|
onOutput
|
|
@@ -65543,6 +65546,7 @@ async function shell_command(args) {
|
|
|
65543
65546
|
signal,
|
|
65544
65547
|
onOutput
|
|
65545
65548
|
} = args;
|
|
65549
|
+
const envOverrides = getMemoryGitIdentityEnvOverrides(command, workdir);
|
|
65546
65550
|
const launchers = buildShellLaunchers(command, { login });
|
|
65547
65551
|
if (launchers.length === 0) {
|
|
65548
65552
|
throw new Error("Command must be a non-empty string");
|
|
@@ -65554,6 +65558,7 @@ async function shell_command(args) {
|
|
|
65554
65558
|
return await shell({
|
|
65555
65559
|
command: launcher,
|
|
65556
65560
|
workdir,
|
|
65561
|
+
env_overrides: envOverrides,
|
|
65557
65562
|
timeout_ms,
|
|
65558
65563
|
justification,
|
|
65559
65564
|
signal,
|
|
@@ -65572,7 +65577,96 @@ async function shell_command(args) {
|
|
|
65572
65577
|
const reason = lastError?.message || "Shell unavailable";
|
|
65573
65578
|
throw new Error(suffix ? `${reason} (tried: ${suffix})` : reason);
|
|
65574
65579
|
}
|
|
65580
|
+
function getMemoryGitIdentityEnvOverrides(command, workdir) {
|
|
65581
|
+
const agentId = getCurrentAgentIdOrEnv();
|
|
65582
|
+
if (!agentId) {
|
|
65583
|
+
return;
|
|
65584
|
+
}
|
|
65585
|
+
if (!containsGitCommitInvocation(command)) {
|
|
65586
|
+
return;
|
|
65587
|
+
}
|
|
65588
|
+
const scopedToMemoryDir = isMemoryDirCommand(command, agentId) || (workdir ? isMemoryDirCommand(`cd ${shellQuote(workdir)} && ${command}`, agentId) : false);
|
|
65589
|
+
if (!scopedToMemoryDir) {
|
|
65590
|
+
return;
|
|
65591
|
+
}
|
|
65592
|
+
const agentName = (process.env.AGENT_NAME || "").trim() || agentId;
|
|
65593
|
+
const agentEmail = `${agentId}@letta.com`;
|
|
65594
|
+
return {
|
|
65595
|
+
GIT_AUTHOR_NAME: agentName,
|
|
65596
|
+
GIT_AUTHOR_EMAIL: agentEmail,
|
|
65597
|
+
GIT_COMMITTER_NAME: agentName,
|
|
65598
|
+
GIT_COMMITTER_EMAIL: agentEmail
|
|
65599
|
+
};
|
|
65600
|
+
}
|
|
65601
|
+
function getCurrentAgentIdOrEnv() {
|
|
65602
|
+
const envAgentId = (process.env.AGENT_ID || process.env.LETTA_AGENT_ID || "").trim();
|
|
65603
|
+
if (envAgentId) {
|
|
65604
|
+
return envAgentId;
|
|
65605
|
+
}
|
|
65606
|
+
try {
|
|
65607
|
+
const agentId = getCurrentAgentId().trim();
|
|
65608
|
+
if (agentId) {
|
|
65609
|
+
return agentId;
|
|
65610
|
+
}
|
|
65611
|
+
} catch {}
|
|
65612
|
+
return "";
|
|
65613
|
+
}
|
|
65614
|
+
function containsGitCommitInvocation(command) {
|
|
65615
|
+
const segments = command.split(/&&|\|\||;|\|/).map((segment) => segment.trim()).filter(Boolean);
|
|
65616
|
+
for (const segment of segments) {
|
|
65617
|
+
const tokens = tokenizeSegment(segment);
|
|
65618
|
+
if (tokens.length === 0) {
|
|
65619
|
+
continue;
|
|
65620
|
+
}
|
|
65621
|
+
let index = 0;
|
|
65622
|
+
while (index < tokens.length && /^[A-Za-z_][A-Za-z0-9_]*=.*/.test(tokens[index] ?? "")) {
|
|
65623
|
+
index += 1;
|
|
65624
|
+
}
|
|
65625
|
+
if (tokens[index] !== "git") {
|
|
65626
|
+
continue;
|
|
65627
|
+
}
|
|
65628
|
+
index += 1;
|
|
65629
|
+
while (index < tokens.length) {
|
|
65630
|
+
const token = tokens[index];
|
|
65631
|
+
if (!token) {
|
|
65632
|
+
index += 1;
|
|
65633
|
+
continue;
|
|
65634
|
+
}
|
|
65635
|
+
if (token === "-c" || token === "-C") {
|
|
65636
|
+
index += 2;
|
|
65637
|
+
continue;
|
|
65638
|
+
}
|
|
65639
|
+
if (token.startsWith("-")) {
|
|
65640
|
+
index += 1;
|
|
65641
|
+
continue;
|
|
65642
|
+
}
|
|
65643
|
+
if (token === "commit") {
|
|
65644
|
+
return true;
|
|
65645
|
+
}
|
|
65646
|
+
break;
|
|
65647
|
+
}
|
|
65648
|
+
}
|
|
65649
|
+
return false;
|
|
65650
|
+
}
|
|
65651
|
+
function tokenizeSegment(segment) {
|
|
65652
|
+
const matches = segment.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g);
|
|
65653
|
+
if (!matches) {
|
|
65654
|
+
return [];
|
|
65655
|
+
}
|
|
65656
|
+
return matches.map(stripWrappingQuotes);
|
|
65657
|
+
}
|
|
65658
|
+
function stripWrappingQuotes(token) {
|
|
65659
|
+
if (token.startsWith('"') && token.endsWith('"') || token.startsWith("'") && token.endsWith("'")) {
|
|
65660
|
+
return token.slice(1, -1);
|
|
65661
|
+
}
|
|
65662
|
+
return token;
|
|
65663
|
+
}
|
|
65664
|
+
function shellQuote(value) {
|
|
65665
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
65666
|
+
}
|
|
65575
65667
|
var init_ShellCommand2 = __esm(async () => {
|
|
65668
|
+
init_context();
|
|
65669
|
+
init_readOnlyShell();
|
|
65576
65670
|
init_shellRunner();
|
|
65577
65671
|
await init_Shell2();
|
|
65578
65672
|
});
|
|
@@ -65827,6 +65921,17 @@ var init_skillContentRegistry = __esm(() => {
|
|
|
65827
65921
|
import { readdirSync as readdirSync7 } from "node:fs";
|
|
65828
65922
|
import { readFile as readFile6 } from "node:fs/promises";
|
|
65829
65923
|
import { dirname as dirname10, join as join20 } from "node:path";
|
|
65924
|
+
function getMemorySkillsDirs(agentId) {
|
|
65925
|
+
const dirs = new Set;
|
|
65926
|
+
const memoryDir = process.env.MEMORY_DIR || process.env.LETTA_MEMORY_DIR;
|
|
65927
|
+
if (memoryDir && memoryDir.trim().length > 0) {
|
|
65928
|
+
dirs.add(join20(memoryDir.trim(), "skills"));
|
|
65929
|
+
}
|
|
65930
|
+
if (agentId) {
|
|
65931
|
+
dirs.add(join20(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "memory", "skills"));
|
|
65932
|
+
}
|
|
65933
|
+
return Array.from(dirs);
|
|
65934
|
+
}
|
|
65830
65935
|
function hasAdditionalFiles(skillMdPath) {
|
|
65831
65936
|
try {
|
|
65832
65937
|
const skillDir = dirname10(skillMdPath);
|
|
@@ -65849,6 +65954,13 @@ async function readSkillContent(skillId, skillsDir, agentId) {
|
|
|
65849
65954
|
return { content, path: agentSkillPath };
|
|
65850
65955
|
} catch {}
|
|
65851
65956
|
}
|
|
65957
|
+
for (const memorySkillsDir of getMemorySkillsDirs(agentId)) {
|
|
65958
|
+
const memorySkillPath = join20(memorySkillsDir, skillId, "SKILL.md");
|
|
65959
|
+
try {
|
|
65960
|
+
const content = await readFile6(memorySkillPath, "utf-8");
|
|
65961
|
+
return { content, path: memorySkillPath };
|
|
65962
|
+
} catch {}
|
|
65963
|
+
}
|
|
65852
65964
|
const globalSkillPath = join20(GLOBAL_SKILLS_DIR, skillId, "SKILL.md");
|
|
65853
65965
|
try {
|
|
65854
65966
|
const content = await readFile6(globalSkillPath, "utf-8");
|
|
@@ -83727,7 +83839,7 @@ function handleModeChange(msg, socket, runtime, scope) {
|
|
|
83727
83839
|
current.modeBeforePlan = null;
|
|
83728
83840
|
}
|
|
83729
83841
|
persistPermissionModeMapForRuntime(runtime);
|
|
83730
|
-
|
|
83842
|
+
emitRuntimeStateUpdates(runtime, scope);
|
|
83731
83843
|
if (isDebugEnabled()) {
|
|
83732
83844
|
console.log(`[Listen] Mode changed to: ${msg.mode}`);
|
|
83733
83845
|
}
|
|
@@ -84089,7 +84201,7 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
84089
84201
|
existsSync: existsSync22,
|
|
84090
84202
|
lstatSync: lstatSync2,
|
|
84091
84203
|
mkdirSync: mkdirSync15,
|
|
84092
|
-
rmdirSync
|
|
84204
|
+
rmdirSync,
|
|
84093
84205
|
symlinkSync,
|
|
84094
84206
|
unlinkSync: unlinkSync8
|
|
84095
84207
|
} = await import("node:fs");
|
|
@@ -84124,7 +84236,7 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
84124
84236
|
const stat6 = lstatSync2(linkPath);
|
|
84125
84237
|
if (stat6.isSymbolicLink()) {
|
|
84126
84238
|
if (process.platform === "win32") {
|
|
84127
|
-
|
|
84239
|
+
rmdirSync(linkPath);
|
|
84128
84240
|
} else {
|
|
84129
84241
|
unlinkSync8(linkPath);
|
|
84130
84242
|
}
|
|
@@ -84182,7 +84294,7 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
84182
84294
|
return true;
|
|
84183
84295
|
}
|
|
84184
84296
|
if (process.platform === "win32") {
|
|
84185
|
-
|
|
84297
|
+
rmdirSync(linkPath);
|
|
84186
84298
|
} else {
|
|
84187
84299
|
unlinkSync8(linkPath);
|
|
84188
84300
|
}
|
|
@@ -85749,6 +85861,7 @@ var init_client4 = __esm(async () => {
|
|
|
85749
85861
|
__listenClientTestUtils = {
|
|
85750
85862
|
createRuntime: createLegacyTestRuntime,
|
|
85751
85863
|
createListenerRuntime: createRuntime,
|
|
85864
|
+
handleModeChange,
|
|
85752
85865
|
getOrCreateScopedRuntime,
|
|
85753
85866
|
buildListModelsEntries,
|
|
85754
85867
|
buildListModelsResponse,
|
|
@@ -119988,7 +120101,7 @@ import {
|
|
|
119988
120101
|
mkdirSync as mkdirSync22,
|
|
119989
120102
|
mkdtempSync,
|
|
119990
120103
|
readFileSync as readFileSync18,
|
|
119991
|
-
rmSync as
|
|
120104
|
+
rmSync as rmSync4,
|
|
119992
120105
|
writeFileSync as writeFileSync16
|
|
119993
120106
|
} from "node:fs";
|
|
119994
120107
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
@@ -120371,7 +120484,7 @@ async function installGithubApp(options) {
|
|
|
120371
120484
|
agentUrl: resolvedAgentId ? buildChatUrl(resolvedAgentId) : null
|
|
120372
120485
|
};
|
|
120373
120486
|
} finally {
|
|
120374
|
-
|
|
120487
|
+
rmSync4(tempDir, { recursive: true, force: true });
|
|
120375
120488
|
}
|
|
120376
120489
|
}
|
|
120377
120490
|
var DEFAULT_WORKFLOW_PATH = ".github/workflows/letta.yml", ALTERNATE_WORKFLOW_PATH = ".github/workflows/letta-code.yml";
|
|
@@ -149303,7 +149416,7 @@ async function runListenSubcommand(argv) {
|
|
|
149303
149416
|
|
|
149304
149417
|
// src/cli/subcommands/memfs.ts
|
|
149305
149418
|
await init_memoryGit();
|
|
149306
|
-
import { cpSync, existsSync as existsSync22, mkdirSync as mkdirSync15, rmSync as
|
|
149419
|
+
import { cpSync, existsSync as existsSync22, mkdirSync as mkdirSync15, rmSync as rmSync3, statSync as statSync8 } from "node:fs";
|
|
149307
149420
|
import { readdir as readdir6 } from "node:fs/promises";
|
|
149308
149421
|
import { homedir as homedir23 } from "node:os";
|
|
149309
149422
|
import { join as join28 } from "node:path";
|
|
@@ -149496,7 +149609,7 @@ async function runMemfsSubcommand(argv) {
|
|
|
149496
149609
|
return 1;
|
|
149497
149610
|
}
|
|
149498
149611
|
const root = getMemoryRoot(agentId);
|
|
149499
|
-
|
|
149612
|
+
rmSync3(root, { recursive: true, force: true });
|
|
149500
149613
|
cpSync(backupPath, root, { recursive: true });
|
|
149501
149614
|
console.log(JSON.stringify({ restoredFrom: backupPath }, null, 2));
|
|
149502
149615
|
return 0;
|
|
@@ -153311,4 +153424,4 @@ Error during initialization: ${message}`);
|
|
|
153311
153424
|
}
|
|
153312
153425
|
main();
|
|
153313
153426
|
|
|
153314
|
-
//# debugId=
|
|
153427
|
+
//# debugId=9A1A4B9B002D45C364756E2164756E21
|