@letta-ai/letta-code 0.24.6 → 0.24.7
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 +480 -206
- package/package.json +1 -1
- package/skills/configuring-your-harness/SKILL.md +242 -0
- package/skills/configuring-your-harness/references/hooks.md +261 -0
- package/skills/modifying-letta-code/SKILL.md +0 -270
- /package/skills/{modifying-letta-code → configuring-your-harness}/scripts/add_hook.py +0 -0
- /package/skills/{modifying-letta-code → configuring-your-harness}/scripts/add_permission.py +0 -0
- /package/skills/{modifying-letta-code → configuring-your-harness}/scripts/show_config.py +0 -0
package/letta.js
CHANGED
|
@@ -3269,7 +3269,7 @@ var package_default;
|
|
|
3269
3269
|
var init_package = __esm(() => {
|
|
3270
3270
|
package_default = {
|
|
3271
3271
|
name: "@letta-ai/letta-code",
|
|
3272
|
-
version: "0.24.
|
|
3272
|
+
version: "0.24.7",
|
|
3273
3273
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3274
3274
|
type: "module",
|
|
3275
3275
|
bin: {
|
|
@@ -72448,6 +72448,15 @@ Results include:
|
|
|
72448
72448
|
`;
|
|
72449
72449
|
var init_recall_subagent = () => {};
|
|
72450
72450
|
|
|
72451
|
+
// src/agent/subagents/contextBudget.ts
|
|
72452
|
+
function estimateStartupContextTokens(text) {
|
|
72453
|
+
return Math.ceil(text.length / STARTUP_CONTEXT_ESTIMATED_CHARS_PER_TOKEN);
|
|
72454
|
+
}
|
|
72455
|
+
var STARTUP_CONTEXT_ESTIMATED_CHARS_PER_TOKEN = 4, REFLECTION_STARTUP_CONTEXT_TOKEN_LIMIT = 16000, REFLECTION_STARTUP_CONTEXT_CHAR_LIMIT, REFLECTION_PARENT_MEMORY_SNAPSHOT_CHAR_LIMIT = 40000;
|
|
72456
|
+
var init_contextBudget = __esm(() => {
|
|
72457
|
+
REFLECTION_STARTUP_CONTEXT_CHAR_LIMIT = REFLECTION_STARTUP_CONTEXT_TOKEN_LIMIT * STARTUP_CONTEXT_ESTIMATED_CHARS_PER_TOKEN;
|
|
72458
|
+
});
|
|
72459
|
+
|
|
72451
72460
|
// src/agent/subagents/manager.ts
|
|
72452
72461
|
import { spawn as spawn5 } from "node:child_process";
|
|
72453
72462
|
function getModelHandleFromAgent(agent) {
|
|
@@ -72765,6 +72774,68 @@ function composeSubagentChildEnv(options) {
|
|
|
72765
72774
|
}
|
|
72766
72775
|
return childEnv;
|
|
72767
72776
|
}
|
|
72777
|
+
function getReflectionStartupNotice() {
|
|
72778
|
+
return `[Reflection startup context truncated: system prompt + initial message are capped at ~${REFLECTION_STARTUP_CONTEXT_TOKEN_LIMIT.toLocaleString()} estimated tokens. Some parent memory preview content was omitted; read files directly from MEMORY_DIR if needed.]`;
|
|
72779
|
+
}
|
|
72780
|
+
function buildMinimalParentMemorySection(maxChars) {
|
|
72781
|
+
const notice = getReflectionStartupNotice();
|
|
72782
|
+
const section = `<parent_memory>
|
|
72783
|
+
${notice}
|
|
72784
|
+
</parent_memory>`;
|
|
72785
|
+
if (section.length <= maxChars) {
|
|
72786
|
+
return section;
|
|
72787
|
+
}
|
|
72788
|
+
return section.slice(0, Math.max(0, maxChars));
|
|
72789
|
+
}
|
|
72790
|
+
function shrinkParentMemorySection(section, maxChars) {
|
|
72791
|
+
const notice = getReflectionStartupNotice();
|
|
72792
|
+
const treeMatch = section.match(/<memory_filesystem>[\s\S]*?<\/memory_filesystem>/);
|
|
72793
|
+
const prefix = `<parent_memory>
|
|
72794
|
+
`;
|
|
72795
|
+
const suffix = `
|
|
72796
|
+
</parent_memory>`;
|
|
72797
|
+
const tree = treeMatch?.[0];
|
|
72798
|
+
if (tree) {
|
|
72799
|
+
const candidate = `${prefix}${tree}
|
|
72800
|
+
${notice}${suffix}`;
|
|
72801
|
+
if (candidate.length <= maxChars) {
|
|
72802
|
+
return candidate;
|
|
72803
|
+
}
|
|
72804
|
+
}
|
|
72805
|
+
return buildMinimalParentMemorySection(maxChars);
|
|
72806
|
+
}
|
|
72807
|
+
function hardTruncateReflectionPrompt(prompt, maxChars) {
|
|
72808
|
+
const notice = `
|
|
72809
|
+
${getReflectionStartupNotice()}`;
|
|
72810
|
+
if (maxChars <= notice.length) {
|
|
72811
|
+
return notice.slice(0, Math.max(0, maxChars));
|
|
72812
|
+
}
|
|
72813
|
+
return `${prompt.slice(0, maxChars - notice.length).trimEnd()}${notice}`;
|
|
72814
|
+
}
|
|
72815
|
+
function capReflectionStartupPrompt(type, systemPrompt, userPrompt) {
|
|
72816
|
+
if (type !== "reflection") {
|
|
72817
|
+
return userPrompt;
|
|
72818
|
+
}
|
|
72819
|
+
const estimatedTokens = estimateStartupContextTokens(`${systemPrompt}
|
|
72820
|
+
${userPrompt}`);
|
|
72821
|
+
if (estimatedTokens <= REFLECTION_STARTUP_CONTEXT_TOKEN_LIMIT) {
|
|
72822
|
+
return userPrompt;
|
|
72823
|
+
}
|
|
72824
|
+
const allowedPromptChars = Math.max(0, REFLECTION_STARTUP_CONTEXT_CHAR_LIMIT - systemPrompt.length - 1);
|
|
72825
|
+
const parentMemoryMatch = userPrompt.match(/<parent_memory>[\s\S]*?<\/parent_memory>/);
|
|
72826
|
+
if (parentMemoryMatch?.index !== undefined) {
|
|
72827
|
+
const start = parentMemoryMatch.index;
|
|
72828
|
+
const end = start + parentMemoryMatch[0].length;
|
|
72829
|
+
const outsideChars = userPrompt.length - parentMemoryMatch[0].length;
|
|
72830
|
+
const parentMemoryBudget = Math.max(0, allowedPromptChars - outsideChars);
|
|
72831
|
+
const replacement = shrinkParentMemorySection(parentMemoryMatch[0], parentMemoryBudget);
|
|
72832
|
+
const candidate = `${userPrompt.slice(0, start)}${replacement}${userPrompt.slice(end)}`;
|
|
72833
|
+
if (candidate.length <= allowedPromptChars) {
|
|
72834
|
+
return candidate;
|
|
72835
|
+
}
|
|
72836
|
+
}
|
|
72837
|
+
return hardTruncateReflectionPrompt(userPrompt, allowedPromptChars);
|
|
72838
|
+
}
|
|
72768
72839
|
function buildSubagentArgs(type, config, model, userPrompt, existingAgentId, existingConversationId, maxTurns) {
|
|
72769
72840
|
const args = [];
|
|
72770
72841
|
const isDeployingExisting = Boolean(existingAgentId || existingConversationId);
|
|
@@ -72782,7 +72853,8 @@ function buildSubagentArgs(type, config, model, userPrompt, existingAgentId, exi
|
|
|
72782
72853
|
args.push("--model", model);
|
|
72783
72854
|
}
|
|
72784
72855
|
}
|
|
72785
|
-
|
|
72856
|
+
const boundedUserPrompt = capReflectionStartupPrompt(type, config.systemPrompt, userPrompt);
|
|
72857
|
+
args.push("-p", boundedUserPrompt);
|
|
72786
72858
|
args.push("--output-format", "stream-json");
|
|
72787
72859
|
const subagentMode = config.permissionMode;
|
|
72788
72860
|
const parentMode = permissionMode.getMode();
|
|
@@ -73073,6 +73145,7 @@ var init_manager2 = __esm(() => {
|
|
|
73073
73145
|
init_model2();
|
|
73074
73146
|
init_recall_subagent();
|
|
73075
73147
|
init_subagents();
|
|
73148
|
+
init_contextBudget();
|
|
73076
73149
|
BYOK_PROVIDER_TO_BASE = {
|
|
73077
73150
|
"lc-anthropic": "anthropic",
|
|
73078
73151
|
"lc-openai": "openai",
|
|
@@ -77350,11 +77423,14 @@ var init_checker = __esm(() => {
|
|
|
77350
77423
|
var exports_loader = {};
|
|
77351
77424
|
__export(exports_loader, {
|
|
77352
77425
|
savePermissionRule: () => savePermissionRule,
|
|
77426
|
+
resetPermissionLoaderCacheForTests: () => resetPermissionLoaderCacheForTests,
|
|
77353
77427
|
loadPermissions: () => loadPermissions,
|
|
77354
77428
|
getUserSettingsPaths: () => getUserSettingsPaths
|
|
77355
77429
|
});
|
|
77430
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
77431
|
+
import { readFileSync as readFileSync18, statSync as statSync6, watch } from "node:fs";
|
|
77356
77432
|
import { homedir as homedir17 } from "node:os";
|
|
77357
|
-
import { join as join26 } from "node:path";
|
|
77433
|
+
import { dirname as dirname13, join as join26, resolve as resolve25 } from "node:path";
|
|
77358
77434
|
function getUserSettingsPaths(options = {}) {
|
|
77359
77435
|
const homeDir = options.homeDir || homedir17();
|
|
77360
77436
|
const xdgConfigHome = options.xdgConfigHome || process.env.XDG_CONFIG_HOME || join26(homeDir, ".config");
|
|
@@ -77363,20 +77439,127 @@ function getUserSettingsPaths(options = {}) {
|
|
|
77363
77439
|
legacy: join26(xdgConfigHome, "letta", "settings.json")
|
|
77364
77440
|
};
|
|
77365
77441
|
}
|
|
77442
|
+
function getPermissionSourcePaths(workingDirectory) {
|
|
77443
|
+
const { canonical: userSettingsPath, legacy: legacyUserSettingsPath } = getUserSettingsPaths();
|
|
77444
|
+
return [
|
|
77445
|
+
legacyUserSettingsPath,
|
|
77446
|
+
userSettingsPath,
|
|
77447
|
+
join26(workingDirectory, ".letta", "settings.json"),
|
|
77448
|
+
join26(workingDirectory, ".letta", "settings.local.json")
|
|
77449
|
+
];
|
|
77450
|
+
}
|
|
77451
|
+
function getFileSignature(path20) {
|
|
77452
|
+
try {
|
|
77453
|
+
const stat5 = statSync6(path20);
|
|
77454
|
+
if (!stat5.isFile()) {
|
|
77455
|
+
return { exists: false };
|
|
77456
|
+
}
|
|
77457
|
+
return {
|
|
77458
|
+
exists: true,
|
|
77459
|
+
mtimeMs: stat5.mtimeMs,
|
|
77460
|
+
size: stat5.size,
|
|
77461
|
+
hash: createHash3("sha256").update(readFileSync18(path20)).digest("hex")
|
|
77462
|
+
};
|
|
77463
|
+
} catch {
|
|
77464
|
+
return { exists: false };
|
|
77465
|
+
}
|
|
77466
|
+
}
|
|
77467
|
+
function getFileSignatures(paths) {
|
|
77468
|
+
const signatures = new Map;
|
|
77469
|
+
for (const path20 of paths) {
|
|
77470
|
+
signatures.set(path20, getFileSignature(path20));
|
|
77471
|
+
}
|
|
77472
|
+
return signatures;
|
|
77473
|
+
}
|
|
77474
|
+
function signaturesEqual(a, b) {
|
|
77475
|
+
if (!a || !b)
|
|
77476
|
+
return false;
|
|
77477
|
+
if (!a.exists || !b.exists)
|
|
77478
|
+
return a.exists === b.exists;
|
|
77479
|
+
return a.mtimeMs === b.mtimeMs && a.size === b.size && a.hash === b.hash;
|
|
77480
|
+
}
|
|
77481
|
+
function cachedEntryMatchesSources(entry, sources, signatures) {
|
|
77482
|
+
if (entry.sources.length !== sources.length) {
|
|
77483
|
+
return false;
|
|
77484
|
+
}
|
|
77485
|
+
for (let i = 0;i < sources.length; i += 1) {
|
|
77486
|
+
if (entry.sources[i] !== sources[i]) {
|
|
77487
|
+
return false;
|
|
77488
|
+
}
|
|
77489
|
+
}
|
|
77490
|
+
for (const source of sources) {
|
|
77491
|
+
if (!signaturesEqual(entry.signatures.get(source), signatures.get(source))) {
|
|
77492
|
+
return false;
|
|
77493
|
+
}
|
|
77494
|
+
}
|
|
77495
|
+
return true;
|
|
77496
|
+
}
|
|
77497
|
+
function clonePermissions(permissions) {
|
|
77498
|
+
return {
|
|
77499
|
+
allow: [...permissions.allow || []],
|
|
77500
|
+
deny: [...permissions.deny || []],
|
|
77501
|
+
ask: [...permissions.ask || []],
|
|
77502
|
+
additionalDirectories: [...permissions.additionalDirectories || []]
|
|
77503
|
+
};
|
|
77504
|
+
}
|
|
77505
|
+
function invalidatePermissionSource(sourcePath) {
|
|
77506
|
+
for (const [cacheKey, entry] of permissionCache) {
|
|
77507
|
+
if (entry.sources.includes(sourcePath)) {
|
|
77508
|
+
permissionCache.delete(cacheKey);
|
|
77509
|
+
}
|
|
77510
|
+
}
|
|
77511
|
+
}
|
|
77512
|
+
function invalidatePermissionSourcesInDirectory(directoryPath) {
|
|
77513
|
+
for (const [cacheKey, entry] of permissionCache) {
|
|
77514
|
+
if (entry.sources.some((source) => dirname13(source) === directoryPath)) {
|
|
77515
|
+
permissionCache.delete(cacheKey);
|
|
77516
|
+
}
|
|
77517
|
+
}
|
|
77518
|
+
}
|
|
77519
|
+
function watchPath(path20, onChange) {
|
|
77520
|
+
if (watchers.has(path20) || !exists(path20)) {
|
|
77521
|
+
return;
|
|
77522
|
+
}
|
|
77523
|
+
try {
|
|
77524
|
+
const watcher = watch(path20, { persistent: false }, onChange);
|
|
77525
|
+
watcher.on("error", () => {
|
|
77526
|
+
watcher.close();
|
|
77527
|
+
watchers.delete(path20);
|
|
77528
|
+
onChange();
|
|
77529
|
+
});
|
|
77530
|
+
watchers.set(path20, watcher);
|
|
77531
|
+
} catch {}
|
|
77532
|
+
}
|
|
77533
|
+
function ensurePermissionWatchers(sources) {
|
|
77534
|
+
for (const source of sources) {
|
|
77535
|
+
watchPath(source, () => invalidatePermissionSource(source));
|
|
77536
|
+
const directoryPath = dirname13(source);
|
|
77537
|
+
watchPath(directoryPath, () => invalidatePermissionSourcesInDirectory(directoryPath));
|
|
77538
|
+
}
|
|
77539
|
+
}
|
|
77540
|
+
function resetPermissionLoaderCacheForTests() {
|
|
77541
|
+
permissionCache.clear();
|
|
77542
|
+
for (const watcher of watchers.values()) {
|
|
77543
|
+
watcher.close();
|
|
77544
|
+
}
|
|
77545
|
+
watchers.clear();
|
|
77546
|
+
}
|
|
77366
77547
|
async function loadPermissions(workingDirectory = process.cwd()) {
|
|
77548
|
+
const normalizedWorkingDirectory = resolve25(workingDirectory);
|
|
77549
|
+
const sources = getPermissionSourcePaths(normalizedWorkingDirectory);
|
|
77550
|
+
const signatures = getFileSignatures(sources);
|
|
77551
|
+
const cacheKey = normalizedWorkingDirectory;
|
|
77552
|
+
const cached = permissionCache.get(cacheKey);
|
|
77553
|
+
if (cached && cachedEntryMatchesSources(cached, sources, signatures)) {
|
|
77554
|
+
ensurePermissionWatchers(sources);
|
|
77555
|
+
return clonePermissions(cached.permissions);
|
|
77556
|
+
}
|
|
77367
77557
|
const merged = {
|
|
77368
77558
|
allow: [],
|
|
77369
77559
|
deny: [],
|
|
77370
77560
|
ask: [],
|
|
77371
77561
|
additionalDirectories: []
|
|
77372
77562
|
};
|
|
77373
|
-
const { canonical: userSettingsPath, legacy: legacyUserSettingsPath } = getUserSettingsPaths();
|
|
77374
|
-
const sources = [
|
|
77375
|
-
legacyUserSettingsPath,
|
|
77376
|
-
userSettingsPath,
|
|
77377
|
-
join26(workingDirectory, ".letta", "settings.json"),
|
|
77378
|
-
join26(workingDirectory, ".letta", "settings.local.json")
|
|
77379
|
-
];
|
|
77380
77563
|
for (const settingsPath of sources) {
|
|
77381
77564
|
try {
|
|
77382
77565
|
if (exists(settingsPath)) {
|
|
@@ -77388,7 +77571,13 @@ async function loadPermissions(workingDirectory = process.cwd()) {
|
|
|
77388
77571
|
}
|
|
77389
77572
|
} catch (_error) {}
|
|
77390
77573
|
}
|
|
77391
|
-
|
|
77574
|
+
permissionCache.set(cacheKey, {
|
|
77575
|
+
permissions: clonePermissions(merged),
|
|
77576
|
+
sources,
|
|
77577
|
+
signatures
|
|
77578
|
+
});
|
|
77579
|
+
ensurePermissionWatchers(sources);
|
|
77580
|
+
return clonePermissions(merged);
|
|
77392
77581
|
}
|
|
77393
77582
|
function mergePermissions(target, source) {
|
|
77394
77583
|
if (source.allow) {
|
|
@@ -77417,16 +77606,17 @@ function mergeRuleList(existing, incoming) {
|
|
|
77417
77606
|
return merged;
|
|
77418
77607
|
}
|
|
77419
77608
|
async function savePermissionRule(rule, ruleType, scope, workingDirectory = process.cwd()) {
|
|
77609
|
+
const normalizedWorkingDirectory = resolve25(workingDirectory);
|
|
77420
77610
|
let settingsPath;
|
|
77421
77611
|
switch (scope) {
|
|
77422
77612
|
case "user":
|
|
77423
77613
|
settingsPath = getUserSettingsPaths().canonical;
|
|
77424
77614
|
break;
|
|
77425
77615
|
case "project":
|
|
77426
|
-
settingsPath = join26(
|
|
77616
|
+
settingsPath = join26(normalizedWorkingDirectory, ".letta", "settings.json");
|
|
77427
77617
|
break;
|
|
77428
77618
|
case "local":
|
|
77429
|
-
settingsPath = join26(
|
|
77619
|
+
settingsPath = join26(normalizedWorkingDirectory, ".letta", "settings.local.json");
|
|
77430
77620
|
break;
|
|
77431
77621
|
}
|
|
77432
77622
|
let settings = {};
|
|
@@ -77447,8 +77637,9 @@ async function savePermissionRule(rule, ruleType, scope, workingDirectory = proc
|
|
|
77447
77637
|
settings.permissions[ruleType].push(normalizedRule);
|
|
77448
77638
|
}
|
|
77449
77639
|
await writeFile(settingsPath, JSON.stringify(settings, null, 2));
|
|
77640
|
+
invalidatePermissionSource(settingsPath);
|
|
77450
77641
|
if (scope === "local") {
|
|
77451
|
-
await ensureLocalSettingsIgnored(
|
|
77642
|
+
await ensureLocalSettingsIgnored(normalizedWorkingDirectory);
|
|
77452
77643
|
}
|
|
77453
77644
|
}
|
|
77454
77645
|
async function ensureLocalSettingsIgnored(workingDirectory) {
|
|
@@ -77468,9 +77659,12 @@ async function ensureLocalSettingsIgnored(workingDirectory) {
|
|
|
77468
77659
|
}
|
|
77469
77660
|
} catch (_error) {}
|
|
77470
77661
|
}
|
|
77662
|
+
var permissionCache, watchers;
|
|
77471
77663
|
var init_loader2 = __esm(() => {
|
|
77472
77664
|
init_fs();
|
|
77473
77665
|
init_rule_normalization();
|
|
77666
|
+
permissionCache = new Map;
|
|
77667
|
+
watchers = new Map;
|
|
77474
77668
|
});
|
|
77475
77669
|
|
|
77476
77670
|
// src/permissions/analyzer.ts
|
|
@@ -77479,7 +77673,7 @@ __export(exports_analyzer, {
|
|
|
77479
77673
|
analyzeApprovalContext: () => analyzeApprovalContext
|
|
77480
77674
|
});
|
|
77481
77675
|
import { homedir as homedir18 } from "node:os";
|
|
77482
|
-
import { dirname as
|
|
77676
|
+
import { dirname as dirname14, relative as relative8, resolve as resolve26, win32 as win323 } from "node:path";
|
|
77483
77677
|
function normalizeOsPath(path20) {
|
|
77484
77678
|
return path20.replace(/\\/g, "/");
|
|
77485
77679
|
}
|
|
@@ -77488,7 +77682,7 @@ function isWindowsPath(path20) {
|
|
|
77488
77682
|
}
|
|
77489
77683
|
function resolvePathForContext(basePath, targetPath) {
|
|
77490
77684
|
const windows = isWindowsPath(basePath) || isWindowsPath(targetPath);
|
|
77491
|
-
return windows ? win323.resolve(basePath, targetPath) :
|
|
77685
|
+
return windows ? win323.resolve(basePath, targetPath) : resolve26(basePath, targetPath);
|
|
77492
77686
|
}
|
|
77493
77687
|
function relativePathForContext(basePath, targetPath) {
|
|
77494
77688
|
const windows = isWindowsPath(basePath) || isWindowsPath(targetPath);
|
|
@@ -77505,7 +77699,7 @@ function isPathWithinDirectory(path20, directory) {
|
|
|
77505
77699
|
return !relativePath.startsWith("../") && relativePath !== ".." && !relativePath.startsWith("/") && !/^[a-zA-Z]:\//.test(relativePath);
|
|
77506
77700
|
}
|
|
77507
77701
|
function dirnameForContext(path20) {
|
|
77508
|
-
return isWindowsPath(path20) ? win323.dirname(path20) :
|
|
77702
|
+
return isWindowsPath(path20) ? win323.dirname(path20) : dirname14(path20);
|
|
77509
77703
|
}
|
|
77510
77704
|
function formatAbsoluteRulePath(path20) {
|
|
77511
77705
|
const normalized = normalizeOsPath(path20).replace(/\/+$/, "");
|
|
@@ -77566,7 +77760,7 @@ function analyzeReadApproval(filePath, workingDir) {
|
|
|
77566
77760
|
};
|
|
77567
77761
|
}
|
|
77568
77762
|
const relativePath = normalizeOsPath(relativePathForContext(workingDir, absolutePath));
|
|
77569
|
-
const relativeDir =
|
|
77763
|
+
const relativeDir = dirname14(relativePath);
|
|
77570
77764
|
const pattern = relativeDir === "." || relativeDir === "" ? "**" : `${relativeDir}/**`;
|
|
77571
77765
|
return {
|
|
77572
77766
|
recommendedRule: `Read(${pattern})`,
|
|
@@ -78192,8 +78386,8 @@ function acquireSwitchLock() {
|
|
|
78192
78386
|
const lock = getSwitchLock();
|
|
78193
78387
|
lock.refCount++;
|
|
78194
78388
|
if (lock.refCount === 1) {
|
|
78195
|
-
lock.promise = new Promise((
|
|
78196
|
-
lock.resolve =
|
|
78389
|
+
lock.promise = new Promise((resolve28) => {
|
|
78390
|
+
lock.resolve = resolve28;
|
|
78197
78391
|
});
|
|
78198
78392
|
}
|
|
78199
78393
|
}
|
|
@@ -80248,7 +80442,7 @@ async function generatePKCE() {
|
|
|
80248
80442
|
return { codeVerifier, codeChallenge };
|
|
80249
80443
|
}
|
|
80250
80444
|
function startLocalOAuthServer(expectedState, port = OPENAI_OAUTH_CONFIG.defaultPort) {
|
|
80251
|
-
return new Promise((
|
|
80445
|
+
return new Promise((resolve28, reject) => {
|
|
80252
80446
|
const server = http.createServer((req, res) => {
|
|
80253
80447
|
const url = new URL(req.url || "", `http://localhost:${port}`);
|
|
80254
80448
|
if (url.pathname === OPENAI_OAUTH_CONFIG.callbackPath) {
|
|
@@ -80294,7 +80488,7 @@ function startLocalOAuthServer(expectedState, port = OPENAI_OAUTH_CONFIG.default
|
|
|
80294
80488
|
message: "You can close this window and return to Letta Code.",
|
|
80295
80489
|
autoClose: true
|
|
80296
80490
|
}));
|
|
80297
|
-
|
|
80491
|
+
resolve28({ result: { code, state }, server });
|
|
80298
80492
|
} else {
|
|
80299
80493
|
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
80300
80494
|
res.end("Not found");
|
|
@@ -80809,14 +81003,14 @@ var execFile11, __dirname2, localXdgOpenPath, platform4, arch, pTryEach = async
|
|
|
80809
81003
|
}
|
|
80810
81004
|
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
|
|
80811
81005
|
if (options.wait) {
|
|
80812
|
-
return new Promise((
|
|
81006
|
+
return new Promise((resolve28, reject) => {
|
|
80813
81007
|
subprocess.once("error", reject);
|
|
80814
81008
|
subprocess.once("close", (exitCode) => {
|
|
80815
81009
|
if (!options.allowNonzeroExitCode && exitCode > 0) {
|
|
80816
81010
|
reject(new Error(`Exited with code ${exitCode}`));
|
|
80817
81011
|
return;
|
|
80818
81012
|
}
|
|
80819
|
-
|
|
81013
|
+
resolve28(subprocess);
|
|
80820
81014
|
});
|
|
80821
81015
|
});
|
|
80822
81016
|
}
|
|
@@ -81202,10 +81396,10 @@ import { randomBytes } from "node:crypto";
|
|
|
81202
81396
|
import {
|
|
81203
81397
|
existsSync as existsSync24,
|
|
81204
81398
|
mkdirSync as mkdirSync18,
|
|
81205
|
-
readFileSync as
|
|
81399
|
+
readFileSync as readFileSync19,
|
|
81206
81400
|
renameSync as renameSync2,
|
|
81207
81401
|
rmSync as rmSync2,
|
|
81208
|
-
statSync as
|
|
81402
|
+
statSync as statSync7,
|
|
81209
81403
|
writeFileSync as writeFileSync15
|
|
81210
81404
|
} from "node:fs";
|
|
81211
81405
|
import { join as join27 } from "node:path";
|
|
@@ -81228,7 +81422,7 @@ function readCronFile() {
|
|
|
81228
81422
|
if (!existsSync24(path21))
|
|
81229
81423
|
return emptyFile();
|
|
81230
81424
|
try {
|
|
81231
|
-
const raw =
|
|
81425
|
+
const raw = readFileSync19(path21, "utf-8");
|
|
81232
81426
|
const data = JSON.parse(raw);
|
|
81233
81427
|
if (data.version !== 1)
|
|
81234
81428
|
return emptyFile();
|
|
@@ -81249,7 +81443,7 @@ function writeCronFile(data) {
|
|
|
81249
81443
|
}
|
|
81250
81444
|
function readLinuxProcessIdentity(pid) {
|
|
81251
81445
|
try {
|
|
81252
|
-
const stat5 =
|
|
81446
|
+
const stat5 = readFileSync19(`/proc/${pid}/stat`, "utf8");
|
|
81253
81447
|
const endCommand = stat5.lastIndexOf(")");
|
|
81254
81448
|
if (endCommand === -1) {
|
|
81255
81449
|
return null;
|
|
@@ -81261,7 +81455,7 @@ function readLinuxProcessIdentity(pid) {
|
|
|
81261
81455
|
}
|
|
81262
81456
|
let bootId = null;
|
|
81263
81457
|
try {
|
|
81264
|
-
bootId =
|
|
81458
|
+
bootId = readFileSync19("/proc/sys/kernel/random/boot_id", "utf8").trim() || null;
|
|
81265
81459
|
} catch {}
|
|
81266
81460
|
return { startTicks, bootId };
|
|
81267
81461
|
} catch {
|
|
@@ -81302,7 +81496,7 @@ function isProcessAlive(pid, owner) {
|
|
|
81302
81496
|
}
|
|
81303
81497
|
function readLockOwner(lockDir) {
|
|
81304
81498
|
try {
|
|
81305
|
-
const raw =
|
|
81499
|
+
const raw = readFileSync19(join27(lockDir, LOCK_TOKEN_FILE), "utf-8");
|
|
81306
81500
|
return JSON.parse(raw);
|
|
81307
81501
|
} catch {
|
|
81308
81502
|
return null;
|
|
@@ -81315,7 +81509,7 @@ function isLockStale(lockDir) {
|
|
|
81315
81509
|
const owner = readLockOwner(lockDir);
|
|
81316
81510
|
if (!owner) {
|
|
81317
81511
|
try {
|
|
81318
|
-
const stat5 =
|
|
81512
|
+
const stat5 = statSync7(lockDir);
|
|
81319
81513
|
return Date.now() - stat5.mtimeMs > LOCK_STALE_AGE_MS;
|
|
81320
81514
|
} catch {
|
|
81321
81515
|
return true;
|
|
@@ -81559,7 +81753,7 @@ function getActiveTasks() {
|
|
|
81559
81753
|
function getCronFileMtime() {
|
|
81560
81754
|
const path21 = getCronFilePath();
|
|
81561
81755
|
try {
|
|
81562
|
-
return
|
|
81756
|
+
return statSync7(path21).mtimeMs;
|
|
81563
81757
|
} catch {
|
|
81564
81758
|
return 0;
|
|
81565
81759
|
}
|
|
@@ -81802,7 +81996,7 @@ async function registerWithCloudRetry(opts, callbacks) {
|
|
|
81802
81996
|
if (error instanceof Error) {
|
|
81803
81997
|
callbacks?.onRetry?.(attempt, delay, error);
|
|
81804
81998
|
}
|
|
81805
|
-
await new Promise((
|
|
81999
|
+
await new Promise((resolve28) => setTimeout(resolve28, delay));
|
|
81806
82000
|
}
|
|
81807
82001
|
}
|
|
81808
82002
|
}
|
|
@@ -83707,7 +83901,7 @@ var init_memoryReminder = __esm(() => {
|
|
|
83707
83901
|
});
|
|
83708
83902
|
|
|
83709
83903
|
// src/utils/systemPromptSize.ts
|
|
83710
|
-
import { existsSync as existsSync26, readdirSync as readdirSync8, readFileSync as
|
|
83904
|
+
import { existsSync as existsSync26, readdirSync as readdirSync8, readFileSync as readFileSync20 } from "node:fs";
|
|
83711
83905
|
import { join as join29 } from "node:path";
|
|
83712
83906
|
function estimateSystemTokens(text) {
|
|
83713
83907
|
return Math.ceil(Buffer.byteLength(text, "utf8") / SYSTEM_PROMPT_BYTES_PER_TOKEN);
|
|
@@ -83744,7 +83938,7 @@ function estimateSystemPromptSize(memoryDir) {
|
|
|
83744
83938
|
const files = walkMarkdownFiles(systemDir).sort();
|
|
83745
83939
|
const rows = [];
|
|
83746
83940
|
for (const filePath of files) {
|
|
83747
|
-
const text =
|
|
83941
|
+
const text = readFileSync20(filePath, "utf8");
|
|
83748
83942
|
const rel = normalizePath2(filePath.slice(memoryDir.length + 1));
|
|
83749
83943
|
rows.push({ path: rel, tokens: estimateSystemTokens(text) });
|
|
83750
83944
|
}
|
|
@@ -87140,10 +87334,36 @@ function buildParentMemoryTree(files) {
|
|
|
87140
87334
|
return lines.join(`
|
|
87141
87335
|
`);
|
|
87142
87336
|
}
|
|
87143
|
-
|
|
87337
|
+
function joinedLength(lines) {
|
|
87338
|
+
return lines.join(`
|
|
87339
|
+
`).length;
|
|
87340
|
+
}
|
|
87341
|
+
function canAppendWithinBudget(lines, additions, maxChars) {
|
|
87342
|
+
return joinedLength([...lines, ...additions, "</parent_memory>"]) <= maxChars;
|
|
87343
|
+
}
|
|
87344
|
+
function truncateMemoryContentToFit(lines, prefix, content, suffix, maxChars) {
|
|
87345
|
+
const fixedLength = joinedLength([
|
|
87346
|
+
...lines,
|
|
87347
|
+
...prefix,
|
|
87348
|
+
"",
|
|
87349
|
+
...suffix,
|
|
87350
|
+
"</parent_memory>"
|
|
87351
|
+
]);
|
|
87352
|
+
const budget = maxChars - fixedLength;
|
|
87353
|
+
if (budget <= 0) {
|
|
87354
|
+
return null;
|
|
87355
|
+
}
|
|
87356
|
+
return content.slice(0, budget).trimEnd();
|
|
87357
|
+
}
|
|
87358
|
+
function buildMemoryPreviewNotice(relativePath, absolutePath, kind) {
|
|
87359
|
+
const action = kind === "truncated" ? "truncated" : "omitted";
|
|
87360
|
+
return `[Memory preview ${action}: startup context is capped at ~16k estimated tokens. Full file available at ${absolutePath}; read it directly if needed. Relative path: ${relativePath}]`;
|
|
87361
|
+
}
|
|
87362
|
+
async function buildParentMemorySnapshot(memoryDir, options = {}) {
|
|
87144
87363
|
const files = await collectParentMemoryFiles(memoryDir);
|
|
87145
87364
|
const tree = buildParentMemoryTree(files);
|
|
87146
87365
|
const systemFiles = files.filter((file) => isSystemMemoryFile(file.relativePath));
|
|
87366
|
+
const maxChars = Math.max(1000, options.maxChars ?? REFLECTION_PARENT_MEMORY_SNAPSHOT_CHAR_LIMIT);
|
|
87147
87367
|
const lines = [
|
|
87148
87368
|
"<parent_memory>",
|
|
87149
87369
|
"<memory_filesystem>",
|
|
@@ -87153,13 +87373,47 @@ async function buildParentMemorySnapshot(memoryDir) {
|
|
|
87153
87373
|
if (files.length === 0) {
|
|
87154
87374
|
lines.push("(no memory markdown files found)");
|
|
87155
87375
|
} else {
|
|
87376
|
+
let omittedSystemFiles = 0;
|
|
87156
87377
|
for (const file of systemFiles) {
|
|
87157
87378
|
const normalizedPath = file.relativePath.replace(/\\/g, "/");
|
|
87158
87379
|
const absolutePath = `${memoryDir.replace(/\\/g, "/")}/${normalizedPath}`;
|
|
87159
|
-
|
|
87160
|
-
|
|
87161
|
-
|
|
87162
|
-
lines
|
|
87380
|
+
const prefix = ["<memory>", `<path>${absolutePath}</path>`];
|
|
87381
|
+
const suffix = ["</memory>"];
|
|
87382
|
+
const fullEntry = [...prefix, file.content, ...suffix];
|
|
87383
|
+
if (canAppendWithinBudget(lines, fullEntry, maxChars)) {
|
|
87384
|
+
lines.push(...fullEntry);
|
|
87385
|
+
continue;
|
|
87386
|
+
}
|
|
87387
|
+
const truncatedNotice = buildMemoryPreviewNotice(normalizedPath, absolutePath, "truncated");
|
|
87388
|
+
const truncatedContent = truncateMemoryContentToFit(lines, prefix, file.content, [truncatedNotice, ...suffix], maxChars);
|
|
87389
|
+
if (truncatedContent) {
|
|
87390
|
+
const truncatedEntry = [
|
|
87391
|
+
...prefix,
|
|
87392
|
+
truncatedContent,
|
|
87393
|
+
truncatedNotice,
|
|
87394
|
+
...suffix
|
|
87395
|
+
];
|
|
87396
|
+
if (canAppendWithinBudget(lines, truncatedEntry, maxChars)) {
|
|
87397
|
+
lines.push(...truncatedEntry);
|
|
87398
|
+
continue;
|
|
87399
|
+
}
|
|
87400
|
+
}
|
|
87401
|
+
const omittedEntry = [
|
|
87402
|
+
...prefix,
|
|
87403
|
+
buildMemoryPreviewNotice(normalizedPath, absolutePath, "omitted"),
|
|
87404
|
+
...suffix
|
|
87405
|
+
];
|
|
87406
|
+
if (canAppendWithinBudget(lines, omittedEntry, maxChars)) {
|
|
87407
|
+
lines.push(...omittedEntry);
|
|
87408
|
+
} else {
|
|
87409
|
+
omittedSystemFiles += 1;
|
|
87410
|
+
}
|
|
87411
|
+
}
|
|
87412
|
+
if (omittedSystemFiles > 0) {
|
|
87413
|
+
const notice = `[Memory preview omitted ${omittedSystemFiles.toLocaleString()} additional system file(s) because the reflection startup context budget was exhausted. Read files directly from ${memoryDir} if needed.]`;
|
|
87414
|
+
if (canAppendWithinBudget(lines, [notice], maxChars)) {
|
|
87415
|
+
lines.push(notice);
|
|
87416
|
+
}
|
|
87163
87417
|
}
|
|
87164
87418
|
}
|
|
87165
87419
|
lines.push("</parent_memory>");
|
|
@@ -87407,12 +87661,13 @@ async function finalizeAutoReflectionPayload(agentId, conversationId, _payloadPa
|
|
|
87407
87661
|
var TRANSCRIPT_ROOT_ENV = "LETTA_TRANSCRIPT_ROOT", DEFAULT_TRANSCRIPT_DIR = "transcripts", TOOL_ARGS_TRUNCATE_LIMIT = 300;
|
|
87408
87662
|
var init_reflectionTranscript = __esm(() => {
|
|
87409
87663
|
init_memoryFilesystem();
|
|
87664
|
+
init_contextBudget();
|
|
87410
87665
|
init_directoryLimits();
|
|
87411
87666
|
});
|
|
87412
87667
|
|
|
87413
87668
|
// src/utils/tuiPerf.ts
|
|
87414
87669
|
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync20 } from "node:fs";
|
|
87415
|
-
import { dirname as
|
|
87670
|
+
import { dirname as dirname15 } from "node:path";
|
|
87416
87671
|
function ensureExitHook() {
|
|
87417
87672
|
if (tuiPerfExitHookRegistered) {
|
|
87418
87673
|
return;
|
|
@@ -87501,7 +87756,7 @@ function flushTuiPerfTelemetry() {
|
|
|
87501
87756
|
};
|
|
87502
87757
|
}
|
|
87503
87758
|
try {
|
|
87504
|
-
const dir =
|
|
87759
|
+
const dir = dirname15(filePath);
|
|
87505
87760
|
if (tuiPerfFileDirEnsured !== dir) {
|
|
87506
87761
|
mkdirSync20(dir, { recursive: true });
|
|
87507
87762
|
tuiPerfFileDirEnsured = dir;
|
|
@@ -87843,11 +88098,11 @@ async function discoverFallbackRunIdWithTimeout(client, ctx) {
|
|
|
87843
88098
|
return withTimeout(discoverFallbackRunIdForResume(client, ctx), FALLBACK_RUN_DISCOVERY_TIMEOUT_MS, `Fallback run discovery timed out after ${FALLBACK_RUN_DISCOVERY_TIMEOUT_MS}ms`);
|
|
87844
88099
|
}
|
|
87845
88100
|
function withTimeout(promise, timeoutMs, timeoutMessage) {
|
|
87846
|
-
return new Promise((
|
|
88101
|
+
return new Promise((resolve28, reject) => {
|
|
87847
88102
|
const timer = setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs);
|
|
87848
88103
|
promise.then((value) => {
|
|
87849
88104
|
clearTimeout(timer);
|
|
87850
|
-
|
|
88105
|
+
resolve28(value);
|
|
87851
88106
|
}, (error) => {
|
|
87852
88107
|
clearTimeout(timer);
|
|
87853
88108
|
reject(error);
|
|
@@ -88742,7 +88997,7 @@ var init_constants2 = __esm(() => {
|
|
|
88742
88997
|
});
|
|
88743
88998
|
|
|
88744
88999
|
// src/websocket/listener/remote-settings.ts
|
|
88745
|
-
import { existsSync as existsSync29, readFileSync as
|
|
89000
|
+
import { existsSync as existsSync29, readFileSync as readFileSync21 } from "node:fs";
|
|
88746
89001
|
import { mkdir as mkdir8, writeFile as writeFile10 } from "node:fs/promises";
|
|
88747
89002
|
import { homedir as homedir22 } from "node:os";
|
|
88748
89003
|
import path21 from "node:path";
|
|
@@ -88757,7 +89012,7 @@ function loadRemoteSettings() {
|
|
|
88757
89012
|
try {
|
|
88758
89013
|
const settingsPath = getRemoteSettingsPath();
|
|
88759
89014
|
if (existsSync29(settingsPath)) {
|
|
88760
|
-
const raw =
|
|
89015
|
+
const raw = readFileSync21(settingsPath, "utf-8");
|
|
88761
89016
|
const parsed = JSON.parse(raw);
|
|
88762
89017
|
loaded = parsed;
|
|
88763
89018
|
}
|
|
@@ -88794,7 +89049,7 @@ function loadLegacyCwdCache() {
|
|
|
88794
89049
|
const legacyPath = path21.join(homedir22(), ".letta", "cwd-cache.json");
|
|
88795
89050
|
if (!existsSync29(legacyPath))
|
|
88796
89051
|
return {};
|
|
88797
|
-
const raw =
|
|
89052
|
+
const raw = readFileSync21(legacyPath, "utf-8");
|
|
88798
89053
|
const parsed = JSON.parse(raw);
|
|
88799
89054
|
const result = {};
|
|
88800
89055
|
for (const [key, value] of Object.entries(parsed)) {
|
|
@@ -88996,7 +89251,7 @@ function requestApprovalOverWS(runtime, socket, requestId, controlRequest) {
|
|
|
88996
89251
|
if (isInterrupted()) {
|
|
88997
89252
|
return Promise.reject(new Error("Cancelled by user"));
|
|
88998
89253
|
}
|
|
88999
|
-
return new Promise((
|
|
89254
|
+
return new Promise((resolve28, reject) => {
|
|
89000
89255
|
let settled = false;
|
|
89001
89256
|
const cleanupAbortListener = () => {
|
|
89002
89257
|
abortSignal?.removeEventListener("abort", handleAbort);
|
|
@@ -89007,7 +89262,7 @@ function requestApprovalOverWS(runtime, socket, requestId, controlRequest) {
|
|
|
89007
89262
|
}
|
|
89008
89263
|
settled = true;
|
|
89009
89264
|
cleanupAbortListener();
|
|
89010
|
-
|
|
89265
|
+
resolve28(response);
|
|
89011
89266
|
};
|
|
89012
89267
|
const wrappedReject = (error) => {
|
|
89013
89268
|
if (settled) {
|
|
@@ -90632,7 +90887,7 @@ async function sendMessageStreamWithRetry(conversationId, messages, opts, socket
|
|
|
90632
90887
|
conversationId
|
|
90633
90888
|
});
|
|
90634
90889
|
}
|
|
90635
|
-
await new Promise((
|
|
90890
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
90636
90891
|
if (abortSignal?.aborted) {
|
|
90637
90892
|
throw new Error("Cancelled by user");
|
|
90638
90893
|
}
|
|
@@ -90687,7 +90942,7 @@ async function sendMessageStreamWithRetry(conversationId, messages, opts, socket
|
|
|
90687
90942
|
agentId: runtime.agentId ?? undefined,
|
|
90688
90943
|
conversationId
|
|
90689
90944
|
});
|
|
90690
|
-
await new Promise((
|
|
90945
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
90691
90946
|
if (abortSignal?.aborted) {
|
|
90692
90947
|
throw new Error("Cancelled by user");
|
|
90693
90948
|
}
|
|
@@ -90774,7 +91029,7 @@ async function sendApprovalContinuationWithRetry(conversationId, messages, opts,
|
|
|
90774
91029
|
conversationId
|
|
90775
91030
|
});
|
|
90776
91031
|
}
|
|
90777
|
-
await new Promise((
|
|
91032
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
90778
91033
|
if (abortSignal?.aborted) {
|
|
90779
91034
|
throw new Error("Cancelled by user");
|
|
90780
91035
|
}
|
|
@@ -90828,7 +91083,7 @@ async function sendApprovalContinuationWithRetry(conversationId, messages, opts,
|
|
|
90828
91083
|
agentId: runtime.agentId ?? undefined,
|
|
90829
91084
|
conversationId
|
|
90830
91085
|
});
|
|
90831
|
-
await new Promise((
|
|
91086
|
+
await new Promise((resolve28) => setTimeout(resolve28, retryDelayMs));
|
|
90832
91087
|
if (abortSignal?.aborted) {
|
|
90833
91088
|
throw new Error("Cancelled by user");
|
|
90834
91089
|
}
|
|
@@ -93829,7 +94084,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
93829
94084
|
agentId,
|
|
93830
94085
|
conversationId
|
|
93831
94086
|
});
|
|
93832
|
-
await new Promise((
|
|
94087
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
93833
94088
|
if (turnAbortSignal.aborted) {
|
|
93834
94089
|
throw new Error("Cancelled by user");
|
|
93835
94090
|
}
|
|
@@ -93874,7 +94129,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
93874
94129
|
agentId,
|
|
93875
94130
|
conversationId
|
|
93876
94131
|
});
|
|
93877
|
-
await new Promise((
|
|
94132
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
93878
94133
|
if (turnAbortSignal.aborted) {
|
|
93879
94134
|
throw new Error("Cancelled by user");
|
|
93880
94135
|
}
|
|
@@ -94379,7 +94634,7 @@ var init_commands = __esm(async () => {
|
|
|
94379
94634
|
|
|
94380
94635
|
// src/websocket/listener/protocol-outbound.ts
|
|
94381
94636
|
import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync22 } from "node:fs";
|
|
94382
|
-
import { dirname as
|
|
94637
|
+
import { dirname as dirname16 } from "node:path";
|
|
94383
94638
|
import { performance as performance2 } from "node:perf_hooks";
|
|
94384
94639
|
import WebSocket3 from "ws";
|
|
94385
94640
|
function getProtocolPerfKey(message) {
|
|
@@ -94428,7 +94683,7 @@ function writeProtocolPerfFile(record, fallbackLine) {
|
|
|
94428
94683
|
return;
|
|
94429
94684
|
}
|
|
94430
94685
|
try {
|
|
94431
|
-
const dir =
|
|
94686
|
+
const dir = dirname16(filePath);
|
|
94432
94687
|
if (protocolPerfFileDirEnsured !== dir) {
|
|
94433
94688
|
mkdirSync22(dir, { recursive: true });
|
|
94434
94689
|
protocolPerfFileDirEnsured = dir;
|
|
@@ -95794,7 +96049,7 @@ async function runGrepInFiles(args) {
|
|
|
95794
96049
|
});
|
|
95795
96050
|
}
|
|
95796
96051
|
function runRipgrep(rgArgs) {
|
|
95797
|
-
return new Promise((
|
|
96052
|
+
return new Promise((resolve28, reject) => {
|
|
95798
96053
|
const child = execFile12(rgPath3, rgArgs, {
|
|
95799
96054
|
maxBuffer: 50 * 1024 * 1024
|
|
95800
96055
|
}, (error, stdout, _stderr) => {
|
|
@@ -95802,7 +96057,7 @@ function runRipgrep(rgArgs) {
|
|
|
95802
96057
|
reject(error);
|
|
95803
96058
|
return;
|
|
95804
96059
|
}
|
|
95805
|
-
|
|
96060
|
+
resolve28(stdout);
|
|
95806
96061
|
});
|
|
95807
96062
|
const timer = setTimeout(() => {
|
|
95808
96063
|
child.kill("SIGTERM");
|
|
@@ -96450,7 +96705,7 @@ var init_protocol_inbound = __esm(async () => {
|
|
|
96450
96705
|
});
|
|
96451
96706
|
|
|
96452
96707
|
// src/websocket/listener/worktree-watcher.ts
|
|
96453
|
-
import { readdir as readdir6, stat as stat5, watch } from "node:fs/promises";
|
|
96708
|
+
import { readdir as readdir6, stat as stat5, watch as watch2 } from "node:fs/promises";
|
|
96454
96709
|
import path24 from "node:path";
|
|
96455
96710
|
function startWorktreeWatcher(params) {
|
|
96456
96711
|
const { runtime, agentId, conversationId } = params;
|
|
@@ -96506,7 +96761,7 @@ async function runWatchLoop(params) {
|
|
|
96506
96761
|
}
|
|
96507
96762
|
const existingEntries = new Set(await safeReaddir(worktreesDir));
|
|
96508
96763
|
let debounceTimer = null;
|
|
96509
|
-
const watcher =
|
|
96764
|
+
const watcher = watch2(worktreesDir, { signal: abort.signal });
|
|
96510
96765
|
for await (const event of watcher) {
|
|
96511
96766
|
if (event.eventType !== "rename" || !event.filename)
|
|
96512
96767
|
continue;
|
|
@@ -96557,7 +96812,7 @@ async function handleNewWorktree(params) {
|
|
|
96557
96812
|
}
|
|
96558
96813
|
}
|
|
96559
96814
|
async function waitForDirectoryCreation(parentDir, targetName, signal) {
|
|
96560
|
-
const watcher =
|
|
96815
|
+
const watcher = watch2(parentDir, { signal });
|
|
96561
96816
|
for await (const event of watcher) {
|
|
96562
96817
|
if (event.eventType === "rename" && event.filename === targetName && await directoryExists(path24.join(parentDir, targetName))) {
|
|
96563
96818
|
return;
|
|
@@ -96594,7 +96849,7 @@ __export(exports_memoryScanner, {
|
|
|
96594
96849
|
readFileContent: () => readFileContent,
|
|
96595
96850
|
getFileNodes: () => getFileNodes
|
|
96596
96851
|
});
|
|
96597
|
-
import { readdirSync as readdirSync10, readFileSync as
|
|
96852
|
+
import { readdirSync as readdirSync10, readFileSync as readFileSync22, statSync as statSync8 } from "node:fs";
|
|
96598
96853
|
import { join as join33, relative as relative13 } from "node:path";
|
|
96599
96854
|
function scanMemoryFilesystem(memoryRoot) {
|
|
96600
96855
|
const nodes = [];
|
|
@@ -96612,10 +96867,10 @@ function scanMemoryFilesystem(memoryRoot) {
|
|
|
96612
96867
|
let aIsDir = false;
|
|
96613
96868
|
let bIsDir = false;
|
|
96614
96869
|
try {
|
|
96615
|
-
aIsDir =
|
|
96870
|
+
aIsDir = statSync8(aPath).isDirectory();
|
|
96616
96871
|
} catch {}
|
|
96617
96872
|
try {
|
|
96618
|
-
bIsDir =
|
|
96873
|
+
bIsDir = statSync8(bPath).isDirectory();
|
|
96619
96874
|
} catch {}
|
|
96620
96875
|
if (aIsDir !== bIsDir)
|
|
96621
96876
|
return aIsDir ? -1 : 1;
|
|
@@ -96631,7 +96886,7 @@ function scanMemoryFilesystem(memoryRoot) {
|
|
|
96631
96886
|
const fullPath = join33(dir, name);
|
|
96632
96887
|
let isDir = false;
|
|
96633
96888
|
try {
|
|
96634
|
-
isDir =
|
|
96889
|
+
isDir = statSync8(fullPath).isDirectory();
|
|
96635
96890
|
} catch {
|
|
96636
96891
|
return;
|
|
96637
96892
|
}
|
|
@@ -96659,7 +96914,7 @@ function getFileNodes(nodes) {
|
|
|
96659
96914
|
}
|
|
96660
96915
|
function readFileContent(fullPath) {
|
|
96661
96916
|
try {
|
|
96662
|
-
return
|
|
96917
|
+
return readFileSync22(fullPath, "utf-8");
|
|
96663
96918
|
} catch {
|
|
96664
96919
|
return "(unable to read file)";
|
|
96665
96920
|
}
|
|
@@ -98923,8 +99178,8 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
98923
99178
|
const delay = Math.min(INITIAL_RETRY_DELAY_MS * 2 ** (attempt - 1), MAX_RETRY_DELAY_MS);
|
|
98924
99179
|
const maxAttempts = Math.ceil(Math.log2(MAX_RETRY_DURATION_MS / INITIAL_RETRY_DELAY_MS));
|
|
98925
99180
|
opts.onRetrying?.(attempt, maxAttempts, delay, opts.connectionId);
|
|
98926
|
-
await new Promise((
|
|
98927
|
-
runtime.reconnectTimeout = setTimeout(
|
|
99181
|
+
await new Promise((resolve28) => {
|
|
99182
|
+
runtime.reconnectTimeout = setTimeout(resolve28, delay);
|
|
98928
99183
|
});
|
|
98929
99184
|
runtime.reconnectTimeout = null;
|
|
98930
99185
|
if (runtime !== getActiveRuntime() || runtime.intentionallyClosed) {
|
|
@@ -99471,11 +99726,11 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
99471
99726
|
return;
|
|
99472
99727
|
}
|
|
99473
99728
|
try {
|
|
99474
|
-
const { watch:
|
|
99729
|
+
const { watch: watch3 } = await import("node:fs");
|
|
99475
99730
|
const { stat: stat7 } = await import("node:fs/promises");
|
|
99476
99731
|
if (cancelledWatches.delete(parsed.path))
|
|
99477
99732
|
return;
|
|
99478
|
-
const watcher =
|
|
99733
|
+
const watcher = watch3(parsed.path, { persistent: false }, (eventType) => {
|
|
99479
99734
|
if (eventType !== "change" && eventType !== "rename")
|
|
99480
99735
|
return;
|
|
99481
99736
|
const existing2 = watchDebounceTimers.get(parsed.path);
|
|
@@ -100402,7 +100657,7 @@ import {
|
|
|
100402
100657
|
existsSync as existsSync31,
|
|
100403
100658
|
mkdirSync as mkdirSync24,
|
|
100404
100659
|
readdirSync as readdirSync11,
|
|
100405
|
-
readFileSync as
|
|
100660
|
+
readFileSync as readFileSync23,
|
|
100406
100661
|
unlinkSync as unlinkSync8
|
|
100407
100662
|
} from "node:fs";
|
|
100408
100663
|
import { homedir as homedir26 } from "node:os";
|
|
@@ -100456,7 +100711,7 @@ class DebugLogFile2 {
|
|
|
100456
100711
|
try {
|
|
100457
100712
|
if (!existsSync31(this.logPath))
|
|
100458
100713
|
return;
|
|
100459
|
-
const content =
|
|
100714
|
+
const content = readFileSync23(this.logPath, "utf8");
|
|
100460
100715
|
const lines = content.trimEnd().split(`
|
|
100461
100716
|
`);
|
|
100462
100717
|
return lines.slice(-maxLines).join(`
|
|
@@ -100540,10 +100795,10 @@ __export(exports_skills2, {
|
|
|
100540
100795
|
});
|
|
100541
100796
|
import { existsSync as existsSync32 } from "node:fs";
|
|
100542
100797
|
import { readdir as readdir8, readFile as readFile13, realpath as realpath4, stat as stat7 } from "node:fs/promises";
|
|
100543
|
-
import { dirname as
|
|
100798
|
+
import { dirname as dirname17, join as join38 } from "node:path";
|
|
100544
100799
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
100545
100800
|
function getBundledSkillsPath2() {
|
|
100546
|
-
const thisDir =
|
|
100801
|
+
const thisDir = dirname17(fileURLToPath9(import.meta.url));
|
|
100547
100802
|
if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
|
|
100548
100803
|
return join38(thisDir, "../skills/builtin");
|
|
100549
100804
|
}
|
|
@@ -100739,12 +100994,12 @@ import {
|
|
|
100739
100994
|
writeFileSync as fsWriteFileSync2,
|
|
100740
100995
|
mkdirSync as mkdirSync25
|
|
100741
100996
|
} from "node:fs";
|
|
100742
|
-
import { dirname as
|
|
100997
|
+
import { dirname as dirname18 } from "node:path";
|
|
100743
100998
|
async function readFile14(path26) {
|
|
100744
100999
|
return fsReadFileSync2(path26, { encoding: "utf-8" });
|
|
100745
101000
|
}
|
|
100746
101001
|
async function writeFile12(path26, content) {
|
|
100747
|
-
const dir =
|
|
101002
|
+
const dir = dirname18(path26);
|
|
100748
101003
|
if (!existsSync33(dir)) {
|
|
100749
101004
|
mkdirSync25(dir, { recursive: true });
|
|
100750
101005
|
}
|
|
@@ -100789,7 +101044,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
|
|
|
100789
101044
|
}
|
|
100790
101045
|
const wasRaw = process.stdin.isRaw;
|
|
100791
101046
|
const wasFlowing = process.stdin.readableFlowing;
|
|
100792
|
-
return new Promise((
|
|
101047
|
+
return new Promise((resolve30) => {
|
|
100793
101048
|
let response = "";
|
|
100794
101049
|
let resolved = false;
|
|
100795
101050
|
const cleanup = () => {
|
|
@@ -100806,7 +101061,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
|
|
|
100806
101061
|
};
|
|
100807
101062
|
const timeout = setTimeout(() => {
|
|
100808
101063
|
cleanup();
|
|
100809
|
-
|
|
101064
|
+
resolve30(null);
|
|
100810
101065
|
}, timeoutMs);
|
|
100811
101066
|
const onData = (data) => {
|
|
100812
101067
|
response += data.toString();
|
|
@@ -100816,7 +101071,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
|
|
|
100816
101071
|
if (match3) {
|
|
100817
101072
|
clearTimeout(timeout);
|
|
100818
101073
|
cleanup();
|
|
100819
|
-
|
|
101074
|
+
resolve30({
|
|
100820
101075
|
r: parseHexComponent(match3[1] ?? "0"),
|
|
100821
101076
|
g: parseHexComponent(match3[2] ?? "0"),
|
|
100822
101077
|
b: parseHexComponent(match3[3] ?? "0")
|
|
@@ -100831,7 +101086,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
|
|
|
100831
101086
|
} catch {
|
|
100832
101087
|
clearTimeout(timeout);
|
|
100833
101088
|
cleanup();
|
|
100834
|
-
|
|
101089
|
+
resolve30(null);
|
|
100835
101090
|
}
|
|
100836
101091
|
});
|
|
100837
101092
|
}
|
|
@@ -102064,10 +102319,10 @@ __export(exports_setup, {
|
|
|
102064
102319
|
runSetup: () => runSetup
|
|
102065
102320
|
});
|
|
102066
102321
|
async function runSetup() {
|
|
102067
|
-
return new Promise((
|
|
102322
|
+
return new Promise((resolve31) => {
|
|
102068
102323
|
const { waitUntilExit } = render_default(import_react32.default.createElement(SetupUI, {
|
|
102069
102324
|
onComplete: () => {
|
|
102070
|
-
|
|
102325
|
+
resolve31();
|
|
102071
102326
|
}
|
|
102072
102327
|
}));
|
|
102073
102328
|
waitUntilExit().catch((error) => {
|
|
@@ -102555,9 +102810,28 @@ function validateRegistryHandleOrThrow2(handle) {
|
|
|
102555
102810
|
}
|
|
102556
102811
|
|
|
102557
102812
|
// src/streamJsonWriter.ts
|
|
102813
|
+
function stampWireMessage(msg) {
|
|
102814
|
+
return msg.timestamp === undefined ? { ...msg, timestamp: new Date().toISOString() } : msg;
|
|
102815
|
+
}
|
|
102558
102816
|
function writeWireMessage(msg) {
|
|
102559
|
-
|
|
102560
|
-
|
|
102817
|
+
console.log(JSON.stringify(stampWireMessage(msg)));
|
|
102818
|
+
}
|
|
102819
|
+
async function writeWireMessageAsync(msg) {
|
|
102820
|
+
const line = `${JSON.stringify(stampWireMessage(msg))}
|
|
102821
|
+
`;
|
|
102822
|
+
await new Promise((resolve31, reject) => {
|
|
102823
|
+
if (process.stdout.destroyed || process.stdout.writableEnded) {
|
|
102824
|
+
resolve31();
|
|
102825
|
+
return;
|
|
102826
|
+
}
|
|
102827
|
+
process.stdout.write(line, (error) => {
|
|
102828
|
+
if (error) {
|
|
102829
|
+
reject(error);
|
|
102830
|
+
return;
|
|
102831
|
+
}
|
|
102832
|
+
resolve31();
|
|
102833
|
+
});
|
|
102834
|
+
});
|
|
102561
102835
|
}
|
|
102562
102836
|
|
|
102563
102837
|
// src/agent/github-utils.ts
|
|
@@ -102601,10 +102875,10 @@ __export(exports_import, {
|
|
|
102601
102875
|
});
|
|
102602
102876
|
import { createReadStream } from "node:fs";
|
|
102603
102877
|
import { chmod, mkdir as mkdir10, readFile as readFile15, writeFile as writeFile13 } from "node:fs/promises";
|
|
102604
|
-
import { dirname as
|
|
102878
|
+
import { dirname as dirname19, resolve as resolve31 } from "node:path";
|
|
102605
102879
|
async function importAgentFromFile(options) {
|
|
102606
102880
|
const client = await getClient();
|
|
102607
|
-
const resolvedPath =
|
|
102881
|
+
const resolvedPath = resolve31(options.filePath);
|
|
102608
102882
|
const file = createReadStream(resolvedPath);
|
|
102609
102883
|
const importResponse = await client.agents.importFile({
|
|
102610
102884
|
file,
|
|
@@ -102639,7 +102913,7 @@ async function extractSkillsFromAf(afPath, destDir) {
|
|
|
102639
102913
|
return [];
|
|
102640
102914
|
}
|
|
102641
102915
|
for (const skill2 of afData.skills) {
|
|
102642
|
-
const skillDir =
|
|
102916
|
+
const skillDir = resolve31(destDir, skill2.name);
|
|
102643
102917
|
await mkdir10(skillDir, { recursive: true });
|
|
102644
102918
|
if (skill2.files) {
|
|
102645
102919
|
await writeSkillFiles(skillDir, skill2.files);
|
|
@@ -102659,8 +102933,8 @@ async function writeSkillFiles(skillDir, files) {
|
|
|
102659
102933
|
}
|
|
102660
102934
|
}
|
|
102661
102935
|
async function writeSkillFile(skillDir, filePath, content) {
|
|
102662
|
-
const fullPath =
|
|
102663
|
-
await mkdir10(
|
|
102936
|
+
const fullPath = resolve31(skillDir, filePath);
|
|
102937
|
+
await mkdir10(dirname19(fullPath), { recursive: true });
|
|
102664
102938
|
await writeFile13(fullPath, content, "utf-8");
|
|
102665
102939
|
const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
|
|
102666
102940
|
if (isScript) {
|
|
@@ -103001,12 +103275,12 @@ async function sendScopedApprovalMessages(params) {
|
|
|
103001
103275
|
});
|
|
103002
103276
|
}
|
|
103003
103277
|
async function flushAndExit(code) {
|
|
103004
|
-
const flushWritable = (stream2) => new Promise((
|
|
103278
|
+
const flushWritable = (stream2) => new Promise((resolve32) => {
|
|
103005
103279
|
if (stream2.destroyed || stream2.writableEnded) {
|
|
103006
|
-
|
|
103280
|
+
resolve32();
|
|
103007
103281
|
return;
|
|
103008
103282
|
}
|
|
103009
|
-
stream2.write("", () =>
|
|
103283
|
+
stream2.write("", () => resolve32());
|
|
103010
103284
|
});
|
|
103011
103285
|
await Promise.allSettled([
|
|
103012
103286
|
flushWritable(process.stdout),
|
|
@@ -103015,12 +103289,12 @@ async function flushAndExit(code) {
|
|
|
103015
103289
|
process.exit(code);
|
|
103016
103290
|
}
|
|
103017
103291
|
async function writeFinalHeadlessStdout(text) {
|
|
103018
|
-
await new Promise((
|
|
103292
|
+
await new Promise((resolve32) => {
|
|
103019
103293
|
if (process.stdout.destroyed || process.stdout.writableEnded) {
|
|
103020
|
-
|
|
103294
|
+
resolve32();
|
|
103021
103295
|
return;
|
|
103022
103296
|
}
|
|
103023
|
-
process.stdout.write(text, () =>
|
|
103297
|
+
process.stdout.write(text, () => resolve32());
|
|
103024
103298
|
});
|
|
103025
103299
|
}
|
|
103026
103300
|
async function handleHeadlessCommand(parsedArgs, model, skillsDirectoryOverride, skillSourcesOverride, systemInfoReminderEnabledOverride) {
|
|
@@ -103853,7 +104127,7 @@ ${loadedContents.join(`
|
|
|
103853
104127
|
session_id: sessionId,
|
|
103854
104128
|
uuid: `error-max-turns-${randomUUID15()}`
|
|
103855
104129
|
};
|
|
103856
|
-
|
|
104130
|
+
await writeWireMessageAsync(errorMsg);
|
|
103857
104131
|
} else {
|
|
103858
104132
|
console.error(`Maximum turns limit reached (${buffers.usage.stepCount}/${maxTurns} steps)`);
|
|
103859
104133
|
}
|
|
@@ -103952,7 +104226,7 @@ ${loadedContents.join(`
|
|
|
103952
104226
|
} else {
|
|
103953
104227
|
console.error(`Conversation is busy, waiting ${Math.round(retryDelayMs / 1000)}s and retrying...`);
|
|
103954
104228
|
}
|
|
103955
|
-
await new Promise((
|
|
104229
|
+
await new Promise((resolve32) => setTimeout(resolve32, retryDelayMs));
|
|
103956
104230
|
continue;
|
|
103957
104231
|
}
|
|
103958
104232
|
}
|
|
@@ -104001,7 +104275,7 @@ ${loadedContents.join(`
|
|
|
104001
104275
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
104002
104276
|
console.error(`Transient API error before streaming (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
104003
104277
|
}
|
|
104004
|
-
await new Promise((
|
|
104278
|
+
await new Promise((resolve32) => setTimeout(resolve32, delayMs));
|
|
104005
104279
|
conversationBusyRetries = 0;
|
|
104006
104280
|
continue;
|
|
104007
104281
|
}
|
|
@@ -104237,7 +104511,7 @@ ${loadedContents.join(`
|
|
|
104237
104511
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
104238
104512
|
console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
104239
104513
|
}
|
|
104240
|
-
await new Promise((
|
|
104514
|
+
await new Promise((resolve32) => setTimeout(resolve32, delayMs));
|
|
104241
104515
|
refreshCurrentInputOtids();
|
|
104242
104516
|
continue;
|
|
104243
104517
|
}
|
|
@@ -104270,7 +104544,7 @@ ${loadedContents.join(`
|
|
|
104270
104544
|
session_id: sessionId,
|
|
104271
104545
|
uuid: `error-${lastRunId || randomUUID15()}`
|
|
104272
104546
|
};
|
|
104273
|
-
|
|
104547
|
+
await writeWireMessageAsync(errorMsg);
|
|
104274
104548
|
} else {
|
|
104275
104549
|
console.error("Failed to fetch pending approvals for resync");
|
|
104276
104550
|
}
|
|
@@ -104327,7 +104601,7 @@ ${loadedContents.join(`
|
|
|
104327
104601
|
} else {
|
|
104328
104602
|
console.error(`Empty LLM response, retrying (attempt ${attempt} of ${EMPTY_RESPONSE_MAX_RETRIES2})...`);
|
|
104329
104603
|
}
|
|
104330
|
-
await new Promise((
|
|
104604
|
+
await new Promise((resolve32) => setTimeout(resolve32, delayMs));
|
|
104331
104605
|
refreshCurrentInputOtids();
|
|
104332
104606
|
continue;
|
|
104333
104607
|
}
|
|
@@ -104355,7 +104629,7 @@ ${loadedContents.join(`
|
|
|
104355
104629
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
104356
104630
|
console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
104357
104631
|
}
|
|
104358
|
-
await new Promise((
|
|
104632
|
+
await new Promise((resolve32) => setTimeout(resolve32, delayMs));
|
|
104359
104633
|
refreshCurrentInputOtids();
|
|
104360
104634
|
continue;
|
|
104361
104635
|
}
|
|
@@ -104385,7 +104659,7 @@ ${loadedContents.join(`
|
|
|
104385
104659
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
104386
104660
|
console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
104387
104661
|
}
|
|
104388
|
-
await new Promise((
|
|
104662
|
+
await new Promise((resolve32) => setTimeout(resolve32, delayMs));
|
|
104389
104663
|
refreshCurrentInputOtids();
|
|
104390
104664
|
continue;
|
|
104391
104665
|
}
|
|
@@ -104423,7 +104697,7 @@ ${loadedContents.join(`
|
|
|
104423
104697
|
session_id: sessionId,
|
|
104424
104698
|
uuid: `error-${lastRunId || randomUUID15()}`
|
|
104425
104699
|
};
|
|
104426
|
-
|
|
104700
|
+
await writeWireMessageAsync(errorMsg);
|
|
104427
104701
|
} else {
|
|
104428
104702
|
console.error(`Error: ${errorMessage}`);
|
|
104429
104703
|
}
|
|
@@ -104442,7 +104716,7 @@ ${loadedContents.join(`
|
|
|
104442
104716
|
session_id: sessionId,
|
|
104443
104717
|
uuid: `error-${lastKnownRunId || randomUUID15()}`
|
|
104444
104718
|
};
|
|
104445
|
-
|
|
104719
|
+
await writeWireMessageAsync(errorMsg);
|
|
104446
104720
|
} else {
|
|
104447
104721
|
console.error(`Error: ${errorDetails}`);
|
|
104448
104722
|
}
|
|
@@ -104505,7 +104779,7 @@ ${loadedContents.join(`
|
|
|
104505
104779
|
usage,
|
|
104506
104780
|
uuid: resultUuid
|
|
104507
104781
|
};
|
|
104508
|
-
|
|
104782
|
+
await writeWireMessageAsync(resultEvent);
|
|
104509
104783
|
} else {
|
|
104510
104784
|
if (!resultText || resultText === "No assistant response found") {
|
|
104511
104785
|
console.error("No assistant response found");
|
|
@@ -104704,9 +104978,9 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
104704
104978
|
const syntheticUserLine = serializeQueuedMessageAsUserLine(queuedMessage);
|
|
104705
104979
|
maybeNotifyBlocked(syntheticUserLine);
|
|
104706
104980
|
if (lineResolver) {
|
|
104707
|
-
const
|
|
104981
|
+
const resolve32 = lineResolver;
|
|
104708
104982
|
lineResolver = null;
|
|
104709
|
-
|
|
104983
|
+
resolve32(syntheticUserLine);
|
|
104710
104984
|
return;
|
|
104711
104985
|
}
|
|
104712
104986
|
lineQueue.push(syntheticUserLine);
|
|
@@ -104714,9 +104988,9 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
104714
104988
|
rl.on("line", (line) => {
|
|
104715
104989
|
maybeNotifyBlocked(line);
|
|
104716
104990
|
if (lineResolver) {
|
|
104717
|
-
const
|
|
104991
|
+
const resolve32 = lineResolver;
|
|
104718
104992
|
lineResolver = null;
|
|
104719
|
-
|
|
104993
|
+
resolve32(line);
|
|
104720
104994
|
} else {
|
|
104721
104995
|
lineQueue.push(line);
|
|
104722
104996
|
}
|
|
@@ -104725,17 +104999,17 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
104725
104999
|
setMessageQueueAdder(null);
|
|
104726
105000
|
msgQueueRuntime.clear("shutdown");
|
|
104727
105001
|
if (lineResolver) {
|
|
104728
|
-
const
|
|
105002
|
+
const resolve32 = lineResolver;
|
|
104729
105003
|
lineResolver = null;
|
|
104730
|
-
|
|
105004
|
+
resolve32(null);
|
|
104731
105005
|
}
|
|
104732
105006
|
});
|
|
104733
105007
|
async function getNextLine() {
|
|
104734
105008
|
if (lineQueue.length > 0) {
|
|
104735
105009
|
return lineQueue.shift() ?? null;
|
|
104736
105010
|
}
|
|
104737
|
-
return new Promise((
|
|
104738
|
-
lineResolver =
|
|
105011
|
+
return new Promise((resolve32) => {
|
|
105012
|
+
lineResolver = resolve32;
|
|
104739
105013
|
});
|
|
104740
105014
|
}
|
|
104741
105015
|
async function requestPermission(toolCallId, toolName, toolInput) {
|
|
@@ -105196,7 +105470,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
105196
105470
|
uuid: `retry-bidir-${randomUUID15()}`
|
|
105197
105471
|
};
|
|
105198
105472
|
writeWireMessage(retryMsg);
|
|
105199
|
-
await new Promise((
|
|
105473
|
+
await new Promise((resolve32) => setTimeout(resolve32, delayMs));
|
|
105200
105474
|
continue;
|
|
105201
105475
|
}
|
|
105202
105476
|
throw preStreamError;
|
|
@@ -105496,10 +105770,10 @@ async function detectAndEnableKittyProtocol() {
|
|
|
105496
105770
|
detectionComplete = true;
|
|
105497
105771
|
return;
|
|
105498
105772
|
}
|
|
105499
|
-
return new Promise((
|
|
105773
|
+
return new Promise((resolve32) => {
|
|
105500
105774
|
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
105501
105775
|
detectionComplete = true;
|
|
105502
|
-
|
|
105776
|
+
resolve32();
|
|
105503
105777
|
return;
|
|
105504
105778
|
}
|
|
105505
105779
|
const originalRawMode = process.stdin.isRaw;
|
|
@@ -105532,7 +105806,7 @@ async function detectAndEnableKittyProtocol() {
|
|
|
105532
105806
|
console.error("[kitty] protocol query unsupported; enabled anyway (best-effort)");
|
|
105533
105807
|
}
|
|
105534
105808
|
detectionComplete = true;
|
|
105535
|
-
|
|
105809
|
+
resolve32();
|
|
105536
105810
|
};
|
|
105537
105811
|
const handleData = (data) => {
|
|
105538
105812
|
if (timeoutId === undefined) {
|
|
@@ -127637,9 +127911,9 @@ var init_pasteRegistry = __esm(() => {
|
|
|
127637
127911
|
|
|
127638
127912
|
// src/cli/helpers/clipboard.ts
|
|
127639
127913
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
127640
|
-
import { existsSync as existsSync38, readFileSync as
|
|
127914
|
+
import { existsSync as existsSync38, readFileSync as readFileSync25, statSync as statSync11, unlinkSync as unlinkSync10 } from "node:fs";
|
|
127641
127915
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
127642
|
-
import { basename as basename13, extname as extname8, isAbsolute as isAbsolute20, join as join45, resolve as
|
|
127916
|
+
import { basename as basename13, extname as extname8, isAbsolute as isAbsolute20, join as join45, resolve as resolve32 } from "node:path";
|
|
127643
127917
|
function countLines2(text) {
|
|
127644
127918
|
return (text.match(/\r\n|\r|\n/g) || []).length + 1;
|
|
127645
127919
|
}
|
|
@@ -127689,21 +127963,21 @@ function translatePasteForImages(paste) {
|
|
|
127689
127963
|
} catch {}
|
|
127690
127964
|
}
|
|
127691
127965
|
if (!isAbsolute20(filePath))
|
|
127692
|
-
filePath =
|
|
127966
|
+
filePath = resolve32(process.cwd(), filePath);
|
|
127693
127967
|
const ext3 = extname8(filePath || "").toLowerCase();
|
|
127694
127968
|
if (IMAGE_EXTS.has(ext3)) {
|
|
127695
127969
|
let buf = null;
|
|
127696
127970
|
try {
|
|
127697
|
-
const stat8 =
|
|
127971
|
+
const stat8 = statSync11(filePath);
|
|
127698
127972
|
if (stat8.isFile())
|
|
127699
|
-
buf =
|
|
127973
|
+
buf = readFileSync25(filePath);
|
|
127700
127974
|
} catch {}
|
|
127701
127975
|
let clipboardMediaType = null;
|
|
127702
127976
|
if (!buf && process.platform === "darwin" && /TemporaryItems\/.*screencaptureui/i.test(filePath)) {
|
|
127703
127977
|
const clipResult = getClipboardImageToTempFile();
|
|
127704
127978
|
if (clipResult) {
|
|
127705
127979
|
try {
|
|
127706
|
-
buf =
|
|
127980
|
+
buf = readFileSync25(clipResult.tempPath);
|
|
127707
127981
|
clipboardMediaType = UTI_TO_MEDIA_TYPE[clipResult.uti] || null;
|
|
127708
127982
|
try {
|
|
127709
127983
|
unlinkSync10(clipResult.tempPath);
|
|
@@ -127772,7 +128046,7 @@ async function tryImportClipboardImageMac() {
|
|
|
127772
128046
|
return null;
|
|
127773
128047
|
const { tempPath, uti } = clipboardResult;
|
|
127774
128048
|
try {
|
|
127775
|
-
const buffer =
|
|
128049
|
+
const buffer = readFileSync25(tempPath);
|
|
127776
128050
|
try {
|
|
127777
128051
|
unlinkSync10(tempPath);
|
|
127778
128052
|
} catch {}
|
|
@@ -128387,8 +128661,8 @@ async function pushToMemoryRepositoryWithTimeout(agentId) {
|
|
|
128387
128661
|
try {
|
|
128388
128662
|
return await Promise.race([
|
|
128389
128663
|
pushToMemoryRepository(agentId),
|
|
128390
|
-
new Promise((
|
|
128391
|
-
timeout = setTimeout(() =>
|
|
128664
|
+
new Promise((resolve33) => {
|
|
128665
|
+
timeout = setTimeout(() => resolve33("timeout"), INITIAL_PUSH_TIMEOUT_MS);
|
|
128392
128666
|
})
|
|
128393
128667
|
]);
|
|
128394
128668
|
} finally {
|
|
@@ -128639,11 +128913,11 @@ import {
|
|
|
128639
128913
|
copyFileSync,
|
|
128640
128914
|
existsSync as existsSync39,
|
|
128641
128915
|
mkdirSync as mkdirSync30,
|
|
128642
|
-
readFileSync as
|
|
128916
|
+
readFileSync as readFileSync26,
|
|
128643
128917
|
writeFileSync as writeFileSync21
|
|
128644
128918
|
} from "node:fs";
|
|
128645
128919
|
import { homedir as homedir32, platform as platform6 } from "node:os";
|
|
128646
|
-
import { dirname as
|
|
128920
|
+
import { dirname as dirname20, join as join46 } from "node:path";
|
|
128647
128921
|
function detectTerminalType() {
|
|
128648
128922
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
128649
128923
|
return "cursor";
|
|
@@ -128709,7 +128983,7 @@ function keybindingExists(keybindingsPath) {
|
|
|
128709
128983
|
if (!existsSync39(keybindingsPath))
|
|
128710
128984
|
return false;
|
|
128711
128985
|
try {
|
|
128712
|
-
const content =
|
|
128986
|
+
const content = readFileSync26(keybindingsPath, { encoding: "utf-8" });
|
|
128713
128987
|
const keybindings = parseKeybindings(content);
|
|
128714
128988
|
if (!keybindings)
|
|
128715
128989
|
return false;
|
|
@@ -128734,7 +129008,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
128734
129008
|
if (keybindingExists(keybindingsPath)) {
|
|
128735
129009
|
return { success: true, alreadyExists: true };
|
|
128736
129010
|
}
|
|
128737
|
-
const parentDir =
|
|
129011
|
+
const parentDir = dirname20(keybindingsPath);
|
|
128738
129012
|
if (!existsSync39(parentDir)) {
|
|
128739
129013
|
mkdirSync30(parentDir, { recursive: true });
|
|
128740
129014
|
}
|
|
@@ -128742,7 +129016,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
128742
129016
|
let backupPath = null;
|
|
128743
129017
|
if (existsSync39(keybindingsPath)) {
|
|
128744
129018
|
backupPath = createBackup(keybindingsPath);
|
|
128745
|
-
const content =
|
|
129019
|
+
const content = readFileSync26(keybindingsPath, { encoding: "utf-8" });
|
|
128746
129020
|
const parsed = parseKeybindings(content);
|
|
128747
129021
|
if (parsed === null) {
|
|
128748
129022
|
return {
|
|
@@ -128773,7 +129047,7 @@ function removeKeybinding(keybindingsPath) {
|
|
|
128773
129047
|
if (!existsSync39(keybindingsPath)) {
|
|
128774
129048
|
return { success: true };
|
|
128775
129049
|
}
|
|
128776
|
-
const content =
|
|
129050
|
+
const content = readFileSync26(keybindingsPath, { encoding: "utf-8" });
|
|
128777
129051
|
const keybindings = parseKeybindings(content);
|
|
128778
129052
|
if (!keybindings) {
|
|
128779
129053
|
return {
|
|
@@ -128850,7 +129124,7 @@ function wezTermDeleteFixExists(configPath) {
|
|
|
128850
129124
|
if (!existsSync39(configPath))
|
|
128851
129125
|
return false;
|
|
128852
129126
|
try {
|
|
128853
|
-
const content =
|
|
129127
|
+
const content = readFileSync26(configPath, { encoding: "utf-8" });
|
|
128854
129128
|
return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
|
|
128855
129129
|
} catch {
|
|
128856
129130
|
return false;
|
|
@@ -128867,7 +129141,7 @@ function installWezTermDeleteFix() {
|
|
|
128867
129141
|
if (existsSync39(configPath)) {
|
|
128868
129142
|
backupPath = `${configPath}.letta-backup`;
|
|
128869
129143
|
copyFileSync(configPath, backupPath);
|
|
128870
|
-
content =
|
|
129144
|
+
content = readFileSync26(configPath, { encoding: "utf-8" });
|
|
128871
129145
|
}
|
|
128872
129146
|
if (content.includes("return {") && !content.includes("local config")) {
|
|
128873
129147
|
content = content.replace(/return\s*\{/, "local config = {");
|
|
@@ -128893,7 +129167,7 @@ return config`);
|
|
|
128893
129167
|
${WEZTERM_DELETE_FIX}
|
|
128894
129168
|
`;
|
|
128895
129169
|
}
|
|
128896
|
-
const parentDir =
|
|
129170
|
+
const parentDir = dirname20(configPath);
|
|
128897
129171
|
if (!existsSync39(parentDir)) {
|
|
128898
129172
|
mkdirSync30(parentDir, { recursive: true });
|
|
128899
129173
|
}
|
|
@@ -129493,7 +129767,7 @@ __export(exports_custom, {
|
|
|
129493
129767
|
});
|
|
129494
129768
|
import { existsSync as existsSync40 } from "node:fs";
|
|
129495
129769
|
import { readdir as readdir10, readFile as readFile16 } from "node:fs/promises";
|
|
129496
|
-
import { basename as basename14, dirname as
|
|
129770
|
+
import { basename as basename14, dirname as dirname21, join as join47 } from "node:path";
|
|
129497
129771
|
async function getCustomCommands() {
|
|
129498
129772
|
if (cachedCommands !== null) {
|
|
129499
129773
|
return cachedCommands;
|
|
@@ -129554,7 +129828,7 @@ async function parseCommandFile(filePath, rootPath, source2) {
|
|
|
129554
129828
|
const content = await readFile16(filePath, "utf-8");
|
|
129555
129829
|
const { frontmatter, body } = parseFrontmatter(content);
|
|
129556
129830
|
const id = basename14(filePath, ".md");
|
|
129557
|
-
const relativePath =
|
|
129831
|
+
const relativePath = dirname21(filePath).slice(rootPath.length);
|
|
129558
129832
|
const namespace = relativePath.replace(/^[/\\]/, "") || undefined;
|
|
129559
129833
|
let description = getStringField(frontmatter, "description");
|
|
129560
129834
|
if (!description) {
|
|
@@ -129903,11 +130177,11 @@ var init_HelpDialog = __esm(async () => {
|
|
|
129903
130177
|
|
|
129904
130178
|
// src/hooks/writer.ts
|
|
129905
130179
|
import { homedir as homedir33 } from "node:os";
|
|
129906
|
-
import { resolve as
|
|
130180
|
+
import { resolve as resolve33 } from "node:path";
|
|
129907
130181
|
function isProjectSettingsPathCollidingWithGlobal2(workingDirectory) {
|
|
129908
130182
|
const home = process.env.HOME || homedir33();
|
|
129909
|
-
const globalSettingsPath =
|
|
129910
|
-
const projectSettingsPath =
|
|
130183
|
+
const globalSettingsPath = resolve33(home, ".letta", "settings.json");
|
|
130184
|
+
const projectSettingsPath = resolve33(workingDirectory, ".letta", "settings.json");
|
|
129911
130185
|
return globalSettingsPath === projectSettingsPath;
|
|
129912
130186
|
}
|
|
129913
130187
|
function loadHooksFromLocation(location, workingDirectory = process.cwd()) {
|
|
@@ -132546,8 +132820,8 @@ var init_AgentInfoBar = __esm(async () => {
|
|
|
132546
132820
|
});
|
|
132547
132821
|
|
|
132548
132822
|
// src/cli/helpers/fileSearch.ts
|
|
132549
|
-
import { readdirSync as readdirSync13, statSync as
|
|
132550
|
-
import { join as join48, relative as relative17, resolve as
|
|
132823
|
+
import { readdirSync as readdirSync13, statSync as statSync12 } from "node:fs";
|
|
132824
|
+
import { join as join48, relative as relative17, resolve as resolve34 } from "node:path";
|
|
132551
132825
|
function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = [], depth = 0, maxDepth = 10, lowerPattern = pattern.toLowerCase()) {
|
|
132552
132826
|
if (results.length >= maxResults || depth >= maxDepth) {
|
|
132553
132827
|
return results;
|
|
@@ -132561,7 +132835,7 @@ function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = [],
|
|
|
132561
132835
|
if (shouldHardExcludeEntry(entry, getIndexRoot())) {
|
|
132562
132836
|
continue;
|
|
132563
132837
|
}
|
|
132564
|
-
const stats =
|
|
132838
|
+
const stats = statSync12(fullPath);
|
|
132565
132839
|
const matches = pattern.length === 0 || relativePath.toLowerCase().includes(lowerPattern);
|
|
132566
132840
|
if (matches) {
|
|
132567
132841
|
results.push({
|
|
@@ -132590,9 +132864,9 @@ async function searchFiles(query, deep = false) {
|
|
|
132590
132864
|
const dirPart = query.slice(0, lastSlashIndex);
|
|
132591
132865
|
const pattern = query.slice(lastSlashIndex + 1);
|
|
132592
132866
|
try {
|
|
132593
|
-
const resolvedDir =
|
|
132867
|
+
const resolvedDir = resolve34(getIndexRoot(), dirPart);
|
|
132594
132868
|
try {
|
|
132595
|
-
|
|
132869
|
+
statSync12(resolvedDir);
|
|
132596
132870
|
searchDir = resolvedDir;
|
|
132597
132871
|
searchPattern = pattern;
|
|
132598
132872
|
} catch {}
|
|
@@ -132635,7 +132909,7 @@ async function searchFiles(query, deep = false) {
|
|
|
132635
132909
|
for (const entry of matchingEntries.slice(0, 50)) {
|
|
132636
132910
|
try {
|
|
132637
132911
|
const fullPath = join48(searchDir, entry);
|
|
132638
|
-
const stats =
|
|
132912
|
+
const stats = statSync12(fullPath);
|
|
132639
132913
|
const relativePath = relative17(getIndexRoot(), fullPath);
|
|
132640
132914
|
results.push({
|
|
132641
132915
|
path: relativePath,
|
|
@@ -134716,12 +134990,12 @@ import {
|
|
|
134716
134990
|
existsSync as existsSync41,
|
|
134717
134991
|
mkdirSync as mkdirSync31,
|
|
134718
134992
|
mkdtempSync,
|
|
134719
|
-
readFileSync as
|
|
134993
|
+
readFileSync as readFileSync27,
|
|
134720
134994
|
rmSync as rmSync4,
|
|
134721
134995
|
writeFileSync as writeFileSync22
|
|
134722
134996
|
} from "node:fs";
|
|
134723
134997
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
134724
|
-
import { dirname as
|
|
134998
|
+
import { dirname as dirname22, join as join49 } from "node:path";
|
|
134725
134999
|
function runCommand(command, args, cwd2, input) {
|
|
134726
135000
|
try {
|
|
134727
135001
|
return execFileSync4(command, args, {
|
|
@@ -134968,13 +135242,13 @@ function runGit3(args, cwd2) {
|
|
|
134968
135242
|
}
|
|
134969
135243
|
function writeWorkflow(repoDir, workflowPath, content) {
|
|
134970
135244
|
const absolutePath = join49(repoDir, workflowPath);
|
|
134971
|
-
if (!existsSync41(
|
|
134972
|
-
mkdirSync31(
|
|
135245
|
+
if (!existsSync41(dirname22(absolutePath))) {
|
|
135246
|
+
mkdirSync31(dirname22(absolutePath), { recursive: true });
|
|
134973
135247
|
}
|
|
134974
135248
|
const next = `${content.trimEnd()}
|
|
134975
135249
|
`;
|
|
134976
135250
|
if (existsSync41(absolutePath)) {
|
|
134977
|
-
const previous =
|
|
135251
|
+
const previous = readFileSync27(absolutePath, "utf8");
|
|
134978
135252
|
if (previous === next) {
|
|
134979
135253
|
return false;
|
|
134980
135254
|
}
|
|
@@ -147735,7 +148009,7 @@ async function executeStatusLineCommand(command, payload, options) {
|
|
|
147735
148009
|
};
|
|
147736
148010
|
}
|
|
147737
148011
|
function runWithLauncher(launcher, inputJson, timeout, signal, workingDirectory, startTime) {
|
|
147738
|
-
return new Promise((
|
|
148012
|
+
return new Promise((resolve35, reject) => {
|
|
147739
148013
|
const [executable, ...args] = launcher;
|
|
147740
148014
|
if (!executable) {
|
|
147741
148015
|
reject(new Error("Empty launcher"));
|
|
@@ -147748,7 +148022,7 @@ function runWithLauncher(launcher, inputJson, timeout, signal, workingDirectory,
|
|
|
147748
148022
|
const safeResolve = (result) => {
|
|
147749
148023
|
if (!resolved) {
|
|
147750
148024
|
resolved = true;
|
|
147751
|
-
|
|
148025
|
+
resolve35(result);
|
|
147752
148026
|
}
|
|
147753
148027
|
};
|
|
147754
148028
|
let child;
|
|
@@ -148195,7 +148469,7 @@ __export(exports_shellAliases, {
|
|
|
148195
148469
|
expandAliases: () => expandAliases,
|
|
148196
148470
|
clearAliasCache: () => clearAliasCache
|
|
148197
148471
|
});
|
|
148198
|
-
import { existsSync as existsSync44, readFileSync as
|
|
148472
|
+
import { existsSync as existsSync44, readFileSync as readFileSync28 } from "node:fs";
|
|
148199
148473
|
import { homedir as homedir36 } from "node:os";
|
|
148200
148474
|
import { join as join52 } from "node:path";
|
|
148201
148475
|
function parseAliasesFromFile(filePath) {
|
|
@@ -148204,7 +148478,7 @@ function parseAliasesFromFile(filePath) {
|
|
|
148204
148478
|
return aliases;
|
|
148205
148479
|
}
|
|
148206
148480
|
try {
|
|
148207
|
-
const content =
|
|
148481
|
+
const content = readFileSync28(filePath, "utf-8");
|
|
148208
148482
|
const lines = content.split(`
|
|
148209
148483
|
`);
|
|
148210
148484
|
let inFunction = false;
|
|
@@ -148923,14 +149197,14 @@ __export(exports_export, {
|
|
|
148923
149197
|
packageSkills: () => packageSkills
|
|
148924
149198
|
});
|
|
148925
149199
|
import { readdir as readdir11, readFile as readFile18 } from "node:fs/promises";
|
|
148926
|
-
import { relative as relative18, resolve as
|
|
149200
|
+
import { relative as relative18, resolve as resolve35 } from "node:path";
|
|
148927
149201
|
async function packageSkills(agentId, skillsDir) {
|
|
148928
149202
|
const skills = [];
|
|
148929
149203
|
const skillNames = new Set;
|
|
148930
149204
|
const dirsToCheck = skillsDir ? [skillsDir] : [
|
|
148931
149205
|
agentId && getAgentSkillsDir(agentId),
|
|
148932
|
-
|
|
148933
|
-
|
|
149206
|
+
resolve35(process.cwd(), ".skills"),
|
|
149207
|
+
resolve35(process.env.HOME || "~", ".letta", "skills")
|
|
148934
149208
|
].filter((dir) => Boolean(dir));
|
|
148935
149209
|
for (const baseDir of dirsToCheck) {
|
|
148936
149210
|
try {
|
|
@@ -148940,8 +149214,8 @@ async function packageSkills(agentId, skillsDir) {
|
|
|
148940
149214
|
continue;
|
|
148941
149215
|
if (skillNames.has(entry.name))
|
|
148942
149216
|
continue;
|
|
148943
|
-
const skillDir =
|
|
148944
|
-
const skillMdPath =
|
|
149217
|
+
const skillDir = resolve35(baseDir, entry.name);
|
|
149218
|
+
const skillMdPath = resolve35(skillDir, "SKILL.md");
|
|
148945
149219
|
try {
|
|
148946
149220
|
await readFile18(skillMdPath, "utf-8");
|
|
148947
149221
|
} catch {
|
|
@@ -148971,7 +149245,7 @@ async function readSkillFiles(skillDir) {
|
|
|
148971
149245
|
async function walk(dir) {
|
|
148972
149246
|
const entries = await readdir11(dir, { withFileTypes: true });
|
|
148973
149247
|
for (const entry of entries) {
|
|
148974
|
-
const fullPath =
|
|
149248
|
+
const fullPath = resolve35(dir, entry.name);
|
|
148975
149249
|
if (entry.isDirectory()) {
|
|
148976
149250
|
await walk(fullPath);
|
|
148977
149251
|
} else {
|
|
@@ -149115,7 +149389,7 @@ __export(exports_App, {
|
|
|
149115
149389
|
default: () => App2
|
|
149116
149390
|
});
|
|
149117
149391
|
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
149118
|
-
import { existsSync as existsSync45, readFileSync as
|
|
149392
|
+
import { existsSync as existsSync45, readFileSync as readFileSync29, renameSync as renameSync3, writeFileSync as writeFileSync24 } from "node:fs";
|
|
149119
149393
|
import { homedir as homedir37, tmpdir as tmpdir7 } from "node:os";
|
|
149120
149394
|
import { join as join53, relative as relative19 } from "node:path";
|
|
149121
149395
|
function deriveReasoningEffort(modelSettings, llmConfig) {
|
|
@@ -149342,7 +149616,7 @@ function _readPlanFile(fallbackPlanFilePath) {
|
|
|
149342
149616
|
return `Plan file not found at ${planFilePath}`;
|
|
149343
149617
|
}
|
|
149344
149618
|
try {
|
|
149345
|
-
return
|
|
149619
|
+
return readFileSync29(planFilePath, "utf-8");
|
|
149346
149620
|
} catch {
|
|
149347
149621
|
return `Failed to read plan file at ${planFilePath}`;
|
|
149348
149622
|
}
|
|
@@ -150693,10 +150967,10 @@ function App2({
|
|
|
150693
150967
|
if (!planFilePath)
|
|
150694
150968
|
return;
|
|
150695
150969
|
try {
|
|
150696
|
-
const { readFileSync:
|
|
150970
|
+
const { readFileSync: readFileSync30, existsSync: existsSync46 } = __require("node:fs");
|
|
150697
150971
|
if (!existsSync46(planFilePath))
|
|
150698
150972
|
return;
|
|
150699
|
-
const planContent =
|
|
150973
|
+
const planContent = readFileSync30(planFilePath, "utf-8");
|
|
150700
150974
|
const previewItem = {
|
|
150701
150975
|
kind: "approval_preview",
|
|
150702
150976
|
id: `approval-preview-${toolCallId}`,
|
|
@@ -151106,12 +151380,12 @@ Memory may be stale. Try running: git -C ~/.letta/agents/${agentId}/memory pull`
|
|
|
151106
151380
|
let watcher = null;
|
|
151107
151381
|
(async () => {
|
|
151108
151382
|
try {
|
|
151109
|
-
const { watch:
|
|
151383
|
+
const { watch: watch3 } = await import("node:fs");
|
|
151110
151384
|
const { existsSync: existsSync46 } = await import("node:fs");
|
|
151111
151385
|
const memRoot = getMemoryFilesystemRoot(agentId);
|
|
151112
151386
|
if (!existsSync46(memRoot))
|
|
151113
151387
|
return;
|
|
151114
|
-
watcher =
|
|
151388
|
+
watcher = watch3(memRoot, { recursive: true }, () => {});
|
|
151115
151389
|
memfsWatcherRef.current = watcher;
|
|
151116
151390
|
debugLog("memfs", `Watching memory directory: ${memRoot}`);
|
|
151117
151391
|
watcher.on("error", (err) => {
|
|
@@ -151438,7 +151712,7 @@ ${newState.originalPrompt}`,
|
|
|
151438
151712
|
cancelled = true;
|
|
151439
151713
|
break;
|
|
151440
151714
|
}
|
|
151441
|
-
await new Promise((
|
|
151715
|
+
await new Promise((resolve36) => setTimeout(resolve36, 100));
|
|
151442
151716
|
}
|
|
151443
151717
|
buffersRef.current.byId.delete(statusId);
|
|
151444
151718
|
buffersRef.current.order = buffersRef.current.order.filter((id) => id !== statusId);
|
|
@@ -151502,7 +151776,7 @@ ${newState.originalPrompt}`,
|
|
|
151502
151776
|
cancelled = true;
|
|
151503
151777
|
break;
|
|
151504
151778
|
}
|
|
151505
|
-
await new Promise((
|
|
151779
|
+
await new Promise((resolve36) => setTimeout(resolve36, 100));
|
|
151506
151780
|
}
|
|
151507
151781
|
if (retryStatusId) {
|
|
151508
151782
|
buffersRef.current.byId.delete(retryStatusId);
|
|
@@ -152252,7 +152526,7 @@ ${feedback}
|
|
|
152252
152526
|
});
|
|
152253
152527
|
buffersRef.current.order.push(statusId);
|
|
152254
152528
|
refreshDerived();
|
|
152255
|
-
await new Promise((
|
|
152529
|
+
await new Promise((resolve36) => setTimeout(resolve36, delayMs));
|
|
152256
152530
|
buffersRef.current.byId.delete(statusId);
|
|
152257
152531
|
buffersRef.current.order = buffersRef.current.order.filter((id) => id !== statusId);
|
|
152258
152532
|
refreshDerived();
|
|
@@ -152312,7 +152586,7 @@ ${feedback}
|
|
|
152312
152586
|
cancelled = true;
|
|
152313
152587
|
break;
|
|
152314
152588
|
}
|
|
152315
|
-
await new Promise((
|
|
152589
|
+
await new Promise((resolve36) => setTimeout(resolve36, 100));
|
|
152316
152590
|
}
|
|
152317
152591
|
if (retryStatusId) {
|
|
152318
152592
|
buffersRef.current.byId.delete(retryStatusId);
|
|
@@ -153474,7 +153748,7 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
|
|
|
153474
153748
|
];
|
|
153475
153749
|
const personaPath = personaCandidates.find((candidate) => existsSync45(candidate));
|
|
153476
153750
|
if (personaPath) {
|
|
153477
|
-
const personaContent =
|
|
153751
|
+
const personaContent = readFileSync29(personaPath, "utf-8");
|
|
153478
153752
|
setCurrentPersonalityId(detectPersonalityFromPersonaFile(personaContent));
|
|
153479
153753
|
} else {
|
|
153480
153754
|
setCurrentPersonalityId(null);
|
|
@@ -158369,11 +158643,11 @@ import {
|
|
|
158369
158643
|
copyFileSync as copyFileSync2,
|
|
158370
158644
|
existsSync as existsSync46,
|
|
158371
158645
|
mkdirSync as mkdirSync33,
|
|
158372
|
-
readFileSync as
|
|
158646
|
+
readFileSync as readFileSync30,
|
|
158373
158647
|
writeFileSync as writeFileSync25
|
|
158374
158648
|
} from "node:fs";
|
|
158375
158649
|
import { homedir as homedir38, platform as platform7 } from "node:os";
|
|
158376
|
-
import { dirname as
|
|
158650
|
+
import { dirname as dirname23, join as join54 } from "node:path";
|
|
158377
158651
|
function detectTerminalType2() {
|
|
158378
158652
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
158379
158653
|
return "cursor";
|
|
@@ -158439,7 +158713,7 @@ function keybindingExists2(keybindingsPath) {
|
|
|
158439
158713
|
if (!existsSync46(keybindingsPath))
|
|
158440
158714
|
return false;
|
|
158441
158715
|
try {
|
|
158442
|
-
const content =
|
|
158716
|
+
const content = readFileSync30(keybindingsPath, { encoding: "utf-8" });
|
|
158443
158717
|
const keybindings = parseKeybindings2(content);
|
|
158444
158718
|
if (!keybindings)
|
|
158445
158719
|
return false;
|
|
@@ -158464,7 +158738,7 @@ function installKeybinding2(keybindingsPath) {
|
|
|
158464
158738
|
if (keybindingExists2(keybindingsPath)) {
|
|
158465
158739
|
return { success: true, alreadyExists: true };
|
|
158466
158740
|
}
|
|
158467
|
-
const parentDir =
|
|
158741
|
+
const parentDir = dirname23(keybindingsPath);
|
|
158468
158742
|
if (!existsSync46(parentDir)) {
|
|
158469
158743
|
mkdirSync33(parentDir, { recursive: true });
|
|
158470
158744
|
}
|
|
@@ -158472,7 +158746,7 @@ function installKeybinding2(keybindingsPath) {
|
|
|
158472
158746
|
let backupPath = null;
|
|
158473
158747
|
if (existsSync46(keybindingsPath)) {
|
|
158474
158748
|
backupPath = createBackup2(keybindingsPath);
|
|
158475
|
-
const content =
|
|
158749
|
+
const content = readFileSync30(keybindingsPath, { encoding: "utf-8" });
|
|
158476
158750
|
const parsed = parseKeybindings2(content);
|
|
158477
158751
|
if (parsed === null) {
|
|
158478
158752
|
return {
|
|
@@ -158503,7 +158777,7 @@ function removeKeybinding2(keybindingsPath) {
|
|
|
158503
158777
|
if (!existsSync46(keybindingsPath)) {
|
|
158504
158778
|
return { success: true };
|
|
158505
158779
|
}
|
|
158506
|
-
const content =
|
|
158780
|
+
const content = readFileSync30(keybindingsPath, { encoding: "utf-8" });
|
|
158507
158781
|
const keybindings = parseKeybindings2(content);
|
|
158508
158782
|
if (!keybindings) {
|
|
158509
158783
|
return {
|
|
@@ -158580,7 +158854,7 @@ function wezTermDeleteFixExists2(configPath) {
|
|
|
158580
158854
|
if (!existsSync46(configPath))
|
|
158581
158855
|
return false;
|
|
158582
158856
|
try {
|
|
158583
|
-
const content =
|
|
158857
|
+
const content = readFileSync30(configPath, { encoding: "utf-8" });
|
|
158584
158858
|
return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
|
|
158585
158859
|
} catch {
|
|
158586
158860
|
return false;
|
|
@@ -158597,7 +158871,7 @@ function installWezTermDeleteFix2() {
|
|
|
158597
158871
|
if (existsSync46(configPath)) {
|
|
158598
158872
|
backupPath = `${configPath}.letta-backup`;
|
|
158599
158873
|
copyFileSync2(configPath, backupPath);
|
|
158600
|
-
content =
|
|
158874
|
+
content = readFileSync30(configPath, { encoding: "utf-8" });
|
|
158601
158875
|
}
|
|
158602
158876
|
if (content.includes("return {") && !content.includes("local config")) {
|
|
158603
158877
|
content = content.replace(/return\s*\{/, "local config = {");
|
|
@@ -158623,7 +158897,7 @@ return config`);
|
|
|
158623
158897
|
${WEZTERM_DELETE_FIX2}
|
|
158624
158898
|
`;
|
|
158625
158899
|
}
|
|
158626
|
-
const parentDir =
|
|
158900
|
+
const parentDir = dirname23(configPath);
|
|
158627
158901
|
if (!existsSync46(parentDir)) {
|
|
158628
158902
|
mkdirSync33(parentDir, { recursive: true });
|
|
158629
158903
|
}
|
|
@@ -159193,10 +159467,10 @@ __export(exports_import2, {
|
|
|
159193
159467
|
});
|
|
159194
159468
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
159195
159469
|
import { chmod as chmod2, mkdir as mkdir11, readFile as readFile19, writeFile as writeFile14 } from "node:fs/promises";
|
|
159196
|
-
import { dirname as
|
|
159470
|
+
import { dirname as dirname24, resolve as resolve36 } from "node:path";
|
|
159197
159471
|
async function importAgentFromFile2(options) {
|
|
159198
159472
|
const client = await getClient();
|
|
159199
|
-
const resolvedPath =
|
|
159473
|
+
const resolvedPath = resolve36(options.filePath);
|
|
159200
159474
|
const file = createReadStream2(resolvedPath);
|
|
159201
159475
|
const importResponse = await client.agents.importFile({
|
|
159202
159476
|
file,
|
|
@@ -159231,7 +159505,7 @@ async function extractSkillsFromAf2(afPath, destDir) {
|
|
|
159231
159505
|
return [];
|
|
159232
159506
|
}
|
|
159233
159507
|
for (const skill2 of afData.skills) {
|
|
159234
|
-
const skillDir =
|
|
159508
|
+
const skillDir = resolve36(destDir, skill2.name);
|
|
159235
159509
|
await mkdir11(skillDir, { recursive: true });
|
|
159236
159510
|
if (skill2.files) {
|
|
159237
159511
|
await writeSkillFiles2(skillDir, skill2.files);
|
|
@@ -159251,8 +159525,8 @@ async function writeSkillFiles2(skillDir, files) {
|
|
|
159251
159525
|
}
|
|
159252
159526
|
}
|
|
159253
159527
|
async function writeSkillFile2(skillDir, filePath, content) {
|
|
159254
|
-
const fullPath =
|
|
159255
|
-
await mkdir11(
|
|
159528
|
+
const fullPath = resolve36(skillDir, filePath);
|
|
159529
|
+
await mkdir11(dirname24(fullPath), { recursive: true });
|
|
159256
159530
|
await writeFile14(fullPath, content, "utf-8");
|
|
159257
159531
|
const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
|
|
159258
159532
|
if (isScript) {
|
|
@@ -159365,7 +159639,7 @@ __export(exports_memoryFilesystem2, {
|
|
|
159365
159639
|
});
|
|
159366
159640
|
import { existsSync as existsSync47, mkdirSync as mkdirSync34 } from "node:fs";
|
|
159367
159641
|
import { homedir as homedir40 } from "node:os";
|
|
159368
|
-
import { join as join56, resolve as
|
|
159642
|
+
import { join as join56, resolve as resolve37 } from "node:path";
|
|
159369
159643
|
function getMemoryFilesystemRoot2(agentId, homeDir = homedir40()) {
|
|
159370
159644
|
return join56(homeDir, MEMORY_FS_ROOT2, MEMORY_FS_AGENTS_DIR2, agentId, MEMORY_FS_MEMORY_DIR2);
|
|
159371
159645
|
}
|
|
@@ -159387,7 +159661,7 @@ function resolveScopedMemoryDir2(options = {}) {
|
|
|
159387
159661
|
} catch {}
|
|
159388
159662
|
const directMemoryDir = (env4.LETTA_MEMORY_DIR || env4.MEMORY_DIR || "").trim();
|
|
159389
159663
|
if (directMemoryDir) {
|
|
159390
|
-
return
|
|
159664
|
+
return resolve37(directMemoryDir);
|
|
159391
159665
|
}
|
|
159392
159666
|
const envAgentId = (env4.LETTA_AGENT_ID || env4.AGENT_ID || "").trim();
|
|
159393
159667
|
if (envAgentId) {
|
|
@@ -164537,11 +164811,11 @@ async function runListenSubcommand(argv) {
|
|
|
164537
164811
|
connectionName = hostname3();
|
|
164538
164812
|
settingsManager.setListenerEnvName(connectionName);
|
|
164539
164813
|
} else {
|
|
164540
|
-
connectionName = await new Promise((
|
|
164814
|
+
connectionName = await new Promise((resolve28) => {
|
|
164541
164815
|
const { unmount } = render_default(/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(PromptEnvName, {
|
|
164542
164816
|
onSubmit: (name) => {
|
|
164543
164817
|
unmount();
|
|
164544
|
-
|
|
164818
|
+
resolve28(name);
|
|
164545
164819
|
}
|
|
164546
164820
|
}, undefined, false, undefined, this));
|
|
164547
164821
|
});
|
|
@@ -164743,7 +165017,7 @@ async function runListenSubcommand(argv) {
|
|
|
164743
165017
|
|
|
164744
165018
|
// src/cli/subcommands/memory.ts
|
|
164745
165019
|
init_memoryGit();
|
|
164746
|
-
import { cpSync, existsSync as existsSync30, mkdirSync as mkdirSync23, rmSync as rmSync3, statSync as
|
|
165020
|
+
import { cpSync, existsSync as existsSync30, mkdirSync as mkdirSync23, rmSync as rmSync3, statSync as statSync9 } from "node:fs";
|
|
164747
165021
|
import { readdir as readdir7 } from "node:fs/promises";
|
|
164748
165022
|
import { homedir as homedir23 } from "node:os";
|
|
164749
165023
|
import { join as join34 } from "node:path";
|
|
@@ -164911,7 +165185,7 @@ async function listBackups(agentId) {
|
|
|
164911
165185
|
const path26 = join34(agentRoot, entry.name);
|
|
164912
165186
|
let createdAt = null;
|
|
164913
165187
|
try {
|
|
164914
|
-
const stat7 =
|
|
165188
|
+
const stat7 = statSync9(path26);
|
|
164915
165189
|
createdAt = stat7.mtime.toISOString();
|
|
164916
165190
|
} catch {
|
|
164917
165191
|
createdAt = null;
|
|
@@ -165029,7 +165303,7 @@ async function runMemorySubcommand(argv) {
|
|
|
165029
165303
|
console.error(`Backup not found: ${backupPath}`);
|
|
165030
165304
|
return 1;
|
|
165031
165305
|
}
|
|
165032
|
-
const stat7 =
|
|
165306
|
+
const stat7 = statSync9(backupPath);
|
|
165033
165307
|
if (!stat7.isDirectory()) {
|
|
165034
165308
|
console.error(`Backup path is not a directory: ${backupPath}`);
|
|
165035
165309
|
return 1;
|
|
@@ -165052,7 +165326,7 @@ async function runMemorySubcommand(argv) {
|
|
|
165052
165326
|
return 1;
|
|
165053
165327
|
}
|
|
165054
165328
|
if (existsSync30(out)) {
|
|
165055
|
-
const stat7 =
|
|
165329
|
+
const stat7 = statSync9(out);
|
|
165056
165330
|
if (stat7.isDirectory()) {
|
|
165057
165331
|
const contents = await readdir7(out);
|
|
165058
165332
|
if (contents.length > 0) {
|
|
@@ -165083,7 +165357,7 @@ async function runMemorySubcommand(argv) {
|
|
|
165083
165357
|
init_client2();
|
|
165084
165358
|
init_settings_manager();
|
|
165085
165359
|
import { writeFile as writeFile11 } from "node:fs/promises";
|
|
165086
|
-
import { resolve as
|
|
165360
|
+
import { resolve as resolve28 } from "node:path";
|
|
165087
165361
|
import { parseArgs as parseArgs9 } from "node:util";
|
|
165088
165362
|
function printUsage6() {
|
|
165089
165363
|
console.log(`
|
|
@@ -165388,7 +165662,7 @@ async function runMessagesSubcommand(argv) {
|
|
|
165388
165662
|
|
|
165389
165663
|
`).trim();
|
|
165390
165664
|
if (outputPathRaw && typeof outputPathRaw === "string") {
|
|
165391
|
-
const outputPath =
|
|
165665
|
+
const outputPath = resolve28(process.cwd(), outputPathRaw);
|
|
165392
165666
|
await writeFile11(outputPath, `${transcript}
|
|
165393
165667
|
`, "utf-8");
|
|
165394
165668
|
console.log(JSON.stringify({
|
|
@@ -165837,7 +166111,7 @@ init_fs();
|
|
|
165837
166111
|
init_secrets();
|
|
165838
166112
|
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
165839
166113
|
import { homedir as homedir25 } from "node:os";
|
|
165840
|
-
import { join as join36, resolve as
|
|
166114
|
+
import { join as join36, resolve as resolve29 } from "node:path";
|
|
165841
166115
|
var DEFAULT_SETTINGS3 = {
|
|
165842
166116
|
lastAgent: null,
|
|
165843
166117
|
tokenStreaming: false,
|
|
@@ -166316,7 +166590,7 @@ class SettingsManager2 {
|
|
|
166316
166590
|
return join36(workingDirectory, ".letta", "settings.json");
|
|
166317
166591
|
}
|
|
166318
166592
|
isProjectSettingsPathCollidingWithGlobal(workingDirectory) {
|
|
166319
|
-
return
|
|
166593
|
+
return resolve29(this.getProjectSettingsPath(workingDirectory)) === resolve29(this.getSettingsPath());
|
|
166320
166594
|
}
|
|
166321
166595
|
getLocalProjectSettingsPath(workingDirectory) {
|
|
166322
166596
|
return join36(workingDirectory, ".letta", "settings.local.json");
|
|
@@ -167348,8 +167622,8 @@ function acquireSwitchLock2() {
|
|
|
167348
167622
|
const lock = getSwitchLock2();
|
|
167349
167623
|
lock.refCount++;
|
|
167350
167624
|
if (lock.refCount === 1) {
|
|
167351
|
-
lock.promise = new Promise((
|
|
167352
|
-
lock.resolve =
|
|
167625
|
+
lock.promise = new Promise((resolve30) => {
|
|
167626
|
+
lock.resolve = resolve30;
|
|
167353
167627
|
});
|
|
167354
167628
|
}
|
|
167355
167629
|
}
|
|
@@ -167834,7 +168108,7 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
167834
168108
|
printHelp();
|
|
167835
168109
|
const helpDelayMs = Number.parseInt(process.env.LETTA_TEST_HELP_EXIT_DELAY_MS ?? "", 10);
|
|
167836
168110
|
if (Number.isFinite(helpDelayMs) && helpDelayMs > 0) {
|
|
167837
|
-
await new Promise((
|
|
168111
|
+
await new Promise((resolve38) => setTimeout(resolve38, helpDelayMs));
|
|
167838
168112
|
}
|
|
167839
168113
|
process.exit(0);
|
|
167840
168114
|
}
|
|
@@ -168056,9 +168330,9 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
168056
168330
|
process.exit(1);
|
|
168057
168331
|
}
|
|
168058
168332
|
} else {
|
|
168059
|
-
const { resolve:
|
|
168333
|
+
const { resolve: resolve38 } = await import("path");
|
|
168060
168334
|
const { existsSync: existsSync48 } = await import("fs");
|
|
168061
|
-
const resolvedPath =
|
|
168335
|
+
const resolvedPath = resolve38(fromAfFile);
|
|
168062
168336
|
if (!existsSync48(resolvedPath)) {
|
|
168063
168337
|
console.error(`Error: AgentFile not found: ${resolvedPath}`);
|
|
168064
168338
|
process.exit(1);
|
|
@@ -168947,4 +169221,4 @@ Error during initialization: ${message}`);
|
|
|
168947
169221
|
}
|
|
168948
169222
|
main();
|
|
168949
169223
|
|
|
168950
|
-
//# debugId=
|
|
169224
|
+
//# debugId=25A0545792FBAA5C64756E2164756E21
|