@letta-ai/letta-code 0.7.0 → 0.7.1

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 +1421 -689
  2. package/package.json +1 -1
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.7.0",
3240
+ version: "0.7.1",
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: {
@@ -3339,7 +3339,7 @@ async function pollForToken(deviceCode, interval = 5, expiresIn = 900, deviceId,
3339
3339
  grant_type: "urn:ietf:params:oauth:grant-type:device_code",
3340
3340
  client_id: OAUTH_CONFIG.clientId,
3341
3341
  device_code: deviceCode,
3342
- ...deviceId && { device_id: deviceId },
3342
+ device_id: deviceId,
3343
3343
  ...deviceName && { device_name: deviceName }
3344
3344
  })
3345
3345
  });
@@ -3371,7 +3371,7 @@ async function pollForToken(deviceCode, interval = 5, expiresIn = 900, deviceId,
3371
3371
  }
3372
3372
  throw new Error("Timeout waiting for authorization (15 minutes)");
3373
3373
  }
3374
- async function refreshAccessToken(refreshToken) {
3374
+ async function refreshAccessToken(refreshToken, deviceId, deviceName) {
3375
3375
  const response = await fetch(`${OAUTH_CONFIG.authBaseUrl}/api/oauth/token`, {
3376
3376
  method: "POST",
3377
3377
  headers: { "Content-Type": "application/json" },
@@ -3379,7 +3379,9 @@ async function refreshAccessToken(refreshToken) {
3379
3379
  grant_type: "refresh_token",
3380
3380
  client_id: OAUTH_CONFIG.clientId,
3381
3381
  refresh_token: refreshToken,
3382
- refresh_token_mode: "new"
3382
+ refresh_token_mode: "new",
3383
+ device_id: deviceId,
3384
+ ...deviceName && { device_name: deviceName }
3383
3385
  })
3384
3386
  });
3385
3387
  if (!response.ok) {
@@ -3811,6 +3813,7 @@ var exports_client = {};
3811
3813
  __export(exports_client, {
3812
3814
  getClient: () => getClient2
3813
3815
  });
3816
+ import { hostname as hostname2 } from "node:os";
3814
3817
  async function getClient2() {
3815
3818
  const settings = settingsManager.getSettings();
3816
3819
  let apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY;
@@ -3819,7 +3822,13 @@ async function getClient2() {
3819
3822
  const expiresAt = settings.tokenExpiresAt;
3820
3823
  if (expiresAt - now < 5 * 60 * 1000) {
3821
3824
  try {
3822
- const tokens = await refreshAccessToken(settings.refreshToken);
3825
+ let deviceId = settings.deviceId;
3826
+ if (!deviceId) {
3827
+ deviceId = crypto.randomUUID();
3828
+ settingsManager.updateSettings({ deviceId });
3829
+ }
3830
+ const deviceName = hostname2();
3831
+ const tokens = await refreshAccessToken(settings.refreshToken, deviceId, deviceName);
3823
3832
  const updatedEnv = { ...settings.env };
3824
3833
  updatedEnv.LETTA_API_KEY = tokens.access_token;
3825
3834
  settingsManager.updateSettings({
@@ -3896,7 +3905,7 @@ async function pollForToken2(deviceCode, interval = 5, expiresIn = 900, deviceId
3896
3905
  grant_type: "urn:ietf:params:oauth:grant-type:device_code",
3897
3906
  client_id: OAUTH_CONFIG2.clientId,
3898
3907
  device_code: deviceCode,
3899
- ...deviceId && { device_id: deviceId },
3908
+ device_id: deviceId,
3900
3909
  ...deviceName && { device_name: deviceName }
3901
3910
  })
3902
3911
  });
@@ -3928,7 +3937,7 @@ async function pollForToken2(deviceCode, interval = 5, expiresIn = 900, deviceId
3928
3937
  }
3929
3938
  throw new Error("Timeout waiting for authorization (15 minutes)");
3930
3939
  }
3931
- async function refreshAccessToken2(refreshToken) {
3940
+ async function refreshAccessToken2(refreshToken, deviceId, deviceName) {
3932
3941
  const response = await fetch(`${OAUTH_CONFIG2.authBaseUrl}/api/oauth/token`, {
3933
3942
  method: "POST",
3934
3943
  headers: { "Content-Type": "application/json" },
@@ -3936,7 +3945,9 @@ async function refreshAccessToken2(refreshToken) {
3936
3945
  grant_type: "refresh_token",
3937
3946
  client_id: OAUTH_CONFIG2.clientId,
3938
3947
  refresh_token: refreshToken,
3939
- refresh_token_mode: "new"
3948
+ refresh_token_mode: "new",
3949
+ device_id: deviceId,
3950
+ ...deviceName && { device_name: deviceName }
3940
3951
  })
3941
3952
  });
3942
3953
  if (!response.ok) {
@@ -20389,11 +20400,28 @@ function isWithinAllowedDirectories(filePath, permissions, workingDirectory) {
20389
20400
  function buildPermissionQuery(toolName, toolArgs) {
20390
20401
  switch (toolName) {
20391
20402
  case "Read":
20392
- case "read_file":
20393
20403
  case "Write":
20394
20404
  case "Edit":
20395
20405
  case "Glob":
20396
- case "Grep": {
20406
+ case "Grep":
20407
+ case "read_file":
20408
+ case "ReadFile":
20409
+ case "list_dir":
20410
+ case "ListDir":
20411
+ case "grep_files":
20412
+ case "GrepFiles":
20413
+ case "read_file_gemini":
20414
+ case "ReadFileGemini":
20415
+ case "write_file_gemini":
20416
+ case "WriteFileGemini":
20417
+ case "glob_gemini":
20418
+ case "GlobGemini":
20419
+ case "list_directory":
20420
+ case "ListDirectory":
20421
+ case "search_file_content":
20422
+ case "SearchFileContent":
20423
+ case "read_many_files":
20424
+ case "ReadManyFiles": {
20397
20425
  const filePath = extractFilePath(toolArgs);
20398
20426
  return filePath ? `${toolName}(${filePath})` : toolName;
20399
20427
  }
@@ -20418,15 +20446,7 @@ function extractShellCommand(toolArgs) {
20418
20446
  return null;
20419
20447
  }
20420
20448
  function matchesPattern(toolName, query, pattern, workingDirectory) {
20421
- if ([
20422
- "Read",
20423
- "read_file",
20424
- "Write",
20425
- "Edit",
20426
- "Glob",
20427
- "Grep",
20428
- "grep_files"
20429
- ].includes(toolName)) {
20449
+ if (FILE_TOOLS.includes(toolName)) {
20430
20450
  return matchesFilePattern(query, pattern, workingDirectory);
20431
20451
  }
20432
20452
  if (toolName === "Bash" || toolName === "shell" || toolName === "shell_command") {
@@ -20451,11 +20471,15 @@ function getDefaultDecision(toolName) {
20451
20471
  "ListDir",
20452
20472
  "GrepFiles",
20453
20473
  "UpdatePlan",
20474
+ "read_file_gemini",
20454
20475
  "list_directory",
20476
+ "glob_gemini",
20455
20477
  "search_file_content",
20456
20478
  "write_todos",
20457
20479
  "read_many_files",
20480
+ "ReadFileGemini",
20458
20481
  "ListDirectory",
20482
+ "GlobGemini",
20459
20483
  "SearchFileContent",
20460
20484
  "WriteTodos",
20461
20485
  "ReadManyFiles"
@@ -20465,14 +20489,34 @@ function getDefaultDecision(toolName) {
20465
20489
  }
20466
20490
  return "ask";
20467
20491
  }
20468
- var WORKING_DIRECTORY_TOOLS, READ_ONLY_SHELL_TOOLS;
20492
+ var WORKING_DIRECTORY_TOOLS, READ_ONLY_SHELL_TOOLS, FILE_TOOLS;
20469
20493
  var init_checker = __esm(() => {
20470
20494
  init_cli();
20471
20495
  init_matcher();
20472
20496
  init_mode();
20473
20497
  init_readOnlyShell();
20474
20498
  init_session();
20475
- WORKING_DIRECTORY_TOOLS = ["Read", "Glob", "Grep"];
20499
+ WORKING_DIRECTORY_TOOLS = [
20500
+ "Read",
20501
+ "Glob",
20502
+ "Grep",
20503
+ "read_file",
20504
+ "ReadFile",
20505
+ "list_dir",
20506
+ "ListDir",
20507
+ "grep_files",
20508
+ "GrepFiles",
20509
+ "read_file_gemini",
20510
+ "ReadFileGemini",
20511
+ "glob_gemini",
20512
+ "GlobGemini",
20513
+ "list_directory",
20514
+ "ListDirectory",
20515
+ "search_file_content",
20516
+ "SearchFileContent",
20517
+ "read_many_files",
20518
+ "ReadManyFiles"
20519
+ ];
20476
20520
  READ_ONLY_SHELL_TOOLS = new Set([
20477
20521
  "Bash",
20478
20522
  "shell",
@@ -20482,6 +20526,31 @@ var init_checker = __esm(() => {
20482
20526
  "run_shell_command",
20483
20527
  "RunShellCommand"
20484
20528
  ]);
20529
+ FILE_TOOLS = [
20530
+ "Read",
20531
+ "Write",
20532
+ "Edit",
20533
+ "Glob",
20534
+ "Grep",
20535
+ "read_file",
20536
+ "ReadFile",
20537
+ "list_dir",
20538
+ "ListDir",
20539
+ "grep_files",
20540
+ "GrepFiles",
20541
+ "read_file_gemini",
20542
+ "ReadFileGemini",
20543
+ "write_file_gemini",
20544
+ "WriteFileGemini",
20545
+ "glob_gemini",
20546
+ "GlobGemini",
20547
+ "list_directory",
20548
+ "ListDirectory",
20549
+ "search_file_content",
20550
+ "SearchFileContent",
20551
+ "read_many_files",
20552
+ "ReadManyFiles"
20553
+ ];
20485
20554
  });
20486
20555
 
20487
20556
  // src/permissions/loader.ts
@@ -20684,23 +20753,21 @@ function analyzeEditApproval(filePath, workingDir) {
20684
20753
  safetyLevel: "safe"
20685
20754
  };
20686
20755
  }
20756
+ function containsDangerousCommand(command) {
20757
+ const segments = command.split(/\s*(?:&&|\||;)\s*/);
20758
+ for (const segment of segments) {
20759
+ const baseCmd = segment.trim().split(/\s+/)[0] || "";
20760
+ if (DANGEROUS_COMMANDS.includes(baseCmd)) {
20761
+ return true;
20762
+ }
20763
+ }
20764
+ return false;
20765
+ }
20687
20766
  function analyzeBashApproval(command, _workingDir) {
20688
20767
  const parts = command.trim().split(/\s+/);
20689
20768
  const baseCommand = parts[0] || "";
20690
20769
  const firstArg = parts[1] || "";
20691
- const dangerousCommands = [
20692
- "rm",
20693
- "mv",
20694
- "chmod",
20695
- "chown",
20696
- "sudo",
20697
- "dd",
20698
- "mkfs",
20699
- "fdisk",
20700
- "kill",
20701
- "killall"
20702
- ];
20703
- if (baseCommand && dangerousCommands.includes(baseCommand)) {
20770
+ if (containsDangerousCommand(command)) {
20704
20771
  return {
20705
20772
  recommendedRule: "",
20706
20773
  ruleDescription: "",
@@ -20780,21 +20847,7 @@ function analyzeBashApproval(command, _workingDir) {
20780
20847
  };
20781
20848
  }
20782
20849
  }
20783
- const safeCommands = [
20784
- "ls",
20785
- "cat",
20786
- "pwd",
20787
- "echo",
20788
- "which",
20789
- "type",
20790
- "whoami",
20791
- "date",
20792
- "grep",
20793
- "find",
20794
- "head",
20795
- "tail"
20796
- ];
20797
- if (baseCommand && safeCommands.includes(baseCommand)) {
20850
+ if (baseCommand && SAFE_READONLY_COMMANDS.includes(baseCommand)) {
20798
20851
  return {
20799
20852
  recommendedRule: `Bash(${baseCommand}:*)`,
20800
20853
  ruleDescription: `'${baseCommand}' commands`,
@@ -20854,6 +20907,16 @@ function analyzeBashApproval(command, _workingDir) {
20854
20907
  };
20855
20908
  }
20856
20909
  }
20910
+ if (segmentBase && SAFE_READONLY_COMMANDS.includes(segmentBase)) {
20911
+ return {
20912
+ recommendedRule: `Bash(${segmentBase}:*)`,
20913
+ ruleDescription: `'${segmentBase}' commands`,
20914
+ approveAlwaysText: `Yes, and don't ask again for '${segmentBase}' commands in this project`,
20915
+ defaultScope: "project",
20916
+ allowPersistence: true,
20917
+ safetyLevel: "safe"
20918
+ };
20919
+ }
20857
20920
  }
20858
20921
  }
20859
20922
  const displayCommand = command.length > 40 ? `${command.slice(0, 40)}...` : command;
@@ -20921,7 +20984,39 @@ function analyzeDefaultApproval(toolName) {
20921
20984
  safetyLevel: "moderate"
20922
20985
  };
20923
20986
  }
20924
- var init_analyzer = () => {};
20987
+ var SAFE_READONLY_COMMANDS, DANGEROUS_COMMANDS;
20988
+ var init_analyzer = __esm(() => {
20989
+ SAFE_READONLY_COMMANDS = [
20990
+ "ls",
20991
+ "cat",
20992
+ "pwd",
20993
+ "echo",
20994
+ "which",
20995
+ "type",
20996
+ "whoami",
20997
+ "date",
20998
+ "grep",
20999
+ "find",
21000
+ "head",
21001
+ "tail",
21002
+ "wc",
21003
+ "diff",
21004
+ "file",
21005
+ "stat"
21006
+ ];
21007
+ DANGEROUS_COMMANDS = [
21008
+ "rm",
21009
+ "mv",
21010
+ "chmod",
21011
+ "chown",
21012
+ "sudo",
21013
+ "dd",
21014
+ "mkfs",
21015
+ "fdisk",
21016
+ "kill",
21017
+ "killall"
21018
+ ];
21019
+ });
20925
21020
 
20926
21021
  // src/tools/filter.ts
20927
21022
  var exports_filter = {};
@@ -21536,6 +21631,10 @@ var init_manager2 = __esm(() => {
21536
21631
  });
21537
21632
 
21538
21633
  // src/version.ts
21634
+ var exports_version = {};
21635
+ __export(exports_version, {
21636
+ getVersion: () => getVersion
21637
+ });
21539
21638
  function getVersion() {
21540
21639
  return package_default.version;
21541
21640
  }
@@ -21543,6 +21642,209 @@ var init_version = __esm(() => {
21543
21642
  init_package();
21544
21643
  });
21545
21644
 
21645
+ // src/agent/skills.ts
21646
+ var exports_skills2 = {};
21647
+ __export(exports_skills2, {
21648
+ formatSkillsForMemory: () => formatSkillsForMemory2,
21649
+ discoverSkills: () => discoverSkills2,
21650
+ SKILLS_DIR: () => SKILLS_DIR2
21651
+ });
21652
+ import { existsSync as existsSync4 } from "node:fs";
21653
+ import { readdir as readdir5, readFile as readFile5 } from "node:fs/promises";
21654
+ import { join as join10 } from "node:path";
21655
+ async function discoverSkills2(skillsPath = join10(process.cwd(), SKILLS_DIR2)) {
21656
+ const errors = [];
21657
+ if (!existsSync4(skillsPath)) {
21658
+ return { skills: [], errors: [] };
21659
+ }
21660
+ const skills = [];
21661
+ try {
21662
+ await findSkillFiles2(skillsPath, skillsPath, skills, errors);
21663
+ } catch (error) {
21664
+ errors.push({
21665
+ path: skillsPath,
21666
+ message: `Failed to read skills directory: ${error instanceof Error ? error.message : String(error)}`
21667
+ });
21668
+ }
21669
+ return { skills, errors };
21670
+ }
21671
+ async function findSkillFiles2(currentPath, rootPath, skills, errors) {
21672
+ try {
21673
+ const entries = await readdir5(currentPath, { withFileTypes: true });
21674
+ for (const entry of entries) {
21675
+ const fullPath = join10(currentPath, entry.name);
21676
+ if (entry.isDirectory()) {
21677
+ await findSkillFiles2(fullPath, rootPath, skills, errors);
21678
+ } else if (entry.isFile() && entry.name.toUpperCase() === "SKILL.MD") {
21679
+ try {
21680
+ const skill2 = await parseSkillFile2(fullPath, rootPath);
21681
+ if (skill2) {
21682
+ skills.push(skill2);
21683
+ }
21684
+ } catch (error) {
21685
+ errors.push({
21686
+ path: fullPath,
21687
+ message: error instanceof Error ? error.message : String(error)
21688
+ });
21689
+ }
21690
+ }
21691
+ }
21692
+ } catch (error) {
21693
+ errors.push({
21694
+ path: currentPath,
21695
+ message: `Failed to read directory: ${error instanceof Error ? error.message : String(error)}`
21696
+ });
21697
+ }
21698
+ }
21699
+ async function parseSkillFile2(filePath, rootPath) {
21700
+ const content = await readFile5(filePath, "utf-8");
21701
+ const { frontmatter, body } = parseFrontmatter(content);
21702
+ const normalizedRoot = rootPath.endsWith("/") ? rootPath.slice(0, -1) : rootPath;
21703
+ const relativePath = filePath.slice(normalizedRoot.length + 1);
21704
+ const dirPath = relativePath.slice(0, -"/SKILL.MD".length);
21705
+ const defaultId = dirPath || "root";
21706
+ const id = (typeof frontmatter.id === "string" ? frontmatter.id : null) || defaultId;
21707
+ const name = (typeof frontmatter.name === "string" ? frontmatter.name : null) || (typeof frontmatter.title === "string" ? frontmatter.title : null) || (id.split("/").pop() ?? "").replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
21708
+ let description = typeof frontmatter.description === "string" ? frontmatter.description : null;
21709
+ if (!description) {
21710
+ const firstParagraph = body.trim().split(`
21711
+
21712
+ `)[0];
21713
+ description = firstParagraph || "No description available";
21714
+ }
21715
+ description = description.trim();
21716
+ if (description.startsWith('"') && description.endsWith('"') || description.startsWith("'") && description.endsWith("'")) {
21717
+ description = description.slice(1, -1);
21718
+ }
21719
+ let tags;
21720
+ if (Array.isArray(frontmatter.tags)) {
21721
+ tags = frontmatter.tags;
21722
+ } else if (typeof frontmatter.tags === "string") {
21723
+ tags = [frontmatter.tags];
21724
+ }
21725
+ return {
21726
+ id,
21727
+ name,
21728
+ description,
21729
+ category: typeof frontmatter.category === "string" ? frontmatter.category : undefined,
21730
+ tags,
21731
+ path: filePath
21732
+ };
21733
+ }
21734
+ function formatSkillsForMemory2(skills, skillsDirectory) {
21735
+ let output = `Skills Directory: ${skillsDirectory}
21736
+
21737
+ `;
21738
+ if (skills.length === 0) {
21739
+ return `${output}[NO SKILLS AVAILABLE]`;
21740
+ }
21741
+ output += `Available Skills:
21742
+
21743
+ `;
21744
+ const categorized = new Map;
21745
+ const uncategorized = [];
21746
+ for (const skill2 of skills) {
21747
+ if (skill2.category) {
21748
+ const existing = categorized.get(skill2.category) || [];
21749
+ existing.push(skill2);
21750
+ categorized.set(skill2.category, existing);
21751
+ } else {
21752
+ uncategorized.push(skill2);
21753
+ }
21754
+ }
21755
+ for (const [category, categorySkills] of categorized) {
21756
+ output += `## ${category}
21757
+
21758
+ `;
21759
+ for (const skill2 of categorySkills) {
21760
+ output += formatSkill2(skill2);
21761
+ }
21762
+ output += `
21763
+ `;
21764
+ }
21765
+ if (uncategorized.length > 0) {
21766
+ if (categorized.size > 0) {
21767
+ output += `## Other
21768
+
21769
+ `;
21770
+ }
21771
+ for (const skill2 of uncategorized) {
21772
+ output += formatSkill2(skill2);
21773
+ }
21774
+ }
21775
+ return output.trim();
21776
+ }
21777
+ function formatSkill2(skill2) {
21778
+ let output = `### ${skill2.name}
21779
+ `;
21780
+ output += `ID: \`${skill2.id}\`
21781
+ `;
21782
+ output += `Description: ${skill2.description}
21783
+ `;
21784
+ if (skill2.tags && skill2.tags.length > 0) {
21785
+ output += `Tags: ${skill2.tags.map((t) => `\`${t}\``).join(", ")}
21786
+ `;
21787
+ }
21788
+ output += `
21789
+ `;
21790
+ return output;
21791
+ }
21792
+ var SKILLS_DIR2 = ".skills";
21793
+ var init_skills3 = () => {};
21794
+
21795
+ // src/utils/fs.ts
21796
+ var exports_fs = {};
21797
+ __export(exports_fs, {
21798
+ writeJsonFile: () => writeJsonFile,
21799
+ writeFile: () => writeFile2,
21800
+ readJsonFile: () => readJsonFile,
21801
+ readFile: () => readFile6,
21802
+ mkdir: () => mkdir2,
21803
+ exists: () => exists2
21804
+ });
21805
+ import {
21806
+ existsSync as existsSync5,
21807
+ readFileSync as fsReadFileSync2,
21808
+ writeFileSync as fsWriteFileSync2,
21809
+ mkdirSync as mkdirSync2
21810
+ } from "node:fs";
21811
+ import { dirname as dirname6 } from "node:path";
21812
+ async function readFile6(path15) {
21813
+ return fsReadFileSync2(path15, { encoding: "utf-8" });
21814
+ }
21815
+ async function writeFile2(path15, content) {
21816
+ const dir = dirname6(path15);
21817
+ if (!existsSync5(dir)) {
21818
+ mkdirSync2(dir, { recursive: true });
21819
+ }
21820
+ fsWriteFileSync2(path15, content, { encoding: "utf-8", flush: true });
21821
+ }
21822
+ function exists2(path15) {
21823
+ return existsSync5(path15);
21824
+ }
21825
+ async function mkdir2(path15, options) {
21826
+ mkdirSync2(path15, options);
21827
+ }
21828
+ async function readJsonFile(path15) {
21829
+ const text = await readFile6(path15);
21830
+ return JSON.parse(text);
21831
+ }
21832
+ async function writeJsonFile(path15, data, options) {
21833
+ const indent = options?.indent ?? 2;
21834
+ const content = `${JSON.stringify(data, null, indent)}
21835
+ `;
21836
+ await writeFile2(path15, content);
21837
+ }
21838
+ var init_fs2 = () => {};
21839
+
21840
+ // src/version.ts
21841
+ function getVersion2() {
21842
+ return package_default.version;
21843
+ }
21844
+ var init_version2 = __esm(() => {
21845
+ init_package();
21846
+ });
21847
+
21546
21848
  // src/updater/auto-update.ts
21547
21849
  var exports_auto_update = {};
21548
21850
  __export(exports_auto_update, {
@@ -21559,7 +21861,7 @@ function isRunningLocally() {
21559
21861
  return !argv.includes("node_modules");
21560
21862
  }
21561
21863
  async function checkForUpdate() {
21562
- const currentVersion = getVersion();
21864
+ const currentVersion = getVersion2();
21563
21865
  try {
21564
21866
  const { stdout } = await execAsync2("npm view @letta-ai/letta-code version", { timeout: 5000 });
21565
21867
  const latestVersion = stdout.trim();
@@ -21627,22 +21929,10 @@ async function manualUpdate() {
21627
21929
  }
21628
21930
  var execAsync2;
21629
21931
  var init_auto_update = __esm(() => {
21630
- init_version();
21932
+ init_version2();
21631
21933
  execAsync2 = promisify3(exec2);
21632
21934
  });
21633
21935
 
21634
- // src/version.ts
21635
- var exports_version = {};
21636
- __export(exports_version, {
21637
- getVersion: () => getVersion2
21638
- });
21639
- function getVersion2() {
21640
- return package_default.version;
21641
- }
21642
- var init_version2 = __esm(() => {
21643
- init_package();
21644
- });
21645
-
21646
21936
  // src/agent/promptAssets.ts
21647
21937
  var exports_promptAssets2 = {};
21648
21938
  __export(exports_promptAssets2, {
@@ -21770,9 +22060,9 @@ __export(exports_subagents2, {
21770
22060
  GLOBAL_AGENTS_DIR: () => GLOBAL_AGENTS_DIR2,
21771
22061
  AGENTS_DIR: () => AGENTS_DIR2
21772
22062
  });
21773
- import { existsSync as existsSync4 } from "node:fs";
21774
- import { readdir as readdir5, readFile as readFile5 } from "node:fs/promises";
21775
- import { join as join10 } from "node:path";
22063
+ import { existsSync as existsSync6 } from "node:fs";
22064
+ import { readdir as readdir6, readFile as readFile7 } from "node:fs/promises";
22065
+ import { join as join11 } from "node:path";
21776
22066
  function isValidName2(name) {
21777
22067
  return /^[a-z][a-z0-9-]*$/.test(name);
21778
22068
  }
@@ -21830,7 +22120,7 @@ function parseSubagentContent2(content) {
21830
22120
  };
21831
22121
  }
21832
22122
  async function parseSubagentFile2(filePath) {
21833
- const content = await readFile5(filePath, "utf-8");
22123
+ const content = await readFile7(filePath, "utf-8");
21834
22124
  return parseSubagentContent2(content);
21835
22125
  }
21836
22126
  function getBuiltinSubagents2() {
@@ -21853,16 +22143,16 @@ function getBuiltinSubagentNames2() {
21853
22143
  return new Set(Object.keys(getBuiltinSubagents2()));
21854
22144
  }
21855
22145
  async function discoverSubagentsFromDir2(agentsDir, seenNames, subagents, errors) {
21856
- if (!existsSync4(agentsDir)) {
22146
+ if (!existsSync6(agentsDir)) {
21857
22147
  return;
21858
22148
  }
21859
22149
  try {
21860
- const entries = await readdir5(agentsDir, { withFileTypes: true });
22150
+ const entries = await readdir6(agentsDir, { withFileTypes: true });
21861
22151
  for (const entry of entries) {
21862
22152
  if (!entry.isFile() || !entry.name.endsWith(".md")) {
21863
22153
  continue;
21864
22154
  }
21865
- const filePath = join10(agentsDir, entry.name);
22155
+ const filePath = join11(agentsDir, entry.name);
21866
22156
  try {
21867
22157
  const config = await parseSubagentFile2(filePath);
21868
22158
  if (config) {
@@ -21894,7 +22184,7 @@ async function discoverSubagents2(workingDirectory = process.cwd()) {
21894
22184
  const subagents = [];
21895
22185
  const seenNames = new Set;
21896
22186
  await discoverSubagentsFromDir2(GLOBAL_AGENTS_DIR2, seenNames, subagents, errors);
21897
- const projectAgentsDir = join10(workingDirectory, AGENTS_DIR2);
22187
+ const projectAgentsDir = join11(workingDirectory, AGENTS_DIR2);
21898
22188
  await discoverSubagentsFromDir2(projectAgentsDir, seenNames, subagents, errors);
21899
22189
  return { subagents, errors };
21900
22190
  }
@@ -21925,7 +22215,7 @@ var init_subagents2 = __esm(() => {
21925
22215
  init_general_purpose();
21926
22216
  init_plan();
21927
22217
  BUILTIN_SOURCES2 = [explore_default, general_purpose_default, plan_default];
21928
- GLOBAL_AGENTS_DIR2 = join10(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
22218
+ GLOBAL_AGENTS_DIR2 = join11(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
21929
22219
  VALID_MEMORY_BLOCKS2 = new Set(MEMORY_BLOCK_LABELS);
21930
22220
  cache2 = {
21931
22221
  builtins: null,
@@ -46943,7 +47233,7 @@ var init_open = __esm(() => {
46943
47233
  });
46944
47234
 
46945
47235
  // src/auth/setup-ui.tsx
46946
- import { hostname } from "node:os";
47236
+ import { hostname as hostname3 } from "node:os";
46947
47237
  function SetupUI({ onComplete }) {
46948
47238
  const [mode, setMode] = import_react22.useState("menu");
46949
47239
  const [selectedOption, setSelectedOption] = import_react22.useState(0);
@@ -46976,16 +47266,17 @@ function SetupUI({ onComplete }) {
46976
47266
  setVerificationUri(deviceData.verification_uri_complete);
46977
47267
  try {
46978
47268
  const { default: open2 } = await Promise.resolve().then(() => (init_open(), exports_open));
46979
- await open2(deviceData.verification_uri_complete);
46980
- } catch (openErr) {
46981
- console.error("Failed to auto-open browser:", openErr);
46982
- }
47269
+ const subprocess = await open2(deviceData.verification_uri_complete, {
47270
+ wait: false
47271
+ });
47272
+ subprocess.on("error", () => {});
47273
+ } catch (openErr) {}
46983
47274
  let deviceId = settingsManager.getSetting("deviceId");
46984
47275
  if (!deviceId) {
46985
47276
  deviceId = crypto.randomUUID();
46986
47277
  settingsManager.updateSettings({ deviceId });
46987
47278
  }
46988
- const deviceName = hostname();
47279
+ const deviceName = hostname3();
46989
47280
  pollForToken(deviceData.device_code, deviceData.interval, deviceData.expires_in, deviceId, deviceName).then((tokens) => {
46990
47281
  const now = Date.now();
46991
47282
  settingsManager.updateSettings({
@@ -47296,6 +47587,9 @@ var init_cli2 = __esm(() => {
47296
47587
  cliPermissions2 = new CliPermissions2;
47297
47588
  });
47298
47589
 
47590
+ // src/constants.ts
47591
+ var DEFAULT_AGENT_NAME = "letta-code-agent";
47592
+
47299
47593
  // src/tools/manager.ts
47300
47594
  var exports_manager2 = {};
47301
47595
  __export(exports_manager2, {
@@ -48112,8 +48406,8 @@ var SLEEPTIME_MEMORY_PERSONA = `I am a sleep-time memory management agent. I obs
48112
48406
  - Continue using memory policies that don't serve the user's actual needs`;
48113
48407
 
48114
48408
  // src/agent/create.ts
48115
- import { join as join11 } from "node:path";
48116
- async function createAgent(name = "letta-code-agent", model, embeddingModel = "openai/text-embedding-3-small", updateArgs, skillsDirectory, parallelToolCalls = true, enableSleeptime = false, systemPrompt, initBlocks, baseTools) {
48409
+ import { join as join12 } from "node:path";
48410
+ async function createAgent(name = DEFAULT_AGENT_NAME, model, embeddingModel = "openai/text-embedding-3-small", updateArgs, skillsDirectory, parallelToolCalls = true, enableSleeptime = false, systemPrompt, initBlocks, baseTools) {
48117
48411
  let modelHandle;
48118
48412
  if (model) {
48119
48413
  const resolved = resolveModel(model);
@@ -48164,7 +48458,7 @@ async function createAgent(name = "letta-code-agent", model, embeddingModel = "o
48164
48458
  }
48165
48459
  }
48166
48460
  const filteredMemoryBlocks = allowedBlockLabels && allowedBlockLabels.size > 0 ? defaultMemoryBlocks.filter((b) => allowedBlockLabels.has(b.label)) : defaultMemoryBlocks;
48167
- const resolvedSkillsDirectory = skillsDirectory || join11(process.cwd(), SKILLS_DIR);
48461
+ const resolvedSkillsDirectory = skillsDirectory || join12(process.cwd(), SKILLS_DIR);
48168
48462
  try {
48169
48463
  const { skills, errors } = await discoverSkills(resolvedSkillsDirectory);
48170
48464
  if (errors.length > 0) {
@@ -49203,17 +49497,17 @@ async function handleHeadlessCommand(argv, model, skillsDirectory) {
49203
49497
  setAgentContext2(agent.id, skillsDirectory);
49204
49498
  await initializeLoadedSkillsFlag2();
49205
49499
  try {
49206
- const { discoverSkills: discoverSkills2, formatSkillsForMemory: formatSkillsForMemory2, SKILLS_DIR: SKILLS_DIR2 } = await Promise.resolve().then(() => (init_skills2(), exports_skills));
49207
- const { join: join12 } = await import("node:path");
49208
- const resolvedSkillsDirectory = skillsDirectory || join12(process.cwd(), SKILLS_DIR2);
49209
- const { skills, errors } = await discoverSkills2(resolvedSkillsDirectory);
49500
+ const { discoverSkills: discoverSkills3, formatSkillsForMemory: formatSkillsForMemory3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills2(), exports_skills));
49501
+ const { join: join13 } = await import("node:path");
49502
+ const resolvedSkillsDirectory = skillsDirectory || join13(process.cwd(), SKILLS_DIR3);
49503
+ const { skills, errors } = await discoverSkills3(resolvedSkillsDirectory);
49210
49504
  if (errors.length > 0) {
49211
49505
  console.warn("Errors encountered during skill discovery:");
49212
49506
  for (const error of errors) {
49213
49507
  console.warn(` ${error.path}: ${error.message}`);
49214
49508
  }
49215
49509
  }
49216
- const formattedSkills = formatSkillsForMemory2(skills, resolvedSkillsDirectory);
49510
+ const formattedSkills = formatSkillsForMemory3(skills, resolvedSkillsDirectory);
49217
49511
  await client.agents.blocks.update("skills", {
49218
49512
  agent_id: agent.id,
49219
49513
  value: formattedSkills
@@ -49788,9 +50082,9 @@ var init_available_models = __esm(() => {
49788
50082
  });
49789
50083
 
49790
50084
  // src/settings.ts
49791
- import { join as join12 } from "node:path";
50085
+ import { join as join13 } from "node:path";
49792
50086
  function getProjectSettingsPath() {
49793
- return join12(process.cwd(), ".letta", "settings.local.json");
50087
+ return join13(process.cwd(), ".letta", "settings.local.json");
49794
50088
  }
49795
50089
  async function loadProjectSettings() {
49796
50090
  const settingsPath = getProjectSettingsPath();
@@ -49808,7 +50102,7 @@ async function loadProjectSettings() {
49808
50102
  }
49809
50103
  async function saveProjectSettings(settings) {
49810
50104
  const settingsPath = getProjectSettingsPath();
49811
- const dirPath = join12(process.cwd(), ".letta");
50105
+ const dirPath = join13(process.cwd(), ".letta");
49812
50106
  try {
49813
50107
  if (!exists(dirPath)) {
49814
50108
  await mkdir(dirPath, { recursive: true });
@@ -51905,7 +52199,7 @@ var init_build4 = __esm(async () => {
51905
52199
 
51906
52200
  // src/cli/helpers/clipboard.ts
51907
52201
  import { execFileSync as execFileSync2 } from "node:child_process";
51908
- import { existsSync as existsSync6, readFileSync as readFileSync2, statSync } from "node:fs";
52202
+ import { existsSync as existsSync8, readFileSync as readFileSync2, statSync } from "node:fs";
51909
52203
  import { basename as basename3, extname, isAbsolute as isAbsolute9, resolve as resolve15 } from "node:path";
51910
52204
  function countLines2(text) {
51911
52205
  return (text.match(/\r\n|\r|\n/g) || []).length + 1;
@@ -51956,7 +52250,7 @@ function translatePasteForImages(paste) {
51956
52250
  if (!isAbsolute9(filePath))
51957
52251
  filePath = resolve15(process.cwd(), filePath);
51958
52252
  const ext3 = extname(filePath || "").toLowerCase();
51959
- if (IMAGE_EXTS.has(ext3) && existsSync6(filePath) && statSync(filePath).isFile()) {
52253
+ if (IMAGE_EXTS.has(ext3) && existsSync8(filePath) && statSync(filePath).isFile()) {
51960
52254
  const buf = readFileSync2(filePath);
51961
52255
  const b64 = buf.toString("base64");
51962
52256
  const mt = ext3 === ".png" ? "image/png" : ext3 === ".jpg" || ext3 === ".jpeg" ? "image/jpeg" : ext3 === ".gif" ? "image/gif" : ext3 === ".webp" ? "image/webp" : ext3 === ".bmp" ? "image/bmp" : ext3 === ".svg" ? "image/svg+xml" : ext3 === ".tif" || ext3 === ".tiff" ? "image/tiff" : ext3 === ".heic" ? "image/heic" : ext3 === ".heif" ? "image/heif" : ext3 === ".avif" ? "image/avif" : "application/octet-stream";
@@ -52386,20 +52680,32 @@ function getHeaderLabel(toolName) {
52386
52680
  return "Plan update";
52387
52681
  if (t === "run_shell_command")
52388
52682
  return "Shell command";
52683
+ if (t === "read_file_gemini")
52684
+ return "Read File";
52389
52685
  if (t === "list_directory")
52390
52686
  return "List Directory";
52687
+ if (t === "glob_gemini")
52688
+ return "Find Files";
52391
52689
  if (t === "search_file_content")
52392
52690
  return "Search in Files";
52691
+ if (t === "write_file_gemini")
52692
+ return "Write File";
52393
52693
  if (t === "write_todos")
52394
52694
  return "Update Todos";
52395
52695
  if (t === "read_many_files")
52396
52696
  return "Read Multiple Files";
52397
52697
  if (t === "runshellcommand")
52398
52698
  return "Shell command";
52699
+ if (t === "readfilegemini")
52700
+ return "Read File";
52399
52701
  if (t === "listdirectory")
52400
52702
  return "List Directory";
52703
+ if (t === "globgemini")
52704
+ return "Find Files";
52401
52705
  if (t === "searchfilecontent")
52402
52706
  return "Search in Files";
52707
+ if (t === "writefilegemini")
52708
+ return "Write File";
52403
52709
  if (t === "writetodos")
52404
52710
  return "Update Todos";
52405
52711
  if (t === "readmanyfiles")
@@ -52582,7 +52888,7 @@ var import_react29, jsx_dev_runtime6, OptionsRenderer, DynamicPreview = ({
52582
52888
  }, undefined, true, undefined, this)
52583
52889
  }, undefined, false, undefined, this);
52584
52890
  }
52585
- if ((t === "write" || t === "edit" || t === "multiedit" || t === "replace" || t === "write_file" || t === "writefile") && parsedArgs) {
52891
+ if ((t === "write" || t === "edit" || t === "multiedit" || t === "replace" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini") && parsedArgs) {
52586
52892
  try {
52587
52893
  const filePath = String(parsedArgs.file_path || "");
52588
52894
  if (!filePath)
@@ -52591,7 +52897,7 @@ var import_react29, jsx_dev_runtime6, OptionsRenderer, DynamicPreview = ({
52591
52897
  return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
52592
52898
  flexDirection: "column",
52593
52899
  paddingLeft: 2,
52594
- children: t === "write" || t === "write_file" || t === "writefile" ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(AdvancedDiffRenderer, {
52900
+ children: t === "write" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini" ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(AdvancedDiffRenderer, {
52595
52901
  precomputed: precomputedDiff,
52596
52902
  kind: "write",
52597
52903
  filePath,
@@ -52614,7 +52920,7 @@ var import_react29, jsx_dev_runtime6, OptionsRenderer, DynamicPreview = ({
52614
52920
  }, undefined, false, undefined, this)
52615
52921
  }, undefined, false, undefined, this);
52616
52922
  }
52617
- if (t === "write" || t === "write_file" || t === "writefile") {
52923
+ if (t === "write" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini") {
52618
52924
  return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
52619
52925
  flexDirection: "column",
52620
52926
  paddingLeft: 2,
@@ -52655,7 +52961,7 @@ var import_react29, jsx_dev_runtime6, OptionsRenderer, DynamicPreview = ({
52655
52961
  }
52656
52962
  } catch {}
52657
52963
  }
52658
- if (t === "write" || t === "edit" || t === "multiedit" || t === "replace" || t === "write_file") {
52964
+ if (t === "write" || t === "edit" || t === "multiedit" || t === "replace" || t === "write_file" || t === "write_file_gemini" || t === "writefilegemini") {
52659
52965
  return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
52660
52966
  flexDirection: "column",
52661
52967
  paddingLeft: 2,
@@ -52825,7 +53131,7 @@ var init_ApprovalDialogRich = __esm(async () => {
52825
53131
  if (!parsedArgs || !approvalRequest)
52826
53132
  return null;
52827
53133
  const toolName = approvalRequest.toolName.toLowerCase();
52828
- if (toolName === "write") {
53134
+ if (toolName === "write" || toolName === "write_file" || toolName === "writefile" || toolName === "write_file_gemini" || toolName === "writefilegemini") {
52829
53135
  const result = computeAdvancedDiff({
52830
53136
  kind: "write",
52831
53137
  filePath: parsedArgs.file_path,
@@ -53486,7 +53792,8 @@ var init_CommandMessage = __esm(async () => {
53486
53792
  flexGrow: 1,
53487
53793
  width: Math.max(0, columns - 5),
53488
53794
  children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(MarkdownDisplay, {
53489
- text: line.output
53795
+ text: line.output,
53796
+ dimColor: line.dimOutput
53490
53797
  }, undefined, false, undefined, this)
53491
53798
  }, undefined, false, undefined, this)
53492
53799
  ]
@@ -56679,7 +56986,7 @@ var init_AgentInfoBar = __esm(async () => {
56679
56986
 
56680
56987
  // src/cli/helpers/fileSearch.ts
56681
56988
  import { readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
56682
- import { join as join13, resolve as resolve16 } from "node:path";
56989
+ import { join as join14, resolve as resolve16 } from "node:path";
56683
56990
  function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = []) {
56684
56991
  if (results.length >= maxResults) {
56685
56992
  return results;
@@ -56691,7 +56998,7 @@ function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = [])
56691
56998
  continue;
56692
56999
  }
56693
57000
  try {
56694
- const fullPath = join13(dir, entry);
57001
+ const fullPath = join14(dir, entry);
56695
57002
  const stats = statSync2(fullPath);
56696
57003
  const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
56697
57004
  const matches = pattern.length === 0 || relativePath.toLowerCase().includes(pattern.toLowerCase());
@@ -56743,7 +57050,7 @@ async function searchFiles(query, deep = false) {
56743
57050
  const matchingEntries = searchPattern.length === 0 ? entries : entries.filter((entry) => entry.toLowerCase().includes(searchPattern.toLowerCase()));
56744
57051
  for (const entry of matchingEntries.slice(0, 50)) {
56745
57052
  try {
56746
- const fullPath = join13(searchDir, entry);
57053
+ const fullPath = join14(searchDir, entry);
56747
57054
  const stats = statSync2(fullPath);
56748
57055
  const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
56749
57056
  results.push({
@@ -57087,7 +57394,7 @@ var init_registry = __esm(() => {
57087
57394
  }
57088
57395
  },
57089
57396
  "/exit": {
57090
- desc: "Exit and show session stats",
57397
+ desc: "Exit this session",
57091
57398
  handler: () => {
57092
57399
  return "Exiting...";
57093
57400
  }
@@ -57219,6 +57526,12 @@ var init_registry = __esm(() => {
57219
57526
  handler: () => {
57220
57527
  return "Opening memory viewer...";
57221
57528
  }
57529
+ },
57530
+ "/usage": {
57531
+ desc: "Show session usage statistics and balance",
57532
+ handler: () => {
57533
+ return "Fetching usage statistics...";
57534
+ }
57222
57535
  }
57223
57536
  };
57224
57537
  });
@@ -57953,7 +58266,7 @@ var init_InputRich = __esm(async () => {
57953
58266
  init_oauth();
57954
58267
  init_mode();
57955
58268
  init_settings_manager();
57956
- init_version();
58269
+ init_version2();
57957
58270
  init_useTerminalWidth();
57958
58271
  init_colors();
57959
58272
  await __promiseAll([
@@ -57967,7 +58280,7 @@ var init_InputRich = __esm(async () => {
57967
58280
  import_react43 = __toESM(require_react(), 1);
57968
58281
  jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
57969
58282
  Spinner2 = build_default2;
57970
- appVersion = getVersion();
58283
+ appVersion = getVersion2();
57971
58284
  stdin.setMaxListeners(20);
57972
58285
  EventEmitter4.defaultMaxListeners = 20;
57973
58286
  });
@@ -58906,8 +59219,217 @@ var init_ModelSelector = __esm(async () => {
58906
59219
  jsx_dev_runtime25 = __toESM(require_jsx_dev_runtime(), 1);
58907
59220
  });
58908
59221
 
59222
+ // src/cli/components/PinDialog.tsx
59223
+ function validateAgentName(name) {
59224
+ if (!name || !name.trim()) {
59225
+ return "Name cannot be empty";
59226
+ }
59227
+ const trimmed = name.trim();
59228
+ const validPattern = /^[\w '-]+$/u;
59229
+ if (!validPattern.test(trimmed)) {
59230
+ return "Name contains invalid characters. Only letters, digits, spaces, hyphens, underscores, and apostrophes are allowed.";
59231
+ }
59232
+ if (trimmed.length > 100) {
59233
+ return "Name is too long (max 100 characters)";
59234
+ }
59235
+ return null;
59236
+ }
59237
+ function isDefaultAgentName(name) {
59238
+ return name === DEFAULT_AGENT_NAME;
59239
+ }
59240
+ function PinDialog({
59241
+ currentName,
59242
+ local,
59243
+ onSubmit,
59244
+ onCancel
59245
+ }) {
59246
+ const isDefault = isDefaultAgentName(currentName);
59247
+ const [mode, setMode] = import_react47.useState(isDefault ? "input" : "choose");
59248
+ const [nameInput, setNameInput] = import_react47.useState("");
59249
+ const [selectedOption, setSelectedOption] = import_react47.useState(0);
59250
+ const [error, setError] = import_react47.useState("");
59251
+ const scopeText = local ? "to this project" : "globally";
59252
+ use_input_default((input, key) => {
59253
+ if (key.escape) {
59254
+ if (mode === "input" && !isDefault) {
59255
+ setMode("choose");
59256
+ setError("");
59257
+ } else {
59258
+ onCancel();
59259
+ }
59260
+ return;
59261
+ }
59262
+ if (mode === "choose") {
59263
+ if (input === "j" || key.downArrow) {
59264
+ setSelectedOption((prev) => Math.min(prev + 1, 1));
59265
+ } else if (input === "k" || key.upArrow) {
59266
+ setSelectedOption((prev) => Math.max(prev - 1, 0));
59267
+ } else if (key.return) {
59268
+ if (selectedOption === 0) {
59269
+ onSubmit(null);
59270
+ } else {
59271
+ setMode("input");
59272
+ }
59273
+ }
59274
+ }
59275
+ });
59276
+ const handleNameSubmit = (text) => {
59277
+ const trimmed = text.trim();
59278
+ const validationError = validateAgentName(trimmed);
59279
+ if (validationError) {
59280
+ setError(validationError);
59281
+ return;
59282
+ }
59283
+ onSubmit(trimmed);
59284
+ };
59285
+ if (isDefault || mode === "input") {
59286
+ return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59287
+ flexDirection: "column",
59288
+ paddingY: 1,
59289
+ children: [
59290
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59291
+ marginBottom: 1,
59292
+ children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59293
+ color: colors.approval.header,
59294
+ bold: true,
59295
+ children: isDefault ? "Name your agent" : "Rename your agent"
59296
+ }, undefined, false, undefined, this)
59297
+ }, undefined, false, undefined, this),
59298
+ isDefault && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59299
+ marginBottom: 1,
59300
+ children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59301
+ dimColor: true,
59302
+ children: [
59303
+ "Give your agent a memorable name before pinning ",
59304
+ scopeText,
59305
+ "."
59306
+ ]
59307
+ }, undefined, true, undefined, this)
59308
+ }, undefined, false, undefined, this),
59309
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59310
+ flexDirection: "column",
59311
+ marginBottom: 1,
59312
+ children: [
59313
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59314
+ marginBottom: 1,
59315
+ children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59316
+ children: "Enter a name:"
59317
+ }, undefined, false, undefined, this)
59318
+ }, undefined, false, undefined, this),
59319
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59320
+ children: [
59321
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59322
+ color: colors.approval.header,
59323
+ children: "> "
59324
+ }, undefined, false, undefined, this),
59325
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(PasteAwareTextInput, {
59326
+ value: nameInput,
59327
+ onChange: (val) => {
59328
+ setNameInput(val);
59329
+ setError("");
59330
+ },
59331
+ onSubmit: handleNameSubmit,
59332
+ placeholder: isDefault ? "e.g., my-coding-agent" : currentName
59333
+ }, undefined, false, undefined, this)
59334
+ ]
59335
+ }, undefined, true, undefined, this)
59336
+ ]
59337
+ }, undefined, true, undefined, this),
59338
+ error && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59339
+ marginBottom: 1,
59340
+ children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59341
+ color: "red",
59342
+ children: error
59343
+ }, undefined, false, undefined, this)
59344
+ }, undefined, false, undefined, this),
59345
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59346
+ children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59347
+ dimColor: true,
59348
+ children: [
59349
+ "Press Enter to confirm ",
59350
+ !isDefault && "• Esc to go back",
59351
+ isDefault && "• Esc to cancel"
59352
+ ]
59353
+ }, undefined, true, undefined, this)
59354
+ }, undefined, false, undefined, this)
59355
+ ]
59356
+ }, undefined, true, undefined, this);
59357
+ }
59358
+ return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59359
+ flexDirection: "column",
59360
+ paddingY: 1,
59361
+ children: [
59362
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59363
+ marginBottom: 1,
59364
+ children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59365
+ color: colors.approval.header,
59366
+ bold: true,
59367
+ children: [
59368
+ "Pin agent ",
59369
+ scopeText
59370
+ ]
59371
+ }, undefined, true, undefined, this)
59372
+ }, undefined, false, undefined, this),
59373
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59374
+ marginBottom: 1,
59375
+ children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59376
+ dimColor: true,
59377
+ children: "Would you like to keep the current name or change it?"
59378
+ }, undefined, false, undefined, this)
59379
+ }, undefined, false, undefined, this),
59380
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59381
+ flexDirection: "column",
59382
+ marginBottom: 1,
59383
+ children: [
59384
+ { label: `Keep name "${currentName}"`, value: "keep" },
59385
+ { label: "Change name", value: "change" }
59386
+ ].map((option, index) => {
59387
+ const isSelected = index === selectedOption;
59388
+ return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59389
+ flexDirection: "row",
59390
+ children: [
59391
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59392
+ width: 2,
59393
+ flexShrink: 0,
59394
+ children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59395
+ color: isSelected ? colors.approval.header : undefined,
59396
+ children: isSelected ? ">" : " "
59397
+ }, undefined, false, undefined, this)
59398
+ }, undefined, false, undefined, this),
59399
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59400
+ color: isSelected ? colors.approval.header : undefined,
59401
+ children: [
59402
+ index + 1,
59403
+ ". ",
59404
+ option.label
59405
+ ]
59406
+ }, undefined, true, undefined, this)
59407
+ ]
59408
+ }, option.value, true, undefined, this);
59409
+ })
59410
+ }, undefined, false, undefined, this),
59411
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59412
+ children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59413
+ dimColor: true,
59414
+ children: "↑↓/jk to select • Enter to confirm • Esc to cancel"
59415
+ }, undefined, false, undefined, this)
59416
+ }, undefined, false, undefined, this)
59417
+ ]
59418
+ }, undefined, true, undefined, this);
59419
+ }
59420
+ var import_react47, jsx_dev_runtime26;
59421
+ var init_PinDialog = __esm(async () => {
59422
+ init_colors();
59423
+ await __promiseAll([
59424
+ init_build2(),
59425
+ init_PasteAwareTextInput()
59426
+ ]);
59427
+ import_react47 = __toESM(require_react(), 1);
59428
+ jsx_dev_runtime26 = __toESM(require_jsx_dev_runtime(), 1);
59429
+ });
59430
+
58909
59431
  // src/cli/components/PlanModeDialog.tsx
58910
- var import_react47, jsx_dev_runtime26, OptionsRenderer2, PlanModeDialog;
59432
+ var import_react48, jsx_dev_runtime27, OptionsRenderer2, PlanModeDialog;
58911
59433
  var init_PlanModeDialog = __esm(async () => {
58912
59434
  init_pasteRegistry();
58913
59435
  init_colors();
@@ -58916,20 +59438,20 @@ var init_PlanModeDialog = __esm(async () => {
58916
59438
  init_MarkdownDisplay(),
58917
59439
  init_PasteAwareTextInput()
58918
59440
  ]);
58919
- import_react47 = __toESM(require_react(), 1);
58920
- jsx_dev_runtime26 = __toESM(require_jsx_dev_runtime(), 1);
58921
- OptionsRenderer2 = import_react47.memo(({
59441
+ import_react48 = __toESM(require_react(), 1);
59442
+ jsx_dev_runtime27 = __toESM(require_jsx_dev_runtime(), 1);
59443
+ OptionsRenderer2 = import_react48.memo(({
58922
59444
  options,
58923
59445
  selectedOption
58924
59446
  }) => {
58925
- return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59447
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
58926
59448
  flexDirection: "column",
58927
59449
  children: options.map((option, index) => {
58928
59450
  const isSelected = index === selectedOption;
58929
59451
  const color = isSelected ? colors.approval.header : undefined;
58930
- return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59452
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
58931
59453
  flexDirection: "row",
58932
- children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59454
+ children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
58933
59455
  color,
58934
59456
  children: [
58935
59457
  isSelected ? "❯" : " ",
@@ -58944,10 +59466,10 @@ var init_PlanModeDialog = __esm(async () => {
58944
59466
  }, undefined, false, undefined, this);
58945
59467
  });
58946
59468
  OptionsRenderer2.displayName = "OptionsRenderer";
58947
- PlanModeDialog = import_react47.memo(({ plan, onApprove, onApproveAndAcceptEdits, onKeepPlanning }) => {
58948
- const [selectedOption, setSelectedOption] = import_react47.useState(0);
58949
- const [isEnteringReason, setIsEnteringReason] = import_react47.useState(false);
58950
- const [denyReason, setDenyReason] = import_react47.useState("");
59469
+ PlanModeDialog = import_react48.memo(({ plan, onApprove, onApproveAndAcceptEdits, onKeepPlanning }) => {
59470
+ const [selectedOption, setSelectedOption] = import_react48.useState(0);
59471
+ const [isEnteringReason, setIsEnteringReason] = import_react48.useState(false);
59472
+ const [denyReason, setDenyReason] = import_react48.useState("");
58951
59473
  const options = [
58952
59474
  { label: "Yes, and auto-accept edits", action: onApproveAndAcceptEdits },
58953
59475
  { label: "Yes, and manually approve edits", action: onApprove },
@@ -58981,30 +59503,30 @@ var init_PlanModeDialog = __esm(async () => {
58981
59503
  }
58982
59504
  });
58983
59505
  if (isEnteringReason) {
58984
- return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59506
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
58985
59507
  flexDirection: "column",
58986
59508
  children: [
58987
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59509
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
58988
59510
  borderStyle: "round",
58989
59511
  borderColor: colors.approval.border,
58990
59512
  width: "100%",
58991
59513
  flexDirection: "column",
58992
59514
  paddingX: 1,
58993
59515
  children: [
58994
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59516
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
58995
59517
  bold: true,
58996
59518
  children: "Enter feedback to continue planning (ESC to cancel):"
58997
59519
  }, undefined, false, undefined, this),
58998
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59520
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
58999
59521
  height: 1
59000
59522
  }, undefined, false, undefined, this),
59001
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59523
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59002
59524
  children: [
59003
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59525
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59004
59526
  dimColor: true,
59005
59527
  children: "> "
59006
59528
  }, undefined, false, undefined, this),
59007
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(PasteAwareTextInput, {
59529
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(PasteAwareTextInput, {
59008
59530
  value: denyReason,
59009
59531
  onChange: setDenyReason
59010
59532
  }, undefined, false, undefined, this)
@@ -59012,49 +59534,49 @@ var init_PlanModeDialog = __esm(async () => {
59012
59534
  }, undefined, true, undefined, this)
59013
59535
  ]
59014
59536
  }, undefined, true, undefined, this),
59015
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59537
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59016
59538
  height: 1
59017
59539
  }, undefined, false, undefined, this)
59018
59540
  ]
59019
59541
  }, undefined, true, undefined, this);
59020
59542
  }
59021
- return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59543
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59022
59544
  flexDirection: "column",
59023
59545
  borderStyle: "round",
59024
59546
  borderColor: colors.approval.border,
59025
59547
  paddingX: 1,
59026
59548
  children: [
59027
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59549
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59028
59550
  bold: true,
59029
59551
  color: colors.approval.header,
59030
59552
  children: "Ready to code?"
59031
59553
  }, undefined, false, undefined, this),
59032
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59554
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59033
59555
  height: 1
59034
59556
  }, undefined, false, undefined, this),
59035
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59557
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59036
59558
  children: "Here's the proposed plan:"
59037
59559
  }, undefined, false, undefined, this),
59038
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59560
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59039
59561
  height: 1
59040
59562
  }, undefined, false, undefined, this),
59041
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59563
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59042
59564
  borderStyle: "round",
59043
59565
  paddingX: 1,
59044
- children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(MarkdownDisplay, {
59566
+ children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(MarkdownDisplay, {
59045
59567
  text: plan
59046
59568
  }, undefined, false, undefined, this)
59047
59569
  }, undefined, false, undefined, this),
59048
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59570
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59049
59571
  height: 1
59050
59572
  }, undefined, false, undefined, this),
59051
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
59573
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59052
59574
  children: "Would you like to proceed?"
59053
59575
  }, undefined, false, undefined, this),
59054
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
59576
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59055
59577
  height: 1
59056
59578
  }, undefined, false, undefined, this),
59057
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(OptionsRenderer2, {
59579
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(OptionsRenderer2, {
59058
59580
  options,
59059
59581
  selectedOption
59060
59582
  }, undefined, false, undefined, this)
@@ -59104,29 +59626,29 @@ function formatModel(agent) {
59104
59626
  }
59105
59627
  return "unknown";
59106
59628
  }
59107
- var import_react48, jsx_dev_runtime27, DISPLAY_PAGE_SIZE2 = 5, ProfileSelector;
59629
+ var import_react49, jsx_dev_runtime28, DISPLAY_PAGE_SIZE2 = 5, ProfileSelector;
59108
59630
  var init_ProfileSelector = __esm(async () => {
59109
59631
  init_client2();
59110
59632
  init_settings_manager();
59111
59633
  init_useTerminalWidth();
59112
59634
  init_colors();
59113
59635
  await init_build2();
59114
- import_react48 = __toESM(require_react(), 1);
59115
- jsx_dev_runtime27 = __toESM(require_jsx_dev_runtime(), 1);
59116
- ProfileSelector = import_react48.memo(function ProfileSelector2({
59636
+ import_react49 = __toESM(require_react(), 1);
59637
+ jsx_dev_runtime28 = __toESM(require_jsx_dev_runtime(), 1);
59638
+ ProfileSelector = import_react49.memo(function ProfileSelector2({
59117
59639
  currentAgentId,
59118
59640
  onSelect,
59119
59641
  onUnpin,
59120
59642
  onCancel
59121
59643
  }) {
59122
59644
  const terminalWidth = useTerminalWidth();
59123
- const [profiles, setProfiles] = import_react48.useState([]);
59124
- const [loading, setLoading] = import_react48.useState(true);
59125
- const [selectedIndex, setSelectedIndex] = import_react48.useState(0);
59126
- const [currentPage, setCurrentPage] = import_react48.useState(0);
59127
- const [mode, setMode] = import_react48.useState("browsing");
59128
- const [deleteConfirmIndex, setDeleteConfirmIndex] = import_react48.useState(0);
59129
- const loadProfiles = import_react48.useCallback(async () => {
59645
+ const [profiles, setProfiles] = import_react49.useState([]);
59646
+ const [loading, setLoading] = import_react49.useState(true);
59647
+ const [selectedIndex, setSelectedIndex] = import_react49.useState(0);
59648
+ const [currentPage, setCurrentPage] = import_react49.useState(0);
59649
+ const [mode, setMode] = import_react49.useState("browsing");
59650
+ const [deleteConfirmIndex, setDeleteConfirmIndex] = import_react49.useState(0);
59651
+ const loadProfiles = import_react49.useCallback(async () => {
59130
59652
  setLoading(true);
59131
59653
  try {
59132
59654
  const mergedPinned = settingsManager.getMergedPinnedAgents();
@@ -59160,7 +59682,7 @@ var init_ProfileSelector = __esm(async () => {
59160
59682
  setLoading(false);
59161
59683
  }
59162
59684
  }, []);
59163
- import_react48.useEffect(() => {
59685
+ import_react49.useEffect(() => {
59164
59686
  loadProfiles();
59165
59687
  }, [loadProfiles]);
59166
59688
  const totalPages = Math.ceil(profiles.length / DISPLAY_PAGE_SIZE2);
@@ -59225,19 +59747,19 @@ var init_ProfileSelector = __esm(async () => {
59225
59747
  });
59226
59748
  if (mode === "confirming-delete" && selectedProfile) {
59227
59749
  const options = ["Yes, unpin", "No, cancel"];
59228
- return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59750
+ return /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59229
59751
  flexDirection: "column",
59230
59752
  gap: 1,
59231
59753
  children: [
59232
- /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59233
- children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59754
+ /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59755
+ children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59234
59756
  bold: true,
59235
59757
  color: colors.selector.title,
59236
59758
  children: "Unpin Agent"
59237
59759
  }, undefined, false, undefined, this)
59238
59760
  }, undefined, false, undefined, this),
59239
- /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59240
- children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59761
+ /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59762
+ children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59241
59763
  children: [
59242
59764
  'Unpin "',
59243
59765
  selectedProfile.name,
@@ -59245,13 +59767,13 @@ var init_ProfileSelector = __esm(async () => {
59245
59767
  ]
59246
59768
  }, undefined, true, undefined, this)
59247
59769
  }, undefined, false, undefined, this),
59248
- /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59770
+ /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59249
59771
  flexDirection: "column",
59250
59772
  marginTop: 1,
59251
59773
  children: options.map((option, index) => {
59252
59774
  const isSelected = index === deleteConfirmIndex;
59253
- return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59254
- children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59775
+ return /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59776
+ children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59255
59777
  color: isSelected ? colors.selector.itemHighlighted : undefined,
59256
59778
  bold: isSelected,
59257
59779
  children: [
@@ -59266,44 +59788,44 @@ var init_ProfileSelector = __esm(async () => {
59266
59788
  ]
59267
59789
  }, undefined, true, undefined, this);
59268
59790
  }
59269
- return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59791
+ return /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59270
59792
  flexDirection: "column",
59271
59793
  gap: 1,
59272
59794
  children: [
59273
- /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59274
- children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59795
+ /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59796
+ children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59275
59797
  bold: true,
59276
59798
  color: colors.selector.title,
59277
59799
  children: "Pinned Agents"
59278
59800
  }, undefined, false, undefined, this)
59279
59801
  }, undefined, false, undefined, this),
59280
- loading && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59281
- children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59802
+ loading && /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59803
+ children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59282
59804
  dimColor: true,
59283
59805
  children: "Loading pinned agents..."
59284
59806
  }, undefined, false, undefined, this)
59285
59807
  }, undefined, false, undefined, this),
59286
- !loading && profiles.length === 0 && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59808
+ !loading && profiles.length === 0 && /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59287
59809
  flexDirection: "column",
59288
59810
  children: [
59289
- /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59811
+ /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59290
59812
  dimColor: true,
59291
59813
  children: "No agents pinned."
59292
59814
  }, undefined, false, undefined, this),
59293
- /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59815
+ /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59294
59816
  dimColor: true,
59295
59817
  children: "Press P to pin the current agent."
59296
59818
  }, undefined, false, undefined, this),
59297
- /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59819
+ /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59298
59820
  marginTop: 1,
59299
- children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59821
+ children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59300
59822
  dimColor: true,
59301
59823
  children: "Esc to close"
59302
59824
  }, undefined, false, undefined, this)
59303
59825
  }, undefined, false, undefined, this)
59304
59826
  ]
59305
59827
  }, undefined, true, undefined, this),
59306
- !loading && profiles.length > 0 && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59828
+ !loading && profiles.length > 0 && /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59307
59829
  flexDirection: "column",
59308
59830
  children: pageProfiles.map((profile, index) => {
59309
59831
  const isSelected = index === selectedIndex;
@@ -59313,26 +59835,26 @@ var init_ProfileSelector = __esm(async () => {
59313
59835
  const fixedChars = 2 + 3 + (isCurrent ? 10 : 0);
59314
59836
  const availableForId = Math.max(15, terminalWidth - nameLen - fixedChars);
59315
59837
  const displayId = truncateAgentId(profile.agentId, availableForId);
59316
- return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59838
+ return /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59317
59839
  flexDirection: "column",
59318
59840
  marginBottom: 1,
59319
59841
  children: [
59320
- /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59842
+ /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59321
59843
  flexDirection: "row",
59322
59844
  children: [
59323
- /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59845
+ /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59324
59846
  color: isSelected ? colors.selector.itemHighlighted : undefined,
59325
59847
  children: isSelected ? ">" : " "
59326
59848
  }, undefined, false, undefined, this),
59327
- /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59849
+ /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59328
59850
  children: " "
59329
59851
  }, undefined, false, undefined, this),
59330
- /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59852
+ /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59331
59853
  bold: isSelected,
59332
59854
  color: isSelected ? colors.selector.itemHighlighted : undefined,
59333
59855
  children: profile.name
59334
59856
  }, undefined, false, undefined, this),
59335
- /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59857
+ /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59336
59858
  dimColor: true,
59337
59859
  children: [
59338
59860
  " ",
@@ -59342,29 +59864,29 @@ var init_ProfileSelector = __esm(async () => {
59342
59864
  displayId
59343
59865
  ]
59344
59866
  }, undefined, true, undefined, this),
59345
- isCurrent && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59867
+ isCurrent && /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59346
59868
  color: colors.selector.itemCurrent,
59347
59869
  children: " (current)"
59348
59870
  }, undefined, false, undefined, this)
59349
59871
  ]
59350
59872
  }, undefined, true, undefined, this),
59351
- /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59873
+ /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59352
59874
  flexDirection: "row",
59353
59875
  marginLeft: 2,
59354
- children: hasAgent ? /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59876
+ children: hasAgent ? /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59355
59877
  dimColor: true,
59356
59878
  italic: true,
59357
59879
  children: profile.agent?.description || "No description"
59358
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59880
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59359
59881
  color: "red",
59360
59882
  italic: true,
59361
59883
  children: profile.error
59362
59884
  }, undefined, false, undefined, this)
59363
59885
  }, undefined, false, undefined, this),
59364
- hasAgent && profile.agent && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59886
+ hasAgent && profile.agent && /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59365
59887
  flexDirection: "row",
59366
59888
  marginLeft: 2,
59367
- children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59889
+ children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59368
59890
  dimColor: true,
59369
59891
  children: [
59370
59892
  formatRelativeTime2(profile.agent.last_run_completion),
@@ -59383,12 +59905,12 @@ var init_ProfileSelector = __esm(async () => {
59383
59905
  }, profile.agentId, true, undefined, this);
59384
59906
  })
59385
59907
  }, undefined, false, undefined, this),
59386
- !loading && profiles.length > 0 && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59908
+ !loading && profiles.length > 0 && /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59387
59909
  flexDirection: "column",
59388
59910
  marginTop: 1,
59389
59911
  children: [
59390
- totalPages > 1 && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59391
- children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59912
+ totalPages > 1 && /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59913
+ children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59392
59914
  dimColor: true,
59393
59915
  children: [
59394
59916
  "Page ",
@@ -59398,8 +59920,8 @@ var init_ProfileSelector = __esm(async () => {
59398
59920
  ]
59399
59921
  }, undefined, true, undefined, this)
59400
59922
  }, undefined, false, undefined, this),
59401
- /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
59402
- children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
59923
+ /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
59924
+ children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
59403
59925
  dimColor: true,
59404
59926
  children: "↑↓ navigate · Enter load · P unpin · D unpin all · Esc close"
59405
59927
  }, undefined, false, undefined, this)
@@ -59413,22 +59935,22 @@ var init_ProfileSelector = __esm(async () => {
59413
59935
  });
59414
59936
 
59415
59937
  // src/cli/components/QuestionDialog.tsx
59416
- var import_react49, jsx_dev_runtime28, QuestionDialog;
59938
+ var import_react50, jsx_dev_runtime29, QuestionDialog;
59417
59939
  var init_QuestionDialog = __esm(async () => {
59418
59940
  init_colors();
59419
59941
  await __promiseAll([
59420
59942
  init_build2(),
59421
59943
  init_PasteAwareTextInput()
59422
59944
  ]);
59423
- import_react49 = __toESM(require_react(), 1);
59424
- jsx_dev_runtime28 = __toESM(require_jsx_dev_runtime(), 1);
59425
- QuestionDialog = import_react49.memo(({ questions, onSubmit }) => {
59426
- const [currentQuestionIndex, setCurrentQuestionIndex] = import_react49.useState(0);
59427
- const [answers, setAnswers] = import_react49.useState({});
59428
- const [selectedOption, setSelectedOption] = import_react49.useState(0);
59429
- const [isOtherMode, setIsOtherMode] = import_react49.useState(false);
59430
- const [otherText, setOtherText] = import_react49.useState("");
59431
- const [selectedMulti, setSelectedMulti] = import_react49.useState(new Set);
59945
+ import_react50 = __toESM(require_react(), 1);
59946
+ jsx_dev_runtime29 = __toESM(require_jsx_dev_runtime(), 1);
59947
+ QuestionDialog = import_react50.memo(({ questions, onSubmit }) => {
59948
+ const [currentQuestionIndex, setCurrentQuestionIndex] = import_react50.useState(0);
59949
+ const [answers, setAnswers] = import_react50.useState({});
59950
+ const [selectedOption, setSelectedOption] = import_react50.useState(0);
59951
+ const [isOtherMode, setIsOtherMode] = import_react50.useState(false);
59952
+ const [otherText, setOtherText] = import_react50.useState("");
59953
+ const [selectedMulti, setSelectedMulti] = import_react50.useState(new Set);
59432
59954
  const currentQuestion = questions[currentQuestionIndex];
59433
59955
  const optionsWithOther = currentQuestion ? [
59434
59956
  ...currentQuestion.options,
@@ -59523,15 +60045,15 @@ var init_QuestionDialog = __esm(async () => {
59523
60045
  };
59524
60046
  if (!currentQuestion)
59525
60047
  return null;
59526
- return /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
60048
+ return /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
59527
60049
  flexDirection: "column",
59528
60050
  children: [
59529
- /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
60051
+ /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
59530
60052
  marginBottom: 1,
59531
- children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
60053
+ children: /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Text, {
59532
60054
  color: colors.approval.header,
59533
60055
  children: [
59534
- /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
60056
+ /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Text, {
59535
60057
  bold: true,
59536
60058
  children: [
59537
60059
  "[",
@@ -59544,9 +60066,9 @@ var init_QuestionDialog = __esm(async () => {
59544
60066
  ]
59545
60067
  }, undefined, true, undefined, this)
59546
60068
  }, undefined, false, undefined, this),
59547
- questions.length > 1 && /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
60069
+ questions.length > 1 && /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
59548
60070
  marginBottom: 1,
59549
- children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
60071
+ children: /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Text, {
59550
60072
  dimColor: true,
59551
60073
  children: [
59552
60074
  "Question ",
@@ -59556,21 +60078,21 @@ var init_QuestionDialog = __esm(async () => {
59556
60078
  ]
59557
60079
  }, undefined, true, undefined, this)
59558
60080
  }, undefined, false, undefined, this),
59559
- isOtherMode ? /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
60081
+ isOtherMode ? /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
59560
60082
  flexDirection: "column",
59561
60083
  children: [
59562
- /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
60084
+ /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Text, {
59563
60085
  dimColor: true,
59564
60086
  children: "Type your response (Esc to cancel):"
59565
60087
  }, undefined, false, undefined, this),
59566
- /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
60088
+ /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
59567
60089
  marginTop: 1,
59568
60090
  children: [
59569
- /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
60091
+ /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Text, {
59570
60092
  color: colors.approval.header,
59571
60093
  children: "> "
59572
60094
  }, undefined, false, undefined, this),
59573
- /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(PasteAwareTextInput, {
60095
+ /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(PasteAwareTextInput, {
59574
60096
  value: otherText,
59575
60097
  onChange: setOtherText,
59576
60098
  onSubmit: handleOtherSubmit
@@ -59578,32 +60100,32 @@ var init_QuestionDialog = __esm(async () => {
59578
60100
  ]
59579
60101
  }, undefined, true, undefined, this)
59580
60102
  ]
59581
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
60103
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
59582
60104
  flexDirection: "column",
59583
60105
  children: [
59584
60106
  optionsWithOther.map((option, index) => {
59585
60107
  const isSelected = index === selectedOption;
59586
60108
  const isChecked = selectedMulti.has(index);
59587
60109
  const color = isSelected ? colors.approval.header : undefined;
59588
- return /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
60110
+ return /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
59589
60111
  flexDirection: "column",
59590
60112
  marginBottom: index < optionsWithOther.length - 1 ? 1 : 0,
59591
60113
  children: [
59592
- /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
60114
+ /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
59593
60115
  flexDirection: "row",
59594
60116
  children: [
59595
- /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
60117
+ /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
59596
60118
  width: 2,
59597
60119
  flexShrink: 0,
59598
- children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
60120
+ children: /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Text, {
59599
60121
  color,
59600
60122
  children: isSelected ? ">" : " "
59601
60123
  }, undefined, false, undefined, this)
59602
60124
  }, undefined, false, undefined, this),
59603
- currentQuestion.multiSelect && index < optionsWithOther.length - 1 && /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
60125
+ currentQuestion.multiSelect && index < optionsWithOther.length - 1 && /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
59604
60126
  width: 4,
59605
60127
  flexShrink: 0,
59606
- children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
60128
+ children: /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Text, {
59607
60129
  color,
59608
60130
  children: [
59609
60131
  "[",
@@ -59612,9 +60134,9 @@ var init_QuestionDialog = __esm(async () => {
59612
60134
  ]
59613
60135
  }, undefined, true, undefined, this)
59614
60136
  }, undefined, false, undefined, this),
59615
- /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
60137
+ /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
59616
60138
  flexGrow: 1,
59617
- children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
60139
+ children: /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Text, {
59618
60140
  color,
59619
60141
  bold: isSelected,
59620
60142
  children: [
@@ -59626,9 +60148,9 @@ var init_QuestionDialog = __esm(async () => {
59626
60148
  }, undefined, false, undefined, this)
59627
60149
  ]
59628
60150
  }, undefined, true, undefined, this),
59629
- option.description && /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
60151
+ option.description && /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
59630
60152
  paddingLeft: currentQuestion.multiSelect ? 6 : 2,
59631
- children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
60153
+ children: /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Text, {
59632
60154
  dimColor: true,
59633
60155
  children: option.description
59634
60156
  }, undefined, false, undefined, this)
@@ -59636,9 +60158,9 @@ var init_QuestionDialog = __esm(async () => {
59636
60158
  ]
59637
60159
  }, option.label, true, undefined, this);
59638
60160
  }),
59639
- /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
60161
+ /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
59640
60162
  marginTop: 1,
59641
- children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
60163
+ children: /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Text, {
59642
60164
  dimColor: true,
59643
60165
  children: currentQuestion.multiSelect ? "Space to toggle, Enter to confirm selection" : `Enter to select, or type 1-${optionsWithOther.length}`
59644
60166
  }, undefined, false, undefined, this)
@@ -59652,7 +60174,7 @@ var init_QuestionDialog = __esm(async () => {
59652
60174
  });
59653
60175
 
59654
60176
  // src/cli/components/ReasoningMessageRich.tsx
59655
- var import_react50, jsx_dev_runtime29, normalize3 = (s) => s.replace(/\r\n/g, `
60177
+ var import_react51, jsx_dev_runtime30, normalize3 = (s) => s.replace(/\r\n/g, `
59656
60178
  `).replace(/[ \t]+$/gm, "").replace(/\n{3,}/g, `
59657
60179
 
59658
60180
  `).replace(/^\n+|\n+$/g, ""), ReasoningMessage;
@@ -59662,53 +60184,53 @@ var init_ReasoningMessageRich = __esm(async () => {
59662
60184
  init_build2(),
59663
60185
  init_MarkdownDisplay()
59664
60186
  ]);
59665
- import_react50 = __toESM(require_react(), 1);
59666
- jsx_dev_runtime29 = __toESM(require_jsx_dev_runtime(), 1);
59667
- ReasoningMessage = import_react50.memo(({ line }) => {
60187
+ import_react51 = __toESM(require_react(), 1);
60188
+ jsx_dev_runtime30 = __toESM(require_jsx_dev_runtime(), 1);
60189
+ ReasoningMessage = import_react51.memo(({ line }) => {
59668
60190
  const columns = useTerminalWidth();
59669
60191
  const contentWidth = Math.max(0, columns - 2);
59670
60192
  const normalizedText = normalize3(line.text);
59671
- return /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
60193
+ return /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
59672
60194
  flexDirection: "column",
59673
60195
  children: [
59674
- /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
60196
+ /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
59675
60197
  flexDirection: "row",
59676
60198
  children: [
59677
- /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
60199
+ /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
59678
60200
  width: 2,
59679
60201
  flexShrink: 0,
59680
- children: /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Text, {
60202
+ children: /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
59681
60203
  dimColor: true,
59682
60204
  children: "✻"
59683
60205
  }, undefined, false, undefined, this)
59684
60206
  }, undefined, false, undefined, this),
59685
- /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
60207
+ /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
59686
60208
  flexGrow: 1,
59687
60209
  width: contentWidth,
59688
- children: /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Text, {
60210
+ children: /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
59689
60211
  dimColor: true,
59690
60212
  children: "Thinking…"
59691
60213
  }, undefined, false, undefined, this)
59692
60214
  }, undefined, false, undefined, this)
59693
60215
  ]
59694
60216
  }, undefined, true, undefined, this),
59695
- /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
60217
+ /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
59696
60218
  height: 1
59697
60219
  }, undefined, false, undefined, this),
59698
- /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
60220
+ /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
59699
60221
  flexDirection: "row",
59700
60222
  children: [
59701
- /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
60223
+ /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
59702
60224
  width: 2,
59703
60225
  flexShrink: 0,
59704
- children: /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Text, {
60226
+ children: /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
59705
60227
  children: " "
59706
60228
  }, undefined, false, undefined, this)
59707
60229
  }, undefined, false, undefined, this),
59708
- /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Box_default, {
60230
+ /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
59709
60231
  flexGrow: 1,
59710
60232
  width: contentWidth,
59711
- children: /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(MarkdownDisplay, {
60233
+ children: /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(MarkdownDisplay, {
59712
60234
  text: normalizedText,
59713
60235
  dimColor: true
59714
60236
  }, undefined, false, undefined, this)
@@ -59767,18 +60289,18 @@ function ResumeSelector({
59767
60289
  onCancel
59768
60290
  }) {
59769
60291
  const terminalWidth = useTerminalWidth();
59770
- const [allAgents, setAllAgents] = import_react51.useState([]);
59771
- const [nextCursor, setNextCursor] = import_react51.useState(null);
59772
- const [currentPage, setCurrentPage] = import_react51.useState(0);
59773
- const [loading, setLoading] = import_react51.useState(true);
59774
- const [loadingMore, setLoadingMore] = import_react51.useState(false);
59775
- const [error, setError] = import_react51.useState(null);
59776
- const [selectedIndex, setSelectedIndex] = import_react51.useState(0);
59777
- const [searchInput, setSearchInput] = import_react51.useState("");
59778
- const [activeQuery, setActiveQuery] = import_react51.useState("");
59779
- const [hasMore, setHasMore] = import_react51.useState(true);
59780
- const clientRef = import_react51.useRef(null);
59781
- const fetchAgents = import_react51.useCallback(async (afterCursor, query) => {
60292
+ const [allAgents, setAllAgents] = import_react52.useState([]);
60293
+ const [nextCursor, setNextCursor] = import_react52.useState(null);
60294
+ const [currentPage, setCurrentPage] = import_react52.useState(0);
60295
+ const [loading, setLoading] = import_react52.useState(true);
60296
+ const [loadingMore, setLoadingMore] = import_react52.useState(false);
60297
+ const [error, setError] = import_react52.useState(null);
60298
+ const [selectedIndex, setSelectedIndex] = import_react52.useState(0);
60299
+ const [searchInput, setSearchInput] = import_react52.useState("");
60300
+ const [activeQuery, setActiveQuery] = import_react52.useState("");
60301
+ const [hasMore, setHasMore] = import_react52.useState(true);
60302
+ const clientRef = import_react52.useRef(null);
60303
+ const fetchAgents = import_react52.useCallback(async (afterCursor, query) => {
59782
60304
  const client = clientRef.current || await getClient2();
59783
60305
  clientRef.current = client;
59784
60306
  const agentList = await client.agents.list({
@@ -59796,7 +60318,7 @@ function ResumeSelector({
59796
60318
  nextCursor: cursor
59797
60319
  };
59798
60320
  }, []);
59799
- import_react51.useEffect(() => {
60321
+ import_react52.useEffect(() => {
59800
60322
  const doFetch = async () => {
59801
60323
  setLoading(true);
59802
60324
  try {
@@ -59814,18 +60336,18 @@ function ResumeSelector({
59814
60336
  };
59815
60337
  doFetch();
59816
60338
  }, [fetchAgents, activeQuery]);
59817
- const submitSearch = import_react51.useCallback(() => {
60339
+ const submitSearch = import_react52.useCallback(() => {
59818
60340
  if (searchInput !== activeQuery) {
59819
60341
  setActiveQuery(searchInput);
59820
60342
  }
59821
60343
  }, [searchInput, activeQuery]);
59822
- const clearSearch = import_react51.useCallback(() => {
60344
+ const clearSearch = import_react52.useCallback(() => {
59823
60345
  setSearchInput("");
59824
60346
  if (activeQuery) {
59825
60347
  setActiveQuery("");
59826
60348
  }
59827
60349
  }, [activeQuery]);
59828
- const fetchMoreAgents = import_react51.useCallback(async () => {
60350
+ const fetchMoreAgents = import_react52.useCallback(async () => {
59829
60351
  if (loadingMore || !hasMore || !nextCursor)
59830
60352
  return;
59831
60353
  setLoadingMore(true);
@@ -59887,72 +60409,72 @@ function ResumeSelector({
59887
60409
  setSearchInput((prev) => prev + input);
59888
60410
  }
59889
60411
  });
59890
- return /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
60412
+ return /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
59891
60413
  flexDirection: "column",
59892
60414
  gap: 1,
59893
60415
  children: [
59894
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
59895
- children: /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60416
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
60417
+ children: /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59896
60418
  bold: true,
59897
60419
  color: colors.selector.title,
59898
60420
  children: "Browsing Agents (sorting by last run)"
59899
60421
  }, undefined, false, undefined, this)
59900
60422
  }, undefined, false, undefined, this),
59901
- (searchInput || activeQuery) && /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
60423
+ (searchInput || activeQuery) && /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
59902
60424
  children: [
59903
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60425
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59904
60426
  dimColor: true,
59905
60427
  children: "Search: "
59906
60428
  }, undefined, false, undefined, this),
59907
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60429
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59908
60430
  children: searchInput
59909
60431
  }, undefined, false, undefined, this),
59910
- searchInput && searchInput !== activeQuery && /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60432
+ searchInput && searchInput !== activeQuery && /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59911
60433
  dimColor: true,
59912
60434
  children: " (press Enter to search)"
59913
60435
  }, undefined, false, undefined, this),
59914
- activeQuery && searchInput === activeQuery && /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60436
+ activeQuery && searchInput === activeQuery && /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59915
60437
  dimColor: true,
59916
60438
  children: " (Esc to clear)"
59917
60439
  }, undefined, false, undefined, this)
59918
60440
  ]
59919
60441
  }, undefined, true, undefined, this),
59920
- error && /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
60442
+ error && /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
59921
60443
  flexDirection: "column",
59922
60444
  children: [
59923
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60445
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59924
60446
  color: "red",
59925
60447
  children: [
59926
60448
  "Error: ",
59927
60449
  error
59928
60450
  ]
59929
60451
  }, undefined, true, undefined, this),
59930
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60452
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59931
60453
  dimColor: true,
59932
60454
  children: "Press ESC to cancel"
59933
60455
  }, undefined, false, undefined, this)
59934
60456
  ]
59935
60457
  }, undefined, true, undefined, this),
59936
- loading && !error && /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
59937
- children: /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60458
+ loading && !error && /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
60459
+ children: /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59938
60460
  dimColor: true,
59939
60461
  children: "Loading agents..."
59940
60462
  }, undefined, false, undefined, this)
59941
60463
  }, undefined, false, undefined, this),
59942
- !loading && !error && allAgents.length === 0 && /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
60464
+ !loading && !error && allAgents.length === 0 && /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
59943
60465
  flexDirection: "column",
59944
60466
  children: [
59945
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60467
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59946
60468
  dimColor: true,
59947
60469
  children: activeQuery ? "No matching agents found" : "No agents found"
59948
60470
  }, undefined, false, undefined, this),
59949
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60471
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59950
60472
  dimColor: true,
59951
60473
  children: "Press ESC to cancel"
59952
60474
  }, undefined, false, undefined, this)
59953
60475
  ]
59954
60476
  }, undefined, true, undefined, this),
