@letta-ai/letta-code 0.10.1 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/letta.js +1135 -30
- package/package.json +2 -2
- package/vendor/ink-text-input/build/index.js +11 -0
package/letta.js
CHANGED
|
@@ -3233,7 +3233,7 @@ var package_default;
|
|
|
3233
3233
|
var init_package = __esm(() => {
|
|
3234
3234
|
package_default = {
|
|
3235
3235
|
name: "@letta-ai/letta-code",
|
|
3236
|
-
version: "0.10.
|
|
3236
|
+
version: "0.10.2",
|
|
3237
3237
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3238
3238
|
type: "module",
|
|
3239
3239
|
bin: {
|
|
@@ -3285,7 +3285,7 @@ var init_package = __esm(() => {
|
|
|
3285
3285
|
typecheck: "tsc --noEmit",
|
|
3286
3286
|
check: "bun run scripts/check.js",
|
|
3287
3287
|
dev: "bun --loader:.md=text --loader:.mdx=text --loader:.txt=text run src/index.ts",
|
|
3288
|
-
build: "bun run build.js",
|
|
3288
|
+
build: "node scripts/postinstall-patches.js && bun run build.js",
|
|
3289
3289
|
prepare: "bun run build",
|
|
3290
3290
|
postinstall: "node scripts/postinstall-patches.js"
|
|
3291
3291
|
},
|
|
@@ -51370,6 +51370,104 @@ var init_headless = __esm(() => {
|
|
|
51370
51370
|
init_manager3();
|
|
51371
51371
|
});
|
|
51372
51372
|
|
|
51373
|
+
// src/cli/utils/kittyProtocolDetector.ts
|
|
51374
|
+
var exports_kittyProtocolDetector = {};
|
|
51375
|
+
__export(exports_kittyProtocolDetector, {
|
|
51376
|
+
isKittyProtocolEnabled: () => isKittyProtocolEnabled,
|
|
51377
|
+
detectAndEnableKittyProtocol: () => detectAndEnableKittyProtocol
|
|
51378
|
+
});
|
|
51379
|
+
import * as fs14 from "node:fs";
|
|
51380
|
+
async function detectAndEnableKittyProtocol() {
|
|
51381
|
+
if (detectionComplete) {
|
|
51382
|
+
return;
|
|
51383
|
+
}
|
|
51384
|
+
return new Promise((resolve16) => {
|
|
51385
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
51386
|
+
detectionComplete = true;
|
|
51387
|
+
resolve16();
|
|
51388
|
+
return;
|
|
51389
|
+
}
|
|
51390
|
+
const originalRawMode = process.stdin.isRaw;
|
|
51391
|
+
if (!originalRawMode) {
|
|
51392
|
+
process.stdin.setRawMode(true);
|
|
51393
|
+
}
|
|
51394
|
+
let responseBuffer = "";
|
|
51395
|
+
let progressiveEnhancementReceived = false;
|
|
51396
|
+
let timeoutId;
|
|
51397
|
+
const finish = () => {
|
|
51398
|
+
if (timeoutId !== undefined) {
|
|
51399
|
+
clearTimeout(timeoutId);
|
|
51400
|
+
timeoutId = undefined;
|
|
51401
|
+
}
|
|
51402
|
+
process.stdin.removeListener("data", handleData);
|
|
51403
|
+
if (!originalRawMode) {
|
|
51404
|
+
process.stdin.setRawMode(false);
|
|
51405
|
+
}
|
|
51406
|
+
if (progressiveEnhancementReceived)
|
|
51407
|
+
kittySupported = true;
|
|
51408
|
+
if (process.stdout.isTTY) {
|
|
51409
|
+
if (DEBUG2) {
|
|
51410
|
+
console.error("[kitty] enabling protocol");
|
|
51411
|
+
}
|
|
51412
|
+
enableKittyKeyboardProtocol();
|
|
51413
|
+
process.on("exit", disableKittyKeyboardProtocol);
|
|
51414
|
+
process.on("SIGTERM", disableKittyKeyboardProtocol);
|
|
51415
|
+
process.on("SIGINT", disableKittyKeyboardProtocol);
|
|
51416
|
+
} else if (DEBUG2 && !kittySupported) {
|
|
51417
|
+
console.error("[kitty] protocol query unsupported; enabled anyway (best-effort)");
|
|
51418
|
+
}
|
|
51419
|
+
detectionComplete = true;
|
|
51420
|
+
resolve16();
|
|
51421
|
+
};
|
|
51422
|
+
const handleData = (data) => {
|
|
51423
|
+
if (timeoutId === undefined) {
|
|
51424
|
+
return;
|
|
51425
|
+
}
|
|
51426
|
+
responseBuffer += data.toString();
|
|
51427
|
+
if (DEBUG2) {
|
|
51428
|
+
console.error("[kitty] rx:", JSON.stringify(data.toString()));
|
|
51429
|
+
}
|
|
51430
|
+
if (responseBuffer.includes("\x1B[?") && responseBuffer.includes("u")) {
|
|
51431
|
+
progressiveEnhancementReceived = true;
|
|
51432
|
+
clearTimeout(timeoutId);
|
|
51433
|
+
timeoutId = setTimeout(finish, 1000);
|
|
51434
|
+
}
|
|
51435
|
+
if (responseBuffer.includes("\x1B[?") && responseBuffer.includes("c")) {
|
|
51436
|
+
if (progressiveEnhancementReceived)
|
|
51437
|
+
kittySupported = true;
|
|
51438
|
+
finish();
|
|
51439
|
+
}
|
|
51440
|
+
};
|
|
51441
|
+
process.stdin.on("data", handleData);
|
|
51442
|
+
if (DEBUG2) {
|
|
51443
|
+
console.error("[kitty] querying support");
|
|
51444
|
+
}
|
|
51445
|
+
fs14.writeSync(process.stdout.fd, "\x1B[?u\x1B[c");
|
|
51446
|
+
timeoutId = setTimeout(finish, 200);
|
|
51447
|
+
});
|
|
51448
|
+
}
|
|
51449
|
+
function isKittyProtocolEnabled() {
|
|
51450
|
+
return kittyEnabled;
|
|
51451
|
+
}
|
|
51452
|
+
function enableKittyKeyboardProtocol() {
|
|
51453
|
+
try {
|
|
51454
|
+
fs14.writeSync(process.stdout.fd, "\x1B[>7u");
|
|
51455
|
+
kittyEnabled = true;
|
|
51456
|
+
} catch {}
|
|
51457
|
+
}
|
|
51458
|
+
function disableKittyKeyboardProtocol() {
|
|
51459
|
+
try {
|
|
51460
|
+
if (kittyEnabled) {
|
|
51461
|
+
fs14.writeSync(process.stdout.fd, "\x1B[<u");
|
|
51462
|
+
kittyEnabled = false;
|
|
51463
|
+
}
|
|
51464
|
+
} catch {}
|
|
51465
|
+
}
|
|
51466
|
+
var detectionComplete = false, kittySupported = false, kittyEnabled = false, DEBUG2;
|
|
51467
|
+
var init_kittyProtocolDetector = __esm(() => {
|
|
51468
|
+
DEBUG2 = process.env.LETTA_DEBUG_KITTY === "1";
|
|
51469
|
+
});
|
|
51470
|
+
|
|
51373
51471
|
// node_modules/react/index.js
|
|
51374
51472
|
var require_react2 = __commonJS((exports, module) => {
|
|
51375
51473
|
var react_development = __toESM(require_react_development(), 1);
|
|
@@ -51498,7 +51596,55 @@ var init_available_models = __esm(() => {
|
|
|
51498
51596
|
});
|
|
51499
51597
|
|
|
51500
51598
|
// src/settings.ts
|
|
51599
|
+
var exports_settings = {};
|
|
51600
|
+
__export(exports_settings, {
|
|
51601
|
+
updateSettings: () => updateSettings,
|
|
51602
|
+
updateProjectSettings: () => updateProjectSettings,
|
|
51603
|
+
saveSettings: () => saveSettings,
|
|
51604
|
+
saveProjectSettings: () => saveProjectSettings,
|
|
51605
|
+
loadSettings: () => loadSettings,
|
|
51606
|
+
loadProjectSettings: () => loadProjectSettings,
|
|
51607
|
+
getSetting: () => getSetting
|
|
51608
|
+
});
|
|
51609
|
+
import { homedir as homedir6 } from "node:os";
|
|
51501
51610
|
import { join as join13 } from "node:path";
|
|
51611
|
+
function getSettingsPath() {
|
|
51612
|
+
return join13(homedir6(), ".letta", "settings.json");
|
|
51613
|
+
}
|
|
51614
|
+
async function loadSettings() {
|
|
51615
|
+
const settingsPath = getSettingsPath();
|
|
51616
|
+
try {
|
|
51617
|
+
if (!exists(settingsPath)) {
|
|
51618
|
+
await saveSettings(DEFAULT_SETTINGS3);
|
|
51619
|
+
return DEFAULT_SETTINGS3;
|
|
51620
|
+
}
|
|
51621
|
+
const content = await readFile(settingsPath);
|
|
51622
|
+
const settings = JSON.parse(content);
|
|
51623
|
+
return { ...DEFAULT_SETTINGS3, ...settings };
|
|
51624
|
+
} catch (error) {
|
|
51625
|
+
console.error("Error loading settings, using defaults:", error);
|
|
51626
|
+
return DEFAULT_SETTINGS3;
|
|
51627
|
+
}
|
|
51628
|
+
}
|
|
51629
|
+
async function saveSettings(settings) {
|
|
51630
|
+
const settingsPath = getSettingsPath();
|
|
51631
|
+
try {
|
|
51632
|
+
await writeFile(settingsPath, JSON.stringify(settings, null, 2));
|
|
51633
|
+
} catch (error) {
|
|
51634
|
+
console.error("Error saving settings:", error);
|
|
51635
|
+
throw error;
|
|
51636
|
+
}
|
|
51637
|
+
}
|
|
51638
|
+
async function updateSettings(updates) {
|
|
51639
|
+
const currentSettings = await loadSettings();
|
|
51640
|
+
const newSettings = { ...currentSettings, ...updates };
|
|
51641
|
+
await saveSettings(newSettings);
|
|
51642
|
+
return newSettings;
|
|
51643
|
+
}
|
|
51644
|
+
async function getSetting(key) {
|
|
51645
|
+
const settings = await loadSettings();
|
|
51646
|
+
return settings[key];
|
|
51647
|
+
}
|
|
51502
51648
|
function getProjectSettingsPath() {
|
|
51503
51649
|
return join13(process.cwd(), ".letta", "settings.local.json");
|
|
51504
51650
|
}
|
|
@@ -51535,8 +51681,14 @@ async function updateProjectSettings(updates) {
|
|
|
51535
51681
|
await saveProjectSettings(newSettings);
|
|
51536
51682
|
return newSettings;
|
|
51537
51683
|
}
|
|
51684
|
+
var DEFAULT_SETTINGS3;
|
|
51538
51685
|
var init_settings = __esm(() => {
|
|
51539
51686
|
init_fs();
|
|
51687
|
+
DEFAULT_SETTINGS3 = {
|
|
51688
|
+
lastAgent: null,
|
|
51689
|
+
tokenStreaming: false,
|
|
51690
|
+
globalSharedBlockIds: {}
|
|
51691
|
+
};
|
|
51540
51692
|
});
|
|
51541
51693
|
|
|
51542
51694
|
// src/cli/commands/mcp.ts
|
|
@@ -54379,6 +54531,8 @@ function isControlSequence(input, key) {
|
|
|
54379
54531
|
return true;
|
|
54380
54532
|
if (key.shift && key.tab)
|
|
54381
54533
|
return true;
|
|
54534
|
+
if (key.return && (key.shift || key.meta || key.ctrl))
|
|
54535
|
+
return true;
|
|
54382
54536
|
if (key.ctrl && (input === "w" || input === "W"))
|
|
54383
54537
|
return true;
|
|
54384
54538
|
if (key.ctrl && input && /^[a-z]$/i.test(input) && !["a", "e", "k", "u", "y"].includes(input.toLowerCase()))
|
|
@@ -54387,6 +54541,9 @@ function isControlSequence(input, key) {
|
|
|
54387
54541
|
return true;
|
|
54388
54542
|
if (input && typeof input === "string" && input.startsWith("\x1B") && input.length > 1)
|
|
54389
54543
|
return true;
|
|
54544
|
+
if (key.delete && globalThis.__lettaForwardDeleteTimestamp && Date.now() - globalThis.__lettaForwardDeleteTimestamp < 100) {
|
|
54545
|
+
return true;
|
|
54546
|
+
}
|
|
54390
54547
|
return false;
|
|
54391
54548
|
}
|
|
54392
54549
|
function TextInput({ value: originalValue, placeholder = "", focus = true, mask, highlightPastedText = false, showCursor = true, onChange, onSubmit, externalCursorOffset, onCursorOffsetChange }) {
|
|
@@ -54736,6 +54893,33 @@ function PasteAwareTextInput({
|
|
|
54736
54893
|
}
|
|
54737
54894
|
}, [value]);
|
|
54738
54895
|
use_input_default((input, key) => {
|
|
54896
|
+
if (key.return && (key.shift || key.meta || key.ctrl)) {
|
|
54897
|
+
const at = Math.max(0, Math.min(caretOffsetRef.current, displayValueRef.current.length));
|
|
54898
|
+
const newValue = displayValueRef.current.slice(0, at) + `
|
|
54899
|
+
` + displayValueRef.current.slice(at);
|
|
54900
|
+
setDisplayValue(newValue);
|
|
54901
|
+
setActualValue(newValue);
|
|
54902
|
+
onChangeRef.current(newValue);
|
|
54903
|
+
const nextCaret = at + 1;
|
|
54904
|
+
setNudgeCursorOffset(nextCaret);
|
|
54905
|
+
caretOffsetRef.current = nextCaret;
|
|
54906
|
+
return;
|
|
54907
|
+
}
|
|
54908
|
+
if (key.ctrl && input === "v") {
|
|
54909
|
+
const clip = tryImportClipboardImageMac();
|
|
54910
|
+
if (clip) {
|
|
54911
|
+
const at = Math.max(0, Math.min(caretOffsetRef.current, displayValueRef.current.length));
|
|
54912
|
+
const newDisplay = displayValueRef.current.slice(0, at) + clip + displayValueRef.current.slice(at);
|
|
54913
|
+
displayValueRef.current = newDisplay;
|
|
54914
|
+
setDisplayValue(newDisplay);
|
|
54915
|
+
setActualValue(newDisplay);
|
|
54916
|
+
onChangeRef.current(newDisplay);
|
|
54917
|
+
const nextCaret = at + clip.length;
|
|
54918
|
+
setNudgeCursorOffset(nextCaret);
|
|
54919
|
+
caretOffsetRef.current = nextCaret;
|
|
54920
|
+
}
|
|
54921
|
+
return;
|
|
54922
|
+
}
|
|
54739
54923
|
const isPasted = key?.isPasted;
|
|
54740
54924
|
if (isPasted) {
|
|
54741
54925
|
lastPasteDetectedAtRef.current = Date.now();
|
|
@@ -54827,6 +55011,29 @@ function PasteAwareTextInput({
|
|
|
54827
55011
|
setNudgeCursorOffset(wordStart);
|
|
54828
55012
|
caretOffsetRef.current = wordStart;
|
|
54829
55013
|
};
|
|
55014
|
+
const forwardDeleteAtCursor = (cursorPos) => {
|
|
55015
|
+
if (cursorPos >= displayValueRef.current.length)
|
|
55016
|
+
return;
|
|
55017
|
+
const newDisplay = displayValueRef.current.slice(0, cursorPos) + displayValueRef.current.slice(cursorPos + 1);
|
|
55018
|
+
const resolvedActual = resolvePlaceholders(newDisplay);
|
|
55019
|
+
displayValueRef.current = newDisplay;
|
|
55020
|
+
caretOffsetRef.current = cursorPos;
|
|
55021
|
+
setDisplayValue(newDisplay);
|
|
55022
|
+
setActualValue(resolvedActual);
|
|
55023
|
+
onChangeRef.current(newDisplay);
|
|
55024
|
+
setNudgeCursorOffset(cursorPos);
|
|
55025
|
+
};
|
|
55026
|
+
const insertNewlineAtCursor = () => {
|
|
55027
|
+
const at = Math.max(0, Math.min(caretOffsetRef.current, displayValueRef.current.length));
|
|
55028
|
+
const newValue = displayValueRef.current.slice(0, at) + `
|
|
55029
|
+
` + displayValueRef.current.slice(at);
|
|
55030
|
+
setDisplayValue(newValue);
|
|
55031
|
+
setActualValue(newValue);
|
|
55032
|
+
onChangeRef.current(newValue);
|
|
55033
|
+
const nextCaret = at + 1;
|
|
55034
|
+
setNudgeCursorOffset(nextCaret);
|
|
55035
|
+
caretOffsetRef.current = nextCaret;
|
|
55036
|
+
};
|
|
54830
55037
|
const handleRawInput = (payload) => {
|
|
54831
55038
|
if (!focusRef.current)
|
|
54832
55039
|
return;
|
|
@@ -54838,6 +55045,72 @@ function PasteAwareTextInput({
|
|
|
54838
55045
|
}
|
|
54839
55046
|
if (!sequence)
|
|
54840
55047
|
return;
|
|
55048
|
+
if (process.env.LETTA_DEBUG_INPUT === "1") {
|
|
55049
|
+
const debugHex = [...sequence].map((c) => `0x${c.charCodeAt(0).toString(16).padStart(2, "0")}`).join(" ");
|
|
55050
|
+
console.error(`[debug:raw-input] len=${sequence.length} hex: ${debugHex}`);
|
|
55051
|
+
}
|
|
55052
|
+
if (sequence === "\x1B\r" || sequence === `\x1B
|
|
55053
|
+
`) {
|
|
55054
|
+
insertNewlineAtCursor();
|
|
55055
|
+
return;
|
|
55056
|
+
}
|
|
55057
|
+
if (sequence === "\\r") {
|
|
55058
|
+
insertNewlineAtCursor();
|
|
55059
|
+
return;
|
|
55060
|
+
}
|
|
55061
|
+
{
|
|
55062
|
+
const prefix = "\x1B[13;";
|
|
55063
|
+
if (sequence.startsWith(prefix) && sequence.endsWith("u")) {
|
|
55064
|
+
const mod = sequence.slice(prefix.length, -1);
|
|
55065
|
+
if (mod.length === 1 && mod >= "2" && mod <= "8") {
|
|
55066
|
+
insertNewlineAtCursor();
|
|
55067
|
+
return;
|
|
55068
|
+
}
|
|
55069
|
+
}
|
|
55070
|
+
}
|
|
55071
|
+
if (sequence === "\x1B[99;5u") {
|
|
55072
|
+
internal_eventEmitter.emit("input", "\x03");
|
|
55073
|
+
return;
|
|
55074
|
+
}
|
|
55075
|
+
if (sequence.startsWith("\x1B[99;5:")) {
|
|
55076
|
+
return;
|
|
55077
|
+
}
|
|
55078
|
+
if (sequence === "\x1B[118;5u") {
|
|
55079
|
+
const clip = tryImportClipboardImageMac();
|
|
55080
|
+
if (clip) {
|
|
55081
|
+
const at = Math.max(0, Math.min(caretOffsetRef.current, displayValueRef.current.length));
|
|
55082
|
+
const newDisplay = displayValueRef.current.slice(0, at) + clip + displayValueRef.current.slice(at);
|
|
55083
|
+
displayValueRef.current = newDisplay;
|
|
55084
|
+
setDisplayValue(newDisplay);
|
|
55085
|
+
setActualValue(newDisplay);
|
|
55086
|
+
onChangeRef.current(newDisplay);
|
|
55087
|
+
const nextCaret = at + clip.length;
|
|
55088
|
+
setNudgeCursorOffset(nextCaret);
|
|
55089
|
+
caretOffsetRef.current = nextCaret;
|
|
55090
|
+
}
|
|
55091
|
+
return;
|
|
55092
|
+
}
|
|
55093
|
+
if (sequence.startsWith("\x1B[118;5:")) {
|
|
55094
|
+
return;
|
|
55095
|
+
}
|
|
55096
|
+
{
|
|
55097
|
+
const arrowMatch = sequence.match(/^\x1b\[1;\d+:[12]([ABCD])$/);
|
|
55098
|
+
if (arrowMatch) {
|
|
55099
|
+
internal_eventEmitter.emit("input", `\x1B[${arrowMatch[1]}`);
|
|
55100
|
+
return;
|
|
55101
|
+
}
|
|
55102
|
+
if (/^\x1b\[1;\d+:3[ABCD]$/.test(sequence)) {
|
|
55103
|
+
return;
|
|
55104
|
+
}
|
|
55105
|
+
}
|
|
55106
|
+
if (sequence === "\x1B[3~" || /^\x1b\[3;\d+:[12]~$/.test(sequence)) {
|
|
55107
|
+
globalThis.__lettaForwardDeleteTimestamp = Date.now();
|
|
55108
|
+
forwardDeleteAtCursor(caretOffsetRef.current);
|
|
55109
|
+
return;
|
|
55110
|
+
}
|
|
55111
|
+
if (/^\x1b\[3;\d+:3~$/.test(sequence)) {
|
|
55112
|
+
return;
|
|
55113
|
+
}
|
|
54841
55114
|
if (sequence === "\x1B" || sequence === "\x1B\b" || sequence === "\x1B\b" || sequence === "\x17") {
|
|
54842
55115
|
deletePreviousWord();
|
|
54843
55116
|
return;
|
|
@@ -54919,11 +55192,11 @@ function PasteAwareTextInput({
|
|
|
54919
55192
|
caretOffsetRef.current = nextCaret;
|
|
54920
55193
|
return;
|
|
54921
55194
|
}
|
|
55195
|
+
displayValueRef.current = newValue;
|
|
54922
55196
|
setDisplayValue(newValue);
|
|
54923
55197
|
const resolved = resolvePlaceholders(newValue);
|
|
54924
55198
|
setActualValue(resolved);
|
|
54925
55199
|
onChange(newValue);
|
|
54926
|
-
caretOffsetRef.current = newValue.length;
|
|
54927
55200
|
};
|
|
54928
55201
|
const handleSubmit = () => {
|
|
54929
55202
|
if (onSubmit) {
|
|
@@ -56712,6 +56985,318 @@ var init_FeedbackDialog = __esm(async () => {
|
|
|
56712
56985
|
jsx_dev_runtime17 = __toESM(require_jsx_dev_runtime(), 1);
|
|
56713
56986
|
});
|
|
56714
56987
|
|
|
56988
|
+
// src/cli/utils/terminalKeybindingInstaller.ts
|
|
56989
|
+
var exports_terminalKeybindingInstaller = {};
|
|
56990
|
+
__export(exports_terminalKeybindingInstaller, {
|
|
56991
|
+
wezTermDeleteFixExists: () => wezTermDeleteFixExists,
|
|
56992
|
+
removeKeybindingForCurrentTerminal: () => removeKeybindingForCurrentTerminal,
|
|
56993
|
+
removeKeybinding: () => removeKeybinding,
|
|
56994
|
+
keybindingExists: () => keybindingExists,
|
|
56995
|
+
isWezTerm: () => isWezTerm,
|
|
56996
|
+
isVSCodeLikeTerminal: () => isVSCodeLikeTerminal,
|
|
56997
|
+
installWezTermDeleteFix: () => installWezTermDeleteFix,
|
|
56998
|
+
installKeybindingForCurrentTerminal: () => installKeybindingForCurrentTerminal,
|
|
56999
|
+
installKeybinding: () => installKeybinding,
|
|
57000
|
+
getWezTermConfigPath: () => getWezTermConfigPath,
|
|
57001
|
+
getKeybindingsPath: () => getKeybindingsPath,
|
|
57002
|
+
detectTerminalType: () => detectTerminalType
|
|
57003
|
+
});
|
|
57004
|
+
import {
|
|
57005
|
+
copyFileSync,
|
|
57006
|
+
existsSync as existsSync10,
|
|
57007
|
+
mkdirSync as mkdirSync3,
|
|
57008
|
+
readFileSync as readFileSync3,
|
|
57009
|
+
writeFileSync
|
|
57010
|
+
} from "node:fs";
|
|
57011
|
+
import { homedir as homedir7, platform as platform3 } from "node:os";
|
|
57012
|
+
import { dirname as dirname9, join as join14 } from "node:path";
|
|
57013
|
+
function detectTerminalType() {
|
|
57014
|
+
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
57015
|
+
return "cursor";
|
|
57016
|
+
}
|
|
57017
|
+
if (process.env.WINDSURF_TRACE_ID || process.env.WINDSURF_CHANNEL) {
|
|
57018
|
+
return "windsurf";
|
|
57019
|
+
}
|
|
57020
|
+
const termProgram = process.env.TERM_PROGRAM?.toLowerCase();
|
|
57021
|
+
if (termProgram === "vscode")
|
|
57022
|
+
return "vscode";
|
|
57023
|
+
if (termProgram === "cursor")
|
|
57024
|
+
return "cursor";
|
|
57025
|
+
if (termProgram === "windsurf")
|
|
57026
|
+
return "windsurf";
|
|
57027
|
+
if (process.env.VSCODE_INJECTION === "1")
|
|
57028
|
+
return "vscode";
|
|
57029
|
+
return null;
|
|
57030
|
+
}
|
|
57031
|
+
function isVSCodeLikeTerminal() {
|
|
57032
|
+
return detectTerminalType() !== null;
|
|
57033
|
+
}
|
|
57034
|
+
function getKeybindingsPath(terminal) {
|
|
57035
|
+
if (!terminal)
|
|
57036
|
+
return null;
|
|
57037
|
+
const appName = {
|
|
57038
|
+
vscode: "Code",
|
|
57039
|
+
cursor: "Cursor",
|
|
57040
|
+
windsurf: "Windsurf"
|
|
57041
|
+
}[terminal];
|
|
57042
|
+
const os3 = platform3();
|
|
57043
|
+
if (os3 === "darwin") {
|
|
57044
|
+
return join14(homedir7(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
57045
|
+
}
|
|
57046
|
+
if (os3 === "win32") {
|
|
57047
|
+
const appData = process.env.APPDATA;
|
|
57048
|
+
if (!appData)
|
|
57049
|
+
return null;
|
|
57050
|
+
return join14(appData, appName, "User", "keybindings.json");
|
|
57051
|
+
}
|
|
57052
|
+
if (os3 === "linux") {
|
|
57053
|
+
return join14(homedir7(), ".config", appName, "User", "keybindings.json");
|
|
57054
|
+
}
|
|
57055
|
+
return null;
|
|
57056
|
+
}
|
|
57057
|
+
function stripJsonComments(jsonc) {
|
|
57058
|
+
let result = jsonc.replace(/\/\/.*$/gm, "");
|
|
57059
|
+
result = result.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
57060
|
+
result = result.replace(/,(\s*[}\]])/g, "$1");
|
|
57061
|
+
return result;
|
|
57062
|
+
}
|
|
57063
|
+
function parseKeybindings(content) {
|
|
57064
|
+
try {
|
|
57065
|
+
const stripped = stripJsonComments(content);
|
|
57066
|
+
const parsed = JSON.parse(stripped);
|
|
57067
|
+
if (!Array.isArray(parsed))
|
|
57068
|
+
return null;
|
|
57069
|
+
return parsed;
|
|
57070
|
+
} catch {
|
|
57071
|
+
return null;
|
|
57072
|
+
}
|
|
57073
|
+
}
|
|
57074
|
+
function keybindingExists(keybindingsPath) {
|
|
57075
|
+
if (!existsSync10(keybindingsPath))
|
|
57076
|
+
return false;
|
|
57077
|
+
try {
|
|
57078
|
+
const content = readFileSync3(keybindingsPath, { encoding: "utf-8" });
|
|
57079
|
+
const keybindings = parseKeybindings(content);
|
|
57080
|
+
if (!keybindings)
|
|
57081
|
+
return false;
|
|
57082
|
+
return keybindings.some((kb) => kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus"));
|
|
57083
|
+
} catch {
|
|
57084
|
+
return false;
|
|
57085
|
+
}
|
|
57086
|
+
}
|
|
57087
|
+
function createBackup(keybindingsPath) {
|
|
57088
|
+
if (!existsSync10(keybindingsPath))
|
|
57089
|
+
return null;
|
|
57090
|
+
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
57091
|
+
try {
|
|
57092
|
+
copyFileSync(keybindingsPath, backupPath);
|
|
57093
|
+
return backupPath;
|
|
57094
|
+
} catch {
|
|
57095
|
+
return null;
|
|
57096
|
+
}
|
|
57097
|
+
}
|
|
57098
|
+
function installKeybinding(keybindingsPath) {
|
|
57099
|
+
try {
|
|
57100
|
+
if (keybindingExists(keybindingsPath)) {
|
|
57101
|
+
return { success: true, alreadyExists: true };
|
|
57102
|
+
}
|
|
57103
|
+
const parentDir = dirname9(keybindingsPath);
|
|
57104
|
+
if (!existsSync10(parentDir)) {
|
|
57105
|
+
mkdirSync3(parentDir, { recursive: true });
|
|
57106
|
+
}
|
|
57107
|
+
let keybindings = [];
|
|
57108
|
+
let backupPath = null;
|
|
57109
|
+
if (existsSync10(keybindingsPath)) {
|
|
57110
|
+
backupPath = createBackup(keybindingsPath);
|
|
57111
|
+
const content = readFileSync3(keybindingsPath, { encoding: "utf-8" });
|
|
57112
|
+
const parsed = parseKeybindings(content);
|
|
57113
|
+
if (parsed === null) {
|
|
57114
|
+
return {
|
|
57115
|
+
success: false,
|
|
57116
|
+
error: `Could not parse ${keybindingsPath}. Please fix syntax errors and try again.`
|
|
57117
|
+
};
|
|
57118
|
+
}
|
|
57119
|
+
keybindings = parsed;
|
|
57120
|
+
}
|
|
57121
|
+
keybindings.push(SHIFT_ENTER_KEYBINDING);
|
|
57122
|
+
const newContent = `${JSON.stringify(keybindings, null, 2)}
|
|
57123
|
+
`;
|
|
57124
|
+
writeFileSync(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
57125
|
+
return {
|
|
57126
|
+
success: true,
|
|
57127
|
+
backupPath: backupPath ?? undefined
|
|
57128
|
+
};
|
|
57129
|
+
} catch (error) {
|
|
57130
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
57131
|
+
return {
|
|
57132
|
+
success: false,
|
|
57133
|
+
error: `Failed to install keybinding: ${message}`
|
|
57134
|
+
};
|
|
57135
|
+
}
|
|
57136
|
+
}
|
|
57137
|
+
function removeKeybinding(keybindingsPath) {
|
|
57138
|
+
try {
|
|
57139
|
+
if (!existsSync10(keybindingsPath)) {
|
|
57140
|
+
return { success: true };
|
|
57141
|
+
}
|
|
57142
|
+
const content = readFileSync3(keybindingsPath, { encoding: "utf-8" });
|
|
57143
|
+
const keybindings = parseKeybindings(content);
|
|
57144
|
+
if (!keybindings) {
|
|
57145
|
+
return {
|
|
57146
|
+
success: false,
|
|
57147
|
+
error: `Could not parse ${keybindingsPath}`
|
|
57148
|
+
};
|
|
57149
|
+
}
|
|
57150
|
+
const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
|
|
57151
|
+
const newContent = `${JSON.stringify(filtered, null, 2)}
|
|
57152
|
+
`;
|
|
57153
|
+
writeFileSync(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
57154
|
+
return { success: true };
|
|
57155
|
+
} catch (error) {
|
|
57156
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
57157
|
+
return {
|
|
57158
|
+
success: false,
|
|
57159
|
+
error: `Failed to remove keybinding: ${message}`
|
|
57160
|
+
};
|
|
57161
|
+
}
|
|
57162
|
+
}
|
|
57163
|
+
function installKeybindingForCurrentTerminal() {
|
|
57164
|
+
const terminal = detectTerminalType();
|
|
57165
|
+
if (!terminal) {
|
|
57166
|
+
return {
|
|
57167
|
+
success: false,
|
|
57168
|
+
error: "Not running in a VS Code-like terminal"
|
|
57169
|
+
};
|
|
57170
|
+
}
|
|
57171
|
+
const path17 = getKeybindingsPath(terminal);
|
|
57172
|
+
if (!path17) {
|
|
57173
|
+
return {
|
|
57174
|
+
success: false,
|
|
57175
|
+
error: `Could not determine keybindings.json path for ${terminal}`
|
|
57176
|
+
};
|
|
57177
|
+
}
|
|
57178
|
+
return installKeybinding(path17);
|
|
57179
|
+
}
|
|
57180
|
+
function removeKeybindingForCurrentTerminal() {
|
|
57181
|
+
const terminal = detectTerminalType();
|
|
57182
|
+
if (!terminal) {
|
|
57183
|
+
return {
|
|
57184
|
+
success: false,
|
|
57185
|
+
error: "Not running in a VS Code-like terminal"
|
|
57186
|
+
};
|
|
57187
|
+
}
|
|
57188
|
+
const path17 = getKeybindingsPath(terminal);
|
|
57189
|
+
if (!path17) {
|
|
57190
|
+
return {
|
|
57191
|
+
success: false,
|
|
57192
|
+
error: `Could not determine keybindings.json path for ${terminal}`
|
|
57193
|
+
};
|
|
57194
|
+
}
|
|
57195
|
+
return removeKeybinding(path17);
|
|
57196
|
+
}
|
|
57197
|
+
function isWezTerm() {
|
|
57198
|
+
return process.env.TERM_PROGRAM === "WezTerm";
|
|
57199
|
+
}
|
|
57200
|
+
function getWezTermConfigPath() {
|
|
57201
|
+
if (process.env.WEZTERM_CONFIG_FILE) {
|
|
57202
|
+
return process.env.WEZTERM_CONFIG_FILE;
|
|
57203
|
+
}
|
|
57204
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
57205
|
+
if (xdgConfig) {
|
|
57206
|
+
const xdgPath = join14(xdgConfig, "wezterm", "wezterm.lua");
|
|
57207
|
+
if (existsSync10(xdgPath))
|
|
57208
|
+
return xdgPath;
|
|
57209
|
+
}
|
|
57210
|
+
const configPath = join14(homedir7(), ".config", "wezterm", "wezterm.lua");
|
|
57211
|
+
if (existsSync10(configPath))
|
|
57212
|
+
return configPath;
|
|
57213
|
+
return join14(homedir7(), ".wezterm.lua");
|
|
57214
|
+
}
|
|
57215
|
+
function wezTermDeleteFixExists(configPath) {
|
|
57216
|
+
if (!existsSync10(configPath))
|
|
57217
|
+
return false;
|
|
57218
|
+
try {
|
|
57219
|
+
const content = readFileSync3(configPath, { encoding: "utf-8" });
|
|
57220
|
+
return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
|
|
57221
|
+
} catch {
|
|
57222
|
+
return false;
|
|
57223
|
+
}
|
|
57224
|
+
}
|
|
57225
|
+
function installWezTermDeleteFix() {
|
|
57226
|
+
const configPath = getWezTermConfigPath();
|
|
57227
|
+
try {
|
|
57228
|
+
if (wezTermDeleteFixExists(configPath)) {
|
|
57229
|
+
return { success: true, alreadyExists: true };
|
|
57230
|
+
}
|
|
57231
|
+
let content = "";
|
|
57232
|
+
let backupPath = null;
|
|
57233
|
+
if (existsSync10(configPath)) {
|
|
57234
|
+
backupPath = `${configPath}.letta-backup`;
|
|
57235
|
+
copyFileSync(configPath, backupPath);
|
|
57236
|
+
content = readFileSync3(configPath, { encoding: "utf-8" });
|
|
57237
|
+
}
|
|
57238
|
+
if (content.includes("return {") && !content.includes("local config")) {
|
|
57239
|
+
content = content.replace(/return\s*\{/, "local config = {");
|
|
57240
|
+
if (!content.includes("return config")) {
|
|
57241
|
+
content = `${content.trimEnd()}
|
|
57242
|
+
|
|
57243
|
+
return config
|
|
57244
|
+
`;
|
|
57245
|
+
}
|
|
57246
|
+
}
|
|
57247
|
+
if (!content.trim()) {
|
|
57248
|
+
content = `-- WezTerm configuration
|
|
57249
|
+
local config = {}
|
|
57250
|
+
|
|
57251
|
+
return config
|
|
57252
|
+
`;
|
|
57253
|
+
}
|
|
57254
|
+
if (content.includes("return config")) {
|
|
57255
|
+
content = content.replace("return config", `${WEZTERM_DELETE_FIX}
|
|
57256
|
+
return config`);
|
|
57257
|
+
} else {
|
|
57258
|
+
content = `${content.trimEnd()}
|
|
57259
|
+
${WEZTERM_DELETE_FIX}
|
|
57260
|
+
`;
|
|
57261
|
+
}
|
|
57262
|
+
const parentDir = dirname9(configPath);
|
|
57263
|
+
if (!existsSync10(parentDir)) {
|
|
57264
|
+
mkdirSync3(parentDir, { recursive: true });
|
|
57265
|
+
}
|
|
57266
|
+
writeFileSync(configPath, content, { encoding: "utf-8" });
|
|
57267
|
+
return {
|
|
57268
|
+
success: true,
|
|
57269
|
+
backupPath: backupPath ?? undefined
|
|
57270
|
+
};
|
|
57271
|
+
} catch (error) {
|
|
57272
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
57273
|
+
return {
|
|
57274
|
+
success: false,
|
|
57275
|
+
error: `Failed to install WezTerm Delete key fix: ${message}`
|
|
57276
|
+
};
|
|
57277
|
+
}
|
|
57278
|
+
}
|
|
57279
|
+
var SHIFT_ENTER_KEYBINDING, WEZTERM_DELETE_FIX = `
|
|
57280
|
+
-- Letta Code: Fix Delete key sending wrong sequence with kitty keyboard protocol
|
|
57281
|
+
-- See: https://github.com/wez/wezterm/issues/3758
|
|
57282
|
+
local wezterm = require 'wezterm'
|
|
57283
|
+
local keys = config.keys or {}
|
|
57284
|
+
table.insert(keys, {
|
|
57285
|
+
key = 'Delete',
|
|
57286
|
+
mods = 'NONE',
|
|
57287
|
+
action = wezterm.action.SendString '\\x1b[3~',
|
|
57288
|
+
})
|
|
57289
|
+
config.keys = keys
|
|
57290
|
+
`;
|
|
57291
|
+
var init_terminalKeybindingInstaller = __esm(() => {
|
|
57292
|
+
SHIFT_ENTER_KEYBINDING = {
|
|
57293
|
+
key: "shift+enter",
|
|
57294
|
+
command: "workbench.action.terminal.sendSequence",
|
|
57295
|
+
args: { text: "\x1B\r" },
|
|
57296
|
+
when: "terminalFocus"
|
|
57297
|
+
};
|
|
57298
|
+
});
|
|
57299
|
+
|
|
56715
57300
|
// src/cli/commands/registry.ts
|
|
56716
57301
|
var exports_registry = {};
|
|
56717
57302
|
__export(exports_registry, {
|
|
@@ -56901,6 +57486,51 @@ var init_registry = __esm(() => {
|
|
|
56901
57486
|
return "Opening help...";
|
|
56902
57487
|
}
|
|
56903
57488
|
},
|
|
57489
|
+
"/terminal": {
|
|
57490
|
+
desc: "Setup terminal shortcuts [--revert]",
|
|
57491
|
+
order: 36,
|
|
57492
|
+
handler: async (args) => {
|
|
57493
|
+
const {
|
|
57494
|
+
detectTerminalType: detectTerminalType2,
|
|
57495
|
+
getKeybindingsPath: getKeybindingsPath2,
|
|
57496
|
+
installKeybinding: installKeybinding2,
|
|
57497
|
+
removeKeybinding: removeKeybinding2
|
|
57498
|
+
} = await Promise.resolve().then(() => (init_terminalKeybindingInstaller(), exports_terminalKeybindingInstaller));
|
|
57499
|
+
const { updateSettings: updateSettings2 } = await Promise.resolve().then(() => (init_settings(), exports_settings));
|
|
57500
|
+
const isRevert = args.includes("--revert") || args.includes("--remove");
|
|
57501
|
+
const terminal = detectTerminalType2();
|
|
57502
|
+
if (!terminal) {
|
|
57503
|
+
return "Not running in a VS Code-like terminal. Shift+Enter keybinding is not needed.";
|
|
57504
|
+
}
|
|
57505
|
+
const terminalName = {
|
|
57506
|
+
vscode: "VS Code",
|
|
57507
|
+
cursor: "Cursor",
|
|
57508
|
+
windsurf: "Windsurf"
|
|
57509
|
+
}[terminal];
|
|
57510
|
+
const keybindingsPath = getKeybindingsPath2(terminal);
|
|
57511
|
+
if (!keybindingsPath) {
|
|
57512
|
+
return `Could not determine keybindings.json path for ${terminalName}`;
|
|
57513
|
+
}
|
|
57514
|
+
if (isRevert) {
|
|
57515
|
+
const result2 = removeKeybinding2(keybindingsPath);
|
|
57516
|
+
if (!result2.success) {
|
|
57517
|
+
return `Failed to remove keybinding: ${result2.error}`;
|
|
57518
|
+
}
|
|
57519
|
+
await updateSettings2({ shiftEnterKeybindingInstalled: false });
|
|
57520
|
+
return `Removed Shift+Enter keybinding from ${terminalName}`;
|
|
57521
|
+
}
|
|
57522
|
+
const result = installKeybinding2(keybindingsPath);
|
|
57523
|
+
if (!result.success) {
|
|
57524
|
+
return `Failed to install keybinding: ${result.error}`;
|
|
57525
|
+
}
|
|
57526
|
+
if (result.alreadyExists) {
|
|
57527
|
+
return `Shift+Enter keybinding already exists in ${terminalName}`;
|
|
57528
|
+
}
|
|
57529
|
+
await updateSettings2({ shiftEnterKeybindingInstalled: true });
|
|
57530
|
+
return `Installed Shift+Enter keybinding for ${terminalName}
|
|
57531
|
+
Location: ${keybindingsPath}`;
|
|
57532
|
+
}
|
|
57533
|
+
},
|
|
56904
57534
|
"/connect": {
|
|
56905
57535
|
desc: "Connect an existing Claude account (/connect claude)",
|
|
56906
57536
|
order: 40,
|
|
@@ -56986,9 +57616,9 @@ __export(exports_custom, {
|
|
|
56986
57616
|
GLOBAL_COMMANDS_DIR: () => GLOBAL_COMMANDS_DIR,
|
|
56987
57617
|
COMMANDS_DIR: () => COMMANDS_DIR
|
|
56988
57618
|
});
|
|
56989
|
-
import { existsSync as
|
|
57619
|
+
import { existsSync as existsSync11 } from "node:fs";
|
|
56990
57620
|
import { readdir as readdir7, readFile as readFile8 } from "node:fs/promises";
|
|
56991
|
-
import { basename as basename3, dirname as
|
|
57621
|
+
import { basename as basename3, dirname as dirname10, join as join15 } from "node:path";
|
|
56992
57622
|
async function getCustomCommands() {
|
|
56993
57623
|
if (cachedCommands !== null) {
|
|
56994
57624
|
return cachedCommands;
|
|
@@ -56999,7 +57629,7 @@ async function getCustomCommands() {
|
|
|
56999
57629
|
function refreshCustomCommands() {
|
|
57000
57630
|
cachedCommands = null;
|
|
57001
57631
|
}
|
|
57002
|
-
async function discoverCustomCommands(projectPath =
|
|
57632
|
+
async function discoverCustomCommands(projectPath = join15(process.cwd(), COMMANDS_DIR)) {
|
|
57003
57633
|
const commandsById = new Map;
|
|
57004
57634
|
const userCommands = await discoverFromDirectory(GLOBAL_COMMANDS_DIR, "user");
|
|
57005
57635
|
for (const cmd of userCommands) {
|
|
@@ -57020,7 +57650,7 @@ async function discoverCustomCommands(projectPath = join14(process.cwd(), COMMAN
|
|
|
57020
57650
|
return result;
|
|
57021
57651
|
}
|
|
57022
57652
|
async function discoverFromDirectory(dirPath, source) {
|
|
57023
|
-
if (!
|
|
57653
|
+
if (!existsSync11(dirPath)) {
|
|
57024
57654
|
return [];
|
|
57025
57655
|
}
|
|
57026
57656
|
const commands2 = [];
|
|
@@ -57031,7 +57661,7 @@ async function findCommandFiles(currentPath, rootPath, commands2, source) {
|
|
|
57031
57661
|
try {
|
|
57032
57662
|
const entries = await readdir7(currentPath, { withFileTypes: true });
|
|
57033
57663
|
for (const entry of entries) {
|
|
57034
|
-
const fullPath =
|
|
57664
|
+
const fullPath = join15(currentPath, entry.name);
|
|
57035
57665
|
if (entry.isDirectory()) {
|
|
57036
57666
|
await findCommandFiles(fullPath, rootPath, commands2, source);
|
|
57037
57667
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
@@ -57049,7 +57679,7 @@ async function parseCommandFile(filePath, rootPath, source) {
|
|
|
57049
57679
|
const content = await readFile8(filePath, "utf-8");
|
|
57050
57680
|
const { frontmatter, body } = parseFrontmatter(content);
|
|
57051
57681
|
const id = basename3(filePath, ".md");
|
|
57052
|
-
const relativePath =
|
|
57682
|
+
const relativePath = dirname10(filePath).slice(rootPath.length);
|
|
57053
57683
|
const namespace = relativePath.replace(/^[/\\]/, "") || undefined;
|
|
57054
57684
|
let description = getStringField(frontmatter, "description");
|
|
57055
57685
|
if (!description) {
|
|
@@ -57116,7 +57746,7 @@ async function findCustomCommand(commandName) {
|
|
|
57116
57746
|
}
|
|
57117
57747
|
var COMMANDS_DIR = ".commands", GLOBAL_COMMANDS_DIR, cachedCommands = null;
|
|
57118
57748
|
var init_custom = __esm(() => {
|
|
57119
|
-
GLOBAL_COMMANDS_DIR =
|
|
57749
|
+
GLOBAL_COMMANDS_DIR = join15(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
|
|
57120
57750
|
});
|
|
57121
57751
|
|
|
57122
57752
|
// src/cli/components/HelpDialog.tsx
|
|
@@ -57155,6 +57785,8 @@ function HelpDialog({ onClose }) {
|
|
|
57155
57785
|
{ keys: "Tab", description: "Autocomplete command or file path" },
|
|
57156
57786
|
{ keys: "↓", description: "Navigate down / next command in history" },
|
|
57157
57787
|
{ keys: "↑", description: "Navigate up / previous command in history" },
|
|
57788
|
+
{ keys: "Shift+Enter", description: "Insert newline (multi-line input)" },
|
|
57789
|
+
{ keys: "Opt+Enter", description: "Insert newline (alternative)" },
|
|
57158
57790
|
{
|
|
57159
57791
|
keys: "Ctrl+C",
|
|
57160
57792
|
description: "Interrupt operation / exit (double press)"
|
|
@@ -60354,7 +60986,7 @@ var init_AgentInfoBar = __esm(async () => {
|
|
|
60354
60986
|
|
|
60355
60987
|
// src/cli/helpers/fileSearch.ts
|
|
60356
60988
|
import { readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
|
|
60357
|
-
import { join as
|
|
60989
|
+
import { join as join16, resolve as resolve17 } from "node:path";
|
|
60358
60990
|
function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = []) {
|
|
60359
60991
|
if (results.length >= maxResults) {
|
|
60360
60992
|
return results;
|
|
@@ -60366,7 +60998,7 @@ function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = [])
|
|
|
60366
60998
|
continue;
|
|
60367
60999
|
}
|
|
60368
61000
|
try {
|
|
60369
|
-
const fullPath =
|
|
61001
|
+
const fullPath = join16(dir, entry);
|
|
60370
61002
|
const stats = statSync2(fullPath);
|
|
60371
61003
|
const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
|
|
60372
61004
|
const matches = pattern.length === 0 || relativePath.toLowerCase().includes(pattern.toLowerCase());
|
|
@@ -60418,7 +61050,7 @@ async function searchFiles(query, deep = false) {
|
|
|
60418
61050
|
const matchingEntries = searchPattern.length === 0 ? entries : entries.filter((entry) => entry.toLowerCase().includes(searchPattern.toLowerCase()));
|
|
60419
61051
|
for (const entry of matchingEntries.slice(0, 50)) {
|
|
60420
61052
|
try {
|
|
60421
|
-
const fullPath =
|
|
61053
|
+
const fullPath = join16(searchDir, entry);
|
|
60422
61054
|
const stats = statSync2(fullPath);
|
|
60423
61055
|
const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
|
|
60424
61056
|
results.push({
|
|
@@ -68297,7 +68929,7 @@ __export(exports_sessionContext, {
|
|
|
68297
68929
|
buildSessionContext: () => buildSessionContext
|
|
68298
68930
|
});
|
|
68299
68931
|
import { execSync } from "node:child_process";
|
|
68300
|
-
import { platform as
|
|
68932
|
+
import { platform as platform4 } from "node:os";
|
|
68301
68933
|
function getLocalTime() {
|
|
68302
68934
|
const now = new Date;
|
|
68303
68935
|
return now.toLocaleString(undefined, {
|
|
@@ -68311,7 +68943,7 @@ function getLocalTime() {
|
|
|
68311
68943
|
});
|
|
68312
68944
|
}
|
|
68313
68945
|
function getDeviceType() {
|
|
68314
|
-
const p =
|
|
68946
|
+
const p = platform4();
|
|
68315
68947
|
switch (p) {
|
|
68316
68948
|
case "darwin":
|
|
68317
68949
|
return "macOS";
|
|
@@ -68434,7 +69066,7 @@ ${gitInfo.status}
|
|
|
68434
69066
|
context3 += `- **Git repository**: No
|
|
68435
69067
|
`;
|
|
68436
69068
|
}
|
|
68437
|
-
if (
|
|
69069
|
+
if (platform4() === "win32") {
|
|
68438
69070
|
context3 += `
|
|
68439
69071
|
## Windows Shell Notes
|
|
68440
69072
|
- The Bash tool uses PowerShell or cmd.exe on Windows
|
|
@@ -68466,7 +69098,7 @@ var exports_App = {};
|
|
|
68466
69098
|
__export(exports_App, {
|
|
68467
69099
|
default: () => App2
|
|
68468
69100
|
});
|
|
68469
|
-
import { existsSync as
|
|
69101
|
+
import { existsSync as existsSync12, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
68470
69102
|
function uid4(prefix) {
|
|
68471
69103
|
return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
68472
69104
|
}
|
|
@@ -68547,18 +69179,18 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
|
|
68547
69179
|
}
|
|
68548
69180
|
function planFileExists() {
|
|
68549
69181
|
const planFilePath = permissionMode2.getPlanFilePath();
|
|
68550
|
-
return !!planFilePath &&
|
|
69182
|
+
return !!planFilePath && existsSync12(planFilePath);
|
|
68551
69183
|
}
|
|
68552
69184
|
function readPlanFile() {
|
|
68553
69185
|
const planFilePath = permissionMode2.getPlanFilePath();
|
|
68554
69186
|
if (!planFilePath) {
|
|
68555
69187
|
return "No plan file path set.";
|
|
68556
69188
|
}
|
|
68557
|
-
if (!
|
|
69189
|
+
if (!existsSync12(planFilePath)) {
|
|
68558
69190
|
return `Plan file not found at ${planFilePath}`;
|
|
68559
69191
|
}
|
|
68560
69192
|
try {
|
|
68561
|
-
return
|
|
69193
|
+
return readFileSync4(planFilePath, "utf-8");
|
|
68562
69194
|
} catch {
|
|
68563
69195
|
return `Failed to read plan file at ${planFilePath}`;
|
|
68564
69196
|
}
|
|
@@ -70427,7 +71059,7 @@ Press Enter to continue, or type anything to cancel.`, false, "running");
|
|
|
70427
71059
|
const client = await getClient2();
|
|
70428
71060
|
const fileContent = await client.agents.exportFile(agentId);
|
|
70429
71061
|
const fileName = `${agentId}.af`;
|
|
70430
|
-
|
|
71062
|
+
writeFileSync2(fileName, JSON.stringify(fileContent, null, 2));
|
|
70431
71063
|
buffersRef.current.byId.set(cmdId2, {
|
|
70432
71064
|
kind: "command",
|
|
70433
71065
|
id: cmdId2,
|
|
@@ -72282,6 +72914,414 @@ var init_App2 = __esm(async () => {
|
|
|
72282
72914
|
jsx_dev_runtime50 = __toESM(require_jsx_dev_runtime(), 1);
|
|
72283
72915
|
});
|
|
72284
72916
|
|
|
72917
|
+
// src/cli/utils/terminalKeybindingInstaller.ts
|
|
72918
|
+
var exports_terminalKeybindingInstaller2 = {};
|
|
72919
|
+
__export(exports_terminalKeybindingInstaller2, {
|
|
72920
|
+
wezTermDeleteFixExists: () => wezTermDeleteFixExists2,
|
|
72921
|
+
removeKeybindingForCurrentTerminal: () => removeKeybindingForCurrentTerminal2,
|
|
72922
|
+
removeKeybinding: () => removeKeybinding2,
|
|
72923
|
+
keybindingExists: () => keybindingExists2,
|
|
72924
|
+
isWezTerm: () => isWezTerm2,
|
|
72925
|
+
isVSCodeLikeTerminal: () => isVSCodeLikeTerminal2,
|
|
72926
|
+
installWezTermDeleteFix: () => installWezTermDeleteFix2,
|
|
72927
|
+
installKeybindingForCurrentTerminal: () => installKeybindingForCurrentTerminal2,
|
|
72928
|
+
installKeybinding: () => installKeybinding2,
|
|
72929
|
+
getWezTermConfigPath: () => getWezTermConfigPath2,
|
|
72930
|
+
getKeybindingsPath: () => getKeybindingsPath2,
|
|
72931
|
+
detectTerminalType: () => detectTerminalType2
|
|
72932
|
+
});
|
|
72933
|
+
import {
|
|
72934
|
+
copyFileSync as copyFileSync2,
|
|
72935
|
+
existsSync as existsSync13,
|
|
72936
|
+
mkdirSync as mkdirSync4,
|
|
72937
|
+
readFileSync as readFileSync5,
|
|
72938
|
+
writeFileSync as writeFileSync3
|
|
72939
|
+
} from "node:fs";
|
|
72940
|
+
import { homedir as homedir8, platform as platform5 } from "node:os";
|
|
72941
|
+
import { dirname as dirname11, join as join17 } from "node:path";
|
|
72942
|
+
function detectTerminalType2() {
|
|
72943
|
+
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
72944
|
+
return "cursor";
|
|
72945
|
+
}
|
|
72946
|
+
if (process.env.WINDSURF_TRACE_ID || process.env.WINDSURF_CHANNEL) {
|
|
72947
|
+
return "windsurf";
|
|
72948
|
+
}
|
|
72949
|
+
const termProgram = process.env.TERM_PROGRAM?.toLowerCase();
|
|
72950
|
+
if (termProgram === "vscode")
|
|
72951
|
+
return "vscode";
|
|
72952
|
+
if (termProgram === "cursor")
|
|
72953
|
+
return "cursor";
|
|
72954
|
+
if (termProgram === "windsurf")
|
|
72955
|
+
return "windsurf";
|
|
72956
|
+
if (process.env.VSCODE_INJECTION === "1")
|
|
72957
|
+
return "vscode";
|
|
72958
|
+
return null;
|
|
72959
|
+
}
|
|
72960
|
+
function isVSCodeLikeTerminal2() {
|
|
72961
|
+
return detectTerminalType2() !== null;
|
|
72962
|
+
}
|
|
72963
|
+
function getKeybindingsPath2(terminal) {
|
|
72964
|
+
if (!terminal)
|
|
72965
|
+
return null;
|
|
72966
|
+
const appName = {
|
|
72967
|
+
vscode: "Code",
|
|
72968
|
+
cursor: "Cursor",
|
|
72969
|
+
windsurf: "Windsurf"
|
|
72970
|
+
}[terminal];
|
|
72971
|
+
const os4 = platform5();
|
|
72972
|
+
if (os4 === "darwin") {
|
|
72973
|
+
return join17(homedir8(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
72974
|
+
}
|
|
72975
|
+
if (os4 === "win32") {
|
|
72976
|
+
const appData = process.env.APPDATA;
|
|
72977
|
+
if (!appData)
|
|
72978
|
+
return null;
|
|
72979
|
+
return join17(appData, appName, "User", "keybindings.json");
|
|
72980
|
+
}
|
|
72981
|
+
if (os4 === "linux") {
|
|
72982
|
+
return join17(homedir8(), ".config", appName, "User", "keybindings.json");
|
|
72983
|
+
}
|
|
72984
|
+
return null;
|
|
72985
|
+
}
|
|
72986
|
+
function stripJsonComments2(jsonc) {
|
|
72987
|
+
let result = jsonc.replace(/\/\/.*$/gm, "");
|
|
72988
|
+
result = result.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
72989
|
+
result = result.replace(/,(\s*[}\]])/g, "$1");
|
|
72990
|
+
return result;
|
|
72991
|
+
}
|
|
72992
|
+
function parseKeybindings2(content) {
|
|
72993
|
+
try {
|
|
72994
|
+
const stripped = stripJsonComments2(content);
|
|
72995
|
+
const parsed = JSON.parse(stripped);
|
|
72996
|
+
if (!Array.isArray(parsed))
|
|
72997
|
+
return null;
|
|
72998
|
+
return parsed;
|
|
72999
|
+
} catch {
|
|
73000
|
+
return null;
|
|
73001
|
+
}
|
|
73002
|
+
}
|
|
73003
|
+
function keybindingExists2(keybindingsPath) {
|
|
73004
|
+
if (!existsSync13(keybindingsPath))
|
|
73005
|
+
return false;
|
|
73006
|
+
try {
|
|
73007
|
+
const content = readFileSync5(keybindingsPath, { encoding: "utf-8" });
|
|
73008
|
+
const keybindings = parseKeybindings2(content);
|
|
73009
|
+
if (!keybindings)
|
|
73010
|
+
return false;
|
|
73011
|
+
return keybindings.some((kb) => kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus"));
|
|
73012
|
+
} catch {
|
|
73013
|
+
return false;
|
|
73014
|
+
}
|
|
73015
|
+
}
|
|
73016
|
+
function createBackup2(keybindingsPath) {
|
|
73017
|
+
if (!existsSync13(keybindingsPath))
|
|
73018
|
+
return null;
|
|
73019
|
+
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
73020
|
+
try {
|
|
73021
|
+
copyFileSync2(keybindingsPath, backupPath);
|
|
73022
|
+
return backupPath;
|
|
73023
|
+
} catch {
|
|
73024
|
+
return null;
|
|
73025
|
+
}
|
|
73026
|
+
}
|
|
73027
|
+
function installKeybinding2(keybindingsPath) {
|
|
73028
|
+
try {
|
|
73029
|
+
if (keybindingExists2(keybindingsPath)) {
|
|
73030
|
+
return { success: true, alreadyExists: true };
|
|
73031
|
+
}
|
|
73032
|
+
const parentDir = dirname11(keybindingsPath);
|
|
73033
|
+
if (!existsSync13(parentDir)) {
|
|
73034
|
+
mkdirSync4(parentDir, { recursive: true });
|
|
73035
|
+
}
|
|
73036
|
+
let keybindings = [];
|
|
73037
|
+
let backupPath = null;
|
|
73038
|
+
if (existsSync13(keybindingsPath)) {
|
|
73039
|
+
backupPath = createBackup2(keybindingsPath);
|
|
73040
|
+
const content = readFileSync5(keybindingsPath, { encoding: "utf-8" });
|
|
73041
|
+
const parsed = parseKeybindings2(content);
|
|
73042
|
+
if (parsed === null) {
|
|
73043
|
+
return {
|
|
73044
|
+
success: false,
|
|
73045
|
+
error: `Could not parse ${keybindingsPath}. Please fix syntax errors and try again.`
|
|
73046
|
+
};
|
|
73047
|
+
}
|
|
73048
|
+
keybindings = parsed;
|
|
73049
|
+
}
|
|
73050
|
+
keybindings.push(SHIFT_ENTER_KEYBINDING2);
|
|
73051
|
+
const newContent = `${JSON.stringify(keybindings, null, 2)}
|
|
73052
|
+
`;
|
|
73053
|
+
writeFileSync3(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
73054
|
+
return {
|
|
73055
|
+
success: true,
|
|
73056
|
+
backupPath: backupPath ?? undefined
|
|
73057
|
+
};
|
|
73058
|
+
} catch (error) {
|
|
73059
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
73060
|
+
return {
|
|
73061
|
+
success: false,
|
|
73062
|
+
error: `Failed to install keybinding: ${message}`
|
|
73063
|
+
};
|
|
73064
|
+
}
|
|
73065
|
+
}
|
|
73066
|
+
function removeKeybinding2(keybindingsPath) {
|
|
73067
|
+
try {
|
|
73068
|
+
if (!existsSync13(keybindingsPath)) {
|
|
73069
|
+
return { success: true };
|
|
73070
|
+
}
|
|
73071
|
+
const content = readFileSync5(keybindingsPath, { encoding: "utf-8" });
|
|
73072
|
+
const keybindings = parseKeybindings2(content);
|
|
73073
|
+
if (!keybindings) {
|
|
73074
|
+
return {
|
|
73075
|
+
success: false,
|
|
73076
|
+
error: `Could not parse ${keybindingsPath}`
|
|
73077
|
+
};
|
|
73078
|
+
}
|
|
73079
|
+
const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
|
|
73080
|
+
const newContent = `${JSON.stringify(filtered, null, 2)}
|
|
73081
|
+
`;
|
|
73082
|
+
writeFileSync3(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
73083
|
+
return { success: true };
|
|
73084
|
+
} catch (error) {
|
|
73085
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
73086
|
+
return {
|
|
73087
|
+
success: false,
|
|
73088
|
+
error: `Failed to remove keybinding: ${message}`
|
|
73089
|
+
};
|
|
73090
|
+
}
|
|
73091
|
+
}
|
|
73092
|
+
function installKeybindingForCurrentTerminal2() {
|
|
73093
|
+
const terminal = detectTerminalType2();
|
|
73094
|
+
if (!terminal) {
|
|
73095
|
+
return {
|
|
73096
|
+
success: false,
|
|
73097
|
+
error: "Not running in a VS Code-like terminal"
|
|
73098
|
+
};
|
|
73099
|
+
}
|
|
73100
|
+
const path17 = getKeybindingsPath2(terminal);
|
|
73101
|
+
if (!path17) {
|
|
73102
|
+
return {
|
|
73103
|
+
success: false,
|
|
73104
|
+
error: `Could not determine keybindings.json path for ${terminal}`
|
|
73105
|
+
};
|
|
73106
|
+
}
|
|
73107
|
+
return installKeybinding2(path17);
|
|
73108
|
+
}
|
|
73109
|
+
function removeKeybindingForCurrentTerminal2() {
|
|
73110
|
+
const terminal = detectTerminalType2();
|
|
73111
|
+
if (!terminal) {
|
|
73112
|
+
return {
|
|
73113
|
+
success: false,
|
|
73114
|
+
error: "Not running in a VS Code-like terminal"
|
|
73115
|
+
};
|
|
73116
|
+
}
|
|
73117
|
+
const path17 = getKeybindingsPath2(terminal);
|
|
73118
|
+
if (!path17) {
|
|
73119
|
+
return {
|
|
73120
|
+
success: false,
|
|
73121
|
+
error: `Could not determine keybindings.json path for ${terminal}`
|
|
73122
|
+
};
|
|
73123
|
+
}
|
|
73124
|
+
return removeKeybinding2(path17);
|
|
73125
|
+
}
|
|
73126
|
+
function isWezTerm2() {
|
|
73127
|
+
return process.env.TERM_PROGRAM === "WezTerm";
|
|
73128
|
+
}
|
|
73129
|
+
function getWezTermConfigPath2() {
|
|
73130
|
+
if (process.env.WEZTERM_CONFIG_FILE) {
|
|
73131
|
+
return process.env.WEZTERM_CONFIG_FILE;
|
|
73132
|
+
}
|
|
73133
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
73134
|
+
if (xdgConfig) {
|
|
73135
|
+
const xdgPath = join17(xdgConfig, "wezterm", "wezterm.lua");
|
|
73136
|
+
if (existsSync13(xdgPath))
|
|
73137
|
+
return xdgPath;
|
|
73138
|
+
}
|
|
73139
|
+
const configPath = join17(homedir8(), ".config", "wezterm", "wezterm.lua");
|
|
73140
|
+
if (existsSync13(configPath))
|
|
73141
|
+
return configPath;
|
|
73142
|
+
return join17(homedir8(), ".wezterm.lua");
|
|
73143
|
+
}
|
|
73144
|
+
function wezTermDeleteFixExists2(configPath) {
|
|
73145
|
+
if (!existsSync13(configPath))
|
|
73146
|
+
return false;
|
|
73147
|
+
try {
|
|
73148
|
+
const content = readFileSync5(configPath, { encoding: "utf-8" });
|
|
73149
|
+
return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
|
|
73150
|
+
} catch {
|
|
73151
|
+
return false;
|
|
73152
|
+
}
|
|
73153
|
+
}
|
|
73154
|
+
function installWezTermDeleteFix2() {
|
|
73155
|
+
const configPath = getWezTermConfigPath2();
|
|
73156
|
+
try {
|
|
73157
|
+
if (wezTermDeleteFixExists2(configPath)) {
|
|
73158
|
+
return { success: true, alreadyExists: true };
|
|
73159
|
+
}
|
|
73160
|
+
let content = "";
|
|
73161
|
+
let backupPath = null;
|
|
73162
|
+
if (existsSync13(configPath)) {
|
|
73163
|
+
backupPath = `${configPath}.letta-backup`;
|
|
73164
|
+
copyFileSync2(configPath, backupPath);
|
|
73165
|
+
content = readFileSync5(configPath, { encoding: "utf-8" });
|
|
73166
|
+
}
|
|
73167
|
+
if (content.includes("return {") && !content.includes("local config")) {
|
|
73168
|
+
content = content.replace(/return\s*\{/, "local config = {");
|
|
73169
|
+
if (!content.includes("return config")) {
|
|
73170
|
+
content = `${content.trimEnd()}
|
|
73171
|
+
|
|
73172
|
+
return config
|
|
73173
|
+
`;
|
|
73174
|
+
}
|
|
73175
|
+
}
|
|
73176
|
+
if (!content.trim()) {
|
|
73177
|
+
content = `-- WezTerm configuration
|
|
73178
|
+
local config = {}
|
|
73179
|
+
|
|
73180
|
+
return config
|
|
73181
|
+
`;
|
|
73182
|
+
}
|
|
73183
|
+
if (content.includes("return config")) {
|
|
73184
|
+
content = content.replace("return config", `${WEZTERM_DELETE_FIX2}
|
|
73185
|
+
return config`);
|
|
73186
|
+
} else {
|
|
73187
|
+
content = `${content.trimEnd()}
|
|
73188
|
+
${WEZTERM_DELETE_FIX2}
|
|
73189
|
+
`;
|
|
73190
|
+
}
|
|
73191
|
+
const parentDir = dirname11(configPath);
|
|
73192
|
+
if (!existsSync13(parentDir)) {
|
|
73193
|
+
mkdirSync4(parentDir, { recursive: true });
|
|
73194
|
+
}
|
|
73195
|
+
writeFileSync3(configPath, content, { encoding: "utf-8" });
|
|
73196
|
+
return {
|
|
73197
|
+
success: true,
|
|
73198
|
+
backupPath: backupPath ?? undefined
|
|
73199
|
+
};
|
|
73200
|
+
} catch (error) {
|
|
73201
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
73202
|
+
return {
|
|
73203
|
+
success: false,
|
|
73204
|
+
error: `Failed to install WezTerm Delete key fix: ${message}`
|
|
73205
|
+
};
|
|
73206
|
+
}
|
|
73207
|
+
}
|
|
73208
|
+
var SHIFT_ENTER_KEYBINDING2, WEZTERM_DELETE_FIX2 = `
|
|
73209
|
+
-- Letta Code: Fix Delete key sending wrong sequence with kitty keyboard protocol
|
|
73210
|
+
-- See: https://github.com/wez/wezterm/issues/3758
|
|
73211
|
+
local wezterm = require 'wezterm'
|
|
73212
|
+
local keys = config.keys or {}
|
|
73213
|
+
table.insert(keys, {
|
|
73214
|
+
key = 'Delete',
|
|
73215
|
+
mods = 'NONE',
|
|
73216
|
+
action = wezterm.action.SendString '\\x1b[3~',
|
|
73217
|
+
})
|
|
73218
|
+
config.keys = keys
|
|
73219
|
+
`;
|
|
73220
|
+
var init_terminalKeybindingInstaller2 = __esm(() => {
|
|
73221
|
+
SHIFT_ENTER_KEYBINDING2 = {
|
|
73222
|
+
key: "shift+enter",
|
|
73223
|
+
command: "workbench.action.terminal.sendSequence",
|
|
73224
|
+
args: { text: "\x1B\r" },
|
|
73225
|
+
when: "terminalFocus"
|
|
73226
|
+
};
|
|
73227
|
+
});
|
|
73228
|
+
|
|
73229
|
+
// src/settings.ts
|
|
73230
|
+
var exports_settings2 = {};
|
|
73231
|
+
__export(exports_settings2, {
|
|
73232
|
+
updateSettings: () => updateSettings2,
|
|
73233
|
+
updateProjectSettings: () => updateProjectSettings2,
|
|
73234
|
+
saveSettings: () => saveSettings2,
|
|
73235
|
+
saveProjectSettings: () => saveProjectSettings2,
|
|
73236
|
+
loadSettings: () => loadSettings2,
|
|
73237
|
+
loadProjectSettings: () => loadProjectSettings2,
|
|
73238
|
+
getSetting: () => getSetting2
|
|
73239
|
+
});
|
|
73240
|
+
import { homedir as homedir9 } from "node:os";
|
|
73241
|
+
import { join as join18 } from "node:path";
|
|
73242
|
+
function getSettingsPath2() {
|
|
73243
|
+
return join18(homedir9(), ".letta", "settings.json");
|
|
73244
|
+
}
|
|
73245
|
+
async function loadSettings2() {
|
|
73246
|
+
const settingsPath = getSettingsPath2();
|
|
73247
|
+
try {
|
|
73248
|
+
if (!exists(settingsPath)) {
|
|
73249
|
+
await saveSettings2(DEFAULT_SETTINGS4);
|
|
73250
|
+
return DEFAULT_SETTINGS4;
|
|
73251
|
+
}
|
|
73252
|
+
const content = await readFile(settingsPath);
|
|
73253
|
+
const settings = JSON.parse(content);
|
|
73254
|
+
return { ...DEFAULT_SETTINGS4, ...settings };
|
|
73255
|
+
} catch (error) {
|
|
73256
|
+
console.error("Error loading settings, using defaults:", error);
|
|
73257
|
+
return DEFAULT_SETTINGS4;
|
|
73258
|
+
}
|
|
73259
|
+
}
|
|
73260
|
+
async function saveSettings2(settings) {
|
|
73261
|
+
const settingsPath = getSettingsPath2();
|
|
73262
|
+
try {
|
|
73263
|
+
await writeFile(settingsPath, JSON.stringify(settings, null, 2));
|
|
73264
|
+
} catch (error) {
|
|
73265
|
+
console.error("Error saving settings:", error);
|
|
73266
|
+
throw error;
|
|
73267
|
+
}
|
|
73268
|
+
}
|
|
73269
|
+
async function updateSettings2(updates) {
|
|
73270
|
+
const currentSettings = await loadSettings2();
|
|
73271
|
+
const newSettings = { ...currentSettings, ...updates };
|
|
73272
|
+
await saveSettings2(newSettings);
|
|
73273
|
+
return newSettings;
|
|
73274
|
+
}
|
|
73275
|
+
async function getSetting2(key) {
|
|
73276
|
+
const settings = await loadSettings2();
|
|
73277
|
+
return settings[key];
|
|
73278
|
+
}
|
|
73279
|
+
function getProjectSettingsPath2() {
|
|
73280
|
+
return join18(process.cwd(), ".letta", "settings.local.json");
|
|
73281
|
+
}
|
|
73282
|
+
async function loadProjectSettings2() {
|
|
73283
|
+
const settingsPath = getProjectSettingsPath2();
|
|
73284
|
+
try {
|
|
73285
|
+
if (!exists(settingsPath)) {
|
|
73286
|
+
return null;
|
|
73287
|
+
}
|
|
73288
|
+
const content = await readFile(settingsPath);
|
|
73289
|
+
const settings = JSON.parse(content);
|
|
73290
|
+
return settings;
|
|
73291
|
+
} catch (error) {
|
|
73292
|
+
console.error("Error loading project settings:", error);
|
|
73293
|
+
return null;
|
|
73294
|
+
}
|
|
73295
|
+
}
|
|
73296
|
+
async function saveProjectSettings2(settings) {
|
|
73297
|
+
const settingsPath = getProjectSettingsPath2();
|
|
73298
|
+
const dirPath = join18(process.cwd(), ".letta");
|
|
73299
|
+
try {
|
|
73300
|
+
if (!exists(dirPath)) {
|
|
73301
|
+
await mkdir(dirPath, { recursive: true });
|
|
73302
|
+
}
|
|
73303
|
+
await writeFile(settingsPath, JSON.stringify(settings, null, 2));
|
|
73304
|
+
} catch (error) {
|
|
73305
|
+
console.error("Error saving project settings:", error);
|
|
73306
|
+
throw error;
|
|
73307
|
+
}
|
|
73308
|
+
}
|
|
73309
|
+
async function updateProjectSettings2(updates) {
|
|
73310
|
+
const currentSettings = await loadProjectSettings2() || { lastAgent: null };
|
|
73311
|
+
const newSettings = { ...currentSettings, ...updates };
|
|
73312
|
+
await saveProjectSettings2(newSettings);
|
|
73313
|
+
return newSettings;
|
|
73314
|
+
}
|
|
73315
|
+
var DEFAULT_SETTINGS4;
|
|
73316
|
+
var init_settings2 = __esm(() => {
|
|
73317
|
+
init_fs();
|
|
73318
|
+
DEFAULT_SETTINGS4 = {
|
|
73319
|
+
lastAgent: null,
|
|
73320
|
+
tokenStreaming: false,
|
|
73321
|
+
globalSharedBlockIds: {}
|
|
73322
|
+
};
|
|
73323
|
+
});
|
|
73324
|
+
|
|
72285
73325
|
// src/tools/toolset.ts
|
|
72286
73326
|
var exports_toolset2 = {};
|
|
72287
73327
|
__export(exports_toolset2, {
|
|
@@ -72685,7 +73725,7 @@ var exports_create = {};
|
|
|
72685
73725
|
__export(exports_create, {
|
|
72686
73726
|
createAgent: () => createAgent2
|
|
72687
73727
|
});
|
|
72688
|
-
import { join as
|
|
73728
|
+
import { join as join19 } from "node:path";
|
|
72689
73729
|
async function createAgent2(name = DEFAULT_AGENT_NAME, model, embeddingModel = "openai/text-embedding-3-small", updateArgs, skillsDirectory, parallelToolCalls = true, enableSleeptime = false, systemPromptId, initBlocks, baseTools) {
|
|
72690
73730
|
let modelHandle;
|
|
72691
73731
|
if (model) {
|
|
@@ -72737,7 +73777,7 @@ async function createAgent2(name = DEFAULT_AGENT_NAME, model, embeddingModel = "
|
|
|
72737
73777
|
}
|
|
72738
73778
|
}
|
|
72739
73779
|
const filteredMemoryBlocks = allowedBlockLabels && allowedBlockLabels.size > 0 ? defaultMemoryBlocks.filter((b) => allowedBlockLabels.has(b.label)) : defaultMemoryBlocks;
|
|
72740
|
-
const resolvedSkillsDirectory = skillsDirectory ||
|
|
73780
|
+
const resolvedSkillsDirectory = skillsDirectory || join19(process.cwd(), SKILLS_DIR);
|
|
72741
73781
|
try {
|
|
72742
73782
|
const { skills, errors } = await discoverSkills(resolvedSkillsDirectory);
|
|
72743
73783
|
if (errors.length > 0) {
|
|
@@ -74213,12 +75253,12 @@ EXAMPLES
|
|
|
74213
75253
|
console.log(usage);
|
|
74214
75254
|
}
|
|
74215
75255
|
async function printInfo() {
|
|
74216
|
-
const { join:
|
|
75256
|
+
const { join: join20 } = await import("path");
|
|
74217
75257
|
const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version2(), exports_version));
|
|
74218
75258
|
const { SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
|
|
74219
75259
|
const { exists: exists3 } = await Promise.resolve().then(() => (init_fs2(), exports_fs));
|
|
74220
75260
|
const cwd2 = process.cwd();
|
|
74221
|
-
const skillsDir =
|
|
75261
|
+
const skillsDir = join20(cwd2, SKILLS_DIR3);
|
|
74222
75262
|
const skillsExist = exists3(skillsDir);
|
|
74223
75263
|
await settingsManager2.loadLocalProjectSettings(cwd2);
|
|
74224
75264
|
const localPinned = settingsManager2.getLocalPinnedAgents(cwd2);
|
|
@@ -74444,9 +75484,9 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
74444
75484
|
process.exit(1);
|
|
74445
75485
|
}
|
|
74446
75486
|
const { resolve: resolve19 } = await import("path");
|
|
74447
|
-
const { existsSync:
|
|
75487
|
+
const { existsSync: existsSync14 } = await import("fs");
|
|
74448
75488
|
const resolvedPath = resolve19(fromAfFile);
|
|
74449
|
-
if (!
|
|
75489
|
+
if (!existsSync14(resolvedPath)) {
|
|
74450
75490
|
console.error(`Error: AgentFile not found: ${resolvedPath}`);
|
|
74451
75491
|
process.exit(1);
|
|
74452
75492
|
}
|
|
@@ -74549,6 +75589,10 @@ Error: ${message}`);
|
|
|
74549
75589
|
await handleHeadlessCommand2(process.argv, specifiedModel, skillsDirectory);
|
|
74550
75590
|
return;
|
|
74551
75591
|
}
|
|
75592
|
+
try {
|
|
75593
|
+
const { detectAndEnableKittyProtocol: detectAndEnableKittyProtocol2 } = await Promise.resolve().then(() => (init_kittyProtocolDetector(), exports_kittyProtocolDetector));
|
|
75594
|
+
await detectAndEnableKittyProtocol2();
|
|
75595
|
+
} catch {}
|
|
74552
75596
|
const React14 = await Promise.resolve().then(() => __toESM(require_react2(), 1));
|
|
74553
75597
|
const { render: render2 } = await init_build3().then(() => exports_build);
|
|
74554
75598
|
const { useState: useState35, useEffect: useEffect26 } = React14;
|
|
@@ -74566,6 +75610,7 @@ Error: ${message}`);
|
|
|
74566
75610
|
skillsDirectory: skillsDirectory2,
|
|
74567
75611
|
fromAfFile: fromAfFile2
|
|
74568
75612
|
}) {
|
|
75613
|
+
const [showKeybindingSetup, setShowKeybindingSetup] = useState35(null);
|
|
74569
75614
|
const [loadingState, setLoadingState] = useState35("selecting");
|
|
74570
75615
|
const [agentId, setAgentId] = useState35(null);
|
|
74571
75616
|
const [agentState, setAgentState] = useState35(null);
|
|
@@ -74573,6 +75618,63 @@ Error: ${message}`);
|
|
|
74573
75618
|
const [isResumingSession, setIsResumingSession] = useState35(false);
|
|
74574
75619
|
const [agentProvenance, setAgentProvenance] = useState35(null);
|
|
74575
75620
|
const [selectedGlobalAgentId, setSelectedGlobalAgentId] = useState35(null);
|
|
75621
|
+
useEffect26(() => {
|
|
75622
|
+
async function autoInstallKeybinding() {
|
|
75623
|
+
const {
|
|
75624
|
+
detectTerminalType: detectTerminalType3,
|
|
75625
|
+
getKeybindingsPath: getKeybindingsPath3,
|
|
75626
|
+
keybindingExists: keybindingExists3,
|
|
75627
|
+
installKeybinding: installKeybinding3
|
|
75628
|
+
} = await Promise.resolve().then(() => (init_terminalKeybindingInstaller2(), exports_terminalKeybindingInstaller2));
|
|
75629
|
+
const { loadSettings: loadSettings3, updateSettings: updateSettings3 } = await Promise.resolve().then(() => (init_settings2(), exports_settings2));
|
|
75630
|
+
const terminal = detectTerminalType3();
|
|
75631
|
+
if (!terminal) {
|
|
75632
|
+
setShowKeybindingSetup(false);
|
|
75633
|
+
return;
|
|
75634
|
+
}
|
|
75635
|
+
const settings2 = await loadSettings3();
|
|
75636
|
+
const keybindingsPath = getKeybindingsPath3(terminal);
|
|
75637
|
+
if (!keybindingsPath || settings2.shiftEnterKeybindingInstalled) {
|
|
75638
|
+
setShowKeybindingSetup(false);
|
|
75639
|
+
return;
|
|
75640
|
+
}
|
|
75641
|
+
if (keybindingExists3(keybindingsPath)) {
|
|
75642
|
+
await updateSettings3({ shiftEnterKeybindingInstalled: true });
|
|
75643
|
+
setShowKeybindingSetup(false);
|
|
75644
|
+
return;
|
|
75645
|
+
}
|
|
75646
|
+
const result = installKeybinding3(keybindingsPath);
|
|
75647
|
+
if (result.success) {
|
|
75648
|
+
await updateSettings3({ shiftEnterKeybindingInstalled: true });
|
|
75649
|
+
}
|
|
75650
|
+
setShowKeybindingSetup(false);
|
|
75651
|
+
}
|
|
75652
|
+
async function autoInstallWezTermFix() {
|
|
75653
|
+
const {
|
|
75654
|
+
isWezTerm: isWezTerm3,
|
|
75655
|
+
wezTermDeleteFixExists: wezTermDeleteFixExists3,
|
|
75656
|
+
getWezTermConfigPath: getWezTermConfigPath3,
|
|
75657
|
+
installWezTermDeleteFix: installWezTermDeleteFix3
|
|
75658
|
+
} = await Promise.resolve().then(() => (init_terminalKeybindingInstaller2(), exports_terminalKeybindingInstaller2));
|
|
75659
|
+
const { loadSettings: loadSettings3, updateSettings: updateSettings3 } = await Promise.resolve().then(() => (init_settings2(), exports_settings2));
|
|
75660
|
+
if (!isWezTerm3())
|
|
75661
|
+
return;
|
|
75662
|
+
const settings2 = await loadSettings3();
|
|
75663
|
+
if (settings2.wezTermDeleteFixInstalled)
|
|
75664
|
+
return;
|
|
75665
|
+
const configPath = getWezTermConfigPath3();
|
|
75666
|
+
if (wezTermDeleteFixExists3(configPath)) {
|
|
75667
|
+
await updateSettings3({ wezTermDeleteFixInstalled: true });
|
|
75668
|
+
return;
|
|
75669
|
+
}
|
|
75670
|
+
const result = installWezTermDeleteFix3();
|
|
75671
|
+
if (result.success) {
|
|
75672
|
+
await updateSettings3({ wezTermDeleteFixInstalled: true });
|
|
75673
|
+
}
|
|
75674
|
+
}
|
|
75675
|
+
autoInstallKeybinding();
|
|
75676
|
+
autoInstallWezTermFix();
|
|
75677
|
+
}, []);
|
|
74576
75678
|
useEffect26(() => {
|
|
74577
75679
|
async function checkAndStart() {
|
|
74578
75680
|
await settingsManager2.loadLocalProjectSettings();
|
|
@@ -74757,8 +75859,8 @@ Error: ${message}`);
|
|
|
74757
75859
|
await initializeLoadedSkillsFlag();
|
|
74758
75860
|
try {
|
|
74759
75861
|
const { discoverSkills: discoverSkills3, formatSkillsForMemory: formatSkillsForMemory3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
|
|
74760
|
-
const { join:
|
|
74761
|
-
const resolvedSkillsDirectory = skillsDirectory2 ||
|
|
75862
|
+
const { join: join20 } = await import("path");
|
|
75863
|
+
const resolvedSkillsDirectory = skillsDirectory2 || join20(process.cwd(), SKILLS_DIR3);
|
|
74762
75864
|
const { skills, errors } = await discoverSkills3(resolvedSkillsDirectory);
|
|
74763
75865
|
if (errors.length > 0) {
|
|
74764
75866
|
console.warn("Errors encountered during skill discovery:");
|
|
@@ -74835,6 +75937,9 @@ Error during initialization: ${message}`);
|
|
|
74835
75937
|
loadingState,
|
|
74836
75938
|
selectedGlobalAgentId
|
|
74837
75939
|
]);
|
|
75940
|
+
if (showKeybindingSetup === null) {
|
|
75941
|
+
return null;
|
|
75942
|
+
}
|
|
74838
75943
|
if (loadingState === "selecting") {
|
|
74839
75944
|
return null;
|
|
74840
75945
|
}
|
|
@@ -74897,4 +76002,4 @@ Error during initialization: ${message}`);
|
|
|
74897
76002
|
}
|
|
74898
76003
|
main();
|
|
74899
76004
|
|
|
74900
|
-
//# debugId=
|
|
76005
|
+
//# debugId=F52C27FCEB893D3264756E2164756E21
|