@letta-ai/letta-code 0.12.6 → 0.12.8

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 CHANGED
@@ -3237,7 +3237,7 @@ var package_default;
3237
3237
  var init_package = __esm(() => {
3238
3238
  package_default = {
3239
3239
  name: "@letta-ai/letta-code",
3240
- version: "0.12.6",
3240
+ version: "0.12.8",
3241
3241
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
3242
3242
  type: "module",
3243
3243
  bin: {
@@ -32126,7 +32126,7 @@ __export(exports_subagents, {
32126
32126
  });
32127
32127
  import { existsSync as existsSync3 } from "node:fs";
32128
32128
  import { readdir, readFile as readFile2 } from "node:fs/promises";
32129
- import { join as join3 } from "node:path";
32129
+ import { join as join4 } from "node:path";
32130
32130
  function isValidName(name) {
32131
32131
  return /^[a-z][a-z0-9-]*$/.test(name);
32132
32132
  }
@@ -32217,7 +32217,7 @@ async function discoverSubagentsFromDir(agentsDir, seenNames, subagents, errors)
32217
32217
  if (!entry.isFile() || !entry.name.endsWith(".md")) {
32218
32218
  continue;
32219
32219
  }
32220
- const filePath = join3(agentsDir, entry.name);
32220
+ const filePath = join4(agentsDir, entry.name);
32221
32221
  try {
32222
32222
  const config = await parseSubagentFile(filePath);
32223
32223
  if (config) {
@@ -32249,7 +32249,7 @@ async function discoverSubagents(workingDirectory = process.cwd()) {
32249
32249
  const subagents = [];
32250
32250
  const seenNames = new Set;
32251
32251
  await discoverSubagentsFromDir(GLOBAL_AGENTS_DIR, seenNames, subagents, errors);
32252
- const projectAgentsDir = join3(workingDirectory, AGENTS_DIR);
32252
+ const projectAgentsDir = join4(workingDirectory, AGENTS_DIR);
32253
32253
  await discoverSubagentsFromDir(projectAgentsDir, seenNames, subagents, errors);
32254
32254
  return { subagents, errors };
32255
32255
  }
@@ -32288,7 +32288,7 @@ var init_subagents = __esm(() => {
32288
32288
  plan_default,
32289
32289
  recall_default
32290
32290
  ];
32291
- GLOBAL_AGENTS_DIR = join3(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
32291
+ GLOBAL_AGENTS_DIR = join4(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
32292
32292
  VALID_MEMORY_BLOCKS = new Set(MEMORY_BLOCK_LABELS);
32293
32293
  cache3 = {
32294
32294
  builtins: null,
@@ -34566,8 +34566,8 @@ String: ${old_string}`);
34566
34566
  var init_Edit2 = () => {};
34567
34567
 
34568
34568
  // src/cli/helpers/planName.ts
34569
- import { homedir as homedir5 } from "node:os";
34570
- import { join as join5 } from "node:path";
34569
+ import { homedir as homedir6 } from "node:os";
34570
+ import { join as join6 } from "node:path";
34571
34571
  function randomElement(arr) {
34572
34572
  return arr[Math.floor(Math.random() * arr.length)];
34573
34573
  }
@@ -34579,7 +34579,7 @@ function generatePlanName() {
34579
34579
  }
34580
34580
  function generatePlanFilePath() {
34581
34581
  const name = generatePlanName();
34582
- return join5(homedir5(), ".letta", "plans", `${name}.md`);
34582
+ return join6(homedir6(), ".letta", "plans", `${name}.md`);
34583
34583
  }
34584
34584
  var adjectives, nouns;
34585
34585
  var init_planName = __esm(() => {
@@ -34688,6 +34688,8 @@ var exports_mode = {};
34688
34688
  __export(exports_mode, {
34689
34689
  permissionMode: () => permissionMode2
34690
34690
  });
34691
+ import { homedir as homedir7 } from "node:os";
34692
+ import { join as join7 } from "node:path";
34691
34693
  function getGlobalMode2() {
34692
34694
  const global2 = globalThis;
34693
34695
  if (!global2[MODE_KEY2]) {
@@ -34790,7 +34792,7 @@ class PermissionModeManager2 {
34790
34792
  return "allow";
34791
34793
  }
34792
34794
  if (writeTools.includes(toolName)) {
34793
- const planFilePath = this.getPlanFilePath();
34795
+ const plansDir = join7(homedir7(), ".letta", "plans");
34794
34796
  let targetPath = toolArgs?.file_path || toolArgs?.path;
34795
34797
  if ((toolName === "ApplyPatch" || toolName === "apply_patch") && toolArgs?.input) {
34796
34798
  const input = toolArgs.input;
@@ -34799,7 +34801,7 @@ class PermissionModeManager2 {
34799
34801
  targetPath = match[1].trim();
34800
34802
  }
34801
34803
  }
34802
- if (planFilePath && targetPath && targetPath === planFilePath) {
34804
+ if (targetPath && targetPath.startsWith(plansDir) && targetPath.endsWith(".md")) {
34803
34805
  return "allow";
34804
34806
  }
34805
34807
  }
@@ -34891,7 +34893,9 @@ var init_EnterPlanMode2 = __esm(() => {
34891
34893
  async function exit_plan_mode() {
34892
34894
  return {
34893
34895
  message: `User has approved your plan. You can now start coding.
34894
- Start with updating your todo list if applicable`
34896
+ ` + `Start with updating your todo list if applicable.
34897
+
34898
+ ` + "Tip: If this plan will be referenced in the future by your future-self, " + "other agents, or humans, consider renaming the plan file to something easily " + "identifiable with a timestamp (e.g., `2026-01-auth-refactor.md`) rather than the random name."
34895
34899
  };
34896
34900
  }
34897
34901
 
@@ -36809,7 +36813,7 @@ var init_LS2 = __esm(() => {
36809
36813
 
36810
36814
  // src/tools/impl/LS.ts
36811
36815
  import { readdir as readdir2, stat } from "node:fs/promises";
36812
- import { join as join7, resolve as resolve6 } from "node:path";
36816
+ import { join as join9, resolve as resolve6 } from "node:path";
36813
36817
  async function ls(args) {
36814
36818
  validateRequiredParams(args, ["path"], "LS");
36815
36819
  validateParamTypes(args, LS_default2, "LS");
@@ -36819,7 +36823,7 @@ async function ls(args) {
36819
36823
  const items = await readdir2(dirPath);
36820
36824
  const filteredItems = items.filter((item) => !ignore.some((pattern) => import_picomatch.default.isMatch(item, pattern)));
36821
36825
  const fileInfos = await Promise.all(filteredItems.map(async (item) => {
36822
- const fullPath = join7(dirPath, item);
36826
+ const fullPath = join9(dirPath, item);
36823
36827
  try {
36824
36828
  const stats = await stat(fullPath);
36825
36829
  return {
@@ -43650,14 +43654,14 @@ __export(exports_skills, {
43650
43654
  });
43651
43655
  import { existsSync as existsSync5 } from "node:fs";
43652
43656
  import { readdir as readdir4, readFile as readFile3 } from "node:fs/promises";
43653
- import { dirname as dirname4, join as join8 } from "node:path";
43657
+ import { dirname as dirname4, join as join10 } from "node:path";
43654
43658
  import { fileURLToPath as fileURLToPath6 } from "node:url";
43655
43659
  function getBundledSkillsPath() {
43656
43660
  const thisDir = dirname4(fileURLToPath6(import.meta.url));
43657
43661
  if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
43658
- return join8(thisDir, "../skills/builtin");
43662
+ return join10(thisDir, "../skills/builtin");
43659
43663
  }
43660
- return join8(thisDir, "skills");
43664
+ return join10(thisDir, "skills");
43661
43665
  }
43662
43666
  async function getBundledSkills() {
43663
43667
  const bundledPath = getBundledSkillsPath();
@@ -43680,7 +43684,7 @@ async function discoverSkillsFromDir(skillsPath, source) {
43680
43684
  }
43681
43685
  return { skills, errors };
43682
43686
  }
43683
- async function discoverSkills(projectSkillsPath = join8(process.cwd(), SKILLS_DIR)) {
43687
+ async function discoverSkills(projectSkillsPath = join10(process.cwd(), SKILLS_DIR)) {
43684
43688
  const allErrors = [];
43685
43689
  const skillsById = new Map;
43686
43690
  const bundledSkills = await getBundledSkills();
@@ -43706,7 +43710,7 @@ async function findSkillFiles(currentPath, rootPath, skills, errors, source) {
43706
43710
  try {
43707
43711
  const entries = await readdir4(currentPath, { withFileTypes: true });
43708
43712
  for (const entry of entries) {
43709
- const fullPath = join8(currentPath, entry.name);
43713
+ const fullPath = join10(currentPath, entry.name);
43710
43714
  if (entry.isDirectory()) {
43711
43715
  await findSkillFiles(fullPath, rootPath, skills, errors, source);
43712
43716
  } else if (entry.isFile() && entry.name.toUpperCase() === "SKILL.MD") {
@@ -43892,13 +43896,13 @@ function formatSkillsForMemory(skills, skillsDirectory) {
43892
43896
  }
43893
43897
  var SKILLS_DIR = ".skills", GLOBAL_SKILLS_DIR, SKILLS_BLOCK_CHAR_LIMIT = 20000;
43894
43898
  var init_skills2 = __esm(() => {
43895
- GLOBAL_SKILLS_DIR = join8(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
43899
+ GLOBAL_SKILLS_DIR = join10(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
43896
43900
  });
43897
43901
 
43898
43902
  // src/tools/impl/Skill.ts
43899
43903
  import { readdirSync as readdirSync3 } from "node:fs";
43900
43904
  import { readFile as readFile4 } from "node:fs/promises";
43901
- import { dirname as dirname5, join as join9 } from "node:path";
43905
+ import { dirname as dirname5, join as join11 } from "node:path";
43902
43906
  function parseLoadedSkills(value) {
43903
43907
  const skillMap = new Map;
43904
43908
  const skillHeaderRegex = /# Skill: ([^\n]+)/g;
@@ -43973,19 +43977,19 @@ async function readSkillContent(skillId, skillsDir) {
43973
43977
  return { content, path: bundledSkill.path };
43974
43978
  } catch {}
43975
43979
  }
43976
- const globalSkillPath = join9(GLOBAL_SKILLS_DIR, skillId, "SKILL.md");
43980
+ const globalSkillPath = join11(GLOBAL_SKILLS_DIR, skillId, "SKILL.md");
43977
43981
  try {
43978
43982
  const content = await readFile4(globalSkillPath, "utf-8");
43979
43983
  return { content, path: globalSkillPath };
43980
43984
  } catch {}
43981
- const projectSkillPath = join9(skillsDir, skillId, "SKILL.md");
43985
+ const projectSkillPath = join11(skillsDir, skillId, "SKILL.md");
43982
43986
  try {
43983
43987
  const content = await readFile4(projectSkillPath, "utf-8");
43984
43988
  return { content, path: projectSkillPath };
43985
43989
  } catch (primaryError) {
43986
43990
  try {
43987
- const bundledSkillsDir = join9(process.cwd(), "skills", "skills");
43988
- const bundledSkillPath = join9(bundledSkillsDir, skillId, "SKILL.md");
43991
+ const bundledSkillsDir = join11(process.cwd(), "skills", "skills");
43992
+ const bundledSkillPath = join11(bundledSkillsDir, skillId, "SKILL.md");
43989
43993
  const content = await readFile4(bundledSkillPath, "utf-8");
43990
43994
  return { content, path: bundledSkillPath };
43991
43995
  } catch {
@@ -44006,7 +44010,7 @@ async function getResolvedSkillsDir(client, agentId) {
44006
44010
  } catch {}
44007
44011
  }
44008
44012
  if (!skillsDir) {
44009
- skillsDir = join9(process.cwd(), SKILLS_DIR);
44013
+ skillsDir = join11(process.cwd(), SKILLS_DIR);
44010
44014
  }
44011
44015
  return skillsDir;
44012
44016
  }
@@ -46324,14 +46328,14 @@ __export(exports_skills2, {
46324
46328
  });
46325
46329
  import { existsSync as existsSync6 } from "node:fs";
46326
46330
  import { readdir as readdir5, readFile as readFile5 } from "node:fs/promises";
46327
- import { dirname as dirname7, join as join10 } from "node:path";
46331
+ import { dirname as dirname7, join as join12 } from "node:path";
46328
46332
  import { fileURLToPath as fileURLToPath7 } from "node:url";
46329
46333
  function getBundledSkillsPath2() {
46330
46334
  const thisDir = dirname7(fileURLToPath7(import.meta.url));
46331
46335
  if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
46332
- return join10(thisDir, "../skills/builtin");
46336
+ return join12(thisDir, "../skills/builtin");
46333
46337
  }
46334
- return join10(thisDir, "skills");
46338
+ return join12(thisDir, "skills");
46335
46339
  }
46336
46340
  async function getBundledSkills2() {
46337
46341
  const bundledPath = getBundledSkillsPath2();
@@ -46354,7 +46358,7 @@ async function discoverSkillsFromDir2(skillsPath, source) {
46354
46358
  }
46355
46359
  return { skills, errors };
46356
46360
  }
46357
- async function discoverSkills2(projectSkillsPath = join10(process.cwd(), SKILLS_DIR2)) {
46361
+ async function discoverSkills2(projectSkillsPath = join12(process.cwd(), SKILLS_DIR2)) {
46358
46362
  const allErrors = [];
46359
46363
  const skillsById = new Map;
46360
46364
  const bundledSkills = await getBundledSkills2();
@@ -46380,7 +46384,7 @@ async function findSkillFiles2(currentPath, rootPath, skills, errors, source) {
46380
46384
  try {
46381
46385
  const entries = await readdir5(currentPath, { withFileTypes: true });
46382
46386
  for (const entry of entries) {
46383
- const fullPath = join10(currentPath, entry.name);
46387
+ const fullPath = join12(currentPath, entry.name);
46384
46388
  if (entry.isDirectory()) {
46385
46389
  await findSkillFiles2(fullPath, rootPath, skills, errors, source);
46386
46390
  } else if (entry.isFile() && entry.name.toUpperCase() === "SKILL.MD") {
@@ -46566,7 +46570,7 @@ function formatSkillsForMemory2(skills, skillsDirectory) {
46566
46570
  }
46567
46571
  var SKILLS_DIR2 = ".skills", GLOBAL_SKILLS_DIR2, SKILLS_BLOCK_CHAR_LIMIT2 = 20000;
46568
46572
  var init_skills3 = __esm(() => {
46569
- GLOBAL_SKILLS_DIR2 = join10(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
46573
+ GLOBAL_SKILLS_DIR2 = join12(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
46570
46574
  });
46571
46575
 
46572
46576
  // src/utils/fs.ts
@@ -47046,7 +47050,7 @@ __export(exports_subagents2, {
47046
47050
  });
47047
47051
  import { existsSync as existsSync8 } from "node:fs";
47048
47052
  import { readdir as readdir6, readFile as readFile7 } from "node:fs/promises";
47049
- import { join as join11 } from "node:path";
47053
+ import { join as join13 } from "node:path";
47050
47054
  function isValidName2(name) {
47051
47055
  return /^[a-z][a-z0-9-]*$/.test(name);
47052
47056
  }
@@ -47137,7 +47141,7 @@ async function discoverSubagentsFromDir2(agentsDir, seenNames, subagents, errors
47137
47141
  if (!entry.isFile() || !entry.name.endsWith(".md")) {
47138
47142
  continue;
47139
47143
  }
47140
- const filePath = join11(agentsDir, entry.name);
47144
+ const filePath = join13(agentsDir, entry.name);
47141
47145
  try {
47142
47146
  const config = await parseSubagentFile2(filePath);
47143
47147
  if (config) {
@@ -47169,7 +47173,7 @@ async function discoverSubagents2(workingDirectory = process.cwd()) {
47169
47173
  const subagents = [];
47170
47174
  const seenNames = new Set;
47171
47175
  await discoverSubagentsFromDir2(GLOBAL_AGENTS_DIR2, seenNames, subagents, errors);
47172
- const projectAgentsDir = join11(workingDirectory, AGENTS_DIR2);
47176
+ const projectAgentsDir = join13(workingDirectory, AGENTS_DIR2);
47173
47177
  await discoverSubagentsFromDir2(projectAgentsDir, seenNames, subagents, errors);
47174
47178
  return { subagents, errors };
47175
47179
  }
@@ -47208,7 +47212,7 @@ var init_subagents2 = __esm(() => {
47208
47212
  plan_default,
47209
47213
  recall_default
47210
47214
  ];
47211
- GLOBAL_AGENTS_DIR2 = join11(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
47215
+ GLOBAL_AGENTS_DIR2 = join13(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
47212
47216
  VALID_MEMORY_BLOCKS2 = new Set(MEMORY_BLOCK_LABELS);
47213
47217
  cache4 = {
47214
47218
  builtins: null,
@@ -47789,6 +47793,7 @@ function SetupUI({ onComplete }) {
47789
47793
  refreshToken: tokens.refresh_token,
47790
47794
  tokenExpiresAt: now + tokens.expires_in * 1000
47791
47795
  });
47796
+ await settingsManager.flush();
47792
47797
  setMode("done");
47793
47798
  setTimeout(() => onComplete(), 1000);
47794
47799
  } catch (err) {
@@ -49522,8 +49527,8 @@ function matchesFilePattern(query, pattern, workingDirectory) {
49522
49527
  globPattern = globPattern.slice(2);
49523
49528
  }
49524
49529
  if (globPattern.startsWith("~/")) {
49525
- const homedir6 = __require("node:os").homedir();
49526
- globPattern = globPattern.replace(/^~/, homedir6);
49530
+ const homedir8 = __require("node:os").homedir();
49531
+ globPattern = globPattern.replace(/^~/, homedir8);
49527
49532
  }
49528
49533
  if (globPattern.startsWith("//")) {
49529
49534
  globPattern = globPattern.slice(1);
@@ -49901,8 +49906,8 @@ __export(exports_loader, {
49901
49906
  savePermissionRule: () => savePermissionRule,
49902
49907
  loadPermissions: () => loadPermissions
49903
49908
  });
49904
- import { homedir as homedir6 } from "node:os";
49905
- import { join as join12 } from "node:path";
49909
+ import { homedir as homedir8 } from "node:os";
49910
+ import { join as join14 } from "node:path";
49906
49911
  async function loadPermissions(workingDirectory = process.cwd()) {
49907
49912
  const merged = {
49908
49913
  allow: [],
@@ -49911,10 +49916,10 @@ async function loadPermissions(workingDirectory = process.cwd()) {
49911
49916
  additionalDirectories: []
49912
49917
  };
49913
49918
  const sources = [
49914
- join12(process.env.XDG_CONFIG_HOME || join12(homedir6(), ".config"), "letta", "settings.json"),
49915
- join12(homedir6(), ".letta", "settings.json"),
49916
- join12(workingDirectory, ".letta", "settings.json"),
49917
- join12(workingDirectory, ".letta", "settings.local.json")
49919
+ join14(process.env.XDG_CONFIG_HOME || join14(homedir8(), ".config"), "letta", "settings.json"),
49920
+ join14(homedir8(), ".letta", "settings.json"),
49921
+ join14(workingDirectory, ".letta", "settings.json"),
49922
+ join14(workingDirectory, ".letta", "settings.local.json")
49918
49923
  ];
49919
49924
  for (const settingsPath of sources) {
49920
49925
  try {
@@ -49950,13 +49955,13 @@ async function savePermissionRule(rule, ruleType, scope, workingDirectory = proc
49950
49955
  let settingsPath;
49951
49956
  switch (scope) {
49952
49957
  case "user":
49953
- settingsPath = join12(process.env.XDG_CONFIG_HOME || join12(homedir6(), ".config"), "letta", "settings.json");
49958
+ settingsPath = join14(process.env.XDG_CONFIG_HOME || join14(homedir8(), ".config"), "letta", "settings.json");
49954
49959
  break;
49955
49960
  case "project":
49956
- settingsPath = join12(workingDirectory, ".letta", "settings.json");
49961
+ settingsPath = join14(workingDirectory, ".letta", "settings.json");
49957
49962
  break;
49958
49963
  case "local":
49959
- settingsPath = join12(workingDirectory, ".letta", "settings.local.json");
49964
+ settingsPath = join14(workingDirectory, ".letta", "settings.local.json");
49960
49965
  break;
49961
49966
  }
49962
49967
  let settings = {};
@@ -49981,7 +49986,7 @@ async function savePermissionRule(rule, ruleType, scope, workingDirectory = proc
49981
49986
  }
49982
49987
  }
49983
49988
  async function ensureLocalSettingsIgnored(workingDirectory) {
49984
- const gitignorePath = join12(workingDirectory, ".gitignore");
49989
+ const gitignorePath = join14(workingDirectory, ".gitignore");
49985
49990
  const pattern = ".letta/settings.local.json";
49986
49991
  try {
49987
49992
  let content = "";
@@ -50588,6 +50593,9 @@ ${after}`;
50588
50593
  function clipToolReturn(text, maxLines = 3, maxChars = 300) {
50589
50594
  if (!text)
50590
50595
  return text;
50596
+ if (text.includes("request to call tool denied")) {
50597
+ return text;
50598
+ }
50591
50599
  let clipped = text;
50592
50600
  if (text.length > maxChars) {
50593
50601
  clipped = text.slice(0, maxChars);
@@ -50887,7 +50895,7 @@ var init_manager4 = __esm(async () => {
50887
50895
  });
50888
50896
 
50889
50897
  // src/agent/create.ts
50890
- import { join as join13 } from "node:path";
50898
+ import { join as join15 } from "node:path";
50891
50899
  async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingModel = "openai/text-embedding-3-small", updateArgs, skillsDirectory, parallelToolCalls = true, enableSleeptime = false, systemPromptPreset, initBlocks, baseTools) {
50892
50900
  let options;
50893
50901
  if (typeof nameOrOptions === "object") {
@@ -50982,7 +50990,7 @@ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingM
50982
50990
  }
50983
50991
  }
50984
50992
  }
50985
- const resolvedSkillsDirectory = options.skillsDirectory || join13(process.cwd(), SKILLS_DIR);
50993
+ const resolvedSkillsDirectory = options.skillsDirectory || join15(process.cwd(), SKILLS_DIR);
50986
50994
  try {
50987
50995
  const { skills, errors } = await discoverSkills(resolvedSkillsDirectory);
50988
50996
  if (errors.length > 0) {
@@ -51931,6 +51939,10 @@ var exports_check_approval = {};
51931
51939
  __export(exports_check_approval, {
51932
51940
  getResumeData: () => getResumeData2
51933
51941
  });
51942
+ function isBackfillEnabled2() {
51943
+ const val = process.env.LETTA_BACKFILL;
51944
+ return val !== "0" && val !== "false";
51945
+ }
51934
51946
  async function getResumeData2(client, agent) {
51935
51947
  try {
51936
51948
  const messagesPage = await client.agents.messages.list(agent.id);
@@ -51953,6 +51965,13 @@ async function getResumeData2(client, agent) {
51953
51965
  const inContextLastMessageId = agent.message_ids && agent.message_ids.length > 0 ? agent.message_ids[agent.message_ids.length - 1] : null;
51954
51966
  if (!inContextLastMessageId) {
51955
51967
  debugWarn("check-approval", `No in-context messages (message_ids empty/null) - no pending approvals`);
51968
+ if (!isBackfillEnabled2()) {
51969
+ return {
51970
+ pendingApproval: null,
51971
+ pendingApprovals: [],
51972
+ messageHistory: []
51973
+ };
51974
+ }
51956
51975
  const historyCount2 = Math.min(MESSAGE_HISTORY_LIMIT2, messages.length);
51957
51976
  let messageHistory2 = messages.slice(-historyCount2);
51958
51977
  if (messageHistory2[0]?.message_type === "tool_return_message") {
@@ -52003,6 +52022,9 @@ async function getResumeData2(client, agent) {
52003
52022
  }
52004
52023
  }
52005
52024
  }
52025
+ if (!isBackfillEnabled2()) {
52026
+ return { pendingApproval, pendingApprovals, messageHistory: [] };
52027
+ }
52006
52028
  const historyCount = Math.min(MESSAGE_HISTORY_LIMIT2, messages.length);
52007
52029
  let messageHistory = messages.slice(-historyCount);
52008
52030
  if (messageHistory[0]?.message_type === "tool_return_message") {
@@ -52556,8 +52578,8 @@ async function handleHeadlessCommand(argv, model, skillsDirectory) {
52556
52578
  await initializeLoadedSkillsFlag2();
52557
52579
  try {
52558
52580
  const { discoverSkills: discoverSkills3, formatSkillsForMemory: formatSkillsForMemory3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills2(), exports_skills));
52559
- const { join: join14 } = await import("node:path");
52560
- const resolvedSkillsDirectory = skillsDirectory || join14(process.cwd(), SKILLS_DIR3);
52581
+ const { join: join16 } = await import("node:path");
52582
+ const resolvedSkillsDirectory = skillsDirectory || join16(process.cwd(), SKILLS_DIR3);
52561
52583
  const { skills, errors } = await discoverSkills3(resolvedSkillsDirectory);
52562
52584
  if (errors.length > 0) {
52563
52585
  console.warn("Errors encountered during skill discovery:");
@@ -53008,7 +53030,17 @@ async function handleHeadlessCommand(argv, model, skillsDirectory) {
53008
53030
  }
53009
53031
  process.exit(1);
53010
53032
  }
53011
- if (stopReason === "error" && lastRunId && llmApiErrorRetries < LLM_API_ERROR_MAX_RETRIES) {
53033
+ const nonRetriableReasons = [
53034
+ "cancelled",
53035
+ "requires_approval",
53036
+ "max_steps",
53037
+ "max_tokens_exceeded",
53038
+ "context_window_overflow_in_system_prompt",
53039
+ "end_turn",
53040
+ "tool_rule",
53041
+ "no_tool_call"
53042
+ ];
53043
+ if (nonRetriableReasons.includes(stopReason)) {} else if (lastRunId && llmApiErrorRetries < LLM_API_ERROR_MAX_RETRIES) {
53012
53044
  try {
53013
53045
  const run = await client.runs.retrieve(lastRunId);
53014
53046
  const metaError = run.metadata?.error;
@@ -53019,9 +53051,10 @@ async function handleHeadlessCommand(argv, model, skillsDirectory) {
53019
53051
  "OpenAI API error",
53020
53052
  "Google Vertex API error",
53021
53053
  "overloaded",
53022
- "api_error"
53054
+ "api_error",
53055
+ "Network error"
53023
53056
  ];
53024
- const isLlmErrorFromDetail = errorType === "internal_error" && llmProviderPatterns.some((pattern) => detail.includes(pattern));
53057
+ const isLlmErrorFromDetail = llmProviderPatterns.some((pattern) => detail.includes(pattern));
53025
53058
  if (errorType === "llm_error" || isLlmErrorFromDetail) {
53026
53059
  const attempt = llmApiErrorRetries + 1;
53027
53060
  const baseDelayMs = 1000;
@@ -53854,10 +53887,10 @@ __export(exports_settings, {
53854
53887
  loadProjectSettings: () => loadProjectSettings,
53855
53888
  getSetting: () => getSetting
53856
53889
  });
53857
- import { homedir as homedir7 } from "node:os";
53858
- import { join as join14 } from "node:path";
53890
+ import { homedir as homedir9 } from "node:os";
53891
+ import { join as join16 } from "node:path";
53859
53892
  function getSettingsPath() {
53860
- return join14(homedir7(), ".letta", "settings.json");
53893
+ return join16(homedir9(), ".letta", "settings.json");
53861
53894
  }
53862
53895
  async function loadSettings() {
53863
53896
  const settingsPath = getSettingsPath();
@@ -53894,7 +53927,7 @@ async function getSetting(key) {
53894
53927
  return settings[key];
53895
53928
  }
53896
53929
  function getProjectSettingsPath() {
53897
- return join14(process.cwd(), ".letta", "settings.local.json");
53930
+ return join16(process.cwd(), ".letta", "settings.local.json");
53898
53931
  }
53899
53932
  async function loadProjectSettings() {
53900
53933
  const settingsPath = getProjectSettingsPath();
@@ -53912,7 +53945,7 @@ async function loadProjectSettings() {
53912
53945
  }
53913
53946
  async function saveProjectSettings(settings) {
53914
53947
  const settingsPath = getProjectSettingsPath();
53915
- const dirPath = join14(process.cwd(), ".letta");
53948
+ const dirPath = join16(process.cwd(), ".letta");
53916
53949
  try {
53917
53950
  if (!exists(dirPath)) {
53918
53951
  await mkdir(dirPath, { recursive: true });
@@ -57510,12 +57543,18 @@ var init_BlinkDot = __esm(async () => {
57510
57543
  });
57511
57544
 
57512
57545
  // src/cli/components/CollapsedOutputDisplay.tsx
57513
- var import_react35, jsx_dev_runtime15, COLLAPSED_LINES = 3, CollapsedOutputDisplay;
57546
+ var import_react35, jsx_dev_runtime15, COLLAPSED_LINES = 3, PREFIX_WIDTH = 5, CollapsedOutputDisplay;
57514
57547
  var init_CollapsedOutputDisplay = __esm(async () => {
57515
- await init_build2();
57548
+ init_useTerminalWidth();
57549
+ await __promiseAll([
57550
+ init_build2(),
57551
+ init_MarkdownDisplay()
57552
+ ]);
57516
57553
  import_react35 = __toESM(require_react(), 1);
57517
57554
  jsx_dev_runtime15 = __toESM(require_jsx_dev_runtime(), 1);
57518
57555
  CollapsedOutputDisplay = import_react35.memo(({ output }) => {
57556
+ const columns = useTerminalWidth();
57557
+ const contentWidth = Math.max(0, columns - PREFIX_WIDTH);
57519
57558
  const lines = output.split(`
57520
57559
  `);
57521
57560
  if (lines.length > 0 && lines[lines.length - 1] === "") {
@@ -57530,28 +57569,65 @@ var init_CollapsedOutputDisplay = __esm(async () => {
57530
57569
  flexDirection: "column",
57531
57570
  children: [
57532
57571
  /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
57572
+ flexDirection: "row",
57533
57573
  children: [
57534
- /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text, {
57535
- children: " ⎿ "
57574
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
57575
+ width: PREFIX_WIDTH,
57576
+ flexShrink: 0,
57577
+ children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text, {
57578
+ children: " ⎿ "
57579
+ }, undefined, false, undefined, this)
57536
57580
  }, undefined, false, undefined, this),
57537
- /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text, {
57538
- children: visibleLines[0]
57581
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
57582
+ flexGrow: 1,
57583
+ width: contentWidth,
57584
+ children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(MarkdownDisplay, {
57585
+ text: visibleLines[0] ?? ""
57586
+ }, undefined, false, undefined, this)
57539
57587
  }, undefined, false, undefined, this)
57540
57588
  ]
57541
57589
  }, undefined, true, undefined, this),
57542
- visibleLines.slice(1).map((line, i) => /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text, {
57590
+ visibleLines.slice(1).map((line, i) => /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
57591
+ flexDirection: "row",
57543
57592
  children: [
57544
- " ",
57545
- line
57593
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
57594
+ width: PREFIX_WIDTH,
57595
+ flexShrink: 0,
57596
+ children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text, {
57597
+ children: " "
57598
+ }, undefined, false, undefined, this)
57599
+ }, undefined, false, undefined, this),
57600
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
57601
+ flexGrow: 1,
57602
+ width: contentWidth,
57603
+ children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(MarkdownDisplay, {
57604
+ text: line
57605
+ }, undefined, false, undefined, this)
57606
+ }, undefined, false, undefined, this)
57546
57607
  ]
57547
57608
  }, i, true, undefined, this)),
57548
- hiddenCount > 0 && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text, {
57549
- dimColor: true,
57609
+ hiddenCount > 0 && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
57610
+ flexDirection: "row",
57550
57611
  children: [
57551
- " ",
57552
- "… +",
57553
- hiddenCount,
57554
- " lines"
57612
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
57613
+ width: PREFIX_WIDTH,
57614
+ flexShrink: 0,
57615
+ children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text, {
57616
+ children: " "
57617
+ }, undefined, false, undefined, this)
57618
+ }, undefined, false, undefined, this),
57619
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
57620
+ flexGrow: 1,
57621
+ width: contentWidth,
57622
+ children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text, {
57623
+ dimColor: true,
57624
+ children: [
57625
+ "… +",
57626
+ hiddenCount,
57627
+ " lines"
57628
+ ]
57629
+ }, undefined, true, undefined, this)
57630
+ }, undefined, false, undefined, this)
57555
57631
  ]
57556
57632
  }, undefined, true, undefined, this)
57557
57633
  ]
@@ -58741,8 +58817,8 @@ import {
58741
58817
  readFileSync as readFileSync3,
58742
58818
  writeFileSync as writeFileSync2
58743
58819
  } from "node:fs";
58744
- import { homedir as homedir8, platform as platform3 } from "node:os";
58745
- import { dirname as dirname10, join as join15 } from "node:path";
58820
+ import { homedir as homedir10, platform as platform3 } from "node:os";
58821
+ import { dirname as dirname10, join as join17 } from "node:path";
58746
58822
  function detectTerminalType() {
58747
58823
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
58748
58824
  return "cursor";
@@ -58774,16 +58850,16 @@ function getKeybindingsPath(terminal) {
58774
58850
  }[terminal];
58775
58851
  const os4 = platform3();
58776
58852
  if (os4 === "darwin") {
58777
- return join15(homedir8(), "Library", "Application Support", appName, "User", "keybindings.json");
58853
+ return join17(homedir10(), "Library", "Application Support", appName, "User", "keybindings.json");
58778
58854
  }
58779
58855
  if (os4 === "win32") {
58780
58856
  const appData = process.env.APPDATA;
58781
58857
  if (!appData)
58782
58858
  return null;
58783
- return join15(appData, appName, "User", "keybindings.json");
58859
+ return join17(appData, appName, "User", "keybindings.json");
58784
58860
  }
58785
58861
  if (os4 === "linux") {
58786
- return join15(homedir8(), ".config", appName, "User", "keybindings.json");
58862
+ return join17(homedir10(), ".config", appName, "User", "keybindings.json");
58787
58863
  }
58788
58864
  return null;
58789
58865
  }
@@ -58936,14 +59012,14 @@ function getWezTermConfigPath() {
58936
59012
  }
58937
59013
  const xdgConfig = process.env.XDG_CONFIG_HOME;
58938
59014
  if (xdgConfig) {
58939
- const xdgPath = join15(xdgConfig, "wezterm", "wezterm.lua");
59015
+ const xdgPath = join17(xdgConfig, "wezterm", "wezterm.lua");
58940
59016
  if (existsSync10(xdgPath))
58941
59017
  return xdgPath;
58942
59018
  }
58943
- const configPath = join15(homedir8(), ".config", "wezterm", "wezterm.lua");
59019
+ const configPath = join17(homedir10(), ".config", "wezterm", "wezterm.lua");
58944
59020
  if (existsSync10(configPath))
58945
59021
  return configPath;
58946
- return join15(homedir8(), ".wezterm.lua");
59022
+ return join17(homedir10(), ".wezterm.lua");
58947
59023
  }
58948
59024
  function wezTermDeleteFixExists(configPath) {
58949
59025
  if (!existsSync10(configPath))
@@ -59265,14 +59341,14 @@ Location: ${keybindingsPath}`;
59265
59341
  }
59266
59342
  },
59267
59343
  "/connect": {
59268
- desc: "Connect an existing Claude account (/connect claude)",
59344
+ desc: "Connect an existing account (/connect zai <api-key>)",
59269
59345
  order: 40,
59270
59346
  handler: () => {
59271
- return "Initiating OAuth connection...";
59347
+ return "Initiating account connection...";
59272
59348
  }
59273
59349
  },
59274
59350
  "/disconnect": {
59275
- desc: "Disconnect from Claude OAuth",
59351
+ desc: "Disconnect an existing account (/disconnect zai)",
59276
59352
  order: 41,
59277
59353
  handler: () => {
59278
59354
  return "Disconnecting...";
@@ -59379,7 +59455,7 @@ __export(exports_custom, {
59379
59455
  });
59380
59456
  import { existsSync as existsSync11 } from "node:fs";
59381
59457
  import { readdir as readdir7, readFile as readFile8 } from "node:fs/promises";
59382
- import { basename as basename3, dirname as dirname11, join as join16 } from "node:path";
59458
+ import { basename as basename3, dirname as dirname11, join as join18 } from "node:path";
59383
59459
  async function getCustomCommands() {
59384
59460
  if (cachedCommands !== null) {
59385
59461
  return cachedCommands;
@@ -59390,7 +59466,7 @@ async function getCustomCommands() {
59390
59466
  function refreshCustomCommands() {
59391
59467
  cachedCommands = null;
59392
59468
  }
59393
- async function discoverCustomCommands(projectPath = join16(process.cwd(), COMMANDS_DIR)) {
59469
+ async function discoverCustomCommands(projectPath = join18(process.cwd(), COMMANDS_DIR)) {
59394
59470
  const commandsById = new Map;
59395
59471
  const userCommands = await discoverFromDirectory(GLOBAL_COMMANDS_DIR, "user");
59396
59472
  for (const cmd of userCommands) {
@@ -59422,7 +59498,7 @@ async function findCommandFiles(currentPath, rootPath, commands2, source) {
59422
59498
  try {
59423
59499
  const entries = await readdir7(currentPath, { withFileTypes: true });
59424
59500
  for (const entry of entries) {
59425
- const fullPath = join16(currentPath, entry.name);
59501
+ const fullPath = join18(currentPath, entry.name);
59426
59502
  if (entry.isDirectory()) {
59427
59503
  await findCommandFiles(fullPath, rootPath, commands2, source);
59428
59504
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
@@ -59507,7 +59583,7 @@ async function findCustomCommand(commandName) {
59507
59583
  }
59508
59584
  var COMMANDS_DIR = ".commands", GLOBAL_COMMANDS_DIR, cachedCommands = null;
59509
59585
  var init_custom = __esm(() => {
59510
- GLOBAL_COMMANDS_DIR = join16(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
59586
+ GLOBAL_COMMANDS_DIR = join18(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
59511
59587
  });
59512
59588
 
59513
59589
  // src/cli/components/HelpDialog.tsx
@@ -64479,7 +64555,7 @@ var init_AgentInfoBar = __esm(async () => {
64479
64555
 
64480
64556
  // src/cli/helpers/fileSearch.ts
64481
64557
  import { readdirSync as readdirSync4, statSync as statSync3 } from "node:fs";
64482
- import { join as join17, resolve as resolve19 } from "node:path";
64558
+ import { join as join19, resolve as resolve19 } from "node:path";
64483
64559
  function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = []) {
64484
64560
  if (results.length >= maxResults) {
64485
64561
  return results;
@@ -64491,7 +64567,7 @@ function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = [])
64491
64567
  continue;
64492
64568
  }
64493
64569
  try {
64494
- const fullPath = join17(dir, entry);
64570
+ const fullPath = join19(dir, entry);
64495
64571
  const stats = statSync3(fullPath);
64496
64572
  const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
64497
64573
  const matches = pattern.length === 0 || relativePath.toLowerCase().includes(pattern.toLowerCase());
@@ -64543,7 +64619,7 @@ async function searchFiles(query, deep = false) {
64543
64619
  const matchingEntries = searchPattern.length === 0 ? entries : entries.filter((entry) => entry.toLowerCase().includes(searchPattern.toLowerCase()));
64544
64620
  for (const entry of matchingEntries.slice(0, 50)) {
64545
64621
  try {
64546
- const fullPath = join17(searchDir, entry);
64622
+ const fullPath = join19(searchDir, entry);
64547
64623
  const stats = statSync3(fullPath);
64548
64624
  const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
64549
64625
  results.push({
@@ -68994,6 +69070,7 @@ var init_StaticPlanApproval = __esm(async () => {
68994
69070
  onApprove,
68995
69071
  onApproveAndAcceptEdits,
68996
69072
  onKeepPlanning,
69073
+ onCancel,
68997
69074
  isFocused = true
68998
69075
  }) => {
68999
69076
  const [selectedOption, setSelectedOption] = import_react71.useState(0);
@@ -69013,7 +69090,7 @@ var init_StaticPlanApproval = __esm(async () => {
69013
69090
  if (!isFocused)
69014
69091
  return;
69015
69092
  if (key.ctrl && input === "c") {
69016
- onKeepPlanning("User pressed CTRL-C to cancel");
69093
+ onCancel();
69017
69094
  return;
69018
69095
  }
69019
69096
  if (key.upArrow) {
@@ -72135,10 +72212,86 @@ var init_useSyncedState = __esm(() => {
72135
72212
  import_react81 = __toESM(require_react(), 1);
72136
72213
  });
72137
72214
 
72215
+ // src/providers/zai-provider.ts
72216
+ async function getLettaConfig2() {
72217
+ const settings = await settingsManager.getSettingsWithSecureTokens();
72218
+ const baseUrl = process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
72219
+ const apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY || "";
72220
+ return { baseUrl, apiKey };
72221
+ }
72222
+ async function providersRequest2(method, path20, body) {
72223
+ const { baseUrl, apiKey } = await getLettaConfig2();
72224
+ const url = `${baseUrl}${path20}`;
72225
+ const response = await fetch(url, {
72226
+ method,
72227
+ headers: {
72228
+ "Content-Type": "application/json",
72229
+ Authorization: `Bearer ${apiKey}`,
72230
+ "X-Letta-Source": "letta-code"
72231
+ },
72232
+ ...body && { body: JSON.stringify(body) }
72233
+ });
72234
+ if (!response.ok) {
72235
+ const errorText = await response.text();
72236
+ throw new Error(`Provider API error (${response.status}): ${errorText}`);
72237
+ }
72238
+ const text = await response.text();
72239
+ if (!text) {
72240
+ return {};
72241
+ }
72242
+ return JSON.parse(text);
72243
+ }
72244
+ async function listProviders2() {
72245
+ try {
72246
+ const response = await providersRequest2("GET", "/v1/providers");
72247
+ return response;
72248
+ } catch {
72249
+ return [];
72250
+ }
72251
+ }
72252
+ async function getZaiProvider() {
72253
+ const providers = await listProviders2();
72254
+ return providers.find((p) => p.name === ZAI_PROVIDER_NAME) || null;
72255
+ }
72256
+ async function createZaiProvider(apiKey) {
72257
+ return providersRequest2("POST", "/v1/providers", {
72258
+ name: ZAI_PROVIDER_NAME,
72259
+ provider_type: "zai",
72260
+ api_key: apiKey
72261
+ });
72262
+ }
72263
+ async function updateZaiProvider(providerId, apiKey) {
72264
+ return providersRequest2("PATCH", `/v1/providers/${providerId}`, {
72265
+ api_key: apiKey
72266
+ });
72267
+ }
72268
+ async function createOrUpdateZaiProvider(apiKey) {
72269
+ const existing = await getZaiProvider();
72270
+ if (existing) {
72271
+ return updateZaiProvider(existing.id, apiKey);
72272
+ }
72273
+ return createZaiProvider(apiKey);
72274
+ }
72275
+ async function deleteZaiProvider(providerId) {
72276
+ await providersRequest2("DELETE", `/v1/providers/${providerId}`);
72277
+ }
72278
+ async function removeZaiProvider() {
72279
+ const existing = await getZaiProvider();
72280
+ if (existing) {
72281
+ await deleteZaiProvider(existing.id);
72282
+ }
72283
+ }
72284
+ var ZAI_PROVIDER_NAME = "zai-coding-plan";
72285
+ var init_zai_provider = __esm(async () => {
72286
+ init_oauth();
72287
+ await init_settings_manager();
72288
+ });
72289
+
72138
72290
  // src/cli/commands/connect.ts
72139
72291
  var exports_connect = {};
72140
72292
  __export(exports_connect, {
72141
72293
  handleDisconnect: () => handleDisconnect,
72294
+ handleConnectZai: () => handleConnectZai,
72142
72295
  handleConnect: () => handleConnect
72143
72296
  });
72144
72297
  function uid3(prefix) {
@@ -72176,16 +72329,22 @@ async function handleConnect(ctx, msg) {
72176
72329
  const provider = parts[1]?.toLowerCase();
72177
72330
  const authCode = parts.slice(2).join("");
72178
72331
  if (!provider) {
72179
- addCommandResult3(ctx.buffersRef, ctx.refreshDerived, msg, `Usage: /connect claude
72332
+ addCommandResult3(ctx.buffersRef, ctx.refreshDerived, msg, `Usage: /connect <provider> [options]
72180
72333
 
72181
- Connect to Claude via OAuth to authenticate without an API key.`, false);
72334
+ Available providers:
72335
+ • claude - Connect via OAuth to authenticate without an API key
72336
+ • zai <api_key> - Connect to Zai with your API key`, false);
72182
72337
  return;
72183
72338
  }
72184
- if (provider !== "claude") {
72339
+ if (provider !== "claude" && provider !== "zai") {
72185
72340
  addCommandResult3(ctx.buffersRef, ctx.refreshDerived, msg, `Error: Unknown provider "${provider}"
72186
72341
 
72187
- Currently only 'claude' provider is supported.
72188
- Usage: /connect claude`, false);
72342
+ Available providers: claude, zai
72343
+ Usage: /connect <provider> [options]`, false);
72344
+ return;
72345
+ }
72346
+ if (provider === "zai") {
72347
+ await handleConnectZai(ctx, msg);
72189
72348
  return;
72190
72349
  }
72191
72350
  if (authCode && authCode.length > 0) {
@@ -72305,13 +72464,26 @@ If you have an Anthropic API key, you can use it directly by setting:
72305
72464
  async function handleDisconnect(ctx, msg) {
72306
72465
  const parts = msg.trim().split(/\s+/);
72307
72466
  const provider = parts[1]?.toLowerCase();
72308
- if (provider && provider !== "claude") {
72309
- addCommandResult3(ctx.buffersRef, ctx.refreshDerived, msg, `Error: Unknown provider "${provider}"
72467
+ if (!provider) {
72468
+ addCommandResult3(ctx.buffersRef, ctx.refreshDerived, msg, `Usage: /disconnect <provider>
72310
72469
 
72311
- Currently only 'claude' provider is supported.
72312
- Usage: /disconnect`, false);
72470
+ Available providers: claude, zai`, false);
72471
+ return;
72472
+ }
72473
+ if (provider === "zai") {
72474
+ await handleDisconnectZai(ctx, msg);
72313
72475
  return;
72314
72476
  }
72477
+ if (provider === "claude") {
72478
+ await handleDisconnectClaude(ctx, msg);
72479
+ return;
72480
+ }
72481
+ addCommandResult3(ctx.buffersRef, ctx.refreshDerived, msg, `Error: Unknown provider "${provider}"
72482
+
72483
+ Available providers: claude, zai
72484
+ Usage: /disconnect <provider>`, false);
72485
+ }
72486
+ async function handleDisconnectClaude(ctx, msg) {
72315
72487
  if (!settingsManager.hasAnthropicOAuth()) {
72316
72488
  addCommandResult3(ctx.buffersRef, ctx.refreshDerived, msg, `Not currently connected to Claude via OAuth.
72317
72489
 
@@ -72336,10 +72508,58 @@ Your local OAuth tokens have been removed.`, true, "finished");
72336
72508
  ctx.setCommandRunning(false);
72337
72509
  }
72338
72510
  }
72511
+ async function handleDisconnectZai(ctx, msg) {
72512
+ const existing = await getZaiProvider();
72513
+ if (!existing) {
72514
+ addCommandResult3(ctx.buffersRef, ctx.refreshDerived, msg, `Not currently connected to Zai.
72515
+
72516
+ Use /connect zai <api_key> to connect.`, false);
72517
+ return;
72518
+ }
72519
+ const cmdId = addCommandResult3(ctx.buffersRef, ctx.refreshDerived, msg, "Disconnecting from Zai...", true, "running");
72520
+ ctx.setCommandRunning(true);
72521
+ try {
72522
+ await removeZaiProvider();
72523
+ updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `✓ Disconnected from Zai.
72524
+
72525
+ ` + `Provider '${ZAI_PROVIDER_NAME}' removed from Letta.`, true, "finished");
72526
+ } catch (error) {
72527
+ updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `✗ Failed to disconnect from Zai: ${getErrorMessage(error)}`, false, "finished");
72528
+ } finally {
72529
+ ctx.setCommandRunning(false);
72530
+ }
72531
+ }
72532
+ async function handleConnectZai(ctx, msg) {
72533
+ const parts = msg.trim().split(/\s+/);
72534
+ const apiKey = parts.slice(2).join("");
72535
+ if (!apiKey || apiKey.length === 0) {
72536
+ addCommandResult3(ctx.buffersRef, ctx.refreshDerived, msg, `Usage: /connect zai <api_key>
72537
+
72538
+ Connect to Zai by providing your API key.
72539
+
72540
+ Example: /connect zai <api_key>...`, false);
72541
+ return;
72542
+ }
72543
+ const cmdId = addCommandResult3(ctx.buffersRef, ctx.refreshDerived, msg, "Creating Zai coding plan provider...", true, "running");
72544
+ ctx.setCommandRunning(true);
72545
+ try {
72546
+ await createOrUpdateZaiProvider(apiKey);
72547
+ updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `✓ Successfully connected to Zai!
72548
+
72549
+ ` + `Provider '${ZAI_PROVIDER_NAME}' created in Letta.
72550
+
72551
+ ` + `The models are populated in /model → "All Available Models"`, true, "finished");
72552
+ } catch (error) {
72553
+ updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `✗ Failed to create Zai provider: ${getErrorMessage(error)}`, false, "finished");
72554
+ } finally {
72555
+ ctx.setCommandRunning(false);
72556
+ }
72557
+ }
72339
72558
  var init_connect = __esm(async () => {
72340
72559
  init_anthropic_oauth();
72341
72560
  await __promiseAll([
72342
72561
  init_anthropic_provider(),
72562
+ init_zai_provider(),
72343
72563
  init_settings_manager()
72344
72564
  ]);
72345
72565
  });
@@ -72520,6 +72740,8 @@ __export(exports_App, {
72520
72740
  default: () => App2
72521
72741
  });
72522
72742
  import { existsSync as existsSync12, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
72743
+ import { homedir as homedir11 } from "node:os";
72744
+ import { join as join20 } from "node:path";
72523
72745
  function uid4(prefix) {
72524
72746
  return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
72525
72747
  }
@@ -72529,7 +72751,19 @@ function sendDesktopNotification() {
72529
72751
  async function isRetriableError(stopReason, lastRunId) {
72530
72752
  if (stopReason === "llm_api_error")
72531
72753
  return true;
72532
- if (stopReason === "error" && lastRunId) {
72754
+ const nonRetriableReasons = [
72755
+ "cancelled",
72756
+ "requires_approval",
72757
+ "max_steps",
72758
+ "max_tokens_exceeded",
72759
+ "context_window_overflow_in_system_prompt",
72760
+ "end_turn",
72761
+ "tool_rule",
72762
+ "no_tool_call"
72763
+ ];
72764
+ if (nonRetriableReasons.includes(stopReason))
72765
+ return false;
72766
+ if (lastRunId) {
72533
72767
  try {
72534
72768
  const client = await getClient2();
72535
72769
  const run = await client.runs.retrieve(lastRunId);
@@ -72543,9 +72777,10 @@ async function isRetriableError(stopReason, lastRunId) {
72543
72777
  "OpenAI API error",
72544
72778
  "Google Vertex API error",
72545
72779
  "overloaded",
72546
- "api_error"
72780
+ "api_error",
72781
+ "Network error"
72547
72782
  ];
72548
- if (errorType === "internal_error" && llmProviderPatterns.some((pattern) => detail.includes(pattern))) {
72783
+ if (llmProviderPatterns.some((pattern) => detail.includes(pattern))) {
72549
72784
  return true;
72550
72785
  }
72551
72786
  return false;
@@ -74460,6 +74695,15 @@ ${newState.originalPrompt}`
74460
74695
  const parts = msg.trim().split(/\s+/);
74461
74696
  const provider = parts[1]?.toLowerCase();
74462
74697
  const hasCode = parts.length > 2;
74698
+ if (provider === "zai") {
74699
+ const { handleConnectZai: handleConnectZai2 } = await init_connect().then(() => exports_connect);
74700
+ await handleConnectZai2({
74701
+ buffersRef,
74702
+ refreshDerived,
74703
+ setCommandRunning
74704
+ }, msg);
74705
+ return { submitted: true };
74706
+ }
74463
74707
  if (provider === "claude" && !hasCode) {
74464
74708
  setActiveOverlay("oauth");
74465
74709
  return { submitted: true };
@@ -76501,13 +76745,47 @@ Consider switching to a different system prompt using /system to match.` : null;
76501
76745
  import_react82.useEffect(() => {
76502
76746
  const currentIndex = approvalResults.length;
76503
76747
  const approval = pendingApprovals[currentIndex];
76504
- if (approval?.toolName === "ExitPlanMode" && !planFileExists()) {
76505
- const planFilePath = permissionMode2.getPlanFilePath();
76506
- handlePlanKeepPlanning(`You must write your plan to the plan file before exiting plan mode.
76507
- ` + `Plan file path: ${planFilePath || "not set"}
76508
- ` + `Use a write tool (e.g. Write, ApplyPatch, etc.) to create your plan, then call ExitPlanMode again.`);
76748
+ if (approval?.toolName === "ExitPlanMode") {
76749
+ if (permissionMode2.getMode() !== "plan") {
76750
+ const statusId = uid4("status");
76751
+ buffersRef.current.byId.set(statusId, {
76752
+ kind: "status",
76753
+ id: statusId,
76754
+ lines: ["⚠️ Plan mode session expired (use /plan to re-enter)"]
76755
+ });
76756
+ buffersRef.current.order.push(statusId);
76757
+ const denialResults = [
76758
+ {
76759
+ type: "approval",
76760
+ tool_call_id: approval.toolCallId,
76761
+ approve: false,
76762
+ reason: "Plan mode session expired (CLI restarted). Use EnterPlanMode to re-enter plan mode, or request the user to re-enter plan mode."
76763
+ }
76764
+ ];
76765
+ setQueuedApprovalResults(denialResults);
76766
+ markIncompleteToolsAsCancelled(buffersRef.current);
76767
+ refreshDerived();
76768
+ setPendingApprovals([]);
76769
+ setApprovalContexts([]);
76770
+ setApprovalResults([]);
76771
+ setAutoHandledResults([]);
76772
+ setAutoDeniedApprovals([]);
76773
+ return;
76774
+ }
76775
+ if (!planFileExists()) {
76776
+ const planFilePath = permissionMode2.getPlanFilePath();
76777
+ const plansDir = join20(homedir11(), ".letta", "plans");
76778
+ handlePlanKeepPlanning(`You must write your plan to a plan file before exiting plan mode.
76779
+ ` + (planFilePath ? `Plan file path: ${planFilePath}
76780
+ ` : "") + `Use a write tool to create your plan in ${plansDir}, then use ExitPlanMode to present the plan to the user.`);
76781
+ }
76509
76782
  }
76510
- }, [pendingApprovals, approvalResults.length, handlePlanKeepPlanning]);
76783
+ }, [
76784
+ pendingApprovals,
76785
+ approvalResults.length,
76786
+ handlePlanKeepPlanning,
76787
+ refreshDerived
76788
+ ]);
76511
76789
  const handleQuestionSubmit = import_react82.useCallback(async (answers) => {
76512
76790
  const currentIndex = approvalResults.length;
76513
76791
  const approval = pendingApprovals[currentIndex];
@@ -76537,6 +76815,9 @@ Consider switching to a different system prompt using /system to match.` : null;
76537
76815
  });
76538
76816
  setThinkingMessage(getRandomThinkingVerb());
76539
76817
  refreshDerived();
76818
+ if (approval.toolCallId) {
76819
+ eagerCommittedPreviewsRef.current.add(approval.toolCallId);
76820
+ }
76540
76821
  const decision = {
76541
76822
  type: "approve",
76542
76823
  approval,
@@ -76710,11 +76991,13 @@ Plan file path: ${planFilePath}`;
76710
76991
  });
76711
76992
  buffersRef.current.order.push(statusId);
76712
76993
  refreshDerived();
76994
+ commitEligibleLines(buffersRef.current);
76713
76995
  }
76714
76996
  }, [
76715
76997
  loadingState,
76716
76998
  continueSession,
76717
76999
  messageHistory.length,
77000
+ commitEligibleLines,
76718
77001
  columns,
76719
77002
  agentProvenance,
76720
77003
  agentState,
@@ -76784,6 +77067,9 @@ Plan file path: ${planFilePath}`;
76784
77067
  if (ln.kind === "tool_call" && ln.name && isTaskTool(ln.name) && ln.toolCallId && !pendingIds.has(ln.toolCallId)) {
76785
77068
  return null;
76786
77069
  }
77070
+ if (ln.kind === "tool_call" && ln.toolCallId && eagerCommittedPreviewsRef.current.has(ln.toolCallId) && ln.toolCallId !== currentApproval?.toolCallId) {
77071
+ return null;
77072
+ }
76787
77073
  const isExitPlanModeApproval = ln.kind === "tool_call" && currentApproval?.toolName === "ExitPlanMode" && ln.toolCallId === currentApproval?.toolCallId;
76788
77074
  const isFileEditApproval = ln.kind === "tool_call" && currentApproval && (isFileEditTool(currentApproval.toolName) || isFileWriteTool(currentApproval.toolName) || isPatchTool(currentApproval.toolName)) && ln.toolCallId === currentApproval.toolCallId;
76789
77075
  const isBashApproval = ln.kind === "tool_call" && currentApproval && isShellTool(currentApproval.toolName) && ln.toolCallId === currentApproval.toolCallId;
@@ -76867,6 +77153,7 @@ Plan file path: ${planFilePath}`;
76867
77153
  onApprove: () => handlePlanApprove(false),
76868
77154
  onApproveAndAcceptEdits: () => handlePlanApprove(true),
76869
77155
  onKeepPlanning: handlePlanKeepPlanning,
77156
+ onCancel: handleCancelApprovals,
76870
77157
  isFocused: true
76871
77158
  }, undefined, false, undefined, this) : isFileEditApproval && fileEditInfo ? /* @__PURE__ */ jsx_dev_runtime59.jsxDEV(InlineFileEditApproval, {
76872
77159
  fileEdit: fileEditInfo,
@@ -76946,6 +77233,20 @@ Plan file path: ${planFilePath}`;
76946
77233
  }, ln.id, false, undefined, this);
76947
77234
  })
76948
77235
  }, undefined, false, undefined, this),
77236
+ liveItems.length === 0 && currentApproval && /* @__PURE__ */ jsx_dev_runtime59.jsxDEV(Box_default, {
77237
+ flexDirection: "column",
77238
+ children: /* @__PURE__ */ jsx_dev_runtime59.jsxDEV(InlineGenericApproval, {
77239
+ toolName: currentApproval.toolName,
77240
+ toolArgs: currentApproval.toolArgs,
77241
+ onApprove: () => handleApproveCurrent(),
77242
+ onApproveAlways: (scope) => handleApproveAlways(scope),
77243
+ onDeny: (reason) => handleDenyCurrent(reason),
77244
+ onCancel: handleCancelApprovals,
77245
+ isFocused: true,
77246
+ approveAlwaysText: currentApprovalContext?.approveAlwaysText,
77247
+ allowPersistence: currentApprovalContext?.allowPersistence ?? true
77248
+ }, undefined, false, undefined, this)
77249
+ }, undefined, false, undefined, this),
76949
77250
  /* @__PURE__ */ jsx_dev_runtime59.jsxDEV(SubagentGroupDisplay, {}, undefined, false, undefined, this)
76950
77251
  ]
76951
77252
  }, undefined, true, undefined, this),
@@ -77254,8 +77555,8 @@ import {
77254
77555
  readFileSync as readFileSync5,
77255
77556
  writeFileSync as writeFileSync4
77256
77557
  } from "node:fs";
77257
- import { homedir as homedir9, platform as platform5 } from "node:os";
77258
- import { dirname as dirname12, join as join18 } from "node:path";
77558
+ import { homedir as homedir12, platform as platform5 } from "node:os";
77559
+ import { dirname as dirname12, join as join21 } from "node:path";
77259
77560
  function detectTerminalType2() {
77260
77561
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
77261
77562
  return "cursor";
@@ -77287,16 +77588,16 @@ function getKeybindingsPath2(terminal) {
77287
77588
  }[terminal];
77288
77589
  const os5 = platform5();
77289
77590
  if (os5 === "darwin") {
77290
- return join18(homedir9(), "Library", "Application Support", appName, "User", "keybindings.json");
77591
+ return join21(homedir12(), "Library", "Application Support", appName, "User", "keybindings.json");
77291
77592
  }
77292
77593
  if (os5 === "win32") {
77293
77594
  const appData = process.env.APPDATA;
77294
77595
  if (!appData)
77295
77596
  return null;
77296
- return join18(appData, appName, "User", "keybindings.json");
77597
+ return join21(appData, appName, "User", "keybindings.json");
77297
77598
  }
77298
77599
  if (os5 === "linux") {
77299
- return join18(homedir9(), ".config", appName, "User", "keybindings.json");
77600
+ return join21(homedir12(), ".config", appName, "User", "keybindings.json");
77300
77601
  }
77301
77602
  return null;
77302
77603
  }
@@ -77449,14 +77750,14 @@ function getWezTermConfigPath2() {
77449
77750
  }
77450
77751
  const xdgConfig = process.env.XDG_CONFIG_HOME;
77451
77752
  if (xdgConfig) {
77452
- const xdgPath = join18(xdgConfig, "wezterm", "wezterm.lua");
77753
+ const xdgPath = join21(xdgConfig, "wezterm", "wezterm.lua");
77453
77754
  if (existsSync13(xdgPath))
77454
77755
  return xdgPath;
77455
77756
  }
77456
- const configPath = join18(homedir9(), ".config", "wezterm", "wezterm.lua");
77757
+ const configPath = join21(homedir12(), ".config", "wezterm", "wezterm.lua");
77457
77758
  if (existsSync13(configPath))
77458
77759
  return configPath;
77459
- return join18(homedir9(), ".wezterm.lua");
77760
+ return join21(homedir12(), ".wezterm.lua");
77460
77761
  }
77461
77762
  function wezTermDeleteFixExists2(configPath) {
77462
77763
  if (!existsSync13(configPath))
@@ -77554,10 +77855,10 @@ __export(exports_settings2, {
77554
77855
  loadProjectSettings: () => loadProjectSettings2,
77555
77856
  getSetting: () => getSetting2
77556
77857
  });
77557
- import { homedir as homedir10 } from "node:os";
77558
- import { join as join19 } from "node:path";
77858
+ import { homedir as homedir13 } from "node:os";
77859
+ import { join as join22 } from "node:path";
77559
77860
  function getSettingsPath2() {
77560
- return join19(homedir10(), ".letta", "settings.json");
77861
+ return join22(homedir13(), ".letta", "settings.json");
77561
77862
  }
77562
77863
  async function loadSettings2() {
77563
77864
  const settingsPath = getSettingsPath2();
@@ -77594,7 +77895,7 @@ async function getSetting2(key) {
77594
77895
  return settings[key];
77595
77896
  }
77596
77897
  function getProjectSettingsPath2() {
77597
- return join19(process.cwd(), ".letta", "settings.local.json");
77898
+ return join22(process.cwd(), ".letta", "settings.local.json");
77598
77899
  }
77599
77900
  async function loadProjectSettings2() {
77600
77901
  const settingsPath = getProjectSettingsPath2();
@@ -77612,7 +77913,7 @@ async function loadProjectSettings2() {
77612
77913
  }
77613
77914
  async function saveProjectSettings2(settings) {
77614
77915
  const settingsPath = getProjectSettingsPath2();
77615
- const dirPath = join19(process.cwd(), ".letta");
77916
+ const dirPath = join22(process.cwd(), ".letta");
77616
77917
  try {
77617
77918
  if (!exists(dirPath)) {
77618
77919
  await mkdir(dirPath, { recursive: true });
@@ -77644,7 +77945,7 @@ var exports_create = {};
77644
77945
  __export(exports_create, {
77645
77946
  createAgent: () => createAgent2
77646
77947
  });
77647
- import { join as join20 } from "node:path";
77948
+ import { join as join23 } from "node:path";
77648
77949
  async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingModel = "openai/text-embedding-3-small", updateArgs, skillsDirectory, parallelToolCalls = true, enableSleeptime = false, systemPromptPreset, initBlocks, baseTools) {
77649
77950
  let options;
77650
77951
  if (typeof nameOrOptions === "object") {
@@ -77739,7 +78040,7 @@ async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embedding
77739
78040
  }
77740
78041
  }
77741
78042
  }
77742
- const resolvedSkillsDirectory = options.skillsDirectory || join20(process.cwd(), SKILLS_DIR);
78043
+ const resolvedSkillsDirectory = options.skillsDirectory || join23(process.cwd(), SKILLS_DIR);
77743
78044
  try {
77744
78045
  const { skills, errors } = await discoverSkills(resolvedSkillsDirectory);
77745
78046
  if (errors.length > 0) {
@@ -78104,6 +78405,10 @@ import { parseArgs as parseArgs2 } from "util";
78104
78405
 
78105
78406
  // src/agent/check-approval.ts
78106
78407
  var MESSAGE_HISTORY_LIMIT = 15;
78408
+ function isBackfillEnabled() {
78409
+ const val = process.env.LETTA_BACKFILL;
78410
+ return val !== "0" && val !== "false";
78411
+ }
78107
78412
  async function getResumeData(client, agent) {
78108
78413
  try {
78109
78414
  const messagesPage = await client.agents.messages.list(agent.id);
@@ -78126,6 +78431,13 @@ async function getResumeData(client, agent) {
78126
78431
  const inContextLastMessageId = agent.message_ids && agent.message_ids.length > 0 ? agent.message_ids[agent.message_ids.length - 1] : null;
78127
78432
  if (!inContextLastMessageId) {
78128
78433
  debugWarn("check-approval", `No in-context messages (message_ids empty/null) - no pending approvals`);
78434
+ if (!isBackfillEnabled()) {
78435
+ return {
78436
+ pendingApproval: null,
78437
+ pendingApprovals: [],
78438
+ messageHistory: []
78439
+ };
78440
+ }
78129
78441
  const historyCount2 = Math.min(MESSAGE_HISTORY_LIMIT, messages.length);
78130
78442
  let messageHistory2 = messages.slice(-historyCount2);
78131
78443
  if (messageHistory2[0]?.message_type === "tool_return_message") {
@@ -78176,6 +78488,9 @@ async function getResumeData(client, agent) {
78176
78488
  }
78177
78489
  }
78178
78490
  }
78491
+ if (!isBackfillEnabled()) {
78492
+ return { pendingApproval, pendingApprovals, messageHistory: [] };
78493
+ }
78179
78494
  const historyCount = Math.min(MESSAGE_HISTORY_LIMIT, messages.length);
78180
78495
  let messageHistory = messages.slice(-historyCount);
78181
78496
  if (messageHistory[0]?.message_type === "tool_return_message") {
@@ -78560,6 +78875,8 @@ function ProfileSelectionInline({
78560
78875
 
78561
78876
  // src/permissions/mode.ts
78562
78877
  init_readOnlyShell();
78878
+ import { homedir as homedir3 } from "node:os";
78879
+ import { join as join2 } from "node:path";
78563
78880
  var MODE_KEY = Symbol.for("@letta/permissionMode");
78564
78881
  var PLAN_FILE_KEY = Symbol.for("@letta/planFilePath");
78565
78882
  function getGlobalMode() {
@@ -78664,7 +78981,7 @@ class PermissionModeManager {
78664
78981
  return "allow";
78665
78982
  }
78666
78983
  if (writeTools.includes(toolName)) {
78667
- const planFilePath = this.getPlanFilePath();
78984
+ const plansDir = join2(homedir3(), ".letta", "plans");
78668
78985
  let targetPath = toolArgs?.file_path || toolArgs?.path;
78669
78986
  if ((toolName === "ApplyPatch" || toolName === "apply_patch") && toolArgs?.input) {
78670
78987
  const input = toolArgs.input;
@@ -78673,7 +78990,7 @@ class PermissionModeManager {
78673
78990
  targetPath = match[1].trim();
78674
78991
  }
78675
78992
  }
78676
- if (planFilePath && targetPath && targetPath === planFilePath) {
78993
+ if (targetPath && targetPath.startsWith(plansDir) && targetPath.endsWith(".md")) {
78677
78994
  return "allow";
78678
78995
  }
78679
78996
  }
@@ -78729,8 +79046,8 @@ var permissionMode = new PermissionModeManager;
78729
79046
  // src/settings-manager.ts
78730
79047
  init_fs();
78731
79048
  await init_secrets();
78732
- import { homedir as homedir3 } from "node:os";
78733
- import { join as join2 } from "node:path";
79049
+ import { homedir as homedir4 } from "node:os";
79050
+ import { join as join3 } from "node:path";
78734
79051
  var DEFAULT_SETTINGS2 = {
78735
79052
  lastAgent: null,
78736
79053
  tokenStreaming: false,
@@ -78976,8 +79293,8 @@ class SettingsManager2 {
78976
79293
  if (!this.settings)
78977
79294
  return;
78978
79295
  const settingsPath = this.getSettingsPath();
78979
- const home = process.env.HOME || homedir3();
78980
- const dirPath = join2(home, ".letta");
79296
+ const home = process.env.HOME || homedir4();
79297
+ const dirPath = join3(home, ".letta");
78981
79298
  try {
78982
79299
  if (!exists(dirPath)) {
78983
79300
  await mkdir(dirPath, { recursive: true });
@@ -78993,7 +79310,7 @@ class SettingsManager2 {
78993
79310
  if (!settings)
78994
79311
  return;
78995
79312
  const settingsPath = this.getProjectSettingsPath(workingDirectory);
78996
- const dirPath = join2(workingDirectory, ".letta");
79313
+ const dirPath = join3(workingDirectory, ".letta");
78997
79314
  try {
78998
79315
  let existingSettings = {};
78999
79316
  if (exists(settingsPath)) {
@@ -79014,14 +79331,14 @@ class SettingsManager2 {
79014
79331
  }
79015
79332
  }
79016
79333
  getSettingsPath() {
79017
- const home = process.env.HOME || homedir3();
79018
- return join2(home, ".letta", "settings.json");
79334
+ const home = process.env.HOME || homedir4();
79335
+ return join3(home, ".letta", "settings.json");
79019
79336
  }
79020
79337
  getProjectSettingsPath(workingDirectory) {
79021
- return join2(workingDirectory, ".letta", "settings.json");
79338
+ return join3(workingDirectory, ".letta", "settings.json");
79022
79339
  }
79023
79340
  getLocalProjectSettingsPath(workingDirectory) {
79024
- return join2(workingDirectory, ".letta", "settings.local.json");
79341
+ return join3(workingDirectory, ".letta", "settings.local.json");
79025
79342
  }
79026
79343
  async loadLocalProjectSettings(workingDirectory = process.cwd()) {
79027
79344
  const cached = this.localProjectSettings.get(workingDirectory);
@@ -79072,7 +79389,7 @@ class SettingsManager2 {
79072
79389
  if (!settings)
79073
79390
  return;
79074
79391
  const settingsPath = this.getLocalProjectSettingsPath(workingDirectory);
79075
- const dirPath = join2(workingDirectory, ".letta");
79392
+ const dirPath = join3(workingDirectory, ".letta");
79076
79393
  try {
79077
79394
  if (!exists(dirPath)) {
79078
79395
  await mkdir(dirPath, { recursive: true });
@@ -79182,7 +79499,7 @@ class SettingsManager2 {
79182
79499
  console.warn("unpinProfile is deprecated, use unpinLocal(agentId) instead");
79183
79500
  }
79184
79501
  hasLocalLettaDir(workingDirectory = process.cwd()) {
79185
- const dirPath = join2(workingDirectory, ".letta");
79502
+ const dirPath = join3(workingDirectory, ".letta");
79186
79503
  return exists(dirPath);
79187
79504
  }
79188
79505
  storeAnthropicTokens(tokens) {
@@ -79773,12 +80090,12 @@ EXAMPLES
79773
80090
  console.log(usage);
79774
80091
  }
79775
80092
  async function printInfo() {
79776
- const { join: join21 } = await import("path");
80093
+ const { join: join24 } = await import("path");
79777
80094
  const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version2(), exports_version));
79778
80095
  const { SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
79779
80096
  const { exists: exists3 } = await Promise.resolve().then(() => (init_fs2(), exports_fs));
79780
80097
  const cwd2 = process.cwd();
79781
- const skillsDir = join21(cwd2, SKILLS_DIR3);
80098
+ const skillsDir = join24(cwd2, SKILLS_DIR3);
79782
80099
  const skillsExist = exists3(skillsDir);
79783
80100
  await settingsManager2.loadLocalProjectSettings(cwd2);
79784
80101
  const localPinned = settingsManager2.getLocalPinnedAgents(cwd2);
@@ -80437,8 +80754,8 @@ Error: ${message}`);
80437
80754
  await initializeLoadedSkillsFlag();
80438
80755
  try {
80439
80756
  const { discoverSkills: discoverSkills3, formatSkillsForMemory: formatSkillsForMemory3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
80440
- const { join: join21 } = await import("path");
80441
- const resolvedSkillsDirectory = skillsDirectory2 || join21(process.cwd(), SKILLS_DIR3);
80757
+ const { join: join24 } = await import("path");
80758
+ const resolvedSkillsDirectory = skillsDirectory2 || join24(process.cwd(), SKILLS_DIR3);
80442
80759
  const { skills, errors } = await discoverSkills3(resolvedSkillsDirectory);
80443
80760
  if (errors.length > 0) {
80444
80761
  console.warn("Errors encountered during skill discovery:");
@@ -80582,4 +80899,4 @@ Error during initialization: ${message}`);
80582
80899
  }
80583
80900
  main();
80584
80901
 
80585
- //# debugId=FBA441943F68A1FC64756E2164756E21
80902
+ //# debugId=C1C8E8CD6D145E1A64756E2164756E21