59955
- !loading && !error && allAgents.length > 0 && /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
60477
+ !loading && !error && allAgents.length > 0 && /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
59956
60478
  flexDirection: "column",
59957
60479
  children: pageAgents.map((agent, index) => {
59958
60480
  const isSelected = index === selectedIndex;
@@ -59964,51 +60486,51 @@ function ResumeSelector({
59964
60486
  const fixedChars = 2 + 3 + (isCurrent ? 10 : 0);
59965
60487
  const availableForId = Math.max(15, terminalWidth - nameLen - fixedChars);
59966
60488
  const displayId = truncateAgentId2(agent.id, availableForId);
59967
- return /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
60489
+ return /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
59968
60490
  flexDirection: "column",
59969
60491
  marginBottom: 1,
59970
60492
  children: [
59971
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
60493
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
59972
60494
  flexDirection: "row",
59973
60495
  children: [
59974
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60496
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59975
60497
  color: isSelected ? colors.selector.itemHighlighted : undefined,
59976
60498
  children: isSelected ? ">" : " "
59977
60499
  }, undefined, false, undefined, this),
59978
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60500
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59979
60501
  children: " "
59980
60502
  }, undefined, false, undefined, this),
59981
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60503
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59982
60504
  bold: isSelected,
59983
60505
  color: isSelected ? colors.selector.itemHighlighted : undefined,
59984
60506
  children: agent.name || "Unnamed"
59985
60507
  }, undefined, false, undefined, this),
