@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.
Files changed (2) hide show
  1. package/letta.js +128 -15
  2. 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.12",
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
- rmdirSync,
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
- rmdirSync(lockDir, { recursive: true });
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
- rmdirSync(lockDir, { recursive: true });
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: getShellEnv(),
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
- emitDeviceStatusUpdate(socket, runtime, scope);
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: rmdirSync2,
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
- rmdirSync2(linkPath);
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
- rmdirSync2(linkPath);
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 rmSync3,
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
- rmSync3(tempDir, { recursive: true, force: true });
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 rmSync2, statSync as statSync8 } from "node:fs";
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
- rmSync2(root, { recursive: true, force: true });
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=1C3BE0588811294864756E2164756E21
153427
+ //# debugId=9A1A4B9B002D45C364756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letta-ai/letta-code",
3
- "version": "0.21.12",
3
+ "version": "0.21.13",
4
4
  "description": "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5
5
  "type": "module",
6
6
  "bin": {