59986
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60508
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59987
60509
  dimColor: true,
59988
60510
  children: [
59989
60511
  " · ",
59990
60512
  displayId
59991
60513
  ]
59992
60514
  }, undefined, true, undefined, this),
59993
- isCurrent && /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60515
+ isCurrent && /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
59994
60516
  color: colors.selector.itemCurrent,
59995
60517
  children: " (current)"
59996
60518
  }, undefined, false, undefined, this)
59997
60519
  ]
59998
60520
  }, undefined, true, undefined, this),
59999
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
60521
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
60000
60522
  flexDirection: "row",
60001
60523
  marginLeft: 2,
60002
- children: /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60524
+ children: /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
60003
60525
  dimColor: true,
60004
60526
  italic: true,
60005
60527
  children: agent.description || "No description"
60006
60528
  }, undefined, false, undefined, this)
60007
60529
  }, undefined, false, undefined, this),
60008
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
60530
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
60009
60531
  flexDirection: "row",
60010
60532
  marginLeft: 2,
60011
- children: /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60533
+ children: /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
60012
60534
  dimColor: true,
60013
60535
  children: [
60014
60536
  relativeTime,
@@ -60025,12 +60547,12 @@ function ResumeSelector({
60025
60547
  }, agent.id, true, undefined, this);
60026
60548
  })
60027
60549
  }, undefined, false, undefined, this),
60028
- !loading && !error && allAgents.length > 0 && /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
60550
+ !loading && !error && allAgents.length > 0 && /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
60029
60551
  flexDirection: "column",
60030
60552
  marginTop: 1,
60031
60553
  children: [
60032
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
60033
- children: /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60554
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
60555
+ children: /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
60034
60556
  dimColor: true,
60035
60557
  children: [
60036
60558
  "Page ",
@@ -60040,8 +60562,8 @@ function ResumeSelector({
60040
60562
  ]
60041
60563
  }, undefined, true, undefined, this)
60042
60564
  }, undefined, false, undefined, this),
60043
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
60044
- children: /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
60565
+ /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
60566
+ children: /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
60045
60567
  dimColor: true,
60046
60568
  children: "↑↓ navigate · Enter to switch agents · J/K page · Type + Enter to search"
60047
60569
  }, undefined, false, undefined, this)
@@ -60051,14 +60573,14 @@ function ResumeSelector({
60051
60573
  ]
60052
60574
  }, undefined, true, undefined, this);
60053
60575
  }
60054
- var import_react51, jsx_dev_runtime30, DISPLAY_PAGE_SIZE3 = 5, FETCH_PAGE_SIZE = 20;
60576
+ var import_react52, jsx_dev_runtime31, DISPLAY_PAGE_SIZE3 = 5, FETCH_PAGE_SIZE = 20;
60055
60577
  var init_ResumeSelector = __esm(async () => {
60056
60578
  init_client2();
60057
60579
  init_useTerminalWidth();
60058
60580
  init_colors();
60059
60581
  await init_build2();
60060
- import_react51 = __toESM(require_react(), 1);
60061
- jsx_dev_runtime30 = __toESM(require_jsx_dev_runtime(), 1);
60582
+ import_react52 = __toESM(require_react(), 1);
60583
+ jsx_dev_runtime31 = __toESM(require_jsx_dev_runtime(), 1);
60062
60584
  });
60063
60585
 
60064
60586
  // src/cli/components/SessionStats.tsx
@@ -60066,70 +60588,50 @@ function formatDuration(ms) {
60066
60588
  if (ms < 1000) {
60067
60589
  return `${Math.round(ms)}ms`;
60068
60590
  }
60591
+ const totalSeconds = Math.floor(ms / 1000);
60592
+ const hours = Math.floor(totalSeconds / 3600);
60593
+ const minutes = Math.floor(totalSeconds % 3600 / 60);
60594
+ const seconds = totalSeconds % 60;
60595
+ if (hours > 0) {
60596
+ return `${hours}h ${minutes}m`;
60597
+ }
60598
+ if (minutes > 0) {
60599
+ return `${minutes}m ${seconds}s`;
60600
+ }
60069
60601
  return `${(ms / 1000).toFixed(1)}s`;
60070
60602
  }
60071
60603
  function formatNumber(n) {
60072
60604
  return n.toLocaleString();
60073
60605
  }
60074
- function SessionStats2({ stats, agentId }) {
60075
- const wallDuration = formatDuration(stats.totalWallMs);
60076
- const apiDuration = formatDuration(stats.totalApiMs);
60077
- return /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
60078
- flexDirection: "column",
60079
- paddingTop: 1,
60080
- children: [
60081
- /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
60082
- dimColor: true,
60083
- children: [
60084
- "Total duration (API): ",
60085
- apiDuration
60086
- ]
60087
- }, undefined, true, undefined, this),
60088
- /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
60089
- dimColor: true,
60090
- children: [
60091
- "Total duration (wall): ",
60092
- wallDuration
60093
- ]
60094
- }, undefined, true, undefined, this),
60095
- /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
60096
- dimColor: true,
60097
- children: [
60098
- "Usage: ",
60099
- stats.usage.stepCount,
60100
- " steps,",
60101
- " ",
60102
- formatNumber(stats.usage.promptTokens),
60103
- " input,",
60104
- " ",
60105
- formatNumber(stats.usage.completionTokens),
60106
- " output"
60107
- ]
60108
- }, undefined, true, undefined, this),
60109
- agentId && /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
60110
- dimColor: true,
60111
- children: [
60112
- "Agent ID: ",
60113
- agentId
60114
- ]
60115
- }, undefined, true, undefined, this)
60116
- ]
60117
- }, undefined, true, undefined, this);
60606
+ function formatUsageStats({
60607
+ stats,
60608
+ balance
60609
+ }) {
60610
+ const outputLines = [
60611
+ `Total duration (API): ${formatDuration(stats.totalApiMs)}`,
60612
+ `Total duration (wall): ${formatDuration(stats.totalWallMs)}`,
60613
+ `Session usage: ${stats.usage.stepCount} steps, ${formatNumber(stats.usage.promptTokens)} input, ${formatNumber(stats.usage.completionTokens)} output`,
60614
+ ""
60615
+ ];
60616
+ if (balance) {
60617
+ const totalCredits = Math.round(balance.total_balance);
60618
+ const monthlyCredits = Math.round(balance.monthly_credit_balance);
60619
+ const purchasedCredits = Math.round(balance.purchased_credit_balance);
60620
+ const toDollars = (credits) => (credits / 1000).toFixed(2);
60621
+ outputLines.push(`Available credits: ◎${formatNumber(totalCredits)} ($${toDollars(totalCredits)}) Plan: [${balance.billing_tier}]`, ` Monthly credits: ◎${formatNumber(monthlyCredits)} ($${toDollars(monthlyCredits)})`, ` Purchased credits: ◎${formatNumber(purchasedCredits)} ($${toDollars(purchasedCredits)})`, "", "https://app.letta.com/settings/organization/usage");
60622
+ }
60623
+ return outputLines.join(`
60624
+ `);
60118
60625
  }
60119
- var jsx_dev_runtime31;
60120
- var init_SessionStats = __esm(async () => {
60121
- await init_build2();
60122
- jsx_dev_runtime31 = __toESM(require_jsx_dev_runtime(), 1);
60123
- });
60124
60626
 
60125
60627
  // src/cli/components/StatusMessage.tsx
60126
- var import_react52, jsx_dev_runtime32, StatusMessage;
60628
+ var import_react53, jsx_dev_runtime32, StatusMessage;
60127
60629
  var init_StatusMessage = __esm(async () => {
60128
60630
  init_useTerminalWidth();
60129
60631
  await init_build2();
60130
- import_react52 = __toESM(require_react(), 1);
60632
+ import_react53 = __toESM(require_react(), 1);
60131
60633
  jsx_dev_runtime32 = __toESM(require_jsx_dev_runtime(), 1);
60132
- StatusMessage = import_react52.memo(({ line }) => {
60634
+ StatusMessage = import_react53.memo(({ line }) => {
60133
60635
  const columns = useTerminalWidth();
60134
60636
  const contentWidth = Math.max(0, columns - 2);
60135
60637
  return /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
@@ -60190,7 +60692,7 @@ function formatToolArgs(argsStr) {
60190
60692
  return "";
60191
60693
  }
60192
60694
  }
60193
- var import_react53, jsx_dev_runtime33, AgentRow, GroupHeader, SubagentGroupDisplay;
60695
+ var import_react54, jsx_dev_runtime33, AgentRow, GroupHeader, SubagentGroupDisplay;
60194
60696
  var init_SubagentGroupDisplay = __esm(async () => {
60195
60697
  init_subagentState();
60196
60698
  init_colors();
@@ -60198,9 +60700,9 @@ var init_SubagentGroupDisplay = __esm(async () => {
60198
60700
  init_build2(),
60199
60701
  init_BlinkDot()
60200
60702
  ]);
60201
- import_react53 = __toESM(require_react(), 1);
60703
+ import_react54 = __toESM(require_react(), 1);
60202
60704
  jsx_dev_runtime33 = __toESM(require_jsx_dev_runtime(), 1);
60203
- AgentRow = import_react53.memo(({ agent, isLast, expanded }) => {
60705
+ AgentRow = import_react54.memo(({ agent, isLast, expanded }) => {
60204
60706
  const { treeChar, continueChar } = getTreeChars(isLast);
60205
60707
  const getDotElement = () => {
60206
60708
  switch (agent.status) {
@@ -60337,7 +60839,7 @@ var init_SubagentGroupDisplay = __esm(async () => {
60337
60839
  }, undefined, true, undefined, this);
60338
60840
  });
60339
60841
  AgentRow.displayName = "AgentRow";
60340
- GroupHeader = import_react53.memo(({ count, allCompleted, expanded }) => {
60842
+ GroupHeader = import_react54.memo(({ count, allCompleted, expanded }) => {
60341
60843
  const statusText = allCompleted ? `Ran ${count} subagent${count !== 1 ? "s" : ""}` : `Running ${count} subagent${count !== 1 ? "s" : ""}…`;
60342
60844
  const hint = expanded ? "(ctrl+o to collapse)" : "(ctrl+o to expand)";
60343
60845
  return /* @__PURE__ */ jsx_dev_runtime33.jsxDEV(Box_default, {
@@ -60365,8 +60867,8 @@ var init_SubagentGroupDisplay = __esm(async () => {
60365
60867
  }, undefined, true, undefined, this);
60366
60868
  });
60367
60869
  GroupHeader.displayName = "GroupHeader";
60368
- SubagentGroupDisplay = import_react53.memo(() => {
60369
- const { agents, expanded } = import_react53.useSyncExternalStore(subscribe, getSnapshot);
60870
+ SubagentGroupDisplay = import_react54.memo(() => {
60871
+ const { agents, expanded } = import_react54.useSyncExternalStore(subscribe, getSnapshot);
60370
60872
  use_input_default((input, key) => {
60371
60873
  if (key.ctrl && input === "o") {
60372
60874
  toggleExpanded();
@@ -60397,13 +60899,13 @@ var init_SubagentGroupDisplay = __esm(async () => {
60397
60899
  });
60398
60900
 
60399
60901
  // src/cli/components/SubagentGroupStatic.tsx
60400
- var import_react54, jsx_dev_runtime34, AgentRow2, SubagentGroupStatic;
60902
+ var import_react55, jsx_dev_runtime34, AgentRow2, SubagentGroupStatic;
60401
60903
  var init_SubagentGroupStatic = __esm(async () => {
60402
60904
  init_colors();
60403
60905
  await init_build2();
60404
- import_react54 = __toESM(require_react(), 1);
60906
+ import_react55 = __toESM(require_react(), 1);
60405
60907
  jsx_dev_runtime34 = __toESM(require_jsx_dev_runtime(), 1);
60406
- AgentRow2 = import_react54.memo(({ agent, isLast }) => {
60908
+ AgentRow2 = import_react55.memo(({ agent, isLast }) => {
60407
60909
  const { treeChar, continueChar } = getTreeChars(isLast);
60408
60910
  const dotColor = agent.status === "completed" ? colors.subagent.completed : colors.subagent.error;
60409
60911
  const stats = formatStats(agent.toolCount, agent.totalTokens);
@@ -60485,7 +60987,7 @@ var init_SubagentGroupStatic = __esm(async () => {
60485
60987
  }, undefined, true, undefined, this);
60486
60988
  });
60487
60989
  AgentRow2.displayName = "AgentRow";
60488
- SubagentGroupStatic = import_react54.memo(({ agents }) => {
60990
+ SubagentGroupStatic = import_react55.memo(({ agents }) => {
60489
60991
  if (agents.length === 0) {
60490
60992
  return null;
60491
60993
  }
@@ -60521,11 +61023,11 @@ var init_SubagentGroupStatic = __esm(async () => {
60521
61023
 
60522
61024
  // src/cli/components/SubagentManager.tsx
60523
61025
  function SubagentManager({ onClose }) {
60524
- const [builtinSubagents, setBuiltinSubagents] = import_react55.useState([]);
60525
- const [customSubagents, setCustomSubagents] = import_react55.useState([]);
60526
- const [loading, setLoading] = import_react55.useState(true);
60527
- const [error, setError] = import_react55.useState(null);
60528
- import_react55.useEffect(() => {
61026
+ const [builtinSubagents, setBuiltinSubagents] = import_react56.useState([]);
61027
+ const [customSubagents, setCustomSubagents] = import_react56.useState([]);
61028
+ const [loading, setLoading] = import_react56.useState(true);
61029
+ const [error, setError] = import_react56.useState(null);
61030
+ import_react56.useEffect(() => {
60529
61031
  async function loadSubagents() {
60530
61032
  setLoading(true);
60531
61033
  setError(null);
@@ -60662,12 +61164,12 @@ function SubagentManager({ onClose }) {
60662
61164
  ]
60663
61165
  }, undefined, true, undefined, this);
60664
61166
  }
60665
- var import_react55, jsx_dev_runtime35;
61167
+ var import_react56, jsx_dev_runtime35;
60666
61168
  var init_SubagentManager = __esm(async () => {
60667
61169
  init_subagents();
60668
61170
  init_colors();
60669
61171
  await init_build2();
60670
- import_react55 = __toESM(require_react(), 1);
61172
+ import_react56 = __toESM(require_react(), 1);
60671
61173
  jsx_dev_runtime35 = __toESM(require_jsx_dev_runtime(), 1);
60672
61174
  });
60673
61175
 
@@ -60677,10 +61179,10 @@ function SystemPromptSelector({
60677
61179
  onSelect,
60678
61180
  onCancel
60679
61181
  }) {
60680
- const [showAll, setShowAll] = import_react56.useState(false);
60681
- const [selectedIndex, setSelectedIndex] = import_react56.useState(0);
60682
- const featuredPrompts = import_react56.useMemo(() => SYSTEM_PROMPTS.filter((prompt) => prompt.isFeatured), []);
60683
- const visiblePrompts = import_react56.useMemo(() => {
61182
+ const [showAll, setShowAll] = import_react57.useState(false);
61183
+ const [selectedIndex, setSelectedIndex] = import_react57.useState(0);
61184
+ const featuredPrompts = import_react57.useMemo(() => SYSTEM_PROMPTS.filter((prompt) => prompt.isFeatured), []);
61185
+ const visiblePrompts = import_react57.useMemo(() => {
60684
61186
  if (showAll)
60685
61187
  return SYSTEM_PROMPTS;
60686
61188
  if (featuredPrompts.length > 0)
@@ -60779,12 +61281,12 @@ function SystemPromptSelector({
60779
61281
  ]
60780
61282
  }, undefined, true, undefined, this);
60781
61283
  }
60782
- var import_react56, jsx_dev_runtime36;
61284
+ var import_react57, jsx_dev_runtime36;
60783
61285
  var init_SystemPromptSelector = __esm(async () => {
60784
61286
  init_promptAssets();
60785
61287
  init_colors();
60786
61288
  await init_build2();
60787
- import_react56 = __toESM(require_react(), 1);
61289
+ import_react57 = __toESM(require_react(), 1);
60788
61290
  jsx_dev_runtime36 = __toESM(require_jsx_dev_runtime(), 1);
60789
61291
  });
60790
61292
 
@@ -60904,20 +61406,32 @@ function getDisplayToolName(rawName) {
60904
61406
  return "Patch";
60905
61407
  if (rawName === "run_shell_command")
60906
61408
  return "Shell";
61409
+ if (rawName === "read_file_gemini")
61410
+ return "Read";
60907
61411
  if (rawName === "list_directory")
60908
61412
  return "LS";
61413
+ if (rawName === "glob_gemini")
61414
+ return "Glob";
60909
61415
  if (rawName === "search_file_content")
60910
61416
  return "Grep";
61417
+ if (rawName === "write_file_gemini")
61418
+ return "Write";
60911
61419
  if (rawName === "write_todos")
60912
61420
  return "TODO";
60913
61421
  if (rawName === "read_many_files")
60914
61422
  return "Read Multiple";
60915
61423
  if (rawName === "RunShellCommand")
60916
61424
  return "Shell";
61425
+ if (rawName === "ReadFileGemini")
61426
+ return "Read";
60917
61427
  if (rawName === "ListDirectory")
60918
61428
  return "LS";
61429
+ if (rawName === "GlobGemini")
61430
+ return "Glob";
60919
61431
  if (rawName === "SearchFileContent")
60920
61432
  return "Grep";
61433
+ if (rawName === "WriteFileGemini")
61434
+ return "Write";
60921
61435
  if (rawName === "WriteTodos")
60922
61436
  return "TODO";
60923
61437
  if (rawName === "ReadManyFiles")
@@ -61073,7 +61587,7 @@ var init_TodoRenderer = __esm(async () => {
61073
61587
  });
61074
61588
 
61075
61589
  // src/cli/components/ToolCallMessageRich.tsx
61076
- var import_react57, jsx_dev_runtime39, ToolCallMessage;
61590
+ var import_react58, jsx_dev_runtime39, ToolCallMessage;
61077
61591
  var init_ToolCallMessageRich = __esm(async () => {
61078
61592
  init_manager3();
61079
61593
  init_useTerminalWidth();
@@ -61085,9 +61599,9 @@ var init_ToolCallMessageRich = __esm(async () => {
61085
61599
  init_PlanRenderer(),
61086
61600
  init_TodoRenderer()
61087
61601
  ]);
61088
- import_react57 = __toESM(require_react(), 1);
61602
+ import_react58 = __toESM(require_react(), 1);
61089
61603
  jsx_dev_runtime39 = __toESM(require_jsx_dev_runtime(), 1);
61090
- ToolCallMessage = import_react57.memo(({ line }) => {
61604
+ ToolCallMessage = import_react58.memo(({ line }) => {
61091
61605
  const columns = useTerminalWidth();
61092
61606
  const rawName = line.name ?? "?";
61093
61607
  const argsText = line.argsText ?? "...";
@@ -61191,7 +61705,7 @@ var init_ToolCallMessageRich = __esm(async () => {
61191
61705
  const rec = isRecord5(t) ? t : {};
61192
61706
  const status = rec.status === "completed" ? "completed" : rec.status === "in_progress" ? "in_progress" : "pending";
61193
61707
  const id = typeof rec.id === "string" ? rec.id : String(i);
61194
- const content = typeof rec.content === "string" ? rec.content : JSON.stringify(t);
61708
+ const content = typeof rec.content === "string" ? rec.content : typeof rec.description === "string" ? rec.description : JSON.stringify(t);
61195
61709
  const priority = rec.priority === "high" ? "high" : rec.priority === "medium" ? "medium" : rec.priority === "low" ? "low" : undefined;
61196
61710
  return { content, status, id, priority };
61197
61711
  });
@@ -61307,10 +61821,10 @@ function ToolsetSelector({
61307
61821
  onSelect,
61308
61822
  onCancel
61309
61823
  }) {
61310
- const [showAll, setShowAll] = import_react58.useState(false);
61311
- const [selectedIndex, setSelectedIndex] = import_react58.useState(0);
61312
- const featuredToolsets = import_react58.useMemo(() => toolsets.filter((toolset) => toolset.isFeatured), []);
61313
- const visibleToolsets = import_react58.useMemo(() => {
61824
+ const [showAll, setShowAll] = import_react59.useState(false);
61825
+ const [selectedIndex, setSelectedIndex] = import_react59.useState(0);
61826
+ const featuredToolsets = import_react59.useMemo(() => toolsets.filter((toolset) => toolset.isFeatured), []);
61827
+ const visibleToolsets = import_react59.useMemo(() => {
61314
61828
  if (showAll)
61315
61829
  return toolsets;
61316
61830
  if (featuredToolsets.length > 0)
@@ -61418,11 +61932,11 @@ function ToolsetSelector({
61418
61932
  ]
61419
61933
  }, undefined, true, undefined, this);
61420
61934
  }
61421
- var import_react58, jsx_dev_runtime40, toolsets;
61935
+ var import_react59, jsx_dev_runtime40, toolsets;
61422
61936
  var init_ToolsetSelector = __esm(async () => {
61423
61937
  init_colors();
61424
61938
  await init_build2();
61425
- import_react58 = __toESM(require_react(), 1);
61939
+ import_react59 = __toESM(require_react(), 1);
61426
61940
  jsx_dev_runtime40 = __toESM(require_jsx_dev_runtime(), 1);
61427
61941
  toolsets = [
61428
61942
  {
@@ -61516,16 +62030,16 @@ var init_ToolsetSelector = __esm(async () => {
61516
62030
  });
61517
62031
 
61518
62032
  // src/cli/components/UserMessageRich.tsx
61519
- var import_react59, jsx_dev_runtime41, UserMessage;
62033
+ var import_react60, jsx_dev_runtime41, UserMessage;
61520
62034
  var init_UserMessageRich = __esm(async () => {
61521
62035
  init_useTerminalWidth();
61522
62036
  await __promiseAll([
61523
62037
  init_build2(),
61524
62038
  init_MarkdownDisplay()
61525
62039
  ]);
61526
- import_react59 = __toESM(require_react(), 1);
62040
+ import_react60 = __toESM(require_react(), 1);
61527
62041
  jsx_dev_runtime41 = __toESM(require_jsx_dev_runtime(), 1);
61528
- UserMessage = import_react59.memo(({ line }) => {
62042
+ UserMessage = import_react60.memo(({ line }) => {
61529
62043
  const columns = useTerminalWidth();
61530
62044
  const contentWidth = Math.max(0, columns - 2);
61531
62045
  return /* @__PURE__ */ jsx_dev_runtime41.jsxDEV(Box_default, {
@@ -61579,7 +62093,7 @@ function getAuthMethod() {
61579
62093
  }
61580
62094
  return "oauth";
61581
62095
  }
61582
- function getAgentStatusHints(continueSession, agentState, agentProvenance) {
62096
+ function getAgentStatusHints(continueSession, agentState, _agentProvenance) {
61583
62097
  const hints = [];
61584
62098
  if (continueSession) {
61585
62099
  if (agentState?.memory?.blocks) {
@@ -61593,12 +62107,6 @@ function getAgentStatusHints(continueSession, agentState, agentProvenance) {
61593
62107
  hints.push("→ To create a new agent, use --new");
61594
62108
  return hints;
61595
62109
  }
61596
- if (agentProvenance) {
61597
- const blockLabels = agentProvenance.blocks.map((b) => b.label);
61598
- if (blockLabels.length > 0) {
61599
- hints.push(`→ Initialized memory blocks: ${blockLabels.join(", ")}`);
61600
- }
61601
- }
61602
62110
  return hints;
61603
62111
  }
61604
62112
  function WelcomeScreen({
@@ -61609,7 +62117,7 @@ function WelcomeScreen({
61609
62117
  }) {
61610
62118
  useTerminalWidth();
61611
62119
  const cwd2 = process.cwd();
61612
- const version = getVersion();
62120
+ const version = getVersion2();
61613
62121
  const logoLines = asciiLogo.trim().split(`
61614
62122
  `);
61615
62123
  const tildePath = toTildePath(cwd2);
@@ -61684,7 +62192,7 @@ function getLoadingMessage(loadingState, continueSession) {
61684
62192
  var jsx_dev_runtime42;
61685
62193
  var init_WelcomeScreen = __esm(async () => {
61686
62194
  init_settings_manager();
61687
- init_version();
62195
+ init_version2();
61688
62196
  init_useTerminalWidth();
61689
62197
  init_colors();
61690
62198
  await init_build2();
@@ -61732,37 +62240,37 @@ function backfillBuffers(buffers, history) {
61732
62240
  const lineId = "otid" in msg && msg.otid ? msg.otid : msg.id;
61733
62241
  switch (msg.message_type) {
61734
62242
  case "user_message": {
61735
- const exists2 = buffers.byId.has(lineId);
62243
+ const exists3 = buffers.byId.has(lineId);
61736
62244
  buffers.byId.set(lineId, {
61737
62245
  kind: "user",
61738
62246
  id: lineId,
61739
62247
  text: renderUserContentParts(msg.content)
61740
62248
  });
61741
- if (!exists2)
62249
+ if (!exists3)
61742
62250
  buffers.order.push(lineId);
61743
62251
  break;
61744
62252
  }
61745
62253
  case "reasoning_message": {
61746
- const exists2 = buffers.byId.has(lineId);
62254
+ const exists3 = buffers.byId.has(lineId);
61747
62255
  buffers.byId.set(lineId, {
61748
62256
  kind: "reasoning",
61749
62257
  id: lineId,
61750
62258
  text: msg.reasoning,
61751
62259
  phase: "finished"
61752
62260
  });
61753
- if (!exists2)
62261
+ if (!exists3)
61754
62262
  buffers.order.push(lineId);
61755
62263
  break;
61756
62264
  }
61757
62265
  case "assistant_message": {
61758
- const exists2 = buffers.byId.has(lineId);
62266
+ const exists3 = buffers.byId.has(lineId);
61759
62267
  buffers.byId.set(lineId, {
61760
62268
  kind: "assistant",
61761
62269
  id: lineId,
61762
62270
  text: renderAssistantContentParts(msg.content),
61763
62271
  phase: "finished"
61764
62272
  });
61765
- if (!exists2)
62273
+ if (!exists3)
61766
62274
  buffers.order.push(lineId);
61767
62275
  break;
61768
62276
  }
@@ -61783,7 +62291,7 @@ function backfillBuffers(buffers, history) {
61783
62291
  uniqueLineId = `${lineId}-${toolCallId.slice(-8)}`;
61784
62292
  }
61785
62293
  }
61786
- const exists2 = buffers.byId.has(uniqueLineId);
62294
+ const exists3 = buffers.byId.has(uniqueLineId);
61787
62295
  buffers.byId.set(uniqueLineId, {
61788
62296
  kind: "tool_call",
61789
62297
  id: uniqueLineId,
@@ -61792,7 +62300,7 @@ function backfillBuffers(buffers, history) {
61792
62300
  argsText: toolCall.arguments,
61793
62301
  phase: "ready"
61794
62302
  });
61795
- if (!exists2)
62303
+ if (!exists3)
61796
62304
  buffers.order.push(uniqueLineId);
61797
62305
  buffers.toolCallIdToLineId.set(toolCallId, uniqueLineId);
61798
62306
  }
@@ -62087,8 +62595,8 @@ var init_thinkingMessages = __esm(() => {
62087
62595
  // src/cli/hooks/useSuspend/useSuspend.ts
62088
62596
  function useSuspend() {
62089
62597
  const { stdin: stdin2, isRawModeSupported } = use_stdin_default();
62090
- const [resumeKey, setResumeKey] = import_react60.useState(0);
62091
- const forceUpdate = import_react60.useCallback(() => {
62598
+ const [resumeKey, setResumeKey] = import_react61.useState(0);
62599
+ const forceUpdate = import_react61.useCallback(() => {
62092
62600
  setResumeKey((prev) => prev + 1);
62093
62601
  }, []);
62094
62602
  use_input_default((input, key) => {
@@ -62100,7 +62608,7 @@ function useSuspend() {
62100
62608
  return;
62101
62609
  }
62102
62610
  });
62103
- import_react60.useEffect(() => {
62611
+ import_react61.useEffect(() => {
62104
62612
  const handleResume = () => {
62105
62613
  if (stdin2 && isRawModeSupported && stdin2.setRawMode) {
62106
62614
  stdin2.setRawMode(true);
@@ -62115,25 +62623,25 @@ function useSuspend() {
62115
62623
  }, [stdin2, isRawModeSupported, forceUpdate]);
62116
62624
  return resumeKey;
62117
62625
  }
62118
- var import_react60;
62626
+ var import_react61;
62119
62627
  var init_useSuspend = __esm(async () => {
62120
62628
  await init_build2();
62121
- import_react60 = __toESM(require_react(), 1);
62629
+ import_react61 = __toESM(require_react(), 1);
62122
62630
  });
62123
62631
 
62124
62632
  // src/cli/hooks/useSyncedState.ts
62125
62633
  function useSyncedState(initialValue) {
62126
- const [state, setState] = import_react61.useState(initialValue);
62127
- const ref = import_react61.useRef(initialValue);
62128
- const setSyncedState = import_react61.useCallback((value) => {
62634
+ const [state, setState] = import_react62.useState(initialValue);
62635
+ const ref = import_react62.useRef(initialValue);
62636
+ const setSyncedState = import_react62.useCallback((value) => {
62129
62637
  ref.current = value;
62130
62638
  setState(value);
62131
62639
  }, []);
62132
62640
  return [state, setSyncedState, ref];
62133
62641
  }
62134
- var import_react61;
62642
+ var import_react62;
62135
62643
  var init_useSyncedState = __esm(() => {
62136
- import_react61 = __toESM(require_react(), 1);
62644
+ import_react62 = __toESM(require_react(), 1);
62137
62645
  });
62138
62646
 
62139
62647
  // src/tools/toolset.ts
@@ -62395,7 +62903,7 @@ function buildSessionContext(options) {
62395
62903
  const cwd2 = process.cwd();
62396
62904
  let version = "unknown";
62397
62905
  try {
62398
- version = getVersion();
62906
+ version = getVersion2();
62399
62907
  } catch {}
62400
62908
  let deviceType = "unknown";
62401
62909
  try {
@@ -62465,7 +62973,7 @@ ${gitInfo.status}
62465
62973
  var init_sessionContext = __esm(() => {
62466
62974
  init_oauth();
62467
62975
  init_settings_manager();
62468
- init_version();
62976
+ init_version2();
62469
62977
  });
62470
62978
 
62471
62979
  // src/cli/App.tsx
@@ -62473,10 +62981,17 @@ var exports_App = {};
62473
62981
  __export(exports_App, {
62474
62982
  default: () => App2
62475
62983
  });
62476
- import { existsSync as existsSync7, readFileSync as readFileSync3, writeFileSync } from "node:fs";
62984
+ import { existsSync as existsSync9, readFileSync as readFileSync3, writeFileSync } from "node:fs";
62477
62985
  function uid2(prefix) {
62478
62986
  return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
62479
62987
  }
62988
+ function saveLastAgentBeforeExit() {
62989
+ try {
62990
+ const currentAgentId = getCurrentAgentId();
62991
+ settingsManager.updateLocalProjectSettings({ lastAgent: currentAgentId });
62992
+ settingsManager.updateSettings({ lastAgent: currentAgentId });
62993
+ } catch {}
62994
+ }
62480
62995
  function getPlanModeReminder() {
62481
62996
  if (permissionMode2.getMode() !== "plan") {
62482
62997
  return "";
@@ -62532,14 +63047,14 @@ NOTE: At any point in time through this workflow you should feel free to ask the
62532
63047
  }
62533
63048
  function planFileExists() {
62534
63049
  const planFilePath = permissionMode2.getPlanFilePath();
62535
- return !!planFilePath && existsSync7(planFilePath);
63050
+ return !!planFilePath && existsSync9(planFilePath);
62536
63051
  }
62537
63052
  function readPlanFile() {
62538
63053
  const planFilePath = permissionMode2.getPlanFilePath();
62539
63054
  if (!planFilePath) {
62540
63055
  return "No plan file path set.";
62541
63056
  }
62542
- if (!existsSync7(planFilePath)) {
63057
+ if (!existsSync9(planFilePath)) {
62543
63058
  return `Plan file not found at ${planFilePath}`;
62544
63059
  }
62545
63060
  try {
@@ -62571,83 +63086,83 @@ function App2({
62571
63086
  tokenStreaming = false,
62572
63087
  agentProvenance = null
62573
63088
  }) {
62574
- import_react62.useEffect(() => {
63089
+ import_react63.useEffect(() => {
62575
63090
  prefetchAvailableModelHandles();
62576
63091
  }, []);
62577
- const [agentId, setAgentId] = import_react62.useState(initialAgentId);
62578
- const [agentState, setAgentState] = import_react62.useState(initialAgentState);
62579
- const agentIdRef = import_react62.useRef(agentId);
62580
- import_react62.useEffect(() => {
63092
+ const [agentId, setAgentId] = import_react63.useState(initialAgentId);
63093
+ const [agentState, setAgentState] = import_react63.useState(initialAgentState);
63094
+ const agentIdRef = import_react63.useRef(agentId);
63095
+ import_react63.useEffect(() => {
62581
63096
  agentIdRef.current = agentId;
62582
63097
  }, [agentId]);
62583
63098
  const resumeKey = useSuspend();
62584
- const prevInitialAgentIdRef = import_react62.useRef(initialAgentId);
62585
- const prevInitialAgentStateRef = import_react62.useRef(initialAgentState);
62586
- import_react62.useEffect(() => {
63099
+ const prevInitialAgentIdRef = import_react63.useRef(initialAgentId);
63100
+ const prevInitialAgentStateRef = import_react63.useRef(initialAgentState);
63101
+ import_react63.useEffect(() => {
62587
63102
  if (initialAgentId !== prevInitialAgentIdRef.current) {
62588
63103
  prevInitialAgentIdRef.current = initialAgentId;
62589
63104
  agentIdRef.current = initialAgentId;
62590
63105
  setAgentId(initialAgentId);
62591
63106
  }
62592
63107
  }, [initialAgentId]);
62593
- import_react62.useEffect(() => {
63108
+ import_react63.useEffect(() => {
62594
63109
  if (initialAgentState !== prevInitialAgentStateRef.current) {
62595
63110
  prevInitialAgentStateRef.current = initialAgentState;
62596
63111
  setAgentState(initialAgentState);
62597
63112
  }
62598
63113
  }, [initialAgentState]);
62599
- import_react62.useEffect(() => {
63114
+ import_react63.useEffect(() => {
62600
63115
  if (agentId) {
62601
63116
  setCurrentAgentId(agentId);
62602
63117
  }
62603
63118
  }, [agentId]);
62604
63119
  const [streaming, setStreaming, streamingRef] = useSyncedState(false);
62605
- const [interruptRequested, setInterruptRequested] = import_react62.useState(false);
63120
+ const [interruptRequested, setInterruptRequested] = import_react63.useState(false);
62606
63121
  const [commandRunning, setCommandRunning, commandRunningRef] = useSyncedState(false);
62607
- const [profileConfirmPending, setProfileConfirmPending] = import_react62.useState(null);
62608
- const [pendingApprovals, setPendingApprovals] = import_react62.useState([]);
62609
- const [approvalContexts, setApprovalContexts] = import_react62.useState([]);
62610
- const [approvalResults, setApprovalResults] = import_react62.useState([]);
62611
- const [isExecutingTool, setIsExecutingTool] = import_react62.useState(false);
62612
- const [queuedApprovalResults, setQueuedApprovalResults] = import_react62.useState(null);
62613
- const toolAbortControllerRef = import_react62.useRef(null);
62614
- const [autoHandledResults, setAutoHandledResults] = import_react62.useState([]);
62615
- const [autoDeniedApprovals, setAutoDeniedApprovals] = import_react62.useState([]);
63122
+ const [profileConfirmPending, setProfileConfirmPending] = import_react63.useState(null);
63123
+ const [pendingApprovals, setPendingApprovals] = import_react63.useState([]);
63124
+ const [approvalContexts, setApprovalContexts] = import_react63.useState([]);
63125
+ const [approvalResults, setApprovalResults] = import_react63.useState([]);
63126
+ const [isExecutingTool, setIsExecutingTool] = import_react63.useState(false);
63127
+ const [queuedApprovalResults, setQueuedApprovalResults] = import_react63.useState(null);
63128
+ const toolAbortControllerRef = import_react63.useRef(null);
63129
+ const [autoHandledResults, setAutoHandledResults] = import_react63.useState([]);
63130
+ const [autoDeniedApprovals, setAutoDeniedApprovals] = import_react63.useState([]);
62616
63131
  const currentApproval = pendingApprovals[approvalResults.length];
62617
- const [activeOverlay, setActiveOverlay] = import_react62.useState(null);
62618
- const closeOverlay = import_react62.useCallback(() => setActiveOverlay(null), []);
63132
+ const [activeOverlay, setActiveOverlay] = import_react63.useState(null);
63133
+ const closeOverlay = import_react63.useCallback(() => setActiveOverlay(null), []);
63134
+ const [pinDialogLocal, setPinDialogLocal] = import_react63.useState(false);
62619
63135
  const anySelectorOpen = activeOverlay !== null;
62620
- const [currentSystemPromptId, setCurrentSystemPromptId] = import_react62.useState("default");
62621
- const [currentToolset, setCurrentToolset] = import_react62.useState(null);
62622
- const [llmConfig, setLlmConfig] = import_react62.useState(null);
62623
- const [agentName, setAgentName] = import_react62.useState(null);
62624
- const [agentDescription, setAgentDescription] = import_react62.useState(null);
62625
- const [agentLastRunAt, setAgentLastRunAt] = import_react62.useState(null);
63136
+ const [currentSystemPromptId, setCurrentSystemPromptId] = import_react63.useState("default");
63137
+ const [currentToolset, setCurrentToolset] = import_react63.useState(null);
63138
+ const [llmConfig, setLlmConfig] = import_react63.useState(null);
63139
+ const [agentName, setAgentName] = import_react63.useState(null);
63140
+ const [agentDescription, setAgentDescription] = import_react63.useState(null);
63141
+ const [agentLastRunAt, setAgentLastRunAt] = import_react63.useState(null);
62626
63142
  const currentModelLabel = llmConfig?.model_endpoint_type && llmConfig?.model ? `${llmConfig.model_endpoint_type}/${llmConfig.model}` : llmConfig?.model ?? null;
62627
63143
  const currentModelDisplay = currentModelLabel?.split("/").pop() ?? null;
62628
- const [tokenStreamingEnabled, setTokenStreamingEnabled] = import_react62.useState(tokenStreaming);
62629
- const [tokenCount, setTokenCount] = import_react62.useState(0);
62630
- const [thinkingMessage, setThinkingMessage] = import_react62.useState(getRandomThinkingMessage(agentName));
62631
- const sessionStatsRef = import_react62.useRef(new SessionStats);
62632
- const hasSentSessionContextRef = import_react62.useRef(false);
62633
- const [showExitStats, setShowExitStats] = import_react62.useState(false);
62634
- const [staticItems, setStaticItems] = import_react62.useState([]);
62635
- const emittedIdsRef = import_react62.useRef(new Set);
62636
- const welcomeCommittedRef = import_react62.useRef(false);
62637
- const abortControllerRef = import_react62.useRef(null);
62638
- const userCancelledRef = import_react62.useRef(false);
62639
- const [messageQueue, setMessageQueue] = import_react62.useState([]);
62640
- const waitingForQueueCancelRef = import_react62.useRef(false);
62641
- const queueSnapshotRef = import_react62.useRef([]);
62642
- const [restoreQueueOnCancel, setRestoreQueueOnCancel] = import_react62.useState(false);
62643
- const restoreQueueOnCancelRef = import_react62.useRef(restoreQueueOnCancel);
62644
- import_react62.useEffect(() => {
63144
+ const [tokenStreamingEnabled, setTokenStreamingEnabled] = import_react63.useState(tokenStreaming);
63145
+ const [tokenCount, setTokenCount] = import_react63.useState(0);
63146
+ const [thinkingMessage, setThinkingMessage] = import_react63.useState(getRandomThinkingMessage(agentName));
63147
+ const sessionStatsRef = import_react63.useRef(new SessionStats);
63148
+ const hasSentSessionContextRef = import_react63.useRef(false);
63149
+ const [staticItems, setStaticItems] = import_react63.useState([]);
63150
+ const emittedIdsRef = import_react63.useRef(new Set);
63151
+ const welcomeCommittedRef = import_react63.useRef(false);
63152
+ const abortControllerRef = import_react63.useRef(null);
63153
+ const userCancelledRef = import_react63.useRef(false);
63154
+ const [messageQueue, setMessageQueue] = import_react63.useState([]);
63155
+ const waitingForQueueCancelRef = import_react63.useRef(false);
63156
+ const queueSnapshotRef = import_react63.useRef([]);
63157
+ const [restoreQueueOnCancel, setRestoreQueueOnCancel] = import_react63.useState(false);
63158
+ const restoreQueueOnCancelRef = import_react63.useRef(restoreQueueOnCancel);
63159
+ import_react63.useEffect(() => {
62645
63160
  restoreQueueOnCancelRef.current = restoreQueueOnCancel;
62646
63161
  }, [restoreQueueOnCancel]);
62647
- const isAgentBusy = import_react62.useCallback(() => {
63162
+ const isAgentBusy = import_react63.useCallback(() => {
62648
63163
  return streamingRef.current || isExecutingTool || commandRunningRef.current || abortControllerRef.current !== null;
62649
63164
  }, [isExecutingTool]);
62650
- const withCommandLock = import_react62.useCallback(async (asyncFn) => {
63165
+ const withCommandLock = import_react63.useCallback(async (asyncFn) => {
62651
63166
  setActiveOverlay(null);
62652
63167
  setCommandRunning(true);
62653
63168
  try {
@@ -62657,9 +63172,9 @@ function App2({
62657
63172
  }
62658
63173
  }, [setCommandRunning]);
62659
63174
  const columns = useTerminalWidth();
62660
- const prevColumnsRef = import_react62.useRef(columns);
62661
- const [staticRenderEpoch, setStaticRenderEpoch] = import_react62.useState(0);
62662
- import_react62.useEffect(() => {
63175
+ const prevColumnsRef = import_react63.useRef(columns);
63176
+ const [staticRenderEpoch, setStaticRenderEpoch] = import_react63.useState(0);
63177
+ import_react63.useEffect(() => {
62663
63178
  const prev = prevColumnsRef.current;
62664
63179
  if (columns === prev)
62665
63180
  return;
@@ -62669,7 +63184,7 @@ function App2({
62669
63184
  setStaticRenderEpoch((epoch) => epoch + 1);
62670
63185
  prevColumnsRef.current = columns;
62671
63186
  }, [columns]);
62672
- const commitEligibleLines = import_react62.useCallback((b) => {
63187
+ const commitEligibleLines = import_react63.useCallback((b) => {
62673
63188
  const newlyCommitted = [];
62674
63189
  let firstTaskIndex = -1;
62675
63190
  const hasInProgress = hasInProgressTaskToolCalls(b.order, b.byId, emittedIdsRef.current);
@@ -62715,17 +63230,17 @@ function App2({
62715
63230
  setStaticItems((prev) => [...prev, ...newlyCommitted]);
62716
63231
  }
62717
63232
  }, []);
62718
- const [lines, setLines] = import_react62.useState([]);
62719
- const buffersRef = import_react62.useRef(createBuffers());
62720
- const hasBackfilledRef = import_react62.useRef(false);
62721
- const refreshDerived = import_react62.useCallback(() => {
63233
+ const [lines, setLines] = import_react63.useState([]);
63234
+ const buffersRef = import_react63.useRef(createBuffers());
63235
+ const hasBackfilledRef = import_react63.useRef(false);
63236
+ const refreshDerived = import_react63.useCallback(() => {
62722
63237
  const b = buffersRef.current;
62723
63238
  setTokenCount(b.tokenCount);
62724
63239
  const newLines = toLines(b);
62725
63240
  setLines(newLines);
62726
63241
  commitEligibleLines(b);
62727
63242
  }, [commitEligibleLines]);
62728
- const refreshDerivedThrottled = import_react62.useCallback(() => {
63243
+ const refreshDerivedThrottled = import_react63.useCallback(() => {
62729
63244
  if (!buffersRef.current.pendingRefresh) {
62730
63245
  buffersRef.current.pendingRefresh = true;
62731
63246
  setTimeout(() => {
@@ -62734,7 +63249,7 @@ function App2({
62734
63249
  }, 16);
62735
63250
  }
62736
63251
  }, [refreshDerived]);
62737
- import_react62.useEffect(() => {
63252
+ import_react63.useEffect(() => {
62738
63253
  const approvals = startupApprovals?.length > 0 ? startupApprovals : startupApproval ? [startupApproval] : [];
62739
63254
  if (loadingState === "ready" && approvals.length > 0) {
62740
63255
  setPendingApprovals(approvals);
@@ -62752,7 +63267,7 @@ function App2({
62752
63267
  analyzeStartupApprovals();
62753
63268
  }
62754
63269
  }, [loadingState, startupApproval, startupApprovals]);
62755
- import_react62.useEffect(() => {
63270
+ import_react63.useEffect(() => {
62756
63271
  if (loadingState === "ready" && messageHistory.length > 0 && !hasBackfilledRef.current) {
62757
63272
  hasBackfilledRef.current = true;
62758
63273
  if (!welcomeCommittedRef.current) {
@@ -62801,7 +63316,7 @@ function App2({
62801
63316
  agentState,
62802
63317
  agentProvenance
62803
63318
  ]);
62804
- import_react62.useEffect(() => {
63319
+ import_react63.useEffect(() => {
62805
63320
  if (loadingState === "ready" && agentId && agentId !== "loading") {
62806
63321
  const fetchConfig = async () => {
62807
63322
  try {
@@ -62825,7 +63340,7 @@ function App2({
62825
63340
  fetchConfig();
62826
63341
  }
62827
63342
  }, [loadingState, agentId]);
62828
- const appendError = import_react62.useCallback((message) => {
63343
+ const appendError = import_react63.useCallback((message) => {
62829
63344
  const id = uid2("err");
62830
63345
  buffersRef.current.byId.set(id, {
62831
63346
  kind: "error",
@@ -62835,7 +63350,7 @@ function App2({
62835
63350
  buffersRef.current.order.push(id);
62836
63351
  refreshDerived();
62837
63352
  }, [refreshDerived]);
62838
- const processConversation = import_react62.useCallback(async (initialInput) => {
63353
+ const processConversation = import_react63.useCallback(async (initialInput) => {
62839
63354
  const currentInput = initialInput;
62840
63355
  try {
62841
63356
  if (userCancelledRef.current) {
@@ -62939,6 +63454,12 @@ function App2({
62939
63454
  setStreaming(false);
62940
63455
  return;
62941
63456
  }
63457
+ if (userCancelledRef.current || abortControllerRef.current?.signal.aborted) {
63458
+ setStreaming(false);
63459
+ markIncompleteToolsAsCancelled(buffersRef.current);
63460
+ refreshDerived();
63461
+ return;
63462
+ }
62942
63463
  const approvalResults2 = await Promise.all(approvalsToProcess.map(async (approvalItem) => {
62943
63464
  if (!approvalItem.toolName) {
62944
63465
  return {
@@ -63106,6 +63627,12 @@ function App2({
63106
63627
  setStreaming(false);
63107
63628
  return;
63108
63629
  }
63630
+ if (userCancelledRef.current || abortControllerRef.current?.signal.aborted) {
63631
+ setStreaming(false);
63632
+ markIncompleteToolsAsCancelled(buffersRef.current);
63633
+ refreshDerived();
63634
+ return;
63635
+ }
63109
63636
  setPendingApprovals(needsUserInput.map((ac) => ac.approval));
63110
63637
  setApprovalContexts(needsUserInput.map((ac) => ac.context).filter((ctx) => ctx !== null));
63111
63638
  setAutoHandledResults(autoAllowedResults);
@@ -63167,16 +63694,16 @@ function App2({
63167
63694
  setStreaming,
63168
63695
  agentName
63169
63696
  ]);
63170
- const handleExit = import_react62.useCallback(() => {
63171
- setShowExitStats(true);
63697
+ const handleExit = import_react63.useCallback(() => {
63698
+ saveLastAgentBeforeExit();
63172
63699
  setTimeout(() => {
63173
63700
  process.exit(0);
63174
63701
  }, 100);
63175
63702
  }, []);
63176
- const handleEnterQueueEditMode = import_react62.useCallback(() => {
63703
+ const handleEnterQueueEditMode = import_react63.useCallback(() => {
63177
63704
  setMessageQueue([]);
63178
63705
  }, []);
63179
- const handleInterrupt = import_react62.useCallback(async () => {
63706
+ const handleInterrupt = import_react63.useCallback(async () => {
63180
63707
  if (isExecutingTool && toolAbortControllerRef.current) {
63181
63708
  toolAbortControllerRef.current.abort();
63182
63709
  setStreaming(false);
@@ -63232,16 +63759,16 @@ function App2({
63232
63759
  refreshDerived,
63233
63760
  setStreaming
63234
63761
  ]);
63235
- const processConversationRef = import_react62.useRef(processConversation);
63236
- import_react62.useEffect(() => {
63762
+ const processConversationRef = import_react63.useRef(processConversation);
63763
+ import_react63.useEffect(() => {
63237
63764
  processConversationRef.current = processConversation;
63238
63765
  }, [processConversation]);
63239
- import_react62.useEffect(() => {
63766
+ import_react63.useEffect(() => {
63240
63767
  if (!streaming) {
63241
63768
  setInterruptRequested(false);
63242
63769
  }
63243
63770
  }, [streaming]);
63244
- const handleAgentSelect = import_react62.useCallback(async (targetAgentId, _opts) => {
63771
+ const handleAgentSelect = import_react63.useCallback(async (targetAgentId, _opts) => {
63245
63772
  setActiveOverlay(null);
63246
63773
  if (targetAgentId === agentId) {
63247
63774
  const label = agentName || targetAgentId.slice(0, 12);
@@ -63326,7 +63853,7 @@ function App2({
63326
63853
  setCommandRunning(false);
63327
63854
  }
63328
63855
  }, [refreshDerived, agentId, agentName, setCommandRunning]);
63329
- const onSubmit = import_react62.useCallback(async (message) => {
63856
+ const onSubmit = import_react63.useCallback(async (message) => {
63330
63857
  const msg = message?.trim() ?? "";
63331
63858
  if (profileConfirmPending && !msg) {
63332
63859
  const { name, agentId: targetAgentId, cmdId } = profileConfirmPending;
@@ -63399,6 +63926,64 @@ function App2({
63399
63926
  setActiveOverlay("memory");
63400
63927
  return { submitted: true };
63401
63928
  }
63929
+ if (trimmed === "/usage") {
63930
+ const cmdId2 = uid2("cmd");
63931
+ buffersRef.current.byId.set(cmdId2, {
63932
+ kind: "command",
63933
+ id: cmdId2,
63934
+ input: trimmed,
63935
+ output: "Fetching usage statistics...",
63936
+ phase: "running"
63937
+ });
63938
+ buffersRef.current.order.push(cmdId2);
63939
+ refreshDerived();
63940
+ (async () => {
63941
+ try {
63942
+ const stats = sessionStatsRef.current.getSnapshot();
63943
+ let balance;
63944
+ try {
63945
+ const settings = settingsManager.getSettings();
63946
+ const baseURL = process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || "https://api.letta.com";
63947
+ const apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY;
63948
+ const balanceResponse = await fetch(`${baseURL}/v1/metadata/balance`, {
63949
+ headers: {
63950
+ "Content-Type": "application/json",
63951
+ Authorization: `Bearer ${apiKey}`,
63952
+ "X-Letta-Source": "letta-code"
63953
+ }
63954
+ });
63955
+ if (balanceResponse.ok) {
63956
+ balance = await balanceResponse.json();
63957
+ }
63958
+ } catch {}
63959
+ const output = formatUsageStats({
63960
+ stats,
63961
+ balance
63962
+ });
63963
+ buffersRef.current.byId.set(cmdId2, {
63964
+ kind: "command",
63965
+ id: cmdId2,
63966
+ input: trimmed,
63967
+ output,
63968
+ phase: "finished",
63969
+ success: true,
63970
+ dimOutput: true
63971
+ });
63972
+ refreshDerived();
63973
+ } catch (error) {
63974
+ buffersRef.current.byId.set(cmdId2, {
63975
+ kind: "command",
63976
+ id: cmdId2,
63977
+ input: trimmed,
63978
+ output: `Error fetching usage: ${error instanceof Error ? error.message : String(error)}`,
63979
+ phase: "finished",
63980
+ success: false
63981
+ });
63982
+ refreshDerived();
63983
+ }
63984
+ })();
63985
+ return { submitted: true };
63986
+ }
63402
63987
  if (trimmed === "/exit") {
63403
63988
  const cmdId2 = uid2("cmd");
63404
63989
  buffersRef.current.byId.set(cmdId2, {
@@ -63449,6 +64034,7 @@ function App2({
63449
64034
  success: true
63450
64035
  });
63451
64036
  refreshDerived();
64037
+ saveLastAgentBeforeExit();
63452
64038
  setTimeout(() => process.exit(0), 500);
63453
64039
  } catch (error) {
63454
64040
  const errorDetails = formatErrorDetails(error, agentId);
@@ -63568,6 +64154,21 @@ function App2({
63568
64154
  refreshDerived();
63569
64155
  return { submitted: true };
63570
64156
  }
64157
+ const validationError = validateAgentName(newName);
64158
+ if (validationError) {
64159
+ const cmdId3 = uid2("cmd");
64160
+ buffersRef.current.byId.set(cmdId3, {
64161
+ kind: "command",
64162
+ id: cmdId3,
64163
+ input: msg,
64164
+ output: validationError,
64165
+ phase: "finished",
64166
+ success: false
64167
+ });
64168
+ buffersRef.current.order.push(cmdId3);
64169
+ refreshDerived();
64170
+ return { submitted: true };
64171
+ }
63571
64172
  const cmdId2 = uid2("cmd");
63572
64173
  buffersRef.current.byId.set(cmdId2, {
63573
64174
  kind: "command",
@@ -63728,6 +64329,22 @@ Press Enter to continue, or type anything to cancel.`, false, "running");
63728
64329
  return { submitted: true };
63729
64330
  }
63730
64331
  if (msg.trim() === "/pin" || msg.trim().startsWith("/pin ")) {
64332
+ const argsStr = msg.trim().slice(4).trim();
64333
+ const parts = argsStr.split(/\s+/).filter(Boolean);
64334
+ let hasNameArg = false;
64335
+ let isLocal = false;
64336
+ for (const part of parts) {
64337
+ if (part === "-l" || part === "--local") {
64338
+ isLocal = true;
64339
+ } else {
64340
+ hasNameArg = true;
64341
+ }
64342
+ }
64343
+ if (!hasNameArg) {
64344
+ setPinDialogLocal(isLocal);
64345
+ setActiveOverlay("pin");
64346
+ return { submitted: true };
64347
+ }
63731
64348
  const profileCtx = {
63732
64349
  buffersRef,
63733
64350
  refreshDerived,
@@ -63736,7 +64353,6 @@ Press Enter to continue, or type anything to cancel.`, false, "running");
63736
64353
  setCommandRunning,
63737
64354
  setAgentName
63738
64355
  };
63739
- const argsStr = msg.trim().slice(4).trim();
63740
64356
  await handlePin(profileCtx, msg, argsStr);
63741
64357
  return { submitted: true };
63742
64358
  }
@@ -64197,25 +64813,160 @@ ${gitContext}
64197
64813
  return { submitted: false };
64198
64814
  }
64199
64815
  if (existingApprovals && existingApprovals.length > 0) {
64200
- buffersRef.current.byId.delete(userId);
64201
- const orderIndex = buffersRef.current.order.indexOf(userId);
64202
- if (orderIndex !== -1) {
64203
- buffersRef.current.order.splice(orderIndex, 1);
64204
- }
64205
- setStreaming(false);
64206
- setPendingApprovals(existingApprovals);
64207
- const contexts = await Promise.all(existingApprovals.map(async (approval) => {
64208
- const parsedArgs = safeJsonParseOr(approval.toolArgs, {});
64209
- return await analyzeToolApproval2(approval.toolName, parsedArgs);
64816
+ const approvalResults2 = await Promise.all(existingApprovals.map(async (approvalItem) => {
64817
+ if (!approvalItem.toolName) {
64818
+ return {
64819
+ approval: approvalItem,
64820
+ permission: {
64821
+ decision: "deny",
64822
+ reason: "Tool call incomplete - missing name"
64823
+ },
64824
+ context: null
64825
+ };
64826
+ }
64827
+ const parsedArgs = safeJsonParseOr(approvalItem.toolArgs, {});
64828
+ const permission = await checkToolPermission2(approvalItem.toolName, parsedArgs);
64829
+ const context3 = await analyzeToolApproval2(approvalItem.toolName, parsedArgs);
64830
+ return { approval: approvalItem, permission, context: context3 };
64210
64831
  }));
64211
64832
  if (userCancelledRef.current || abortControllerRef.current?.signal.aborted) {
64833
+ buffersRef.current.byId.delete(userId);
64834
+ const orderIndex = buffersRef.current.order.indexOf(userId);
64835
+ if (orderIndex !== -1) {
64836
+ buffersRef.current.order.splice(orderIndex, 1);
64837
+ }
64212
64838
  setStreaming(false);
64213
64839
  refreshDerived();
64214
64840
  return { submitted: false };
64215
64841
  }
64216
- setApprovalContexts(contexts);
64217
- refreshDerived();
64218
- return { submitted: false };
64842
+ const needsUserInput = [];
64843
+ const autoAllowed = [];
64844
+ const autoDenied = [];
64845
+ for (const ac of approvalResults2) {
64846
+ const { approval, permission } = ac;
64847
+ let decision = permission.decision;
64848
+ if (isFancyUITool(approval.toolName) && decision === "allow") {
64849
+ decision = "ask";
64850
+ }
64851
+ if (decision === "ask") {
64852
+ needsUserInput.push(ac);
64853
+ } else if (decision === "deny") {
64854
+ autoDenied.push(ac);
64855
+ } else {
64856
+ autoAllowed.push(ac);
64857
+ }
64858
+ }
64859
+ if (needsUserInput.length === 0) {
64860
+ const autoAllowedResults = await Promise.all(autoAllowed.map(async (ac) => {
64861
+ const parsedArgs = safeJsonParseOr(ac.approval.toolArgs, {});
64862
+ const result = await executeTool2(ac.approval.toolName, parsedArgs, { toolCallId: ac.approval.toolCallId });
64863
+ onChunk(buffersRef.current, {
64864
+ message_type: "tool_return_message",
64865
+ id: "dummy",
64866
+ date: new Date().toISOString(),
64867
+ tool_call_id: ac.approval.toolCallId,
64868
+ tool_return: result.toolReturn,
64869
+ status: result.status,
64870
+ stdout: result.stdout,
64871
+ stderr: result.stderr
64872
+ });
64873
+ return {
64874
+ toolCallId: ac.approval.toolCallId,
64875
+ result
64876
+ };
64877
+ }));
64878
+ const autoDeniedResults = autoDenied.map((ac) => {
64879
+ const reason = "matchedRule" in ac.permission && ac.permission.matchedRule ? `Permission denied by rule: ${ac.permission.matchedRule}` : `Permission denied: ${ac.permission.reason || "Unknown"}`;
64880
+ onChunk(buffersRef.current, {
64881
+ message_type: "tool_return_message",
64882
+ id: "dummy",
64883
+ date: new Date().toISOString(),
64884
+ tool_call_id: ac.approval.toolCallId,
64885
+ tool_return: `Error: request to call tool denied. User reason: ${reason}`,
64886
+ status: "error",
64887
+ stdout: null,
64888
+ stderr: null
64889
+ });
64890
+ return {
64891
+ type: "approval",
64892
+ tool_call_id: ac.approval.toolCallId,
64893
+ approve: false,
64894
+ reason
64895
+ };
64896
+ });
64897
+ refreshDerived();
64898
+ const recoveryApprovalResults = [
64899
+ ...autoAllowedResults.map((ar) => ({
64900
+ type: "approval",
64901
+ tool_call_id: ar.toolCallId,
64902
+ approve: true,
64903
+ tool_return: ar.result.toolReturn
64904
+ })),
64905
+ ...autoDeniedResults
64906
+ ];
64907
+ const initialInput2 = [
64908
+ {
64909
+ type: "approval",
64910
+ approvals: recoveryApprovalResults
64911
+ },
64912
+ {
64913
+ type: "message",
64914
+ role: "user",
64915
+ content: messageContent
64916
+ }
64917
+ ];
64918
+ await processConversation(initialInput2);
64919
+ clearPlaceholdersInText(msg);
64920
+ return { submitted: true };
64921
+ } else {
64922
+ buffersRef.current.byId.delete(userId);
64923
+ const orderIndex = buffersRef.current.order.indexOf(userId);
64924
+ if (orderIndex !== -1) {
64925
+ buffersRef.current.order.splice(orderIndex, 1);
64926
+ }
64927
+ setStreaming(false);
64928
+ setPendingApprovals(needsUserInput.map((ac) => ac.approval));
64929
+ setApprovalContexts(needsUserInput.map((ac) => ac.context).filter(Boolean));
64930
+ const autoAllowedWithResults = await Promise.all(autoAllowed.map(async (ac) => {
64931
+ const parsedArgs = safeJsonParseOr(ac.approval.toolArgs, {});
64932
+ const result = await executeTool2(ac.approval.toolName, parsedArgs, { toolCallId: ac.approval.toolCallId });
64933
+ onChunk(buffersRef.current, {
64934
+ message_type: "tool_return_message",
64935
+ id: "dummy",
64936
+ date: new Date().toISOString(),
64937
+ tool_call_id: ac.approval.toolCallId,
64938
+ tool_return: result.toolReturn,
64939
+ status: result.status,
64940
+ stdout: result.stdout,
64941
+ stderr: result.stderr
64942
+ });
64943
+ return {
64944
+ toolCallId: ac.approval.toolCallId,
64945
+ result
64946
+ };
64947
+ }));
64948
+ const autoDeniedWithReasons = autoDenied.map((ac) => {
64949
+ const reason = "matchedRule" in ac.permission && ac.permission.matchedRule ? `Permission denied by rule: ${ac.permission.matchedRule}` : `Permission denied: ${ac.permission.reason || "Unknown"}`;
64950
+ onChunk(buffersRef.current, {
64951
+ message_type: "tool_return_message",
64952
+ id: "dummy",
64953
+ date: new Date().toISOString(),
64954
+ tool_call_id: ac.approval.toolCallId,
64955
+ tool_return: `Error: request to call tool denied. User reason: ${reason}`,
64956
+ status: "error",
64957
+ stdout: null,
64958
+ stderr: null
64959
+ });
64960
+ return {
64961
+ approval: ac.approval,
64962
+ reason
64963
+ };
64964
+ });
64965
+ setAutoHandledResults(autoAllowedWithResults);
64966
+ setAutoDeniedApprovals(autoDeniedWithReasons);
64967
+ refreshDerived();
64968
+ return { submitted: false };
64969
+ }
64219
64970
  }
64220
64971
  } catch (_error) {}
64221
64972
  }
@@ -64255,11 +65006,11 @@ ${gitContext}
64255
65006
  setStreaming,
64256
65007
  setCommandRunning
64257
65008
  ]);
64258
- const onSubmitRef = import_react62.useRef(onSubmit);
64259
- import_react62.useEffect(() => {
65009
+ const onSubmitRef = import_react63.useRef(onSubmit);
65010
+ import_react63.useEffect(() => {
64260
65011
  onSubmitRef.current = onSubmit;
64261
65012
  }, [onSubmit]);
64262
- import_react62.useEffect(() => {
65013
+ import_react63.useEffect(() => {
64263
65014
  if (!streaming && messageQueue.length > 0 && pendingApprovals.length === 0 && !commandRunning && !isExecutingTool && !anySelectorOpen && !waitingForQueueCancelRef.current && !userCancelledRef.current) {
64264
65015
  const [firstMessage, ...rest] = messageQueue;
64265
65016
  setMessageQueue(rest);
@@ -64273,7 +65024,7 @@ ${gitContext}
64273
65024
  isExecutingTool,
64274
65025
  anySelectorOpen
64275
65026
  ]);
64276
- const sendAllResults = import_react62.useCallback(async (additionalDecision) => {
65027
+ const sendAllResults = import_react63.useCallback(async (additionalDecision) => {
64277
65028
  try {
64278
65029
  if (userCancelledRef.current || abortControllerRef.current?.signal.aborted) {
64279
65030
  setStreaming(false);
@@ -64376,7 +65127,7 @@ ${gitContext}
64376
65127
  agentName,
64377
65128
  setStreaming
64378
65129
  ]);
64379
- const handleApproveCurrent = import_react62.useCallback(async () => {
65130
+ const handleApproveCurrent = import_react63.useCallback(async () => {
64380
65131
  if (isExecutingTool)
64381
65132
  return;
64382
65133
  const currentIndex = approvalResults.length;
@@ -64410,7 +65161,7 @@ ${gitContext}
64410
65161
  isExecutingTool,
64411
65162
  setStreaming
64412
65163
  ]);
64413
- const handleApproveAlways = import_react62.useCallback(async (scope) => {
65164
+ const handleApproveAlways = import_react63.useCallback(async (scope) => {
64414
65165
  if (isExecutingTool)
64415
65166
  return;
64416
65167
  if (pendingApprovals.length === 0 || approvalContexts.length === 0)
@@ -64441,7 +65192,7 @@ ${gitContext}
64441
65192
  refreshDerived,
64442
65193
  isExecutingTool
64443
65194
  ]);
64444
- const handleDenyCurrent = import_react62.useCallback(async (reason) => {
65195
+ const handleDenyCurrent = import_react63.useCallback(async (reason) => {
64445
65196
  if (isExecutingTool)
64446
65197
  return;
64447
65198
  const currentIndex = approvalResults.length;
@@ -64478,7 +65229,7 @@ ${gitContext}
64478
65229
  agentName,
64479
65230
  setStreaming
64480
65231
  ]);
64481
- const handleCancelApprovals = import_react62.useCallback(() => {
65232
+ const handleCancelApprovals = import_react63.useCallback(() => {
64482
65233
  if (pendingApprovals.length === 0)
64483
65234
  return;
64484
65235
  const denialResults = pendingApprovals.map((approval) => ({
@@ -64496,7 +65247,7 @@ ${gitContext}
64496
65247
  setAutoHandledResults([]);
64497
65248
  setAutoDeniedApprovals([]);
64498
65249
  }, [pendingApprovals, refreshDerived]);
64499
- const handleModelSelect = import_react62.useCallback(async (modelId) => {
65250
+ const handleModelSelect = import_react63.useCallback(async (modelId) => {
64500
65251
  await withCommandLock(async () => {
64501
65252
  let cmdId = null;
64502
65253
  try {
@@ -64569,7 +65320,7 @@ Consider switching to a different system prompt using /system to match.` : null;
64569
65320
  }
64570
65321
  });
64571
65322
  }, [agentId, refreshDerived, currentToolset, withCommandLock]);
64572
- const handleSystemPromptSelect = import_react62.useCallback(async (promptId) => {
65323
+ const handleSystemPromptSelect = import_react63.useCallback(async (promptId) => {
64573
65324
  await withCommandLock(async () => {
64574
65325
  const cmdId = uid2("cmd");
64575
65326
  try {
@@ -64634,7 +65385,7 @@ Consider switching to a different system prompt using /system to match.` : null;
64634
65385
  }
64635
65386
  });
64636
65387
  }, [agentId, refreshDerived, withCommandLock]);
64637
- const handleToolsetSelect = import_react62.useCallback(async (toolsetId) => {
65388
+ const handleToolsetSelect = import_react63.useCallback(async (toolsetId) => {
64638
65389
  await withCommandLock(async () => {
64639
65390
  const cmdId = uid2("cmd");
64640
65391
  try {
@@ -64673,7 +65424,7 @@ Consider switching to a different system prompt using /system to match.` : null;
64673
65424
  }
64674
65425
  });
64675
65426
  }, [agentId, refreshDerived, withCommandLock]);
64676
- const handleFeedbackSubmit = import_react62.useCallback(async (message) => {
65427
+ const handleFeedbackSubmit = import_react63.useCallback(async (message) => {
64677
65428
  closeOverlay();
64678
65429
  await withCommandLock(async () => {
64679
65430
  const cmdId = uid2("cmd");
@@ -64729,7 +65480,7 @@ Consider switching to a different system prompt using /system to match.` : null;
64729
65480
  }
64730
65481
  });
64731
65482
  }, [agentId, refreshDerived, withCommandLock, closeOverlay]);
64732
- const handleProfileEscapeCancel = import_react62.useCallback(() => {
65483
+ const handleProfileEscapeCancel = import_react63.useCallback(() => {
64733
65484
  if (profileConfirmPending) {
64734
65485
  const { cmdId, name } = profileConfirmPending;
64735
65486
  buffersRef.current.byId.set(cmdId, {
@@ -64744,8 +65495,8 @@ Consider switching to a different system prompt using /system to match.` : null;
64744
65495
  setProfileConfirmPending(null);
64745
65496
  }
64746
65497
  }, [profileConfirmPending, refreshDerived]);
64747
- const [uiPermissionMode, setUiPermissionMode] = import_react62.useState(permissionMode2.getMode());
64748
- const handlePlanApprove = import_react62.useCallback(async (acceptEdits = false) => {
65498
+ const [uiPermissionMode, setUiPermissionMode] = import_react63.useState(permissionMode2.getMode());
65499
+ const handlePlanApprove = import_react63.useCallback(async (acceptEdits = false) => {
64749
65500
  const currentIndex = approvalResults.length;
64750
65501
  const approval = pendingApprovals[currentIndex];
64751
65502
  if (!approval)
@@ -64795,7 +65546,7 @@ Consider switching to a different system prompt using /system to match.` : null;
64795
65546
  agentName,
64796
65547
  setStreaming
64797
65548
  ]);
64798
- const handlePlanKeepPlanning = import_react62.useCallback(async (reason) => {
65549
+ const handlePlanKeepPlanning = import_react63.useCallback(async (reason) => {
64799
65550
  const currentIndex = approvalResults.length;
64800
65551
  const approval = pendingApprovals[currentIndex];
64801
65552
  if (!approval)
@@ -64814,7 +65565,7 @@ Consider switching to a different system prompt using /system to match.` : null;
64814
65565
  setApprovalResults((prev) => [...prev, decision]);
64815
65566
  }
64816
65567
  }, [pendingApprovals, approvalResults, sendAllResults]);
64817
- import_react62.useEffect(() => {
65568
+ import_react63.useEffect(() => {
64818
65569
  const currentIndex = approvalResults.length;
64819
65570
  const approval = pendingApprovals[currentIndex];
64820
65571
  if (approval?.toolName === "ExitPlanMode" && !planFileExists()) {
@@ -64824,7 +65575,7 @@ Consider switching to a different system prompt using /system to match.` : null;
64824
65575
  ` + `Use the Write tool to create your plan, then call ExitPlanMode again.`);
64825
65576
  }
64826
65577
  }, [pendingApprovals, approvalResults.length, handlePlanKeepPlanning]);
64827
- const handleQuestionSubmit = import_react62.useCallback(async (answers) => {
65578
+ const handleQuestionSubmit = import_react63.useCallback(async (answers) => {
64828
65579
  const currentIndex = approvalResults.length;
64829
65580
  const approval = pendingApprovals[currentIndex];
64830
65581
  if (!approval)
@@ -64870,7 +65621,7 @@ Consider switching to a different system prompt using /system to match.` : null;
64870
65621
  refreshDerived,
64871
65622
  agentName
64872
65623
  ]);
64873
- const handleEnterPlanModeApprove = import_react62.useCallback(async () => {
65624
+ const handleEnterPlanModeApprove = import_react63.useCallback(async () => {
64874
65625
  const currentIndex = approvalResults.length;
64875
65626
  const approval = pendingApprovals[currentIndex];
64876
65627
  if (!approval)
@@ -64927,7 +65678,7 @@ Plan file path: ${planFilePath}`;
64927
65678
  refreshDerived,
64928
65679
  agentName
64929
65680
  ]);
64930
- const handleEnterPlanModeReject = import_react62.useCallback(async () => {
65681
+ const handleEnterPlanModeReject = import_react63.useCallback(async () => {
64931
65682
  const currentIndex = approvalResults.length;
64932
65683
  const approval = pendingApprovals[currentIndex];
64933
65684
  if (!approval)
@@ -64946,7 +65697,7 @@ Plan file path: ${planFilePath}`;
64946
65697
  setApprovalResults((prev) => [...prev, decision]);
64947
65698
  }
64948
65699
  }, [pendingApprovals, approvalResults, sendAllResults]);
64949
- const liveItems = import_react62.useMemo(() => {
65700
+ const liveItems = import_react63.useMemo(() => {
64950
65701
  return lines.filter((ln) => {
64951
65702
  if (!("phase" in ln))
64952
65703
  return false;
@@ -64964,7 +65715,7 @@ Plan file path: ${planFilePath}`;
64964
65715
  return ln.phase === "streaming";
64965
65716
  });
64966
65717
  }, [lines, tokenStreamingEnabled]);
64967
- import_react62.useEffect(() => {
65718
+ import_react63.useEffect(() => {
64968
65719
  if (loadingState === "ready" && !welcomeCommittedRef.current && messageHistory.length === 0) {
64969
65720
  if (!continueSession && !agentProvenance) {
64970
65721
  return;
@@ -64986,13 +65737,11 @@ Plan file path: ${planFilePath}`;
64986
65737
  const agentUrl = agentState?.id ? `https://app.letta.com/agents/${agentState.id}` : null;
64987
65738
  const statusId = `status-agent-${Date.now().toString(36)}`;
64988
65739
  const hints = getAgentStatusHints(!!continueSession, agentState, agentProvenance);
64989
- const resumedMessage = continueSession ? agentState?.name ? `Resumed **${agentState.name}**` : "Resumed agent" : "Created a new agent (use /pin to save, /pinned or /resume to switch)";
64990
- const agentNameLine = !continueSession && agentState?.name ? `→ Agent: ${agentState.name} (use /rename to rename)` : "";
64991
- const statusLines = [
65740
+ const resumedMessage = continueSession ? agentState?.name ? `Resumed **${agentState.name}**` : "Resumed agent" : "Creating a new agent (use /pin to save)";
65741
+ const statusLines = continueSession ? [resumedMessage, ...hints, agentUrl ? `→ ${agentUrl}` : ""].filter(Boolean) : [
64992
65742
  resumedMessage,
64993
- agentNameLine,
64994
- ...hints,
64995
- agentUrl ? `→ ${agentUrl}` : ""
65743
+ agentUrl ? `→ ${agentUrl}` : "",
65744
+ "→ Tip: use /init to initialize your agent's memory system!"
64996
65745
  ].filter(Boolean);
64997
65746
  buffersRef.current.byId.set(statusId, {
64998
65747
  kind: "status",
@@ -65081,12 +65830,8 @@ Plan file path: ${planFilePath}`;
65081
65830
  liveItems.length === 0 && /* @__PURE__ */ jsx_dev_runtime43.jsxDEV(Box_default, {
65082
65831
  height: 1
65083
65832
  }, undefined, false, undefined, this),
65084
- showExitStats && /* @__PURE__ */ jsx_dev_runtime43.jsxDEV(SessionStats2, {
65085
- stats: sessionStatsRef.current.getSnapshot(),
65086
- agentId
65087
- }, undefined, false, undefined, this),
65088
65833
  /* @__PURE__ */ jsx_dev_runtime43.jsxDEV(Input, {
65089
- visible: !showExitStats && pendingApprovals.length === 0 && !anySelectorOpen,
65834
+ visible: pendingApprovals.length === 0 && !anySelectorOpen,
65090
65835
  streaming: streaming && !abortControllerRef.current?.signal.aborted,
65091
65836
  tokenCount,
65092
65837
  thinkingMessage,
@@ -65171,6 +65916,59 @@ Plan file path: ${planFilePath}`;
65171
65916
  agentName,
65172
65917
  onClose: closeOverlay
65173
65918
  }, undefined, false, undefined, this),
65919
+ activeOverlay === "pin" && /* @__PURE__ */ jsx_dev_runtime43.jsxDEV(PinDialog, {
65920
+ currentName: agentName || "",
65921
+ local: pinDialogLocal,
65922
+ onSubmit: async (newName) => {
65923
+ closeOverlay();
65924
+ setCommandRunning(true);
65925
+ const cmdId = uid2("cmd");
65926
+ const scopeText = pinDialogLocal ? "to this project" : "globally";
65927
+ const displayName = newName || agentName || agentId.slice(0, 12);
65928
+ buffersRef.current.byId.set(cmdId, {
65929
+ kind: "command",
65930
+ id: cmdId,
65931
+ input: "/pin",
65932
+ output: `Pinning "${displayName}" ${scopeText}...`,
65933
+ phase: "running"
65934
+ });
65935
+ buffersRef.current.order.push(cmdId);
65936
+ refreshDerived();
65937
+ try {
65938
+ const client = await getClient2();
65939
+ if (newName && newName !== agentName) {
65940
+ await client.agents.update(agentId, { name: newName });
65941
+ setAgentName(newName);
65942
+ }
65943
+ if (pinDialogLocal) {
65944
+ settingsManager.pinLocal(agentId);
65945
+ } else {
65946
+ settingsManager.pinGlobal(agentId);
65947
+ }
65948
+ buffersRef.current.byId.set(cmdId, {
65949
+ kind: "command",
65950
+ id: cmdId,
65951
+ input: "/pin",
65952
+ output: `Pinned "${newName || agentName || agentId.slice(0, 12)}" ${scopeText}.`,
65953
+ phase: "finished",
65954
+ success: true
65955
+ });
65956
+ } catch (error) {
65957
+ buffersRef.current.byId.set(cmdId, {
65958
+ kind: "command",
65959
+ id: cmdId,
65960
+ input: "/pin",
65961
+ output: `Failed to pin: ${error}`,
65962
+ phase: "finished",
65963
+ success: false
65964
+ });
65965
+ } finally {
65966
+ setCommandRunning(false);
65967
+ refreshDerived();
65968
+ }
65969
+ },
65970
+ onCancel: closeOverlay
65971
+ }, undefined, false, undefined, this),
65174
65972
  currentApproval?.toolName === "ExitPlanMode" && /* @__PURE__ */ jsx_dev_runtime43.jsxDEV(jsx_dev_runtime43.Fragment, {
65175
65973
  children: [
65176
65974
  /* @__PURE__ */ jsx_dev_runtime43.jsxDEV(Box_default, {
@@ -65236,7 +66034,7 @@ Plan file path: ${planFilePath}`;
65236
66034
  ]
65237
66035
  }, resumeKey, true, undefined, this);
65238
66036
  }
65239
- var import_react62, jsx_dev_runtime43, CLEAR_SCREEN_AND_HOME = "\x1B[2J\x1B[H", CHECK_PENDING_APPROVALS_BEFORE_SEND = true, EAGER_CANCEL = true;
66037
+ var import_react63, jsx_dev_runtime43, CLEAR_SCREEN_AND_HOME = "\x1B[2J\x1B[H", CHECK_PENDING_APPROVALS_BEFORE_SEND = true, EAGER_CANCEL = true;
65240
66038
  var init_App2 = __esm(async () => {
65241
66039
  init_error();
65242
66040
  init_available_models();
@@ -65271,12 +66069,12 @@ var init_App2 = __esm(async () => {
65271
66069
  init_MemoryViewer(),
65272
66070
  init_MessageSearch(),
65273
66071
  init_ModelSelector(),
66072
+ init_PinDialog(),
65274
66073
  init_PlanModeDialog(),
65275
66074
  init_ProfileSelector(),
65276
66075
  init_QuestionDialog(),
65277
66076
  init_ReasoningMessageRich(),
65278
66077
  init_ResumeSelector(),
65279
- init_SessionStats(),
65280
66078
  init_StatusMessage(),
65281
66079
  init_SubagentGroupDisplay(),
65282
66080
  init_SubagentGroupStatic(),
@@ -65288,7 +66086,7 @@ var init_App2 = __esm(async () => {
65288
66086
  init_WelcomeScreen(),
65289
66087
  init_useSuspend()
65290
66088
  ]);
65291
- import_react62 = __toESM(require_react(), 1);
66089
+ import_react63 = __toESM(require_react(), 1);
65292
66090
  jsx_dev_runtime43 = __toESM(require_jsx_dev_runtime(), 1);
65293
66091
  });
65294
66092
 
@@ -65667,8 +66465,8 @@ var exports_create = {};
65667
66465
  __export(exports_create, {
65668
66466
  createAgent: () => createAgent2
65669
66467
  });
65670
- import { join as join14 } from "node:path";
65671
- async function createAgent2(name = "letta-code-agent", model, embeddingModel = "openai/text-embedding-3-small", updateArgs, skillsDirectory, parallelToolCalls = true, enableSleeptime = false, systemPrompt, initBlocks, baseTools) {
66468
+ import { join as join15 } from "node:path";
66469
+ async function createAgent2(name = DEFAULT_AGENT_NAME, model, embeddingModel = "openai/text-embedding-3-small", updateArgs, skillsDirectory, parallelToolCalls = true, enableSleeptime = false, systemPrompt, initBlocks, baseTools) {
65672
66470
  let modelHandle;
65673
66471
  if (model) {
65674
66472
  const resolved = resolveModel(model);
@@ -65719,7 +66517,7 @@ async function createAgent2(name = "letta-code-agent", model, embeddingModel = "
65719
66517
  }
65720
66518
  }
65721
66519
  const filteredMemoryBlocks = allowedBlockLabels && allowedBlockLabels.size > 0 ? defaultMemoryBlocks.filter((b) => allowedBlockLabels.has(b.label)) : defaultMemoryBlocks;
65722
- const resolvedSkillsDirectory = skillsDirectory || join14(process.cwd(), SKILLS_DIR);
66520
+ const resolvedSkillsDirectory = skillsDirectory || join15(process.cwd(), SKILLS_DIR);
65723
66521
  try {
65724
66522
  const { skills, errors } = await discoverSkills(resolvedSkillsDirectory);
65725
66523
  if (errors.length > 0) {
@@ -65899,156 +66697,6 @@ var init_import2 = __esm(() => {
65899
66697
  init_modify();
65900
66698
  });
65901
66699
 
65902
- // src/agent/skills.ts
65903
- var exports_skills2 = {};
65904
- __export(exports_skills2, {
65905
- formatSkillsForMemory: () => formatSkillsForMemory2,
65906
- discoverSkills: () => discoverSkills2,
65907
- SKILLS_DIR: () => SKILLS_DIR2
65908
- });
65909
- import { existsSync as existsSync8 } from "node:fs";
65910
- import { readdir as readdir6, readFile as readFile6 } from "node:fs/promises";
65911
- import { join as join15 } from "node:path";
65912
- async function discoverSkills2(skillsPath = join15(process.cwd(), SKILLS_DIR2)) {
65913
- const errors = [];
65914
- if (!existsSync8(skillsPath)) {
65915
- return { skills: [], errors: [] };
65916
- }
65917
- const skills = [];
65918
- try {
65919
- await findSkillFiles2(skillsPath, skillsPath, skills, errors);
65920
- } catch (error) {
65921
- errors.push({
65922
- path: skillsPath,
65923
- message: `Failed to read skills directory: ${error instanceof Error ? error.message : String(error)}`
65924
- });
65925
- }
65926
- return { skills, errors };
65927
- }
65928
- async function findSkillFiles2(currentPath, rootPath, skills, errors) {
65929
- try {
65930
- const entries = await readdir6(currentPath, { withFileTypes: true });
65931
- for (const entry of entries) {
65932
- const fullPath = join15(currentPath, entry.name);
65933
- if (entry.isDirectory()) {
65934
- await findSkillFiles2(fullPath, rootPath, skills, errors);
65935
- } else if (entry.isFile() && entry.name.toUpperCase() === "SKILL.MD") {
65936
- try {
65937
- const skill2 = await parseSkillFile2(fullPath, rootPath);
65938
- if (skill2) {
65939
- skills.push(skill2);
65940
- }
65941
- } catch (error) {
65942
- errors.push({
65943
- path: fullPath,
65944
- message: error instanceof Error ? error.message : String(error)
65945
- });
65946
- }
65947
- }
65948
- }
65949
- } catch (error) {
65950
- errors.push({
65951
- path: currentPath,
65952
- message: `Failed to read directory: ${error instanceof Error ? error.message : String(error)}`
65953
- });
65954
- }
65955
- }
65956
- async function parseSkillFile2(filePath, rootPath) {
65957
- const content = await readFile6(filePath, "utf-8");
65958
- const { frontmatter, body } = parseFrontmatter(content);
65959
- const normalizedRoot = rootPath.endsWith("/") ? rootPath.slice(0, -1) : rootPath;
65960
- const relativePath = filePath.slice(normalizedRoot.length + 1);
65961
- const dirPath = relativePath.slice(0, -"/SKILL.MD".length);
65962
- const defaultId = dirPath || "root";
65963
- const id = (typeof frontmatter.id === "string" ? frontmatter.id : null) || defaultId;
65964
- const name = (typeof frontmatter.name === "string" ? frontmatter.name : null) || (typeof frontmatter.title === "string" ? frontmatter.title : null) || (id.split("/").pop() ?? "").replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
65965
- let description = typeof frontmatter.description === "string" ? frontmatter.description : null;
65966
- if (!description) {
65967
- const firstParagraph = body.trim().split(`
65968
-
65969
- `)[0];
65970
- description = firstParagraph || "No description available";
65971
- }
65972
- description = description.trim();
65973
- if (description.startsWith('"') && description.endsWith('"') || description.startsWith("'") && description.endsWith("'")) {
65974
- description = description.slice(1, -1);
65975
- }
65976
- let tags;
65977
- if (Array.isArray(frontmatter.tags)) {
65978
- tags = frontmatter.tags;
65979
- } else if (typeof frontmatter.tags === "string") {
65980
- tags = [frontmatter.tags];
65981
- }
65982
- return {
65983
- id,
65984
- name,
65985
- description,
65986
- category: typeof frontmatter.category === "string" ? frontmatter.category : undefined,
65987
- tags,
65988
- path: filePath
65989
- };
65990
- }
65991
- function formatSkillsForMemory2(skills, skillsDirectory) {
65992
- let output = `Skills Directory: ${skillsDirectory}
65993
-
65994
- `;
65995
- if (skills.length === 0) {
65996
- return `${output}[NO SKILLS AVAILABLE]`;
65997
- }
65998
- output += `Available Skills:
65999
-
66000
- `;
66001
- const categorized = new Map;
66002
- const uncategorized = [];
66003
- for (const skill2 of skills) {
66004
- if (skill2.category) {
66005
- const existing = categorized.get(skill2.category) || [];
66006
- existing.push(skill2);
66007
- categorized.set(skill2.category, existing);
66008
- } else {
66009
- uncategorized.push(skill2);
66010
- }
66011
- }
66012
- for (const [category, categorySkills] of categorized) {
66013
- output += `## ${category}
66014
-
66015
- `;
66016
- for (const skill2 of categorySkills) {
66017
- output += formatSkill2(skill2);
66018
- }
66019
- output += `
66020
- `;
66021
- }
66022
- if (uncategorized.length > 0) {
66023
- if (categorized.size > 0) {
66024
- output += `## Other
66025
-
66026
- `;
66027
- }
66028
- for (const skill2 of uncategorized) {
66029
- output += formatSkill2(skill2);
66030
- }
66031
- }
66032
- return output.trim();
66033
- }
66034
- function formatSkill2(skill2) {
66035
- let output = `### ${skill2.name}
66036
- `;
66037
- output += `ID: \`${skill2.id}\`
66038
- `;
66039
- output += `Description: ${skill2.description}
66040
- `;
66041
- if (skill2.tags && skill2.tags.length > 0) {
66042
- output += `Tags: ${skill2.tags.map((t) => `\`${t}\``).join(", ")}
66043
- `;
66044
- }
66045
- output += `
66046
- `;
66047
- return output;
66048
- }
66049
- var SKILLS_DIR2 = ".skills";
66050
- var init_skills3 = () => {};
66051
-
66052
66700
  // src/index.ts
66053
66701
  import { parseArgs as parseArgs2 } from "util";
66054
66702
 
@@ -66131,6 +66779,7 @@ init_letta_client();
66131
66779
  init_package();
66132
66780
  init_oauth();
66133
66781
  init_settings_manager();
66782
+ import { hostname } from "node:os";
66134
66783
  async function getClient() {
66135
66784
  const settings = settingsManager.getSettings();
66136
66785
  let apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY;
@@ -66139,7 +66788,13 @@ async function getClient() {
66139
66788
  const expiresAt = settings.tokenExpiresAt;
66140
66789
  if (expiresAt - now < 5 * 60 * 1000) {
66141
66790
  try {
66142
- const tokens = await refreshAccessToken(settings.refreshToken);
66791
+ let deviceId = settings.deviceId;
66792
+ if (!deviceId) {
66793
+ deviceId = crypto.randomUUID();
66794
+ settingsManager.updateSettings({ deviceId });
66795
+ }
66796
+ const deviceName = hostname();
66797
+ const tokens = await refreshAccessToken(settings.refreshToken, deviceId, deviceName);
66143
66798
  const updatedEnv = { ...settings.env };
66144
66799
  updatedEnv.LETTA_API_KEY = tokens.access_token;
66145
66800
  settingsManager.updateSettings({
@@ -66692,6 +67347,7 @@ USAGE
66692
67347
  OPTIONS
66693
67348
  -h, --help Show this help and exit
66694
67349
  -v, --version Print version and exit
67350
+ --info Show current directory, skills, and pinned agents
66695
67351
  --new Create new agent directly (skip profile selection)
66696
67352
  --init-blocks <list> Comma-separated memory blocks to initialize when using --new (e.g., "persona,skills")
66697
67353
  --base-tools <list> Comma-separated base tools to attach when using --new (e.g., "memory,web_search,conversation_search")
@@ -66738,6 +67394,77 @@ EXAMPLES
66738
67394
  `.trim();
66739
67395
  console.log(usage);
66740
67396
  }
67397
+ async function printInfo() {
67398
+ const { join: join16 } = await import("path");
67399
+ const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version(), exports_version));
67400
+ const { SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
67401
+ const { exists: exists3 } = await Promise.resolve().then(() => (init_fs2(), exports_fs));
67402
+ const cwd2 = process.cwd();
67403
+ const skillsDir = join16(cwd2, SKILLS_DIR3);
67404
+ const skillsExist = exists3(skillsDir);
67405
+ await settingsManager2.loadLocalProjectSettings(cwd2);
67406
+ const localPinned = settingsManager2.getLocalPinnedAgents(cwd2);
67407
+ const globalPinned = settingsManager2.getGlobalPinnedAgents();
67408
+ const localSettings = settingsManager2.getLocalProjectSettings(cwd2);
67409
+ const lastAgent = localSettings.lastAgent;
67410
+ const agentNames = {};
67411
+ const allAgentIds = [
67412
+ ...new Set([
67413
+ ...localPinned,
67414
+ ...globalPinned,
67415
+ ...lastAgent ? [lastAgent] : []
67416
+ ])
67417
+ ];
67418
+ if (allAgentIds.length > 0) {
67419
+ try {
67420
+ const client = await getClient();
67421
+ await Promise.all(allAgentIds.map(async (id) => {
67422
+ try {
67423
+ const agent = await client.agents.retrieve(id);
67424
+ agentNames[id] = agent.name;
67425
+ } catch {}
67426
+ }));
67427
+ } catch {}
67428
+ }
67429
+ const formatAgent = (id) => {
67430
+ const name = agentNames[id];
67431
+ return name ? `${id} (${name})` : `${id} (not found)`;
67432
+ };
67433
+ console.log(`Letta Code ${getVersion3()}
67434
+ `);
67435
+ console.log(`Current directory: ${cwd2}`);
67436
+ console.log(`Skills directory: ${skillsDir}${skillsExist ? "" : " (not found)"}`);
67437
+ console.log("");
67438
+ if (lastAgent) {
67439
+ console.log(`Will resume: ${formatAgent(lastAgent)}`);
67440
+ } else if (localPinned.length > 0 || globalPinned.length > 0) {
67441
+ console.log("Will resume: (will show selector)");
67442
+ } else {
67443
+ console.log("Will resume: (will create new agent)");
67444
+ }
67445
+ console.log("");
67446
+ if (localPinned.length > 0) {
67447
+ console.log("Locally pinned agents (this project):");
67448
+ for (const id of localPinned) {
67449
+ const isLast = id === lastAgent;
67450
+ const prefix = isLast ? "\u2192 " : " ";
67451
+ const suffix = isLast ? " (last used)" : "";
67452
+ console.log(` ${prefix}${formatAgent(id)}${suffix}`);
67453
+ }
67454
+ } else {
67455
+ console.log("Locally pinned agents: (none)");
67456
+ }
67457
+ console.log("");
67458
+ if (globalPinned.length > 0) {
67459
+ console.log("Globally pinned agents:");
67460
+ for (const id of globalPinned) {
67461
+ const isLocal = localPinned.includes(id);
67462
+ console.log(` ${formatAgent(id)}${isLocal ? " (also local)" : ""}`);
67463
+ }
67464
+ } else {
67465
+ console.log("Globally pinned agents: (none)");
67466
+ }
67467
+ }
66741
67468
  function getModelForToolLoading(specifiedModel, specifiedToolset) {
66742
67469
  if (specifiedToolset === "codex") {
66743
67470
  return "openai/gpt-4";
@@ -66763,6 +67490,7 @@ async function main() {
66763
67490
  options: {
66764
67491
  help: { type: "boolean", short: "h" },
66765
67492
  version: { type: "boolean", short: "v" },
67493
+ info: { type: "boolean" },
66766
67494
  continue: { type: "boolean", short: "c" },
66767
67495
  new: { type: "boolean" },
66768
67496
  "init-blocks": { type: "string" },
@@ -66808,10 +67536,14 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
66808
67536
  process.exit(0);
66809
67537
  }
66810
67538
  if (values.version) {
66811
- const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version2(), exports_version));
67539
+ const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version(), exports_version));
66812
67540
  console.log(`${getVersion3()} (Letta Code)`);
66813
67541
  process.exit(0);
66814
67542
  }
67543
+ if (values.info) {
67544
+ await printInfo();
67545
+ process.exit(0);
67546
+ }
66815
67547
  if (command === "update") {
66816
67548
  const { manualUpdate: manualUpdate2 } = await Promise.resolve().then(() => (init_auto_update(), exports_auto_update));
66817
67549
  const result = await manualUpdate2();
@@ -66893,9 +67625,9 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
66893
67625
  process.exit(1);
66894
67626
  }
66895
67627
  const { resolve: resolve18 } = await import("path");
66896
- const { existsSync: existsSync9 } = await import("fs");
67628
+ const { existsSync: existsSync10 } = await import("fs");
66897
67629
  const resolvedPath = resolve18(fromAfFile);
66898
- if (!existsSync9(resolvedPath)) {
67630
+ if (!existsSync10(resolvedPath)) {
66899
67631
  console.error(`Error: AgentFile not found: ${resolvedPath}`);
66900
67632
  process.exit(1);
66901
67633
  }
@@ -66992,7 +67724,7 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
66992
67724
  }
66993
67725
  const React13 = await Promise.resolve().then(() => __toESM(require_react2(), 1));
66994
67726
  const { render: render2 } = await init_build3().then(() => exports_build);
66995
- const { useState: useState29, useEffect: useEffect22 } = React13;
67727
+ const { useState: useState30, useEffect: useEffect22 } = React13;
66996
67728
  const AppModule = await init_App2().then(() => exports_App);
66997
67729
  const App3 = AppModule.default;
66998
67730
  function LoadingApp({
@@ -67007,12 +67739,12 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
67007
67739
  skillsDirectory: skillsDirectory2,
67008
67740
  fromAfFile: fromAfFile2
67009
67741
  }) {
67010
- const [loadingState, setLoadingState] = useState29("selecting");
67011
- const [agentId, setAgentId] = useState29(null);
67012
- const [agentState, setAgentState] = useState29(null);
67013
- const [resumeData, setResumeData] = useState29(null);
67014
- const [isResumingSession, setIsResumingSession] = useState29(false);
67015
- const [agentProvenance, setAgentProvenance] = useState29(null);
67742
+ const [loadingState, setLoadingState] = useState30("selecting");
67743
+ const [agentId, setAgentId] = useState30(null);
67744
+ const [agentState, setAgentState] = useState30(null);
67745
+ const [resumeData, setResumeData] = useState30(null);
67746
+ const [isResumingSession, setIsResumingSession] = useState30(false);
67747
+ const [agentProvenance, setAgentProvenance] = useState30(null);
67016
67748
  useEffect22(() => {
67017
67749
  async function checkAndStart() {
67018
67750
  await settingsManager2.loadLocalProjectSettings();
@@ -67263,4 +67995,4 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
67263
67995
  }
67264
67996
  main();
67265
67997
 
67266
- //# debugId=38F3C2E9A717C8AC64756E2164756E21
67998
+ //# debugId=51160339EAC9ACF264756E2164756E21