@letta-ai/letta-code 0.23.7 → 0.23.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/letta.js +560 -354
- package/package.json +1 -1
package/letta.js
CHANGED
|
@@ -3269,7 +3269,7 @@ var package_default;
|
|
|
3269
3269
|
var init_package = __esm(() => {
|
|
3270
3270
|
package_default = {
|
|
3271
3271
|
name: "@letta-ai/letta-code",
|
|
3272
|
-
version: "0.23.
|
|
3272
|
+
version: "0.23.8",
|
|
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: {
|
|
@@ -39657,6 +39657,9 @@ var init_personality = __esm(() => {
|
|
|
39657
39657
|
import { existsSync as existsSync10, readFileSync as readFileSync7 } from "node:fs";
|
|
39658
39658
|
import { homedir as homedir7 } from "node:os";
|
|
39659
39659
|
import { join as join9 } from "node:path";
|
|
39660
|
+
function getChannelsRoot() {
|
|
39661
|
+
return CHANNELS_ROOT;
|
|
39662
|
+
}
|
|
39660
39663
|
function getChannelDir(channelId) {
|
|
39661
39664
|
return join9(CHANNELS_ROOT, channelId);
|
|
39662
39665
|
}
|
|
@@ -39675,6 +39678,9 @@ function getChannelPairingPath(channelId) {
|
|
|
39675
39678
|
function getChannelTargetsPath(channelId) {
|
|
39676
39679
|
return join9(getChannelDir(channelId), "targets.json");
|
|
39677
39680
|
}
|
|
39681
|
+
function getPendingChannelControlRequestsPath() {
|
|
39682
|
+
return join9(getChannelsRoot(), "pending-control-requests.json");
|
|
39683
|
+
}
|
|
39678
39684
|
function parseSimpleYaml(text) {
|
|
39679
39685
|
const result = {};
|
|
39680
39686
|
const lines = text.split(`
|
|
@@ -42982,6 +42988,93 @@ var init_pluginRegistry = __esm(() => {
|
|
|
42982
42988
|
};
|
|
42983
42989
|
});
|
|
42984
42990
|
|
|
42991
|
+
// src/channels/pendingControlRequests.ts
|
|
42992
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "node:fs";
|
|
42993
|
+
import { dirname as dirname4 } from "node:path";
|
|
42994
|
+
function cloneEvent(event) {
|
|
42995
|
+
return structuredClone(event);
|
|
42996
|
+
}
|
|
42997
|
+
function cloneStore(nextStore) {
|
|
42998
|
+
return {
|
|
42999
|
+
requests: nextStore.requests.map((event) => cloneEvent(event))
|
|
43000
|
+
};
|
|
43001
|
+
}
|
|
43002
|
+
function isChannelControlRequestEvent(value) {
|
|
43003
|
+
if (!value || typeof value !== "object") {
|
|
43004
|
+
return false;
|
|
43005
|
+
}
|
|
43006
|
+
const candidate = value;
|
|
43007
|
+
return typeof candidate.requestId === "string" && candidate.source !== undefined && typeof candidate.source === "object" && candidate.source !== null && typeof candidate.source.channel === "string" && typeof candidate.source.chatId === "string" && typeof candidate.source.agentId === "string" && typeof candidate.source.conversationId === "string" && typeof candidate.toolName === "string" && candidate.input !== null && typeof candidate.input === "object";
|
|
43008
|
+
}
|
|
43009
|
+
function ensureStoreLoaded() {
|
|
43010
|
+
if (storeLoaded) {
|
|
43011
|
+
return;
|
|
43012
|
+
}
|
|
43013
|
+
storeLoaded = true;
|
|
43014
|
+
if (loadPendingControlRequestStoreOverride) {
|
|
43015
|
+
const overridden = loadPendingControlRequestStoreOverride();
|
|
43016
|
+
store = overridden ? cloneStore(overridden) : EMPTY_STORE();
|
|
43017
|
+
return;
|
|
43018
|
+
}
|
|
43019
|
+
const storePath = getPendingChannelControlRequestsPath();
|
|
43020
|
+
if (!existsSync13(storePath)) {
|
|
43021
|
+
store = EMPTY_STORE();
|
|
43022
|
+
return;
|
|
43023
|
+
}
|
|
43024
|
+
try {
|
|
43025
|
+
const text = readFileSync10(storePath, "utf-8");
|
|
43026
|
+
const parsed = JSON.parse(text);
|
|
43027
|
+
store = {
|
|
43028
|
+
requests: Array.isArray(parsed.requests) ? parsed.requests.filter(isChannelControlRequestEvent).map(cloneEvent) : []
|
|
43029
|
+
};
|
|
43030
|
+
} catch {
|
|
43031
|
+
store = EMPTY_STORE();
|
|
43032
|
+
}
|
|
43033
|
+
}
|
|
43034
|
+
function saveStore() {
|
|
43035
|
+
ensureStoreLoaded();
|
|
43036
|
+
const snapshot = cloneStore(store);
|
|
43037
|
+
if (savePendingControlRequestStoreOverride) {
|
|
43038
|
+
savePendingControlRequestStoreOverride(snapshot);
|
|
43039
|
+
return;
|
|
43040
|
+
}
|
|
43041
|
+
const storePath = getPendingChannelControlRequestsPath();
|
|
43042
|
+
mkdirSync10(dirname4(storePath), { recursive: true });
|
|
43043
|
+
writeFileSync8(storePath, `${JSON.stringify(snapshot, null, 2)}
|
|
43044
|
+
`, "utf-8");
|
|
43045
|
+
}
|
|
43046
|
+
function listPendingControlRequests() {
|
|
43047
|
+
ensureStoreLoaded();
|
|
43048
|
+
return store.requests.map((event) => cloneEvent(event));
|
|
43049
|
+
}
|
|
43050
|
+
function upsertPendingControlRequest(event) {
|
|
43051
|
+
ensureStoreLoaded();
|
|
43052
|
+
const nextEvent = cloneEvent(event);
|
|
43053
|
+
const existingIndex = store.requests.findIndex((candidate) => candidate.requestId === event.requestId);
|
|
43054
|
+
if (existingIndex >= 0) {
|
|
43055
|
+
store.requests[existingIndex] = nextEvent;
|
|
43056
|
+
} else {
|
|
43057
|
+
store.requests.push(nextEvent);
|
|
43058
|
+
}
|
|
43059
|
+
saveStore();
|
|
43060
|
+
return cloneEvent(nextEvent);
|
|
43061
|
+
}
|
|
43062
|
+
function removePendingControlRequest(requestId) {
|
|
43063
|
+
ensureStoreLoaded();
|
|
43064
|
+
const nextRequests = store.requests.filter((candidate) => candidate.requestId !== requestId);
|
|
43065
|
+
if (nextRequests.length === store.requests.length) {
|
|
43066
|
+
return false;
|
|
43067
|
+
}
|
|
43068
|
+
store.requests = nextRequests;
|
|
43069
|
+
saveStore();
|
|
43070
|
+
return true;
|
|
43071
|
+
}
|
|
43072
|
+
var EMPTY_STORE = () => ({ requests: [] }), store, storeLoaded = false, loadPendingControlRequestStoreOverride = null, savePendingControlRequestStoreOverride = null;
|
|
43073
|
+
var init_pendingControlRequests = __esm(() => {
|
|
43074
|
+
init_config();
|
|
43075
|
+
store = EMPTY_STORE();
|
|
43076
|
+
});
|
|
43077
|
+
|
|
42985
43078
|
// src/channels/routing.ts
|
|
42986
43079
|
var exports_routing = {};
|
|
42987
43080
|
__export(exports_routing, {
|
|
@@ -43001,7 +43094,7 @@ __export(exports_routing, {
|
|
|
43001
43094
|
__testOverrideSaveRoutes: () => __testOverrideSaveRoutes,
|
|
43002
43095
|
__testOverrideLoadRoutes: () => __testOverrideLoadRoutes
|
|
43003
43096
|
});
|
|
43004
|
-
import { existsSync as
|
|
43097
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync11, writeFileSync as writeFileSync9 } from "node:fs";
|
|
43005
43098
|
function normalizeAccountId2(accountId) {
|
|
43006
43099
|
return accountId ?? LEGACY_CHANNEL_ACCOUNT_ID;
|
|
43007
43100
|
}
|
|
@@ -43042,10 +43135,10 @@ function loadRoutes(channelId) {
|
|
|
43042
43135
|
return;
|
|
43043
43136
|
}
|
|
43044
43137
|
const path2 = getChannelRoutingPath(channelId);
|
|
43045
|
-
if (!
|
|
43138
|
+
if (!existsSync14(path2))
|
|
43046
43139
|
return;
|
|
43047
43140
|
try {
|
|
43048
|
-
const text =
|
|
43141
|
+
const text = readFileSync11(path2, "utf-8");
|
|
43049
43142
|
const parsed = JSON.parse(text);
|
|
43050
43143
|
const routes = parsed.routes ?? [];
|
|
43051
43144
|
for (const route of routes) {
|
|
@@ -43077,10 +43170,10 @@ function saveRoutes(channelId) {
|
|
|
43077
43170
|
return;
|
|
43078
43171
|
}
|
|
43079
43172
|
const dir = getChannelDir(channelId);
|
|
43080
|
-
|
|
43173
|
+
mkdirSync11(dir, { recursive: true });
|
|
43081
43174
|
const routes = getRoutesForChannel(channelId);
|
|
43082
43175
|
const data = { routes };
|
|
43083
|
-
|
|
43176
|
+
writeFileSync9(getChannelRoutingPath(channelId), `${JSON.stringify(data, null, 2)}
|
|
43084
43177
|
`, "utf-8");
|
|
43085
43178
|
}
|
|
43086
43179
|
function getRoute(channel, chatId, accountId, threadId) {
|
|
@@ -43170,14 +43263,14 @@ var init_routing = __esm(() => {
|
|
|
43170
43263
|
});
|
|
43171
43264
|
|
|
43172
43265
|
// src/channels/targets.ts
|
|
43173
|
-
import { existsSync as
|
|
43266
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync12, readFileSync as readFileSync12, writeFileSync as writeFileSync10 } from "node:fs";
|
|
43174
43267
|
function getStore3(channelId) {
|
|
43175
|
-
let
|
|
43176
|
-
if (!
|
|
43177
|
-
|
|
43178
|
-
stores3.set(channelId,
|
|
43268
|
+
let store2 = stores3.get(channelId);
|
|
43269
|
+
if (!store2) {
|
|
43270
|
+
store2 = { targets: [] };
|
|
43271
|
+
stores3.set(channelId, store2);
|
|
43179
43272
|
}
|
|
43180
|
-
return
|
|
43273
|
+
return store2;
|
|
43181
43274
|
}
|
|
43182
43275
|
function loadTargetStore(channelId) {
|
|
43183
43276
|
if (loadTargetStoreOverride) {
|
|
@@ -43185,11 +43278,11 @@ function loadTargetStore(channelId) {
|
|
|
43185
43278
|
return;
|
|
43186
43279
|
}
|
|
43187
43280
|
const path2 = getChannelTargetsPath(channelId);
|
|
43188
|
-
if (!
|
|
43281
|
+
if (!existsSync15(path2)) {
|
|
43189
43282
|
return;
|
|
43190
43283
|
}
|
|
43191
43284
|
try {
|
|
43192
|
-
const text =
|
|
43285
|
+
const text = readFileSync12(path2, "utf-8");
|
|
43193
43286
|
const parsed = JSON.parse(text);
|
|
43194
43287
|
stores3.set(channelId, {
|
|
43195
43288
|
targets: parsed.targets ?? []
|
|
@@ -43202,8 +43295,8 @@ function saveTargetStore(channelId) {
|
|
|
43202
43295
|
return;
|
|
43203
43296
|
}
|
|
43204
43297
|
const dir = getChannelDir(channelId);
|
|
43205
|
-
|
|
43206
|
-
|
|
43298
|
+
mkdirSync12(dir, { recursive: true });
|
|
43299
|
+
writeFileSync10(getChannelTargetsPath(channelId), `${JSON.stringify(getStore3(channelId), null, 2)}
|
|
43207
43300
|
`, "utf-8");
|
|
43208
43301
|
}
|
|
43209
43302
|
function listChannelTargets(channelId, accountId) {
|
|
@@ -43211,11 +43304,11 @@ function listChannelTargets(channelId, accountId) {
|
|
|
43211
43304
|
return getStore3(channelId).targets.filter((target) => normalizedAccountId === undefined || normalizeAccountId3(target.accountId) === normalizedAccountId);
|
|
43212
43305
|
}
|
|
43213
43306
|
function upsertChannelTarget(channelId, target) {
|
|
43214
|
-
const
|
|
43307
|
+
const store2 = getStore3(channelId);
|
|
43215
43308
|
const normalizedAccountId = normalizeAccountId3(target.accountId);
|
|
43216
|
-
const existingIndex =
|
|
43309
|
+
const existingIndex = store2.targets.findIndex((candidate) => candidate.targetId === target.targetId && normalizeAccountId3(candidate.accountId) === normalizedAccountId);
|
|
43217
43310
|
if (existingIndex >= 0) {
|
|
43218
|
-
const existing =
|
|
43311
|
+
const existing = store2.targets[existingIndex];
|
|
43219
43312
|
if (!existing) {
|
|
43220
43313
|
throw new Error(`Target index ${existingIndex} missing for ${target.targetId}`);
|
|
43221
43314
|
}
|
|
@@ -43226,11 +43319,11 @@ function upsertChannelTarget(channelId, target) {
|
|
|
43226
43319
|
discoveredAt: existing.discoveredAt,
|
|
43227
43320
|
lastSeenAt: target.lastSeenAt
|
|
43228
43321
|
};
|
|
43229
|
-
|
|
43322
|
+
store2.targets[existingIndex] = merged;
|
|
43230
43323
|
saveTargetStore(channelId);
|
|
43231
43324
|
return merged;
|
|
43232
43325
|
}
|
|
43233
|
-
|
|
43326
|
+
store2.targets.push({
|
|
43234
43327
|
...target,
|
|
43235
43328
|
accountId: normalizedAccountId
|
|
43236
43329
|
});
|
|
@@ -43241,25 +43334,25 @@ function upsertChannelTarget(channelId, target) {
|
|
|
43241
43334
|
};
|
|
43242
43335
|
}
|
|
43243
43336
|
function removeChannelTarget(channelId, targetId, accountId) {
|
|
43244
|
-
const
|
|
43337
|
+
const store2 = getStore3(channelId);
|
|
43245
43338
|
const normalizedAccountId = normalizeAccountId3(accountId);
|
|
43246
|
-
const nextTargets =
|
|
43247
|
-
if (nextTargets.length ===
|
|
43339
|
+
const nextTargets = store2.targets.filter((target) => !(target.targetId === targetId && normalizeAccountId3(target.accountId) === normalizedAccountId));
|
|
43340
|
+
if (nextTargets.length === store2.targets.length) {
|
|
43248
43341
|
return false;
|
|
43249
43342
|
}
|
|
43250
|
-
|
|
43343
|
+
store2.targets = nextTargets;
|
|
43251
43344
|
saveTargetStore(channelId);
|
|
43252
43345
|
return true;
|
|
43253
43346
|
}
|
|
43254
43347
|
function removeChannelTargetsForAccount(channelId, accountId) {
|
|
43255
|
-
const
|
|
43348
|
+
const store2 = getStore3(channelId);
|
|
43256
43349
|
const normalizedAccountId = normalizeAccountId3(accountId);
|
|
43257
|
-
const nextTargets =
|
|
43258
|
-
const removed =
|
|
43350
|
+
const nextTargets = store2.targets.filter((target) => normalizeAccountId3(target.accountId) !== normalizedAccountId);
|
|
43351
|
+
const removed = store2.targets.length - nextTargets.length;
|
|
43259
43352
|
if (removed === 0) {
|
|
43260
43353
|
return 0;
|
|
43261
43354
|
}
|
|
43262
|
-
|
|
43355
|
+
store2.targets = nextTargets;
|
|
43263
43356
|
saveTargetStore(channelId);
|
|
43264
43357
|
return removed;
|
|
43265
43358
|
}
|
|
@@ -43749,6 +43842,7 @@ class ChannelRegistry {
|
|
|
43749
43842
|
throw new Error("ChannelRegistry is a singleton — use getChannelRegistry()");
|
|
43750
43843
|
}
|
|
43751
43844
|
instance = this;
|
|
43845
|
+
this.primePersistedPendingControlRequests();
|
|
43752
43846
|
}
|
|
43753
43847
|
getAdapterKey(channelId, accountId = LEGACY_CHANNEL_ACCOUNT_ID) {
|
|
43754
43848
|
return `${channelId}:${accountId}`;
|
|
@@ -43819,6 +43913,54 @@ class ChannelRegistry {
|
|
|
43819
43913
|
setEventHandler(handler) {
|
|
43820
43914
|
this.eventHandler = handler;
|
|
43821
43915
|
}
|
|
43916
|
+
hasPendingControlRequest(requestId) {
|
|
43917
|
+
return this.pendingControlRequestsById.has(requestId);
|
|
43918
|
+
}
|
|
43919
|
+
getPendingControlRequests() {
|
|
43920
|
+
return Array.from(this.pendingControlRequestsById.values()).map((pending) => ({
|
|
43921
|
+
event: structuredClone(pending.event),
|
|
43922
|
+
deliveredThisProcess: pending.deliveredThisProcess
|
|
43923
|
+
}));
|
|
43924
|
+
}
|
|
43925
|
+
primePersistedPendingControlRequests() {
|
|
43926
|
+
for (const event of listPendingControlRequests()) {
|
|
43927
|
+
this.pendingControlRequestsById.set(event.requestId, {
|
|
43928
|
+
event,
|
|
43929
|
+
deliveredThisProcess: false
|
|
43930
|
+
});
|
|
43931
|
+
this.pendingControlRequestIdByScope.set(getChannelApprovalScopeKey({
|
|
43932
|
+
channel: event.source.channel,
|
|
43933
|
+
accountId: event.source.accountId,
|
|
43934
|
+
chatId: event.source.chatId,
|
|
43935
|
+
threadId: event.source.threadId
|
|
43936
|
+
}), event.requestId);
|
|
43937
|
+
}
|
|
43938
|
+
}
|
|
43939
|
+
async deliverPendingControlRequest(requestId) {
|
|
43940
|
+
const pending = this.pendingControlRequestsById.get(requestId);
|
|
43941
|
+
if (!pending) {
|
|
43942
|
+
return false;
|
|
43943
|
+
}
|
|
43944
|
+
const event = pending.event;
|
|
43945
|
+
const adapter = this.getAdapter(event.source.channel, event.source.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID);
|
|
43946
|
+
if (!adapter) {
|
|
43947
|
+
return false;
|
|
43948
|
+
}
|
|
43949
|
+
try {
|
|
43950
|
+
if (adapter.handleControlRequestEvent) {
|
|
43951
|
+
await adapter.handleControlRequestEvent(event);
|
|
43952
|
+
} else {
|
|
43953
|
+
await adapter.sendDirectReply(event.source.chatId, formatChannelControlRequestPrompt(event), {
|
|
43954
|
+
replyToMessageId: event.source.threadId ?? event.source.messageId
|
|
43955
|
+
});
|
|
43956
|
+
}
|
|
43957
|
+
pending.deliveredThisProcess = true;
|
|
43958
|
+
return true;
|
|
43959
|
+
} catch (error) {
|
|
43960
|
+
console.error(`[Channels] Failed to deliver control request prompt for ${event.source.channel}/${event.source.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID}:`, error instanceof Error ? error.message : error);
|
|
43961
|
+
return false;
|
|
43962
|
+
}
|
|
43963
|
+
}
|
|
43822
43964
|
async registerPendingControlRequest(event) {
|
|
43823
43965
|
const scopeKey = getChannelApprovalScopeKey({
|
|
43824
43966
|
channel: event.source.channel,
|
|
@@ -43830,35 +43972,29 @@ class ChannelRegistry {
|
|
|
43830
43972
|
if (existingRequestId) {
|
|
43831
43973
|
this.clearPendingControlRequest(existingRequestId);
|
|
43832
43974
|
}
|
|
43833
|
-
this.pendingControlRequestsById.set(event.requestId,
|
|
43975
|
+
this.pendingControlRequestsById.set(event.requestId, {
|
|
43976
|
+
event,
|
|
43977
|
+
deliveredThisProcess: false
|
|
43978
|
+
});
|
|
43834
43979
|
this.pendingControlRequestIdByScope.set(scopeKey, event.requestId);
|
|
43835
|
-
|
|
43836
|
-
|
|
43837
|
-
|
|
43838
|
-
|
|
43839
|
-
|
|
43840
|
-
if (adapter.handleControlRequestEvent) {
|
|
43841
|
-
await adapter.handleControlRequestEvent(event);
|
|
43842
|
-
return;
|
|
43843
|
-
}
|
|
43844
|
-
await adapter.sendDirectReply(event.source.chatId, formatChannelControlRequestPrompt(event), {
|
|
43845
|
-
replyToMessageId: event.source.threadId ?? event.source.messageId
|
|
43846
|
-
});
|
|
43847
|
-
} catch (error) {
|
|
43848
|
-
console.error(`[Channels] Failed to deliver control request prompt for ${event.source.channel}/${event.source.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID}:`, error instanceof Error ? error.message : error);
|
|
43849
|
-
}
|
|
43980
|
+
upsertPendingControlRequest(event);
|
|
43981
|
+
await this.deliverPendingControlRequest(event.requestId);
|
|
43982
|
+
}
|
|
43983
|
+
async redeliverPendingControlRequest(requestId) {
|
|
43984
|
+
return this.deliverPendingControlRequest(requestId);
|
|
43850
43985
|
}
|
|
43851
43986
|
clearPendingControlRequest(requestId) {
|
|
43987
|
+
removePendingControlRequest(requestId);
|
|
43852
43988
|
const pending = this.pendingControlRequestsById.get(requestId);
|
|
43853
43989
|
if (!pending) {
|
|
43854
43990
|
return;
|
|
43855
43991
|
}
|
|
43856
43992
|
this.pendingControlRequestsById.delete(requestId);
|
|
43857
43993
|
const scopeKey = getChannelApprovalScopeKey({
|
|
43858
|
-
channel: pending.source.channel,
|
|
43859
|
-
accountId: pending.source.accountId,
|
|
43860
|
-
chatId: pending.source.chatId,
|
|
43861
|
-
threadId: pending.source.threadId
|
|
43994
|
+
channel: pending.event.source.channel,
|
|
43995
|
+
accountId: pending.event.source.accountId,
|
|
43996
|
+
chatId: pending.event.source.chatId,
|
|
43997
|
+
threadId: pending.event.source.threadId
|
|
43862
43998
|
});
|
|
43863
43999
|
if (this.pendingControlRequestIdByScope.get(scopeKey) === requestId) {
|
|
43864
44000
|
this.pendingControlRequestIdByScope.delete(scopeKey);
|
|
@@ -43987,7 +44123,7 @@ class ChannelRegistry {
|
|
|
43987
44123
|
this.pendingControlRequestIdByScope.delete(scopeKey);
|
|
43988
44124
|
return false;
|
|
43989
44125
|
}
|
|
43990
|
-
const parsed = parseChannelControlRequestResponse(pending, msg.text);
|
|
44126
|
+
const parsed = parseChannelControlRequestResponse(pending.event, msg.text);
|
|
43991
44127
|
if (parsed.type === "reprompt") {
|
|
43992
44128
|
await adapter.sendDirectReply(msg.chatId, parsed.message, {
|
|
43993
44129
|
replyToMessageId: msg.threadId ?? msg.messageId
|
|
@@ -44002,8 +44138,8 @@ class ChannelRegistry {
|
|
|
44002
44138
|
}
|
|
44003
44139
|
const handled = await this.approvalResponseHandler({
|
|
44004
44140
|
runtime: {
|
|
44005
|
-
agent_id: pending.source.agentId,
|
|
44006
|
-
conversation_id: pending.source.conversationId
|
|
44141
|
+
agent_id: pending.event.source.agentId,
|
|
44142
|
+
conversation_id: pending.event.source.conversationId
|
|
44007
44143
|
},
|
|
44008
44144
|
response: parsed.response
|
|
44009
44145
|
});
|
|
@@ -44250,6 +44386,7 @@ var init_registry = __esm(() => {
|
|
|
44250
44386
|
init_memory();
|
|
44251
44387
|
init_accounts();
|
|
44252
44388
|
init_pairing();
|
|
44389
|
+
init_pendingControlRequests();
|
|
44253
44390
|
init_pluginRegistry();
|
|
44254
44391
|
init_routing();
|
|
44255
44392
|
init_targets();
|
|
@@ -44645,13 +44782,13 @@ var init_messageTool = __esm(() => {
|
|
|
44645
44782
|
// src/cli/helpers/fileIndex.ts
|
|
44646
44783
|
import { createHash as createHash2 } from "node:crypto";
|
|
44647
44784
|
import {
|
|
44648
|
-
existsSync as
|
|
44649
|
-
mkdirSync as
|
|
44785
|
+
existsSync as existsSync16,
|
|
44786
|
+
mkdirSync as mkdirSync13,
|
|
44650
44787
|
readdirSync as readdirSync3,
|
|
44651
|
-
readFileSync as
|
|
44788
|
+
readFileSync as readFileSync13,
|
|
44652
44789
|
statSync as statSync2,
|
|
44653
44790
|
unlinkSync as unlinkSync3,
|
|
44654
|
-
writeFileSync as
|
|
44791
|
+
writeFileSync as writeFileSync11
|
|
44655
44792
|
} from "node:fs";
|
|
44656
44793
|
import { homedir as homedir8 } from "node:os";
|
|
44657
44794
|
import { join as join13, normalize as normalize3, relative as relative2, sep as sep2 } from "node:path";
|
|
@@ -44670,7 +44807,7 @@ function hashFile2(fullPath, entryPath, stat) {
|
|
|
44670
44807
|
return hashValue2(`meta:${entryPath}:${stat.size}:${stat.mtimeMs}:${stat.ino ?? 0}`);
|
|
44671
44808
|
}
|
|
44672
44809
|
try {
|
|
44673
|
-
const content =
|
|
44810
|
+
const content = readFileSync13(fullPath);
|
|
44674
44811
|
return createHash2("sha256").update(content).digest("hex");
|
|
44675
44812
|
} catch (err) {
|
|
44676
44813
|
debugLog("file-index", `Cannot read file for hashing ${fullPath}: ${err}`);
|
|
@@ -44923,8 +45060,8 @@ function getProjectStorageDir2() {
|
|
|
44923
45060
|
}
|
|
44924
45061
|
function ensureProjectStorageDir2() {
|
|
44925
45062
|
const storageDir = getProjectStorageDir2();
|
|
44926
|
-
if (!
|
|
44927
|
-
|
|
45063
|
+
if (!existsSync16(storageDir)) {
|
|
45064
|
+
mkdirSync13(storageDir, { recursive: true });
|
|
44928
45065
|
}
|
|
44929
45066
|
return storageDir;
|
|
44930
45067
|
}
|
|
@@ -44933,7 +45070,7 @@ function getProjectIndexPath2() {
|
|
|
44933
45070
|
}
|
|
44934
45071
|
function loadCachedIndex2() {
|
|
44935
45072
|
const indexPath = getProjectIndexPath2();
|
|
44936
|
-
if (!
|
|
45073
|
+
if (!existsSync16(indexPath)) {
|
|
44937
45074
|
return null;
|
|
44938
45075
|
}
|
|
44939
45076
|
try {
|
|
@@ -44948,7 +45085,7 @@ function loadCachedIndex2() {
|
|
|
44948
45085
|
}
|
|
44949
45086
|
return null;
|
|
44950
45087
|
}
|
|
44951
|
-
const content =
|
|
45088
|
+
const content = readFileSync13(indexPath, "utf-8");
|
|
44952
45089
|
const parsed = JSON.parse(content);
|
|
44953
45090
|
if (parsed?.metadata && typeof parsed.metadata.rootHash === "string" && Array.isArray(parsed.entries) && parsed.merkle && typeof parsed.merkle === "object") {
|
|
44954
45091
|
if (parsed.metadata.version !== CACHE_VERSION2) {
|
|
@@ -45028,7 +45165,7 @@ function cacheProjectIndex2(result) {
|
|
|
45028
45165
|
merkle: cappedMerkle,
|
|
45029
45166
|
stats: cappedStats
|
|
45030
45167
|
};
|
|
45031
|
-
|
|
45168
|
+
writeFileSync11(indexPath, JSON.stringify(payload), "utf-8");
|
|
45032
45169
|
} catch (err) {
|
|
45033
45170
|
debugLog("file-index", `Failed to persist index cache: ${err}`);
|
|
45034
45171
|
}
|
|
@@ -46704,7 +46841,7 @@ __export(exports_memoryFilesystem, {
|
|
|
46704
46841
|
MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR,
|
|
46705
46842
|
MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR
|
|
46706
46843
|
});
|
|
46707
|
-
import { existsSync as
|
|
46844
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync14 } from "node:fs";
|
|
46708
46845
|
import { homedir as homedir10 } from "node:os";
|
|
46709
46846
|
import { join as join14 } from "node:path";
|
|
46710
46847
|
function getMemoryFilesystemRoot(agentId, homeDir = homedir10()) {
|
|
@@ -46716,11 +46853,11 @@ function getMemorySystemDir(agentId, homeDir = homedir10()) {
|
|
|
46716
46853
|
function ensureMemoryFilesystemDirs(agentId, homeDir = homedir10()) {
|
|
46717
46854
|
const root = getMemoryFilesystemRoot(agentId, homeDir);
|
|
46718
46855
|
const systemDir = getMemorySystemDir(agentId, homeDir);
|
|
46719
|
-
if (!
|
|
46720
|
-
|
|
46856
|
+
if (!existsSync17(root)) {
|
|
46857
|
+
mkdirSync14(root, { recursive: true });
|
|
46721
46858
|
}
|
|
46722
|
-
if (!
|
|
46723
|
-
|
|
46859
|
+
if (!existsSync17(systemDir)) {
|
|
46860
|
+
mkdirSync14(systemDir, { recursive: true });
|
|
46724
46861
|
}
|
|
46725
46862
|
}
|
|
46726
46863
|
async function isMemfsEnabledOnServer(agentId) {
|
|
@@ -46946,7 +47083,7 @@ var init_memoryFilesystem = __esm(() => {
|
|
|
46946
47083
|
|
|
46947
47084
|
// src/permissions/memoryScope.ts
|
|
46948
47085
|
import { homedir as homedir11 } from "node:os";
|
|
46949
|
-
import { basename as basename5, dirname as
|
|
47086
|
+
import { basename as basename5, dirname as dirname5, isAbsolute as isAbsolute2, resolve as resolve4 } from "node:path";
|
|
46950
47087
|
function normalizeScopedPath(path3) {
|
|
46951
47088
|
const resolvedPath = resolve4(expandHomePath(path3));
|
|
46952
47089
|
const normalized = resolvedPath.replace(/\\/g, "/");
|
|
@@ -46993,7 +47130,7 @@ function addRootAndSiblingWorktree(root, acc) {
|
|
|
46993
47130
|
acc.add(normalizedRoot);
|
|
46994
47131
|
const leaf = basename5(normalizedRoot);
|
|
46995
47132
|
if (leaf === "memory") {
|
|
46996
|
-
acc.add(normalizeScopedPath(resolve4(
|
|
47133
|
+
acc.add(normalizeScopedPath(resolve4(dirname5(normalizedRoot), "memory-worktrees")));
|
|
46997
47134
|
}
|
|
46998
47135
|
}
|
|
46999
47136
|
function getExplicitEnvRoots(env3) {
|
|
@@ -50923,7 +51060,7 @@ __export(exports_shellEnv, {
|
|
|
50923
51060
|
getShellEnv: () => getShellEnv,
|
|
50924
51061
|
ensureLettaShimDir: () => ensureLettaShimDir
|
|
50925
51062
|
});
|
|
50926
|
-
import { mkdirSync as
|
|
51063
|
+
import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync12 } from "node:fs";
|
|
50927
51064
|
import { createRequire as createRequire3 } from "node:module";
|
|
50928
51065
|
import { tmpdir } from "node:os";
|
|
50929
51066
|
import * as path4 from "node:path";
|
|
@@ -51009,19 +51146,19 @@ function ensureLettaShimDir(invocation) {
|
|
|
51009
51146
|
if (!invocation.command)
|
|
51010
51147
|
return null;
|
|
51011
51148
|
const shimDir = path4.join(tmpdir(), "letta-code-shell-shim");
|
|
51012
|
-
|
|
51149
|
+
mkdirSync15(shimDir, { recursive: true });
|
|
51013
51150
|
if (process.platform === "win32") {
|
|
51014
51151
|
const cmdPath = path4.join(shimDir, "letta.cmd");
|
|
51015
51152
|
const quotedCommand = `"${invocation.command.replaceAll('"', '""')}"`;
|
|
51016
51153
|
const quotedArgs = invocation.args.map((arg) => `"${arg.replaceAll('"', '""')}"`).join(" ");
|
|
51017
|
-
|
|
51154
|
+
writeFileSync12(cmdPath, `@echo off\r
|
|
51018
51155
|
${quotedCommand} ${quotedArgs} %*\r
|
|
51019
51156
|
`);
|
|
51020
51157
|
return shimDir;
|
|
51021
51158
|
}
|
|
51022
51159
|
const shimPath = path4.join(shimDir, "letta");
|
|
51023
51160
|
const commandWithArgs = [invocation.command, ...invocation.args].map(shellEscape).join(" ");
|
|
51024
|
-
|
|
51161
|
+
writeFileSync12(shimPath, `#!/bin/sh
|
|
51025
51162
|
exec ${commandWithArgs} "$@"
|
|
51026
51163
|
`, {
|
|
51027
51164
|
mode: 493
|
|
@@ -51677,7 +51814,7 @@ var init_Bash2 = __esm(() => {
|
|
|
51677
51814
|
});
|
|
51678
51815
|
|
|
51679
51816
|
// src/tools/impl/BashOutput.ts
|
|
51680
|
-
import { readFileSync as
|
|
51817
|
+
import { readFileSync as readFileSync14, statSync as statSync4 } from "node:fs";
|
|
51681
51818
|
function sleep2(ms) {
|
|
51682
51819
|
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
51683
51820
|
}
|
|
@@ -51694,7 +51831,7 @@ function readOutputFile(filePath) {
|
|
|
51694
51831
|
fallbackNotice: `[Output file too large to load fully here (${stats.size.toLocaleString()} bytes). Showing the bounded in-memory buffer instead. Full transcript: ${filePath}]`
|
|
51695
51832
|
};
|
|
51696
51833
|
}
|
|
51697
|
-
return { content:
|
|
51834
|
+
return { content: readFileSync14(filePath, "utf-8") };
|
|
51698
51835
|
} catch {
|
|
51699
51836
|
return { content: null };
|
|
51700
51837
|
}
|
|
@@ -53227,7 +53364,7 @@ var init_runtime3 = () => {};
|
|
|
53227
53364
|
|
|
53228
53365
|
// src/tools/impl/Memory.ts
|
|
53229
53366
|
import { execFile as execFileCb3 } from "node:child_process";
|
|
53230
|
-
import { existsSync as
|
|
53367
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
53231
53368
|
import {
|
|
53232
53369
|
mkdir as mkdir5,
|
|
53233
53370
|
readFile as readFile5,
|
|
@@ -53238,7 +53375,7 @@ import {
|
|
|
53238
53375
|
writeFile as writeFile5
|
|
53239
53376
|
} from "node:fs/promises";
|
|
53240
53377
|
import { homedir as homedir16 } from "node:os";
|
|
53241
|
-
import { dirname as
|
|
53378
|
+
import { dirname as dirname8, isAbsolute as isAbsolute9, relative as relative5, resolve as resolve13 } from "node:path";
|
|
53242
53379
|
import { promisify as promisify6 } from "node:util";
|
|
53243
53380
|
async function getAgentIdentity() {
|
|
53244
53381
|
const envAgentId = (process.env.AGENT_ID || process.env.LETTA_AGENT_ID || "").trim();
|
|
@@ -53280,14 +53417,14 @@ async function memory(args) {
|
|
|
53280
53417
|
const label = normalizeMemoryLabel(memoryDir, pathArg, "file_path");
|
|
53281
53418
|
const filePath = resolveMemoryFilePath(memoryDir, label);
|
|
53282
53419
|
const relPath = toRepoRelative(memoryDir, filePath);
|
|
53283
|
-
if (
|
|
53420
|
+
if (existsSync19(filePath)) {
|
|
53284
53421
|
throw new Error(`memory create: block already exists at ${pathArg}`);
|
|
53285
53422
|
}
|
|
53286
53423
|
const body = args.file_text ?? "";
|
|
53287
53424
|
const rendered = renderMemoryFile({
|
|
53288
53425
|
description
|
|
53289
53426
|
}, body);
|
|
53290
|
-
await mkdir5(
|
|
53427
|
+
await mkdir5(dirname8(filePath), { recursive: true });
|
|
53291
53428
|
await writeFile5(filePath, rendered, "utf8");
|
|
53292
53429
|
affectedPaths = [relPath];
|
|
53293
53430
|
} else if (command === "str_replace") {
|
|
@@ -53332,7 +53469,7 @@ async function memory(args) {
|
|
|
53332
53469
|
const pathArg = requireString(args.file_path, "file_path", "delete");
|
|
53333
53470
|
const label = normalizeMemoryLabel(memoryDir, pathArg, "file_path");
|
|
53334
53471
|
const targetPath = resolveMemoryPath(memoryDir, label);
|
|
53335
|
-
if (
|
|
53472
|
+
if (existsSync19(targetPath) && (await stat2(targetPath)).isDirectory()) {
|
|
53336
53473
|
const relPath = toRepoRelative(memoryDir, targetPath);
|
|
53337
53474
|
await rm(targetPath, { recursive: true, force: false });
|
|
53338
53475
|
affectedPaths = [relPath];
|
|
@@ -53352,11 +53489,11 @@ async function memory(args) {
|
|
|
53352
53489
|
const newFilePath = resolveMemoryFilePath(memoryDir, newLabel);
|
|
53353
53490
|
const oldRelPath = toRepoRelative(memoryDir, oldFilePath);
|
|
53354
53491
|
const newRelPath = toRepoRelative(memoryDir, newFilePath);
|
|
53355
|
-
if (
|
|
53492
|
+
if (existsSync19(newFilePath)) {
|
|
53356
53493
|
throw new Error(`memory rename: destination already exists at ${newPathArg}`);
|
|
53357
53494
|
}
|
|
53358
53495
|
await loadEditableMemoryFile(oldFilePath, oldPathArg);
|
|
53359
|
-
await mkdir5(
|
|
53496
|
+
await mkdir5(dirname8(newFilePath), { recursive: true });
|
|
53360
53497
|
await rename(oldFilePath, newFilePath);
|
|
53361
53498
|
affectedPaths = [oldRelPath, newRelPath];
|
|
53362
53499
|
} else if (command === "update_description") {
|
|
@@ -53409,10 +53546,10 @@ function resolveMemoryDir() {
|
|
|
53409
53546
|
throw new Error("memory: unable to resolve memory directory. Ensure MEMORY_DIR (or AGENT_ID) is available.");
|
|
53410
53547
|
}
|
|
53411
53548
|
function ensureMemoryRepo(memoryDir) {
|
|
53412
|
-
if (!
|
|
53549
|
+
if (!existsSync19(memoryDir)) {
|
|
53413
53550
|
throw new Error(`memory: memory directory does not exist: ${memoryDir}`);
|
|
53414
53551
|
}
|
|
53415
|
-
if (!
|
|
53552
|
+
if (!existsSync19(resolve13(memoryDir, ".git"))) {
|
|
53416
53553
|
throw new Error(`memory: ${memoryDir} is not a git repository. This tool requires a git-backed memory filesystem.`);
|
|
53417
53554
|
}
|
|
53418
53555
|
}
|
|
@@ -53657,7 +53794,7 @@ var init_Memory2 = __esm(() => {
|
|
|
53657
53794
|
|
|
53658
53795
|
// src/tools/impl/MemoryApplyPatch.ts
|
|
53659
53796
|
import { execFile as execFileCb4 } from "node:child_process";
|
|
53660
|
-
import { existsSync as
|
|
53797
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
53661
53798
|
import {
|
|
53662
53799
|
access,
|
|
53663
53800
|
mkdir as mkdir6,
|
|
@@ -53668,7 +53805,7 @@ import {
|
|
|
53668
53805
|
writeFile as writeFile6
|
|
53669
53806
|
} from "node:fs/promises";
|
|
53670
53807
|
import { homedir as homedir17 } from "node:os";
|
|
53671
|
-
import { dirname as
|
|
53808
|
+
import { dirname as dirname9, isAbsolute as isAbsolute10, relative as relative6, resolve as resolve14 } from "node:path";
|
|
53672
53809
|
import { promisify as promisify7 } from "node:util";
|
|
53673
53810
|
async function getAgentIdentity2() {
|
|
53674
53811
|
const envAgentId = (process.env.AGENT_ID || process.env.LETTA_AGENT_ID || "").trim();
|
|
@@ -53781,7 +53918,7 @@ async function memory_apply_patch(args) {
|
|
|
53781
53918
|
}
|
|
53782
53919
|
}
|
|
53783
53920
|
for (const [absPath, content] of pendingWrites.entries()) {
|
|
53784
|
-
await mkdir6(
|
|
53921
|
+
await mkdir6(dirname9(absPath), { recursive: true });
|
|
53785
53922
|
await writeFile6(absPath, content, "utf8");
|
|
53786
53923
|
}
|
|
53787
53924
|
for (const absPath of pendingDeletes) {
|
|
@@ -53960,10 +54097,10 @@ function resolveMemoryDir2() {
|
|
|
53960
54097
|
throw new Error("memory_apply_patch: unable to resolve memory directory. Ensure MEMORY_DIR (or AGENT_ID) is available.");
|
|
53961
54098
|
}
|
|
53962
54099
|
function ensureMemoryRepo2(memoryDir) {
|
|
53963
|
-
if (!
|
|
54100
|
+
if (!existsSync20(memoryDir)) {
|
|
53964
54101
|
throw new Error(`memory_apply_patch: memory directory does not exist: ${memoryDir}`);
|
|
53965
54102
|
}
|
|
53966
|
-
if (!
|
|
54103
|
+
if (!existsSync20(resolve14(memoryDir, ".git"))) {
|
|
53967
54104
|
throw new Error(`memory_apply_patch: ${memoryDir} is not a git repository. This tool requires a git-backed memory filesystem.`);
|
|
53968
54105
|
}
|
|
53969
54106
|
}
|
|
@@ -54725,12 +54862,12 @@ __export(exports_imageResize_magick, {
|
|
|
54725
54862
|
MAX_IMAGE_BYTES: () => MAX_IMAGE_BYTES
|
|
54726
54863
|
});
|
|
54727
54864
|
import { execSync } from "node:child_process";
|
|
54728
|
-
import { readFileSync as
|
|
54865
|
+
import { readFileSync as readFileSync15, unlinkSync as unlinkSync5, writeFileSync as writeFileSync14 } from "node:fs";
|
|
54729
54866
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
54730
54867
|
import { join as join21 } from "node:path";
|
|
54731
54868
|
async function getImageDimensions(buffer) {
|
|
54732
54869
|
const tempInput = join21(tmpdir2(), `image-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
|
|
54733
|
-
|
|
54870
|
+
writeFileSync14(tempInput, buffer);
|
|
54734
54871
|
try {
|
|
54735
54872
|
const output = execSync(`magick identify -format "%w %h %m" "${tempInput}"`, {
|
|
54736
54873
|
encoding: "utf-8"
|
|
@@ -54753,7 +54890,7 @@ async function compressToFitByteLimit(buffer, currentWidth, currentHeight) {
|
|
|
54753
54890
|
return null;
|
|
54754
54891
|
}
|
|
54755
54892
|
const tempInput = join21(tmpdir2(), `compress-input-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
|
|
54756
|
-
|
|
54893
|
+
writeFileSync14(tempInput, buffer);
|
|
54757
54894
|
try {
|
|
54758
54895
|
const qualities = [85, 70, 55, 40];
|
|
54759
54896
|
for (const quality of qualities) {
|
|
@@ -54762,7 +54899,7 @@ async function compressToFitByteLimit(buffer, currentWidth, currentHeight) {
|
|
|
54762
54899
|
execSync(`magick "${tempInput}" -quality ${quality} "${tempOutput}"`, {
|
|
54763
54900
|
stdio: "ignore"
|
|
54764
54901
|
});
|
|
54765
|
-
const compressed =
|
|
54902
|
+
const compressed = readFileSync15(tempOutput);
|
|
54766
54903
|
if (compressed.length <= MAX_IMAGE_BYTES) {
|
|
54767
54904
|
const { width, height } = await getImageDimensions(compressed);
|
|
54768
54905
|
return {
|
|
@@ -54788,7 +54925,7 @@ async function compressToFitByteLimit(buffer, currentWidth, currentHeight) {
|
|
|
54788
54925
|
execSync(`magick "${tempInput}" -resize ${scaledWidth}x${scaledHeight} -quality 70 "${tempOutput}"`, {
|
|
54789
54926
|
stdio: "ignore"
|
|
54790
54927
|
});
|
|
54791
|
-
const reduced =
|
|
54928
|
+
const reduced = readFileSync15(tempOutput);
|
|
54792
54929
|
if (reduced.length <= MAX_IMAGE_BYTES) {
|
|
54793
54930
|
const { width, height } = await getImageDimensions(reduced);
|
|
54794
54931
|
return {
|
|
@@ -54828,7 +54965,7 @@ async function resizeImageIfNeeded(buffer, inputMediaType) {
|
|
|
54828
54965
|
};
|
|
54829
54966
|
}
|
|
54830
54967
|
const tempInput = join21(tmpdir2(), `resize-input-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
|
|
54831
|
-
|
|
54968
|
+
writeFileSync14(tempInput, buffer);
|
|
54832
54969
|
try {
|
|
54833
54970
|
if (needsResize) {
|
|
54834
54971
|
const tempOutput2 = join21(tmpdir2(), `resize-output-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
@@ -54838,14 +54975,14 @@ async function resizeImageIfNeeded(buffer, inputMediaType) {
|
|
|
54838
54975
|
execSync(`magick "${tempInput}" -resize ${MAX_IMAGE_WIDTH}x${MAX_IMAGE_HEIGHT}> -quality 85 "${tempOutput2}.jpg"`, {
|
|
54839
54976
|
stdio: "ignore"
|
|
54840
54977
|
});
|
|
54841
|
-
outputBuffer2 =
|
|
54978
|
+
outputBuffer2 = readFileSync15(`${tempOutput2}.jpg`);
|
|
54842
54979
|
outputMediaType = "image/jpeg";
|
|
54843
54980
|
unlinkSync5(`${tempOutput2}.jpg`);
|
|
54844
54981
|
} else {
|
|
54845
54982
|
execSync(`magick "${tempInput}" -resize ${MAX_IMAGE_WIDTH}x${MAX_IMAGE_HEIGHT}> "${tempOutput2}.png"`, {
|
|
54846
54983
|
stdio: "ignore"
|
|
54847
54984
|
});
|
|
54848
|
-
outputBuffer2 =
|
|
54985
|
+
outputBuffer2 = readFileSync15(`${tempOutput2}.png`);
|
|
54849
54986
|
outputMediaType = "image/png";
|
|
54850
54987
|
unlinkSync5(`${tempOutput2}.png`);
|
|
54851
54988
|
}
|
|
@@ -54866,7 +55003,7 @@ async function resizeImageIfNeeded(buffer, inputMediaType) {
|
|
|
54866
55003
|
execSync(`magick "${tempInput}" "${tempOutput}"`, {
|
|
54867
55004
|
stdio: "ignore"
|
|
54868
55005
|
});
|
|
54869
|
-
const outputBuffer =
|
|
55006
|
+
const outputBuffer = readFileSync15(tempOutput);
|
|
54870
55007
|
unlinkSync5(tempOutput);
|
|
54871
55008
|
const compressed = await compressToFitByteLimit(outputBuffer, width, height);
|
|
54872
55009
|
if (compressed) {
|
|
@@ -54973,7 +55110,7 @@ var require_filesystem = __commonJS((exports, module) => {
|
|
|
54973
55110
|
var LDD_PATH = "/usr/bin/ldd";
|
|
54974
55111
|
var SELF_PATH = "/proc/self/exe";
|
|
54975
55112
|
var MAX_LENGTH = 2048;
|
|
54976
|
-
var
|
|
55113
|
+
var readFileSync16 = (path11) => {
|
|
54977
55114
|
const fd = fs7.openSync(path11, "r");
|
|
54978
55115
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
54979
55116
|
const bytesRead = fs7.readSync(fd, buffer, 0, MAX_LENGTH, 0);
|
|
@@ -54996,7 +55133,7 @@ var require_filesystem = __commonJS((exports, module) => {
|
|
|
54996
55133
|
module.exports = {
|
|
54997
55134
|
LDD_PATH,
|
|
54998
55135
|
SELF_PATH,
|
|
54999
|
-
readFileSync:
|
|
55136
|
+
readFileSync: readFileSync16,
|
|
55000
55137
|
readFile: readFile7
|
|
55001
55138
|
};
|
|
55002
55139
|
});
|
|
@@ -55039,7 +55176,7 @@ var require_elf = __commonJS((exports, module) => {
|
|
|
55039
55176
|
var require_detect_libc = __commonJS((exports, module) => {
|
|
55040
55177
|
var childProcess = __require("child_process");
|
|
55041
55178
|
var { isLinux: isLinux2, getReport } = require_process();
|
|
55042
|
-
var { LDD_PATH, SELF_PATH, readFile: readFile7, readFileSync:
|
|
55179
|
+
var { LDD_PATH, SELF_PATH, readFile: readFile7, readFileSync: readFileSync16 } = require_filesystem();
|
|
55043
55180
|
var { interpreterPath } = require_elf();
|
|
55044
55181
|
var cachedFamilyInterpreter;
|
|
55045
55182
|
var cachedFamilyFilesystem;
|
|
@@ -55130,7 +55267,7 @@ var require_detect_libc = __commonJS((exports, module) => {
|
|
|
55130
55267
|
}
|
|
55131
55268
|
cachedFamilyFilesystem = null;
|
|
55132
55269
|
try {
|
|
55133
|
-
const lddContent =
|
|
55270
|
+
const lddContent = readFileSync16(LDD_PATH);
|
|
55134
55271
|
cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
|
|
55135
55272
|
} catch (e) {}
|
|
55136
55273
|
return cachedFamilyFilesystem;
|
|
@@ -55153,7 +55290,7 @@ var require_detect_libc = __commonJS((exports, module) => {
|
|
|
55153
55290
|
}
|
|
55154
55291
|
cachedFamilyInterpreter = null;
|
|
55155
55292
|
try {
|
|
55156
|
-
const selfContent =
|
|
55293
|
+
const selfContent = readFileSync16(SELF_PATH);
|
|
55157
55294
|
const path11 = interpreterPath(selfContent);
|
|
55158
55295
|
cachedFamilyInterpreter = familyFromInterpreterPath(path11);
|
|
55159
55296
|
} catch (e) {}
|
|
@@ -55215,7 +55352,7 @@ var require_detect_libc = __commonJS((exports, module) => {
|
|
|
55215
55352
|
}
|
|
55216
55353
|
cachedVersionFilesystem = null;
|
|
55217
55354
|
try {
|
|
55218
|
-
const lddContent =
|
|
55355
|
+
const lddContent = readFileSync16(LDD_PATH);
|
|
55219
55356
|
const versionMatch = lddContent.match(RE_GLIBC_VERSION);
|
|
55220
55357
|
if (versionMatch) {
|
|
55221
55358
|
cachedVersionFilesystem = versionMatch[1];
|
|
@@ -67011,8 +67148,8 @@ var init_ignore = __esm(() => {
|
|
|
67011
67148
|
// node_modules/glob/dist/esm/processor.js
|
|
67012
67149
|
class HasWalkedCache {
|
|
67013
67150
|
store;
|
|
67014
|
-
constructor(
|
|
67015
|
-
this.store =
|
|
67151
|
+
constructor(store2 = new Map) {
|
|
67152
|
+
this.store = store2;
|
|
67016
67153
|
}
|
|
67017
67154
|
copy() {
|
|
67018
67155
|
return new HasWalkedCache(new Map(this.store));
|
|
@@ -67913,7 +68050,7 @@ var init_ReplaceGemini2 = __esm(() => {
|
|
|
67913
68050
|
});
|
|
67914
68051
|
|
|
67915
68052
|
// src/tools/impl/Shell.ts
|
|
67916
|
-
import { existsSync as
|
|
68053
|
+
import { existsSync as existsSync21, statSync as statSync5 } from "node:fs";
|
|
67917
68054
|
import * as path15 from "node:path";
|
|
67918
68055
|
function resolveShellWorkdir(workdir) {
|
|
67919
68056
|
const defaultCwd = process.env.USER_CWD || process.cwd();
|
|
@@ -68007,7 +68144,7 @@ function arraysEqual(a, b) {
|
|
|
68007
68144
|
}
|
|
68008
68145
|
function isUsableDirectory(candidate) {
|
|
68009
68146
|
try {
|
|
68010
|
-
return
|
|
68147
|
+
return existsSync21(candidate) && statSync5(candidate).isDirectory();
|
|
68011
68148
|
} catch {
|
|
68012
68149
|
return false;
|
|
68013
68150
|
}
|
|
@@ -68262,12 +68399,12 @@ __export(exports_skills, {
|
|
|
68262
68399
|
SKILLS_DIR: () => SKILLS_DIR,
|
|
68263
68400
|
GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR
|
|
68264
68401
|
});
|
|
68265
|
-
import { existsSync as
|
|
68402
|
+
import { existsSync as existsSync22 } from "node:fs";
|
|
68266
68403
|
import { readdir as readdir4, readFile as readFile7, realpath as realpath2, stat as stat4 } from "node:fs/promises";
|
|
68267
|
-
import { dirname as
|
|
68404
|
+
import { dirname as dirname10, join as join22 } from "node:path";
|
|
68268
68405
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
68269
68406
|
function getBundledSkillsPath() {
|
|
68270
|
-
const thisDir =
|
|
68407
|
+
const thisDir = dirname10(fileURLToPath6(import.meta.url));
|
|
68271
68408
|
if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
|
|
68272
68409
|
return join22(thisDir, "../skills/builtin");
|
|
68273
68410
|
}
|
|
@@ -68286,7 +68423,7 @@ async function getBundledSkills() {
|
|
|
68286
68423
|
}
|
|
68287
68424
|
async function discoverSkillsFromDir(skillsPath, source) {
|
|
68288
68425
|
const errors = [];
|
|
68289
|
-
if (!
|
|
68426
|
+
if (!existsSync22(skillsPath)) {
|
|
68290
68427
|
return { skills: [], errors: [] };
|
|
68291
68428
|
}
|
|
68292
68429
|
const skills = [];
|
|
@@ -68469,7 +68606,7 @@ var init_skillContentRegistry = __esm(() => {
|
|
|
68469
68606
|
// src/tools/impl/Skill.ts
|
|
68470
68607
|
import { readdirSync as readdirSync6 } from "node:fs";
|
|
68471
68608
|
import { readFile as readFile8 } from "node:fs/promises";
|
|
68472
|
-
import { dirname as
|
|
68609
|
+
import { dirname as dirname11, join as join23 } from "node:path";
|
|
68473
68610
|
function getMemorySkillsDirs(agentId) {
|
|
68474
68611
|
const dirs = new Set;
|
|
68475
68612
|
const memoryDir = process.env.MEMORY_DIR || process.env.LETTA_MEMORY_DIR;
|
|
@@ -68483,7 +68620,7 @@ function getMemorySkillsDirs(agentId) {
|
|
|
68483
68620
|
}
|
|
68484
68621
|
function hasAdditionalFiles(skillMdPath) {
|
|
68485
68622
|
try {
|
|
68486
|
-
const skillDir =
|
|
68623
|
+
const skillDir = dirname11(skillMdPath);
|
|
68487
68624
|
const entries = readdirSync6(skillDir);
|
|
68488
68625
|
return entries.some((e) => e.toUpperCase() !== "SKILL.MD");
|
|
68489
68626
|
} catch {
|
|
@@ -68559,7 +68696,7 @@ async function skill(args) {
|
|
|
68559
68696
|
const agentId = getResolvedAgentId(args);
|
|
68560
68697
|
const skillsDir = await getResolvedSkillsDir();
|
|
68561
68698
|
const { content: skillContent, path: skillPath } = await readSkillContent(skillName, skillsDir, agentId);
|
|
68562
|
-
const skillDir =
|
|
68699
|
+
const skillDir = dirname11(skillPath);
|
|
68563
68700
|
const hasExtras = hasAdditionalFiles(skillPath);
|
|
68564
68701
|
const processedContent = hasExtras ? skillContent.replace(/<SKILL_DIR>/g, skillDir) : skillContent;
|
|
68565
68702
|
const dirHeader = hasExtras ? `# Skill Directory: ${skillDir}
|
|
@@ -68588,13 +68725,13 @@ var init_Skill2 = __esm(() => {
|
|
|
68588
68725
|
// src/cli/helpers/subagentState.ts
|
|
68589
68726
|
function updateSnapshot() {
|
|
68590
68727
|
cachedSnapshot = {
|
|
68591
|
-
agents: Array.from(
|
|
68592
|
-
expanded:
|
|
68728
|
+
agents: Array.from(store2.agents.values()),
|
|
68729
|
+
expanded: store2.expanded
|
|
68593
68730
|
};
|
|
68594
68731
|
}
|
|
68595
68732
|
function notifyListeners() {
|
|
68596
68733
|
updateSnapshot();
|
|
68597
|
-
for (const listener of
|
|
68734
|
+
for (const listener of store2.listeners) {
|
|
68598
68735
|
listener();
|
|
68599
68736
|
}
|
|
68600
68737
|
}
|
|
@@ -68612,18 +68749,18 @@ function unrefTimer2(timer) {
|
|
|
68612
68749
|
}
|
|
68613
68750
|
}
|
|
68614
68751
|
function scheduleCompletedSubagentCleanup(id) {
|
|
68615
|
-
const agent =
|
|
68752
|
+
const agent = store2.agents.get(id);
|
|
68616
68753
|
if (!agent || agent.status !== "completed" && agent.status !== "error") {
|
|
68617
68754
|
return;
|
|
68618
68755
|
}
|
|
68619
68756
|
clearCompletedSubagentCleanup(id);
|
|
68620
68757
|
const timer = setTimeout(() => {
|
|
68621
|
-
const current =
|
|
68758
|
+
const current = store2.agents.get(id);
|
|
68622
68759
|
if (!current || current.status !== "completed" && current.status !== "error") {
|
|
68623
68760
|
completedSubagentCleanupTimers.delete(id);
|
|
68624
68761
|
return;
|
|
68625
68762
|
}
|
|
68626
|
-
|
|
68763
|
+
store2.agents.delete(id);
|
|
68627
68764
|
completedSubagentCleanupTimers.delete(id);
|
|
68628
68765
|
notifyListeners();
|
|
68629
68766
|
}, completedSubagentRetentionMs);
|
|
@@ -68634,7 +68771,7 @@ function generateSubagentId() {
|
|
|
68634
68771
|
return `subagent-${Date.now()}-${++subagentCounter}`;
|
|
68635
68772
|
}
|
|
68636
68773
|
function getSubagentByToolCallId(toolCallId) {
|
|
68637
|
-
for (const agent of
|
|
68774
|
+
for (const agent of store2.agents.values()) {
|
|
68638
68775
|
if (agent.toolCallId === toolCallId) {
|
|
68639
68776
|
return agent;
|
|
68640
68777
|
}
|
|
@@ -68661,11 +68798,11 @@ function registerSubagent(id, type, description, toolCallId, isBackground, silen
|
|
|
68661
68798
|
parentConversationId: parentScope?.conversationId && parentScope.conversationId.length > 0 ? parentScope.conversationId : undefined
|
|
68662
68799
|
};
|
|
68663
68800
|
clearCompletedSubagentCleanup(id);
|
|
68664
|
-
|
|
68801
|
+
store2.agents.set(id, agent);
|
|
68665
68802
|
notifyListeners();
|
|
68666
68803
|
}
|
|
68667
68804
|
function updateSubagent(id, updates) {
|
|
68668
|
-
const agent =
|
|
68805
|
+
const agent = store2.agents.get(id);
|
|
68669
68806
|
if (!agent)
|
|
68670
68807
|
return;
|
|
68671
68808
|
if (updates.agentURL && agent.status === "pending") {
|
|
@@ -68678,7 +68815,7 @@ function updateSubagent(id, updates) {
|
|
|
68678
68815
|
if (isNoop)
|
|
68679
68816
|
return;
|
|
68680
68817
|
const updatedAgent = { ...agent, ...updates, maxToolCallsSeen: nextMax };
|
|
68681
|
-
|
|
68818
|
+
store2.agents.set(id, updatedAgent);
|
|
68682
68819
|
if (updatedAgent.status === "completed" || updatedAgent.status === "error") {
|
|
68683
68820
|
scheduleCompletedSubagentCleanup(id);
|
|
68684
68821
|
} else {
|
|
@@ -68687,7 +68824,7 @@ function updateSubagent(id, updates) {
|
|
|
68687
68824
|
notifyListeners();
|
|
68688
68825
|
}
|
|
68689
68826
|
function addToolCall(subagentId, toolCallId, toolName, toolArgs) {
|
|
68690
|
-
const agent =
|
|
68827
|
+
const agent = store2.agents.get(subagentId);
|
|
68691
68828
|
if (!agent)
|
|
68692
68829
|
return;
|
|
68693
68830
|
if (agent.toolCalls.some((tc) => tc.id === toolCallId))
|
|
@@ -68700,11 +68837,11 @@ function addToolCall(subagentId, toolCallId, toolName, toolArgs) {
|
|
|
68700
68837
|
],
|
|
68701
68838
|
maxToolCallsSeen: Math.max(agent.maxToolCallsSeen, agent.toolCalls.length + 1)
|
|
68702
68839
|
};
|
|
68703
|
-
|
|
68840
|
+
store2.agents.set(subagentId, updatedAgent);
|
|
68704
68841
|
notifyListeners();
|
|
68705
68842
|
}
|
|
68706
68843
|
function completeSubagent(id, result) {
|
|
68707
|
-
const agent =
|
|
68844
|
+
const agent = store2.agents.get(id);
|
|
68708
68845
|
if (!agent)
|
|
68709
68846
|
return;
|
|
68710
68847
|
const updatedAgent = {
|
|
@@ -68715,7 +68852,7 @@ function completeSubagent(id, result) {
|
|
|
68715
68852
|
totalTokens: result.totalTokens ?? agent.totalTokens,
|
|
68716
68853
|
maxToolCallsSeen: Math.max(agent.maxToolCallsSeen, agent.toolCalls.length)
|
|
68717
68854
|
};
|
|
68718
|
-
|
|
68855
|
+
store2.agents.set(id, updatedAgent);
|
|
68719
68856
|
scheduleCompletedSubagentCleanup(id);
|
|
68720
68857
|
notifyListeners();
|
|
68721
68858
|
}
|
|
@@ -68723,21 +68860,21 @@ function getSubagentToolCount(agent) {
|
|
|
68723
68860
|
return Math.max(agent.toolCalls.length, agent.maxToolCallsSeen);
|
|
68724
68861
|
}
|
|
68725
68862
|
function toggleExpanded() {
|
|
68726
|
-
|
|
68863
|
+
store2.expanded = !store2.expanded;
|
|
68727
68864
|
notifyListeners();
|
|
68728
68865
|
}
|
|
68729
68866
|
function getSubagents() {
|
|
68730
|
-
return Array.from(
|
|
68867
|
+
return Array.from(store2.agents.values());
|
|
68731
68868
|
}
|
|
68732
68869
|
function getActiveBackgroundAgents() {
|
|
68733
|
-
return Array.from(
|
|
68870
|
+
return Array.from(store2.agents.values()).filter((a) => a.silent === true && (a.status === "pending" || a.status === "running"));
|
|
68734
68871
|
}
|
|
68735
68872
|
function clearCompletedSubagents() {
|
|
68736
68873
|
let removedAny = false;
|
|
68737
|
-
for (const [id, agent] of
|
|
68874
|
+
for (const [id, agent] of store2.agents.entries()) {
|
|
68738
68875
|
if (agent.status === "completed" || agent.status === "error") {
|
|
68739
68876
|
clearCompletedSubagentCleanup(id);
|
|
68740
|
-
|
|
68877
|
+
store2.agents.delete(id);
|
|
68741
68878
|
removedAny = true;
|
|
68742
68879
|
}
|
|
68743
68880
|
}
|
|
@@ -68749,14 +68886,14 @@ function clearSubagentsByIds(ids) {
|
|
|
68749
68886
|
let removedAny = false;
|
|
68750
68887
|
for (const id of ids) {
|
|
68751
68888
|
clearCompletedSubagentCleanup(id);
|
|
68752
|
-
removedAny =
|
|
68889
|
+
removedAny = store2.agents.delete(id) || removedAny;
|
|
68753
68890
|
}
|
|
68754
68891
|
if (removedAny) {
|
|
68755
68892
|
notifyListeners();
|
|
68756
68893
|
}
|
|
68757
68894
|
}
|
|
68758
68895
|
function hasActiveSubagents() {
|
|
68759
|
-
for (const agent of
|
|
68896
|
+
for (const agent of store2.agents.values()) {
|
|
68760
68897
|
if (agent.status === "pending" || agent.status === "running") {
|
|
68761
68898
|
return true;
|
|
68762
68899
|
}
|
|
@@ -68765,7 +68902,7 @@ function hasActiveSubagents() {
|
|
|
68765
68902
|
}
|
|
68766
68903
|
function interruptActiveSubagents(errorMessage) {
|
|
68767
68904
|
let anyInterrupted = false;
|
|
68768
|
-
for (const [id, agent] of
|
|
68905
|
+
for (const [id, agent] of store2.agents.entries()) {
|
|
68769
68906
|
if (agent.status === "pending" || agent.status === "running") {
|
|
68770
68907
|
const updatedAgent = {
|
|
68771
68908
|
...agent,
|
|
@@ -68773,7 +68910,7 @@ function interruptActiveSubagents(errorMessage) {
|
|
|
68773
68910
|
error: errorMessage,
|
|
68774
68911
|
durationMs: Date.now() - agent.startTime
|
|
68775
68912
|
};
|
|
68776
|
-
|
|
68913
|
+
store2.agents.set(id, updatedAgent);
|
|
68777
68914
|
scheduleCompletedSubagentCleanup(id);
|
|
68778
68915
|
anyInterrupted = true;
|
|
68779
68916
|
}
|
|
@@ -68783,9 +68920,9 @@ function interruptActiveSubagents(errorMessage) {
|
|
|
68783
68920
|
}
|
|
68784
68921
|
}
|
|
68785
68922
|
function subscribe2(listener) {
|
|
68786
|
-
|
|
68923
|
+
store2.listeners.add(listener);
|
|
68787
68924
|
return () => {
|
|
68788
|
-
|
|
68925
|
+
store2.listeners.delete(listener);
|
|
68789
68926
|
};
|
|
68790
68927
|
}
|
|
68791
68928
|
function getSnapshot2() {
|
|
@@ -68802,9 +68939,9 @@ function emitStreamEvent(subagentId, event) {
|
|
|
68802
68939
|
listener(subagentId, event);
|
|
68803
68940
|
}
|
|
68804
68941
|
}
|
|
68805
|
-
var
|
|
68942
|
+
var store2, cachedSnapshot, DEFAULT_COMPLETED_SUBAGENT_RETENTION_MS = 30000, completedSubagentRetentionMs, completedSubagentCleanupTimers, subagentCounter = 0, streamEventListeners;
|
|
68806
68943
|
var init_subagentState = __esm(() => {
|
|
68807
|
-
|
|
68944
|
+
store2 = {
|
|
68808
68945
|
agents: new Map,
|
|
68809
68946
|
expanded: false,
|
|
68810
68947
|
listeners: new Set
|
|
@@ -69176,11 +69313,20 @@ function swapProviderPrefix(parentHandle, recommendedHandle) {
|
|
|
69176
69313
|
const modelPortion = recommendedHandle.slice(recommendedProvider.length + 1);
|
|
69177
69314
|
return `${parentProvider}/${modelPortion}`;
|
|
69178
69315
|
}
|
|
69316
|
+
function isEnvFlagEnabled(name) {
|
|
69317
|
+
const value = process.env[name]?.trim();
|
|
69318
|
+
if (!value)
|
|
69319
|
+
return false;
|
|
69320
|
+
return value === "1" || value.toLowerCase() === "true";
|
|
69321
|
+
}
|
|
69179
69322
|
async function resolveSubagentModel(options) {
|
|
69180
69323
|
const { userModel, recommendedModel, parentModelHandle, billingTier } = options;
|
|
69181
69324
|
const isFreeTier = billingTier?.toLowerCase() === "free";
|
|
69182
69325
|
if (userModel)
|
|
69183
69326
|
return userModel;
|
|
69327
|
+
if (options.subagentType === "reflection" && isEnvFlagEnabled("AUTO_MEMORY")) {
|
|
69328
|
+
return "letta/auto-memory";
|
|
69329
|
+
}
|
|
69184
69330
|
let recommendedHandle = null;
|
|
69185
69331
|
if (recommendedModel && recommendedModel !== "inherit") {
|
|
69186
69332
|
recommendedHandle = resolveModel2(recommendedModel);
|
|
@@ -69666,7 +69812,8 @@ async function spawnSubagent(type, prompt, userModel, subagentId, signal, existi
|
|
|
69666
69812
|
userModel,
|
|
69667
69813
|
recommendedModel: config.recommendedModel,
|
|
69668
69814
|
parentModelHandle,
|
|
69669
|
-
billingTier
|
|
69815
|
+
billingTier,
|
|
69816
|
+
subagentType: type
|
|
69670
69817
|
});
|
|
69671
69818
|
const baseURL = getBaseURL();
|
|
69672
69819
|
let finalPrompt = prompt;
|
|
@@ -74071,7 +74218,7 @@ __export(exports_analyzer, {
|
|
|
74071
74218
|
analyzeApprovalContext: () => analyzeApprovalContext
|
|
74072
74219
|
});
|
|
74073
74220
|
import { homedir as homedir19 } from "node:os";
|
|
74074
|
-
import { dirname as
|
|
74221
|
+
import { dirname as dirname13, relative as relative8, resolve as resolve23, win32 as win322 } from "node:path";
|
|
74075
74222
|
function normalizeOsPath(path19) {
|
|
74076
74223
|
return path19.replace(/\\/g, "/");
|
|
74077
74224
|
}
|
|
@@ -74097,7 +74244,7 @@ function isPathWithinDirectory(path19, directory) {
|
|
|
74097
74244
|
return !relativePath.startsWith("../") && relativePath !== ".." && !relativePath.startsWith("/") && !/^[a-zA-Z]:\//.test(relativePath);
|
|
74098
74245
|
}
|
|
74099
74246
|
function dirnameForContext(path19) {
|
|
74100
|
-
return isWindowsPath(path19) ? win322.dirname(path19) :
|
|
74247
|
+
return isWindowsPath(path19) ? win322.dirname(path19) : dirname13(path19);
|
|
74101
74248
|
}
|
|
74102
74249
|
function formatAbsoluteRulePath(path19) {
|
|
74103
74250
|
const normalized = normalizeOsPath(path19).replace(/\/+$/, "");
|
|
@@ -74158,7 +74305,7 @@ function analyzeReadApproval(filePath, workingDir) {
|
|
|
74158
74305
|
};
|
|
74159
74306
|
}
|
|
74160
74307
|
const relativePath = normalizeOsPath(relativePathForContext(workingDir, absolutePath));
|
|
74161
|
-
const relativeDir =
|
|
74308
|
+
const relativeDir = dirname13(relativePath);
|
|
74162
74309
|
const pattern = relativeDir === "." || relativeDir === "" ? "**" : `${relativeDir}/**`;
|
|
74163
74310
|
return {
|
|
74164
74311
|
recommendedRule: `Read(${pattern})`,
|
|
@@ -77714,13 +77861,13 @@ var init_parseInterval = __esm(() => {
|
|
|
77714
77861
|
// src/cron/cronFile.ts
|
|
77715
77862
|
import { randomBytes } from "node:crypto";
|
|
77716
77863
|
import {
|
|
77717
|
-
existsSync as
|
|
77718
|
-
mkdirSync as
|
|
77719
|
-
readFileSync as
|
|
77864
|
+
existsSync as existsSync23,
|
|
77865
|
+
mkdirSync as mkdirSync17,
|
|
77866
|
+
readFileSync as readFileSync16,
|
|
77720
77867
|
renameSync as renameSync2,
|
|
77721
77868
|
rmSync as rmSync2,
|
|
77722
77869
|
statSync as statSync6,
|
|
77723
|
-
writeFileSync as
|
|
77870
|
+
writeFileSync as writeFileSync15
|
|
77724
77871
|
} from "node:fs";
|
|
77725
77872
|
import { join as join25 } from "node:path";
|
|
77726
77873
|
function getLettaDir() {
|
|
@@ -77739,10 +77886,10 @@ function emptyFile() {
|
|
|
77739
77886
|
}
|
|
77740
77887
|
function readCronFile() {
|
|
77741
77888
|
const path20 = getCronFilePath();
|
|
77742
|
-
if (!
|
|
77889
|
+
if (!existsSync23(path20))
|
|
77743
77890
|
return emptyFile();
|
|
77744
77891
|
try {
|
|
77745
|
-
const raw =
|
|
77892
|
+
const raw = readFileSync16(path20, "utf-8");
|
|
77746
77893
|
const data = JSON.parse(raw);
|
|
77747
77894
|
if (data.version !== 1)
|
|
77748
77895
|
return emptyFile();
|
|
@@ -77754,16 +77901,16 @@ function readCronFile() {
|
|
|
77754
77901
|
function writeCronFile(data) {
|
|
77755
77902
|
const path20 = getCronFilePath();
|
|
77756
77903
|
const dir = getLettaDir();
|
|
77757
|
-
if (!
|
|
77758
|
-
|
|
77904
|
+
if (!existsSync23(dir)) {
|
|
77905
|
+
mkdirSync17(dir, { recursive: true });
|
|
77759
77906
|
}
|
|
77760
77907
|
const tmp = `${path20}.tmp`;
|
|
77761
|
-
|
|
77908
|
+
writeFileSync15(tmp, JSON.stringify(data, null, 2), { flush: true });
|
|
77762
77909
|
renameSync2(tmp, path20);
|
|
77763
77910
|
}
|
|
77764
77911
|
function readLinuxProcessIdentity(pid) {
|
|
77765
77912
|
try {
|
|
77766
|
-
const stat5 =
|
|
77913
|
+
const stat5 = readFileSync16(`/proc/${pid}/stat`, "utf8");
|
|
77767
77914
|
const endCommand = stat5.lastIndexOf(")");
|
|
77768
77915
|
if (endCommand === -1) {
|
|
77769
77916
|
return null;
|
|
@@ -77775,7 +77922,7 @@ function readLinuxProcessIdentity(pid) {
|
|
|
77775
77922
|
}
|
|
77776
77923
|
let bootId = null;
|
|
77777
77924
|
try {
|
|
77778
|
-
bootId =
|
|
77925
|
+
bootId = readFileSync16("/proc/sys/kernel/random/boot_id", "utf8").trim() || null;
|
|
77779
77926
|
} catch {}
|
|
77780
77927
|
return { startTicks, bootId };
|
|
77781
77928
|
} catch {
|
|
@@ -77816,14 +77963,14 @@ function isProcessAlive(pid, owner) {
|
|
|
77816
77963
|
}
|
|
77817
77964
|
function readLockOwner(lockDir) {
|
|
77818
77965
|
try {
|
|
77819
|
-
const raw =
|
|
77966
|
+
const raw = readFileSync16(join25(lockDir, LOCK_TOKEN_FILE), "utf-8");
|
|
77820
77967
|
return JSON.parse(raw);
|
|
77821
77968
|
} catch {
|
|
77822
77969
|
return null;
|
|
77823
77970
|
}
|
|
77824
77971
|
}
|
|
77825
77972
|
function writeLockOwner(lockDir, owner) {
|
|
77826
|
-
|
|
77973
|
+
writeFileSync15(join25(lockDir, LOCK_TOKEN_FILE), JSON.stringify(owner));
|
|
77827
77974
|
}
|
|
77828
77975
|
function isLockStale(lockDir) {
|
|
77829
77976
|
const owner = readLockOwner(lockDir);
|
|
@@ -77850,7 +77997,7 @@ function acquireLock() {
|
|
|
77850
77997
|
const token = randomBytes(4).toString("hex");
|
|
77851
77998
|
while (Date.now() < deadline) {
|
|
77852
77999
|
try {
|
|
77853
|
-
|
|
78000
|
+
mkdirSync17(lockDir, { recursive: false });
|
|
77854
78001
|
const owner = {
|
|
77855
78002
|
pid: process.pid,
|
|
77856
78003
|
token,
|
|
@@ -83666,11 +83813,11 @@ var init_reflectionTranscript = __esm(() => {
|
|
|
83666
83813
|
|
|
83667
83814
|
// src/cli/helpers/chunkLog.ts
|
|
83668
83815
|
import {
|
|
83669
|
-
existsSync as
|
|
83670
|
-
mkdirSync as
|
|
83816
|
+
existsSync as existsSync25,
|
|
83817
|
+
mkdirSync as mkdirSync19,
|
|
83671
83818
|
readdirSync as readdirSync8,
|
|
83672
83819
|
unlinkSync as unlinkSync7,
|
|
83673
|
-
writeFileSync as
|
|
83820
|
+
writeFileSync as writeFileSync16
|
|
83674
83821
|
} from "node:fs";
|
|
83675
83822
|
import { homedir as homedir22 } from "node:os";
|
|
83676
83823
|
import { join as join29 } from "node:path";
|
|
@@ -83767,8 +83914,8 @@ class ChunkLog {
|
|
|
83767
83914
|
if (this.dirCreated || !this.agentDir)
|
|
83768
83915
|
return;
|
|
83769
83916
|
try {
|
|
83770
|
-
if (!
|
|
83771
|
-
|
|
83917
|
+
if (!existsSync25(this.agentDir)) {
|
|
83918
|
+
mkdirSync19(this.agentDir, { recursive: true });
|
|
83772
83919
|
}
|
|
83773
83920
|
this.dirCreated = true;
|
|
83774
83921
|
} catch (e) {
|
|
@@ -83782,7 +83929,7 @@ class ChunkLog {
|
|
|
83782
83929
|
try {
|
|
83783
83930
|
const content = this.buffer.map((entry) => JSON.stringify(entry)).join(`
|
|
83784
83931
|
`);
|
|
83785
|
-
|
|
83932
|
+
writeFileSync16(this.logPath, `${content}
|
|
83786
83933
|
`, "utf8");
|
|
83787
83934
|
} catch (e) {
|
|
83788
83935
|
debugWarn("chunkLog", `Failed to write ${this.logPath}: ${e instanceof Error ? e.message : String(e)}`);
|
|
@@ -83792,7 +83939,7 @@ class ChunkLog {
|
|
|
83792
83939
|
if (!this.agentDir)
|
|
83793
83940
|
return;
|
|
83794
83941
|
try {
|
|
83795
|
-
if (!
|
|
83942
|
+
if (!existsSync25(this.agentDir))
|
|
83796
83943
|
return;
|
|
83797
83944
|
const files = readdirSync8(this.agentDir).filter((f) => f.endsWith(".jsonl")).sort();
|
|
83798
83945
|
if (files.length >= MAX_SESSION_FILES2) {
|
|
@@ -84811,7 +84958,7 @@ var init_constants2 = __esm(() => {
|
|
|
84811
84958
|
});
|
|
84812
84959
|
|
|
84813
84960
|
// src/websocket/listener/remote-settings.ts
|
|
84814
|
-
import { existsSync as
|
|
84961
|
+
import { existsSync as existsSync26, readFileSync as readFileSync17 } from "node:fs";
|
|
84815
84962
|
import { mkdir as mkdir8, writeFile as writeFile8 } from "node:fs/promises";
|
|
84816
84963
|
import { homedir as homedir23 } from "node:os";
|
|
84817
84964
|
import path20 from "node:path";
|
|
@@ -84825,8 +84972,8 @@ function loadRemoteSettings() {
|
|
|
84825
84972
|
let loaded = {};
|
|
84826
84973
|
try {
|
|
84827
84974
|
const settingsPath = getRemoteSettingsPath();
|
|
84828
|
-
if (
|
|
84829
|
-
const raw =
|
|
84975
|
+
if (existsSync26(settingsPath)) {
|
|
84976
|
+
const raw = readFileSync17(settingsPath, "utf-8");
|
|
84830
84977
|
const parsed = JSON.parse(raw);
|
|
84831
84978
|
loaded = parsed;
|
|
84832
84979
|
}
|
|
@@ -84834,7 +84981,7 @@ function loadRemoteSettings() {
|
|
|
84834
84981
|
if (loaded.cwdMap) {
|
|
84835
84982
|
const validCwdMap = {};
|
|
84836
84983
|
for (const [key, value] of Object.entries(loaded.cwdMap)) {
|
|
84837
|
-
if (typeof value === "string" &&
|
|
84984
|
+
if (typeof value === "string" && existsSync26(value)) {
|
|
84838
84985
|
validCwdMap[key] = value;
|
|
84839
84986
|
}
|
|
84840
84987
|
}
|
|
@@ -84861,13 +85008,13 @@ function saveRemoteSettings(updates) {
|
|
|
84861
85008
|
function loadLegacyCwdCache() {
|
|
84862
85009
|
try {
|
|
84863
85010
|
const legacyPath = path20.join(homedir23(), ".letta", "cwd-cache.json");
|
|
84864
|
-
if (!
|
|
85011
|
+
if (!existsSync26(legacyPath))
|
|
84865
85012
|
return {};
|
|
84866
|
-
const raw =
|
|
85013
|
+
const raw = readFileSync17(legacyPath, "utf-8");
|
|
84867
85014
|
const parsed = JSON.parse(raw);
|
|
84868
85015
|
const result = {};
|
|
84869
85016
|
for (const [key, value] of Object.entries(parsed)) {
|
|
84870
|
-
if (typeof value === "string" &&
|
|
85017
|
+
if (typeof value === "string" && existsSync26(value)) {
|
|
84871
85018
|
result[key] = value;
|
|
84872
85019
|
}
|
|
84873
85020
|
}
|
|
@@ -92382,7 +92529,7 @@ __export(exports_memoryScanner, {
|
|
|
92382
92529
|
readFileContent: () => readFileContent,
|
|
92383
92530
|
getFileNodes: () => getFileNodes
|
|
92384
92531
|
});
|
|
92385
|
-
import { readdirSync as readdirSync9, readFileSync as
|
|
92532
|
+
import { readdirSync as readdirSync9, readFileSync as readFileSync18, statSync as statSync7 } from "node:fs";
|
|
92386
92533
|
import { join as join30, relative as relative12 } from "node:path";
|
|
92387
92534
|
function scanMemoryFilesystem(memoryRoot) {
|
|
92388
92535
|
const nodes = [];
|
|
@@ -92447,7 +92594,7 @@ function getFileNodes(nodes) {
|
|
|
92447
92594
|
}
|
|
92448
92595
|
function readFileContent(fullPath) {
|
|
92449
92596
|
try {
|
|
92450
|
-
return
|
|
92597
|
+
return readFileSync18(fullPath, "utf-8");
|
|
92451
92598
|
} catch {
|
|
92452
92599
|
return "(unable to read file)";
|
|
92453
92600
|
}
|
|
@@ -92510,6 +92657,63 @@ async function replaySyncStateForRuntime(listenerRuntime, socket, scope, opts) {
|
|
|
92510
92657
|
}
|
|
92511
92658
|
emitStateSync(socket, listenerRuntime, scope);
|
|
92512
92659
|
}
|
|
92660
|
+
async function recoverPendingChannelControlRequests(listener, opts) {
|
|
92661
|
+
const registry = getChannelRegistry();
|
|
92662
|
+
if (!registry) {
|
|
92663
|
+
return;
|
|
92664
|
+
}
|
|
92665
|
+
const pendingEntries = registry.getPendingControlRequests();
|
|
92666
|
+
if (pendingEntries.length === 0) {
|
|
92667
|
+
return;
|
|
92668
|
+
}
|
|
92669
|
+
const recoverFn = opts?.recoverApprovalStateForSync ?? recoverApprovalStateForSync;
|
|
92670
|
+
const entriesByScope = new Map;
|
|
92671
|
+
for (const entry of pendingEntries) {
|
|
92672
|
+
const scope = {
|
|
92673
|
+
agent_id: entry.event.source.agentId,
|
|
92674
|
+
conversation_id: entry.event.source.conversationId
|
|
92675
|
+
};
|
|
92676
|
+
const scopeKey = `${scope.agent_id}:${scope.conversation_id}`;
|
|
92677
|
+
const existing = entriesByScope.get(scopeKey);
|
|
92678
|
+
if (existing) {
|
|
92679
|
+
existing.entries.push(entry);
|
|
92680
|
+
continue;
|
|
92681
|
+
}
|
|
92682
|
+
entriesByScope.set(scopeKey, {
|
|
92683
|
+
scope,
|
|
92684
|
+
entries: [entry]
|
|
92685
|
+
});
|
|
92686
|
+
}
|
|
92687
|
+
for (const { scope, entries } of entriesByScope.values()) {
|
|
92688
|
+
const runtime = getOrCreateScopedRuntime(listener, scope.agent_id, scope.conversation_id);
|
|
92689
|
+
const livePendingRequestIds = new Set(runtime.pendingApprovalResolvers.keys());
|
|
92690
|
+
const shouldRecoverFromBackend = entries.some((entry) => !livePendingRequestIds.has(entry.event.requestId));
|
|
92691
|
+
if (shouldRecoverFromBackend) {
|
|
92692
|
+
try {
|
|
92693
|
+
await recoverFn(runtime, scope);
|
|
92694
|
+
} catch (error) {
|
|
92695
|
+
trackListenerError("listener_channel_control_request_recovery_failed", error, "listener_channel_control_request_recovery");
|
|
92696
|
+
if (isDebugEnabled()) {
|
|
92697
|
+
console.warn("[Listen] Channel control request recovery failed:", error);
|
|
92698
|
+
}
|
|
92699
|
+
continue;
|
|
92700
|
+
}
|
|
92701
|
+
}
|
|
92702
|
+
const recoveredPendingRequestIds = getRecoveredApprovalStateForScope(listener, scope)?.pendingRequestIds ?? new Set;
|
|
92703
|
+
for (const entry of entries) {
|
|
92704
|
+
const requestId = entry.event.requestId;
|
|
92705
|
+
const stillPending = livePendingRequestIds.has(requestId) || recoveredPendingRequestIds.has(requestId);
|
|
92706
|
+
if (!stillPending) {
|
|
92707
|
+
registry.clearPendingControlRequest(requestId);
|
|
92708
|
+
continue;
|
|
92709
|
+
}
|
|
92710
|
+
if (entry.deliveredThisProcess) {
|
|
92711
|
+
continue;
|
|
92712
|
+
}
|
|
92713
|
+
await registry.redeliverPendingControlRequest(requestId);
|
|
92714
|
+
}
|
|
92715
|
+
}
|
|
92716
|
+
}
|
|
92513
92717
|
function getParsedRuntimeScope(parsed) {
|
|
92514
92718
|
if (!parsed || typeof parsed !== "object" || !("runtime" in parsed)) {
|
|
92515
92719
|
return null;
|
|
@@ -92810,10 +93014,10 @@ async function handleListMemoryCommand(parsed, socket, overrides = {}) {
|
|
|
92810
93014
|
const isMemfsEnabledOnServer2 = overrides.isMemfsEnabledOnServer ?? actualIsMemfsEnabledOnServer;
|
|
92811
93015
|
const { scanMemoryFilesystem: scanMemoryFilesystem2, getFileNodes: getFileNodes2, readFileContent: readFileContent2 } = await Promise.resolve().then(() => (init_memoryScanner(), exports_memoryScanner));
|
|
92812
93016
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => exports_frontmatter);
|
|
92813
|
-
const { existsSync:
|
|
93017
|
+
const { existsSync: existsSync27 } = await import("node:fs");
|
|
92814
93018
|
const { join: join31, posix: posix2 } = await import("node:path");
|
|
92815
93019
|
const memoryRoot = getMemoryFilesystemRoot2(parsed.agent_id);
|
|
92816
|
-
let memfsInitialized =
|
|
93020
|
+
let memfsInitialized = existsSync27(join31(memoryRoot, ".git"));
|
|
92817
93021
|
const memfsEnabled = memfsInitialized ? true : await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
92818
93022
|
if (!memfsEnabled) {
|
|
92819
93023
|
safeSocketSend(socket, {
|
|
@@ -92830,7 +93034,7 @@ async function handleListMemoryCommand(parsed, socket, overrides = {}) {
|
|
|
92830
93034
|
}
|
|
92831
93035
|
if (!memfsInitialized) {
|
|
92832
93036
|
await ensureLocalMemfsCheckout2(parsed.agent_id);
|
|
92833
|
-
memfsInitialized =
|
|
93037
|
+
memfsInitialized = existsSync27(join31(memoryRoot, ".git"));
|
|
92834
93038
|
}
|
|
92835
93039
|
if (!memfsInitialized) {
|
|
92836
93040
|
throw new Error("MemFS is enabled, but the local memory checkout could not be initialized.");
|
|
@@ -93447,7 +93651,7 @@ async function handleChannelsProtocolCommand(parsed, socket, runtime, opts, proc
|
|
|
93447
93651
|
if (parsed.type === "channel_account_start") {
|
|
93448
93652
|
try {
|
|
93449
93653
|
const account = await startChannelAccountLive2(parsed.channel_id, parsed.account_id);
|
|
93450
|
-
wireChannelIngress(runtime, socket, opts, processQueuedTurn);
|
|
93654
|
+
await wireChannelIngress(runtime, socket, opts, processQueuedTurn);
|
|
93451
93655
|
safeSocketSend(socket, {
|
|
93452
93656
|
type: "channel_account_start_response",
|
|
93453
93657
|
request_id: parsed.request_id,
|
|
@@ -93529,7 +93733,7 @@ async function handleChannelsProtocolCommand(parsed, socket, runtime, opts, proc
|
|
|
93529
93733
|
allowedUsers: parsed.config.allowed_users
|
|
93530
93734
|
}, parsed.account_id);
|
|
93531
93735
|
if (snapshot.enabled) {
|
|
93532
|
-
wireChannelIngress(runtime, socket, opts, processQueuedTurn);
|
|
93736
|
+
await wireChannelIngress(runtime, socket, opts, processQueuedTurn);
|
|
93533
93737
|
}
|
|
93534
93738
|
safeSocketSend(socket, {
|
|
93535
93739
|
type: "channel_set_config_response",
|
|
@@ -93556,7 +93760,7 @@ async function handleChannelsProtocolCommand(parsed, socket, runtime, opts, proc
|
|
|
93556
93760
|
if (parsed.type === "channel_start") {
|
|
93557
93761
|
try {
|
|
93558
93762
|
const summary = await startChannelLive2(parsed.channel_id, parsed.account_id);
|
|
93559
|
-
wireChannelIngress(runtime, socket, opts, processQueuedTurn);
|
|
93763
|
+
await wireChannelIngress(runtime, socket, opts, processQueuedTurn);
|
|
93560
93764
|
safeSocketSend(socket, {
|
|
93561
93765
|
type: "channel_start_response",
|
|
93562
93766
|
request_id: parsed.request_id,
|
|
@@ -93806,9 +94010,9 @@ function emitSkillsUpdated(socket) {
|
|
|
93806
94010
|
}
|
|
93807
94011
|
async function handleSkillCommand(parsed, socket) {
|
|
93808
94012
|
const {
|
|
93809
|
-
existsSync:
|
|
94013
|
+
existsSync: existsSync27,
|
|
93810
94014
|
lstatSync: lstatSync2,
|
|
93811
|
-
mkdirSync:
|
|
94015
|
+
mkdirSync: mkdirSync20,
|
|
93812
94016
|
rmdirSync,
|
|
93813
94017
|
symlinkSync,
|
|
93814
94018
|
unlinkSync: unlinkSync8
|
|
@@ -93818,7 +94022,7 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
93818
94022
|
const globalSkillsDir = join31(lettaHome, "skills");
|
|
93819
94023
|
if (parsed.type === "skill_enable") {
|
|
93820
94024
|
try {
|
|
93821
|
-
if (!
|
|
94025
|
+
if (!existsSync27(parsed.skill_path)) {
|
|
93822
94026
|
safeSocketSend(socket, {
|
|
93823
94027
|
type: "skill_enable_response",
|
|
93824
94028
|
request_id: parsed.request_id,
|
|
@@ -93828,7 +94032,7 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
93828
94032
|
return true;
|
|
93829
94033
|
}
|
|
93830
94034
|
const skillMdPath = join31(parsed.skill_path, "SKILL.md");
|
|
93831
|
-
if (!
|
|
94035
|
+
if (!existsSync27(skillMdPath)) {
|
|
93832
94036
|
safeSocketSend(socket, {
|
|
93833
94037
|
type: "skill_enable_response",
|
|
93834
94038
|
request_id: parsed.request_id,
|
|
@@ -93839,8 +94043,8 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
93839
94043
|
}
|
|
93840
94044
|
const linkName = basename10(parsed.skill_path);
|
|
93841
94045
|
const linkPath = join31(globalSkillsDir, linkName);
|
|
93842
|
-
|
|
93843
|
-
if (
|
|
94046
|
+
mkdirSync20(globalSkillsDir, { recursive: true });
|
|
94047
|
+
if (existsSync27(linkPath)) {
|
|
93844
94048
|
const stat7 = lstatSync2(linkPath);
|
|
93845
94049
|
if (stat7.isSymbolicLink()) {
|
|
93846
94050
|
if (process.platform === "win32") {
|
|
@@ -93882,7 +94086,7 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
93882
94086
|
if (parsed.type === "skill_disable") {
|
|
93883
94087
|
try {
|
|
93884
94088
|
const linkPath = join31(globalSkillsDir, parsed.name);
|
|
93885
|
-
if (!
|
|
94089
|
+
if (!existsSync27(linkPath)) {
|
|
93886
94090
|
safeSocketSend(socket, {
|
|
93887
94091
|
type: "skill_disable_response",
|
|
93888
94092
|
request_id: parsed.request_id,
|
|
@@ -94045,7 +94249,7 @@ async function handleReflectionSettingsCommand(parsed, socket, listener) {
|
|
|
94045
94249
|
}
|
|
94046
94250
|
return true;
|
|
94047
94251
|
}
|
|
94048
|
-
function wireChannelIngress(listener, socket, opts, processQueuedTurn) {
|
|
94252
|
+
async function wireChannelIngress(listener, socket, opts, processQueuedTurn) {
|
|
94049
94253
|
const registry = getChannelRegistry();
|
|
94050
94254
|
if (!registry)
|
|
94051
94255
|
return;
|
|
@@ -94066,6 +94270,10 @@ function wireChannelIngress(listener, socket, opts, processQueuedTurn) {
|
|
|
94066
94270
|
}
|
|
94067
94271
|
scheduleQueuePump(conversationRuntime, socket, opts, processQueuedTurn);
|
|
94068
94272
|
});
|
|
94273
|
+
registry.setEventHandler((event) => {
|
|
94274
|
+
handleChannelRegistryEvent(event, socket, listener);
|
|
94275
|
+
});
|
|
94276
|
+
await recoverPendingChannelControlRequests(listener);
|
|
94069
94277
|
registry.setApprovalResponseHandler(async ({ runtime, response }) => handleApprovalResponseInput(listener, {
|
|
94070
94278
|
runtime,
|
|
94071
94279
|
response,
|
|
@@ -94073,9 +94281,6 @@ function wireChannelIngress(listener, socket, opts, processQueuedTurn) {
|
|
|
94073
94281
|
opts,
|
|
94074
94282
|
processQueuedTurn
|
|
94075
94283
|
}));
|
|
94076
|
-
registry.setEventHandler((event) => {
|
|
94077
|
-
handleChannelRegistryEvent(event, socket, listener);
|
|
94078
|
-
});
|
|
94079
94284
|
registry.setReady();
|
|
94080
94285
|
}
|
|
94081
94286
|
function handleChannelRegistryEvent(event, socket, runtime) {
|
|
@@ -94598,7 +94803,7 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
94598
94803
|
const scopedRuntime = getOrCreateScopedRuntime(runtime, queuedTurn.agentId, queuedTurn.conversationId);
|
|
94599
94804
|
await handleIncomingMessage(queuedTurn, socket, scopedRuntime, opts.onStatusChange, opts.connectionId, dequeuedBatch.batchId);
|
|
94600
94805
|
};
|
|
94601
|
-
socket.on("open", () => {
|
|
94806
|
+
socket.on("open", async () => {
|
|
94602
94807
|
if (runtime !== getActiveRuntime() || runtime.intentionallyClosed) {
|
|
94603
94808
|
return;
|
|
94604
94809
|
}
|
|
@@ -94670,7 +94875,7 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
94670
94875
|
}
|
|
94671
94876
|
}, 30000);
|
|
94672
94877
|
startScheduler(socket, opts, processQueuedTurn);
|
|
94673
|
-
wireChannelIngress(runtime, socket, opts, processQueuedTurn);
|
|
94878
|
+
await wireChannelIngress(runtime, socket, opts, processQueuedTurn);
|
|
94674
94879
|
});
|
|
94675
94880
|
socket.on("message", async (data) => {
|
|
94676
94881
|
const raw = data.toString();
|
|
@@ -95882,6 +96087,7 @@ var init_client4 = __esm(async () => {
|
|
|
95882
96087
|
enqueueChannelTurn,
|
|
95883
96088
|
scheduleQueuePump,
|
|
95884
96089
|
replaySyncStateForRuntime,
|
|
96090
|
+
recoverPendingChannelControlRequests,
|
|
95885
96091
|
recoverApprovalStateForSync,
|
|
95886
96092
|
clearRecoveredApprovalStateForScope: (runtime, scope) => clearRecoveredApprovalStateForScope(asListenerRuntimeForTests(runtime), scope),
|
|
95887
96093
|
emitStateSync
|
|
@@ -95915,10 +96121,10 @@ __export(exports_debug2, {
|
|
|
95915
96121
|
});
|
|
95916
96122
|
import {
|
|
95917
96123
|
appendFileSync as appendFileSync3,
|
|
95918
|
-
existsSync as
|
|
95919
|
-
mkdirSync as
|
|
96124
|
+
existsSync as existsSync28,
|
|
96125
|
+
mkdirSync as mkdirSync21,
|
|
95920
96126
|
readdirSync as readdirSync10,
|
|
95921
|
-
readFileSync as
|
|
96127
|
+
readFileSync as readFileSync19,
|
|
95922
96128
|
unlinkSync as unlinkSync8
|
|
95923
96129
|
} from "node:fs";
|
|
95924
96130
|
import { homedir as homedir27 } from "node:os";
|
|
@@ -95970,9 +96176,9 @@ class DebugLogFile2 {
|
|
|
95970
96176
|
if (!this.logPath)
|
|
95971
96177
|
return;
|
|
95972
96178
|
try {
|
|
95973
|
-
if (!
|
|
96179
|
+
if (!existsSync28(this.logPath))
|
|
95974
96180
|
return;
|
|
95975
|
-
const content =
|
|
96181
|
+
const content = readFileSync19(this.logPath, "utf8");
|
|
95976
96182
|
const lines = content.trimEnd().split(`
|
|
95977
96183
|
`);
|
|
95978
96184
|
return lines.slice(-maxLines).join(`
|
|
@@ -95985,8 +96191,8 @@ class DebugLogFile2 {
|
|
|
95985
96191
|
if (this.dirCreated || !this.agentDir)
|
|
95986
96192
|
return;
|
|
95987
96193
|
try {
|
|
95988
|
-
if (!
|
|
95989
|
-
|
|
96194
|
+
if (!existsSync28(this.agentDir)) {
|
|
96195
|
+
mkdirSync21(this.agentDir, { recursive: true });
|
|
95990
96196
|
}
|
|
95991
96197
|
this.dirCreated = true;
|
|
95992
96198
|
} catch {}
|
|
@@ -95995,7 +96201,7 @@ class DebugLogFile2 {
|
|
|
95995
96201
|
if (!this.agentDir)
|
|
95996
96202
|
return;
|
|
95997
96203
|
try {
|
|
95998
|
-
if (!
|
|
96204
|
+
if (!existsSync28(this.agentDir))
|
|
95999
96205
|
return;
|
|
96000
96206
|
const files = readdirSync10(this.agentDir).filter((f) => f.endsWith(".log")).sort();
|
|
96001
96207
|
if (files.length >= MAX_SESSION_FILES3) {
|
|
@@ -96054,12 +96260,12 @@ __export(exports_skills2, {
|
|
|
96054
96260
|
SKILLS_DIR: () => SKILLS_DIR2,
|
|
96055
96261
|
GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR2
|
|
96056
96262
|
});
|
|
96057
|
-
import { existsSync as
|
|
96263
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
96058
96264
|
import { readdir as readdir8, readFile as readFile12, realpath as realpath4, stat as stat7 } from "node:fs/promises";
|
|
96059
|
-
import { dirname as
|
|
96265
|
+
import { dirname as dirname14, join as join35 } from "node:path";
|
|
96060
96266
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
96061
96267
|
function getBundledSkillsPath2() {
|
|
96062
|
-
const thisDir =
|
|
96268
|
+
const thisDir = dirname14(fileURLToPath8(import.meta.url));
|
|
96063
96269
|
if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
|
|
96064
96270
|
return join35(thisDir, "../skills/builtin");
|
|
96065
96271
|
}
|
|
@@ -96078,7 +96284,7 @@ async function getBundledSkills2() {
|
|
|
96078
96284
|
}
|
|
96079
96285
|
async function discoverSkillsFromDir2(skillsPath, source) {
|
|
96080
96286
|
const errors = [];
|
|
96081
|
-
if (!
|
|
96287
|
+
if (!existsSync29(skillsPath)) {
|
|
96082
96288
|
return { skills: [], errors: [] };
|
|
96083
96289
|
}
|
|
96084
96290
|
const skills = [];
|
|
@@ -96250,27 +96456,27 @@ __export(exports_fs, {
|
|
|
96250
96456
|
exists: () => exists2
|
|
96251
96457
|
});
|
|
96252
96458
|
import {
|
|
96253
|
-
existsSync as
|
|
96459
|
+
existsSync as existsSync30,
|
|
96254
96460
|
readFileSync as fsReadFileSync2,
|
|
96255
96461
|
writeFileSync as fsWriteFileSync2,
|
|
96256
|
-
mkdirSync as
|
|
96462
|
+
mkdirSync as mkdirSync22
|
|
96257
96463
|
} from "node:fs";
|
|
96258
|
-
import { dirname as
|
|
96464
|
+
import { dirname as dirname15 } from "node:path";
|
|
96259
96465
|
async function readFile13(path24) {
|
|
96260
96466
|
return fsReadFileSync2(path24, { encoding: "utf-8" });
|
|
96261
96467
|
}
|
|
96262
96468
|
async function writeFile10(path24, content) {
|
|
96263
|
-
const dir =
|
|
96264
|
-
if (!
|
|
96265
|
-
|
|
96469
|
+
const dir = dirname15(path24);
|
|
96470
|
+
if (!existsSync30(dir)) {
|
|
96471
|
+
mkdirSync22(dir, { recursive: true });
|
|
96266
96472
|
}
|
|
96267
96473
|
fsWriteFileSync2(path24, content, { encoding: "utf-8", flush: true });
|
|
96268
96474
|
}
|
|
96269
96475
|
function exists2(path24) {
|
|
96270
|
-
return
|
|
96476
|
+
return existsSync30(path24);
|
|
96271
96477
|
}
|
|
96272
96478
|
async function mkdir9(path24, options) {
|
|
96273
|
-
|
|
96479
|
+
mkdirSync22(path24, options);
|
|
96274
96480
|
}
|
|
96275
96481
|
async function readJsonFile(path24) {
|
|
96276
96482
|
const text = await readFile13(path24);
|
|
@@ -96403,18 +96609,18 @@ var exports_bootstrap_tools = {};
|
|
|
96403
96609
|
__export(exports_bootstrap_tools, {
|
|
96404
96610
|
bootstrapBaseToolsIfNeeded: () => bootstrapBaseToolsIfNeeded
|
|
96405
96611
|
});
|
|
96406
|
-
import { existsSync as
|
|
96612
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync23, writeFileSync as writeFileSync17 } from "node:fs";
|
|
96407
96613
|
import { homedir as homedir28 } from "node:os";
|
|
96408
96614
|
import { join as join36 } from "node:path";
|
|
96409
96615
|
async function bootstrapBaseToolsIfNeeded() {
|
|
96410
|
-
if (
|
|
96616
|
+
if (existsSync31(MARKER_PATH))
|
|
96411
96617
|
return;
|
|
96412
96618
|
debugLog("bootstrap", "No marker found, bootstrapping base tools...");
|
|
96413
96619
|
try {
|
|
96414
96620
|
const success = await addBaseToolsToServer();
|
|
96415
96621
|
if (success) {
|
|
96416
|
-
|
|
96417
|
-
|
|
96622
|
+
mkdirSync23(join36(homedir28(), ".letta"), { recursive: true });
|
|
96623
|
+
writeFileSync17(MARKER_PATH, new Date().toISOString(), "utf-8");
|
|
96418
96624
|
}
|
|
96419
96625
|
} catch (err) {
|
|
96420
96626
|
debugWarn("bootstrap", `Failed to bootstrap base tools: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -98113,7 +98319,7 @@ __export(exports_import, {
|
|
|
98113
98319
|
});
|
|
98114
98320
|
import { createReadStream } from "node:fs";
|
|
98115
98321
|
import { chmod, mkdir as mkdir10, readFile as readFile14, writeFile as writeFile11 } from "node:fs/promises";
|
|
98116
|
-
import { dirname as
|
|
98322
|
+
import { dirname as dirname16, resolve as resolve28 } from "node:path";
|
|
98117
98323
|
async function importAgentFromFile(options) {
|
|
98118
98324
|
const client = await getClient();
|
|
98119
98325
|
const resolvedPath = resolve28(options.filePath);
|
|
@@ -98172,7 +98378,7 @@ async function writeSkillFiles(skillDir, files) {
|
|
|
98172
98378
|
}
|
|
98173
98379
|
async function writeSkillFile(skillDir, filePath, content) {
|
|
98174
98380
|
const fullPath = resolve28(skillDir, filePath);
|
|
98175
|
-
await mkdir10(
|
|
98381
|
+
await mkdir10(dirname16(fullPath), { recursive: true });
|
|
98176
98382
|
await writeFile11(fullPath, content, "utf-8");
|
|
98177
98383
|
const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
|
|
98178
98384
|
if (isScript) {
|
|
@@ -118135,9 +118341,9 @@ function getFileEditHeader(toolName, toolArgs) {
|
|
|
118135
118341
|
const relPath = relative16(cwd2, filePath);
|
|
118136
118342
|
const displayPath = relPath.startsWith("..") ? filePath : relPath;
|
|
118137
118343
|
if (t === "write" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini") {
|
|
118138
|
-
const { existsSync:
|
|
118344
|
+
const { existsSync: existsSync34 } = __require("node:fs");
|
|
118139
118345
|
try {
|
|
118140
|
-
if (
|
|
118346
|
+
if (existsSync34(filePath)) {
|
|
118141
118347
|
return `Overwrite ${displayPath}?`;
|
|
118142
118348
|
}
|
|
118143
118349
|
} catch {}
|
|
@@ -118914,9 +119120,9 @@ function getHeaderText(fileEdit) {
|
|
|
118914
119120
|
const relPath = relative16(cwd2, fileEdit.filePath);
|
|
118915
119121
|
const displayPath = relPath.startsWith("..") ? fileEdit.filePath : relPath;
|
|
118916
119122
|
if (t === "write" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini") {
|
|
118917
|
-
const { existsSync:
|
|
119123
|
+
const { existsSync: existsSync34 } = __require("node:fs");
|
|
118918
119124
|
try {
|
|
118919
|
-
if (
|
|
119125
|
+
if (existsSync34(fileEdit.filePath)) {
|
|
118920
119126
|
return `Overwrite ${displayPath}?`;
|
|
118921
119127
|
}
|
|
118922
119128
|
} catch {}
|
|
@@ -121002,7 +121208,7 @@ html.dark .agent-name { color: var(--text-dim); }
|
|
|
121002
121208
|
var init_plan_viewer_template = () => {};
|
|
121003
121209
|
|
|
121004
121210
|
// src/web/generate-plan-viewer.ts
|
|
121005
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
121211
|
+
import { chmodSync as chmodSync2, existsSync as existsSync34, mkdirSync as mkdirSync26, writeFileSync as writeFileSync20 } from "node:fs";
|
|
121006
121212
|
import { homedir as homedir32 } from "node:os";
|
|
121007
121213
|
import { join as join41 } from "node:path";
|
|
121008
121214
|
async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
|
|
@@ -121014,14 +121220,14 @@ async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
|
|
|
121014
121220
|
};
|
|
121015
121221
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
121016
121222
|
const html = plan_viewer_template_default.replace("<!--LETTA_PLAN_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
121017
|
-
if (!
|
|
121018
|
-
|
|
121223
|
+
if (!existsSync34(VIEWERS_DIR)) {
|
|
121224
|
+
mkdirSync26(VIEWERS_DIR, { recursive: true, mode: 448 });
|
|
121019
121225
|
}
|
|
121020
121226
|
try {
|
|
121021
121227
|
chmodSync2(VIEWERS_DIR, 448);
|
|
121022
121228
|
} catch {}
|
|
121023
121229
|
const filePath = join41(VIEWERS_DIR, "plan.html");
|
|
121024
|
-
|
|
121230
|
+
writeFileSync20(filePath, html);
|
|
121025
121231
|
chmodSync2(filePath, 384);
|
|
121026
121232
|
const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
|
|
121027
121233
|
if (!skipOpen) {
|
|
@@ -123377,7 +123583,7 @@ var init_pasteRegistry = __esm(() => {
|
|
|
123377
123583
|
|
|
123378
123584
|
// src/cli/helpers/clipboard.ts
|
|
123379
123585
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
123380
|
-
import { existsSync as
|
|
123586
|
+
import { existsSync as existsSync35, readFileSync as readFileSync21, statSync as statSync10, unlinkSync as unlinkSync10 } from "node:fs";
|
|
123381
123587
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
123382
123588
|
import { basename as basename10, extname as extname8, isAbsolute as isAbsolute20, join as join42, resolve as resolve29 } from "node:path";
|
|
123383
123589
|
function countLines2(text) {
|
|
@@ -123429,8 +123635,8 @@ function translatePasteForImages(paste) {
|
|
|
123429
123635
|
if (!isAbsolute20(filePath))
|
|
123430
123636
|
filePath = resolve29(process.cwd(), filePath);
|
|
123431
123637
|
const ext3 = extname8(filePath || "").toLowerCase();
|
|
123432
|
-
if (IMAGE_EXTS.has(ext3) &&
|
|
123433
|
-
const buf =
|
|
123638
|
+
if (IMAGE_EXTS.has(ext3) && existsSync35(filePath) && statSync10(filePath).isFile()) {
|
|
123639
|
+
const buf = readFileSync21(filePath);
|
|
123434
123640
|
const b64 = buf.toString("base64");
|
|
123435
123641
|
const mt = ext3 === ".png" ? "image/png" : ext3 === ".jpg" || ext3 === ".jpeg" ? "image/jpeg" : ext3 === ".gif" ? "image/gif" : ext3 === ".webp" ? "image/webp" : ext3 === ".bmp" ? "image/bmp" : ext3 === ".svg" ? "image/svg+xml" : ext3 === ".tif" || ext3 === ".tiff" ? "image/tiff" : ext3 === ".heic" ? "image/heic" : ext3 === ".heif" ? "image/heif" : ext3 === ".avif" ? "image/avif" : "application/octet-stream";
|
|
123436
123642
|
const id = allocateImage({
|
|
@@ -123470,11 +123676,11 @@ function getClipboardImageToTempFile() {
|
|
|
123470
123676
|
encoding: "utf8",
|
|
123471
123677
|
stdio: ["ignore", "pipe", "ignore"]
|
|
123472
123678
|
}).trim();
|
|
123473
|
-
if (!uti || !
|
|
123679
|
+
if (!uti || !existsSync35(tempPath))
|
|
123474
123680
|
return null;
|
|
123475
123681
|
return { tempPath, uti };
|
|
123476
123682
|
} catch {
|
|
123477
|
-
if (
|
|
123683
|
+
if (existsSync35(tempPath)) {
|
|
123478
123684
|
try {
|
|
123479
123685
|
unlinkSync10(tempPath);
|
|
123480
123686
|
} catch {}
|
|
@@ -123490,7 +123696,7 @@ async function tryImportClipboardImageMac() {
|
|
|
123490
123696
|
return null;
|
|
123491
123697
|
const { tempPath, uti } = clipboardResult;
|
|
123492
123698
|
try {
|
|
123493
|
-
const buffer =
|
|
123699
|
+
const buffer = readFileSync21(tempPath);
|
|
123494
123700
|
try {
|
|
123495
123701
|
unlinkSync10(tempPath);
|
|
123496
123702
|
} catch {}
|
|
@@ -123507,7 +123713,7 @@ async function tryImportClipboardImageMac() {
|
|
|
123507
123713
|
height: resized.height
|
|
123508
123714
|
};
|
|
123509
123715
|
} catch (err) {
|
|
123510
|
-
if (
|
|
123716
|
+
if (existsSync35(tempPath)) {
|
|
123511
123717
|
try {
|
|
123512
123718
|
unlinkSync10(tempPath);
|
|
123513
123719
|
} catch {}
|
|
@@ -124197,13 +124403,13 @@ __export(exports_terminalKeybindingInstaller, {
|
|
|
124197
124403
|
});
|
|
124198
124404
|
import {
|
|
124199
124405
|
copyFileSync,
|
|
124200
|
-
existsSync as
|
|
124201
|
-
mkdirSync as
|
|
124202
|
-
readFileSync as
|
|
124203
|
-
writeFileSync as
|
|
124406
|
+
existsSync as existsSync36,
|
|
124407
|
+
mkdirSync as mkdirSync27,
|
|
124408
|
+
readFileSync as readFileSync22,
|
|
124409
|
+
writeFileSync as writeFileSync21
|
|
124204
124410
|
} from "node:fs";
|
|
124205
124411
|
import { homedir as homedir33, platform as platform6 } from "node:os";
|
|
124206
|
-
import { dirname as
|
|
124412
|
+
import { dirname as dirname17, join as join43 } from "node:path";
|
|
124207
124413
|
function detectTerminalType() {
|
|
124208
124414
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
124209
124415
|
return "cursor";
|
|
@@ -124266,10 +124472,10 @@ function parseKeybindings(content) {
|
|
|
124266
124472
|
}
|
|
124267
124473
|
}
|
|
124268
124474
|
function keybindingExists(keybindingsPath) {
|
|
124269
|
-
if (!
|
|
124475
|
+
if (!existsSync36(keybindingsPath))
|
|
124270
124476
|
return false;
|
|
124271
124477
|
try {
|
|
124272
|
-
const content =
|
|
124478
|
+
const content = readFileSync22(keybindingsPath, { encoding: "utf-8" });
|
|
124273
124479
|
const keybindings = parseKeybindings(content);
|
|
124274
124480
|
if (!keybindings)
|
|
124275
124481
|
return false;
|
|
@@ -124279,7 +124485,7 @@ function keybindingExists(keybindingsPath) {
|
|
|
124279
124485
|
}
|
|
124280
124486
|
}
|
|
124281
124487
|
function createBackup(keybindingsPath) {
|
|
124282
|
-
if (!
|
|
124488
|
+
if (!existsSync36(keybindingsPath))
|
|
124283
124489
|
return null;
|
|
124284
124490
|
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
124285
124491
|
try {
|
|
@@ -124294,15 +124500,15 @@ function installKeybinding(keybindingsPath) {
|
|
|
124294
124500
|
if (keybindingExists(keybindingsPath)) {
|
|
124295
124501
|
return { success: true, alreadyExists: true };
|
|
124296
124502
|
}
|
|
124297
|
-
const parentDir =
|
|
124298
|
-
if (!
|
|
124299
|
-
|
|
124503
|
+
const parentDir = dirname17(keybindingsPath);
|
|
124504
|
+
if (!existsSync36(parentDir)) {
|
|
124505
|
+
mkdirSync27(parentDir, { recursive: true });
|
|
124300
124506
|
}
|
|
124301
124507
|
let keybindings = [];
|
|
124302
124508
|
let backupPath = null;
|
|
124303
|
-
if (
|
|
124509
|
+
if (existsSync36(keybindingsPath)) {
|
|
124304
124510
|
backupPath = createBackup(keybindingsPath);
|
|
124305
|
-
const content =
|
|
124511
|
+
const content = readFileSync22(keybindingsPath, { encoding: "utf-8" });
|
|
124306
124512
|
const parsed = parseKeybindings(content);
|
|
124307
124513
|
if (parsed === null) {
|
|
124308
124514
|
return {
|
|
@@ -124315,7 +124521,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
124315
124521
|
keybindings.push(SHIFT_ENTER_KEYBINDING);
|
|
124316
124522
|
const newContent = `${JSON.stringify(keybindings, null, 2)}
|
|
124317
124523
|
`;
|
|
124318
|
-
|
|
124524
|
+
writeFileSync21(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
124319
124525
|
return {
|
|
124320
124526
|
success: true,
|
|
124321
124527
|
backupPath: backupPath ?? undefined
|
|
@@ -124330,10 +124536,10 @@ function installKeybinding(keybindingsPath) {
|
|
|
124330
124536
|
}
|
|
124331
124537
|
function removeKeybinding(keybindingsPath) {
|
|
124332
124538
|
try {
|
|
124333
|
-
if (!
|
|
124539
|
+
if (!existsSync36(keybindingsPath)) {
|
|
124334
124540
|
return { success: true };
|
|
124335
124541
|
}
|
|
124336
|
-
const content =
|
|
124542
|
+
const content = readFileSync22(keybindingsPath, { encoding: "utf-8" });
|
|
124337
124543
|
const keybindings = parseKeybindings(content);
|
|
124338
124544
|
if (!keybindings) {
|
|
124339
124545
|
return {
|
|
@@ -124344,7 +124550,7 @@ function removeKeybinding(keybindingsPath) {
|
|
|
124344
124550
|
const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
|
|
124345
124551
|
const newContent = `${JSON.stringify(filtered, null, 2)}
|
|
124346
124552
|
`;
|
|
124347
|
-
|
|
124553
|
+
writeFileSync21(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
124348
124554
|
return { success: true };
|
|
124349
124555
|
} catch (error) {
|
|
124350
124556
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -124398,19 +124604,19 @@ function getWezTermConfigPath() {
|
|
|
124398
124604
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
124399
124605
|
if (xdgConfig) {
|
|
124400
124606
|
const xdgPath = join43(xdgConfig, "wezterm", "wezterm.lua");
|
|
124401
|
-
if (
|
|
124607
|
+
if (existsSync36(xdgPath))
|
|
124402
124608
|
return xdgPath;
|
|
124403
124609
|
}
|
|
124404
124610
|
const configPath = join43(homedir33(), ".config", "wezterm", "wezterm.lua");
|
|
124405
|
-
if (
|
|
124611
|
+
if (existsSync36(configPath))
|
|
124406
124612
|
return configPath;
|
|
124407
124613
|
return join43(homedir33(), ".wezterm.lua");
|
|
124408
124614
|
}
|
|
124409
124615
|
function wezTermDeleteFixExists(configPath) {
|
|
124410
|
-
if (!
|
|
124616
|
+
if (!existsSync36(configPath))
|
|
124411
124617
|
return false;
|
|
124412
124618
|
try {
|
|
124413
|
-
const content =
|
|
124619
|
+
const content = readFileSync22(configPath, { encoding: "utf-8" });
|
|
124414
124620
|
return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
|
|
124415
124621
|
} catch {
|
|
124416
124622
|
return false;
|
|
@@ -124424,10 +124630,10 @@ function installWezTermDeleteFix() {
|
|
|
124424
124630
|
}
|
|
124425
124631
|
let content = "";
|
|
124426
124632
|
let backupPath = null;
|
|
124427
|
-
if (
|
|
124633
|
+
if (existsSync36(configPath)) {
|
|
124428
124634
|
backupPath = `${configPath}.letta-backup`;
|
|
124429
124635
|
copyFileSync(configPath, backupPath);
|
|
124430
|
-
content =
|
|
124636
|
+
content = readFileSync22(configPath, { encoding: "utf-8" });
|
|
124431
124637
|
}
|
|
124432
124638
|
if (content.includes("return {") && !content.includes("local config")) {
|
|
124433
124639
|
content = content.replace(/return\s*\{/, "local config = {");
|
|
@@ -124453,11 +124659,11 @@ return config`);
|
|
|
124453
124659
|
${WEZTERM_DELETE_FIX}
|
|
124454
124660
|
`;
|
|
124455
124661
|
}
|
|
124456
|
-
const parentDir =
|
|
124457
|
-
if (!
|
|
124458
|
-
|
|
124662
|
+
const parentDir = dirname17(configPath);
|
|
124663
|
+
if (!existsSync36(parentDir)) {
|
|
124664
|
+
mkdirSync27(parentDir, { recursive: true });
|
|
124459
124665
|
}
|
|
124460
|
-
|
|
124666
|
+
writeFileSync21(configPath, content, { encoding: "utf-8" });
|
|
124461
124667
|
return {
|
|
124462
124668
|
success: true,
|
|
124463
124669
|
backupPath: backupPath ?? undefined
|
|
@@ -125041,9 +125247,9 @@ __export(exports_custom, {
|
|
|
125041
125247
|
GLOBAL_COMMANDS_DIR: () => GLOBAL_COMMANDS_DIR,
|
|
125042
125248
|
COMMANDS_DIR: () => COMMANDS_DIR
|
|
125043
125249
|
});
|
|
125044
|
-
import { existsSync as
|
|
125250
|
+
import { existsSync as existsSync37 } from "node:fs";
|
|
125045
125251
|
import { readdir as readdir10, readFile as readFile15 } from "node:fs/promises";
|
|
125046
|
-
import { basename as basename11, dirname as
|
|
125252
|
+
import { basename as basename11, dirname as dirname18, join as join44 } from "node:path";
|
|
125047
125253
|
async function getCustomCommands() {
|
|
125048
125254
|
if (cachedCommands !== null) {
|
|
125049
125255
|
return cachedCommands;
|
|
@@ -125075,7 +125281,7 @@ async function discoverCustomCommands(projectPath = join44(process.cwd(), COMMAN
|
|
|
125075
125281
|
return result;
|
|
125076
125282
|
}
|
|
125077
125283
|
async function discoverFromDirectory(dirPath, source2) {
|
|
125078
|
-
if (!
|
|
125284
|
+
if (!existsSync37(dirPath)) {
|
|
125079
125285
|
return [];
|
|
125080
125286
|
}
|
|
125081
125287
|
const commands2 = [];
|
|
@@ -125104,7 +125310,7 @@ async function parseCommandFile(filePath, rootPath, source2) {
|
|
|
125104
125310
|
const content = await readFile15(filePath, "utf-8");
|
|
125105
125311
|
const { frontmatter, body } = parseFrontmatter(content);
|
|
125106
125312
|
const id = basename11(filePath, ".md");
|
|
125107
|
-
const relativePath =
|
|
125313
|
+
const relativePath = dirname18(filePath).slice(rootPath.length);
|
|
125108
125314
|
const namespace = relativePath.replace(/^[/\\]/, "") || undefined;
|
|
125109
125315
|
let description = getStringField(frontmatter, "description");
|
|
125110
125316
|
if (!description) {
|
|
@@ -130263,15 +130469,15 @@ var init_InputRich = __esm(async () => {
|
|
|
130263
130469
|
// src/cli/commands/install-github-app.ts
|
|
130264
130470
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
130265
130471
|
import {
|
|
130266
|
-
existsSync as
|
|
130267
|
-
mkdirSync as
|
|
130472
|
+
existsSync as existsSync38,
|
|
130473
|
+
mkdirSync as mkdirSync28,
|
|
130268
130474
|
mkdtempSync,
|
|
130269
|
-
readFileSync as
|
|
130475
|
+
readFileSync as readFileSync23,
|
|
130270
130476
|
rmSync as rmSync4,
|
|
130271
|
-
writeFileSync as
|
|
130477
|
+
writeFileSync as writeFileSync22
|
|
130272
130478
|
} from "node:fs";
|
|
130273
130479
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
130274
|
-
import { dirname as
|
|
130480
|
+
import { dirname as dirname19, join as join46 } from "node:path";
|
|
130275
130481
|
function runCommand(command, args, cwd2, input) {
|
|
130276
130482
|
try {
|
|
130277
130483
|
return execFileSync4(command, args, {
|
|
@@ -130518,18 +130724,18 @@ function runGit6(args, cwd2) {
|
|
|
130518
130724
|
}
|
|
130519
130725
|
function writeWorkflow(repoDir, workflowPath, content) {
|
|
130520
130726
|
const absolutePath = join46(repoDir, workflowPath);
|
|
130521
|
-
if (!
|
|
130522
|
-
|
|
130727
|
+
if (!existsSync38(dirname19(absolutePath))) {
|
|
130728
|
+
mkdirSync28(dirname19(absolutePath), { recursive: true });
|
|
130523
130729
|
}
|
|
130524
130730
|
const next = `${content.trimEnd()}
|
|
130525
130731
|
`;
|
|
130526
|
-
if (
|
|
130527
|
-
const previous =
|
|
130732
|
+
if (existsSync38(absolutePath)) {
|
|
130733
|
+
const previous = readFileSync23(absolutePath, "utf8");
|
|
130528
130734
|
if (previous === next) {
|
|
130529
130735
|
return false;
|
|
130530
130736
|
}
|
|
130531
130737
|
}
|
|
130532
|
-
|
|
130738
|
+
writeFileSync22(absolutePath, next, "utf8");
|
|
130533
130739
|
return true;
|
|
130534
130740
|
}
|
|
130535
130741
|
function getDefaultBaseBranch(repoDir) {
|
|
@@ -134761,7 +134967,7 @@ __export(exports_generate_memory_viewer, {
|
|
|
134761
134967
|
generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
|
|
134762
134968
|
});
|
|
134763
134969
|
import { execFile as execFileCb5 } from "node:child_process";
|
|
134764
|
-
import { chmodSync as chmodSync3, existsSync as
|
|
134970
|
+
import { chmodSync as chmodSync3, existsSync as existsSync39, mkdirSync as mkdirSync29, writeFileSync as writeFileSync23 } from "node:fs";
|
|
134765
134971
|
import { homedir as homedir35 } from "node:os";
|
|
134766
134972
|
import { join as join47 } from "node:path";
|
|
134767
134973
|
import { promisify as promisify15 } from "node:util";
|
|
@@ -135081,14 +135287,14 @@ async function generateAndOpenMemoryViewer(agentId, options) {
|
|
|
135081
135287
|
}
|
|
135082
135288
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
135083
135289
|
const html = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
135084
|
-
if (!
|
|
135085
|
-
|
|
135290
|
+
if (!existsSync39(VIEWERS_DIR2)) {
|
|
135291
|
+
mkdirSync29(VIEWERS_DIR2, { recursive: true, mode: 448 });
|
|
135086
135292
|
}
|
|
135087
135293
|
try {
|
|
135088
135294
|
chmodSync3(VIEWERS_DIR2, 448);
|
|
135089
135295
|
} catch {}
|
|
135090
135296
|
const filePath = join47(VIEWERS_DIR2, `memory-${encodeURIComponent(agentId)}.html`);
|
|
135091
|
-
|
|
135297
|
+
writeFileSync23(filePath, html);
|
|
135092
135298
|
chmodSync3(filePath, 384);
|
|
135093
135299
|
const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
|
|
135094
135300
|
if (!skipOpen) {
|
|
@@ -135114,7 +135320,7 @@ var init_generate_memory_viewer = __esm(() => {
|
|
|
135114
135320
|
});
|
|
135115
135321
|
|
|
135116
135322
|
// src/cli/components/MemfsTreeViewer.tsx
|
|
135117
|
-
import { existsSync as
|
|
135323
|
+
import { existsSync as existsSync40 } from "node:fs";
|
|
135118
135324
|
function renderTreePrefix(node) {
|
|
135119
135325
|
let prefix = "";
|
|
135120
135326
|
for (let i = 0;i < node.depth; i++) {
|
|
@@ -135140,7 +135346,7 @@ function MemfsTreeViewer({
|
|
|
135140
135346
|
const [status, setStatus] = import_react79.useState(null);
|
|
135141
135347
|
const statusTimerRef = import_react79.useRef(null);
|
|
135142
135348
|
const memoryRoot = getMemoryFilesystemRoot(agentId);
|
|
135143
|
-
const memoryExists =
|
|
135349
|
+
const memoryExists = existsSync40(memoryRoot);
|
|
135144
135350
|
const hasGitRepo = import_react79.useMemo(() => isGitRepo(agentId), [agentId]);
|
|
135145
135351
|
function showStatus(msg, durationMs) {
|
|
135146
135352
|
if (statusTimerRef.current)
|
|
@@ -142944,18 +143150,18 @@ var init_reasoningTabToggle = __esm(() => {
|
|
|
142944
143150
|
});
|
|
142945
143151
|
|
|
142946
143152
|
// src/cli/helpers/startupSystemPromptWarning.ts
|
|
142947
|
-
import { existsSync as
|
|
143153
|
+
import { existsSync as existsSync41, readdirSync as readdirSync13, readFileSync as readFileSync24 } from "node:fs";
|
|
142948
143154
|
import { join as join49 } from "node:path";
|
|
142949
143155
|
function estimateSystemTokens(text) {
|
|
142950
143156
|
return Math.ceil(Buffer.byteLength(text, "utf8") / STARTUP_SYSTEM_PROMPT_ESTIMATED_BYTES_PER_TOKEN);
|
|
142951
143157
|
}
|
|
142952
143158
|
function estimateSystemPromptTokensFromMemoryDir(memoryDir) {
|
|
142953
143159
|
const systemDir = join49(memoryDir, "system");
|
|
142954
|
-
if (!
|
|
143160
|
+
if (!existsSync41(systemDir)) {
|
|
142955
143161
|
return 0;
|
|
142956
143162
|
}
|
|
142957
143163
|
const walkMarkdownFiles = (dir) => {
|
|
142958
|
-
if (!
|
|
143164
|
+
if (!existsSync41(dir)) {
|
|
142959
143165
|
return [];
|
|
142960
143166
|
}
|
|
142961
143167
|
const out = [];
|
|
@@ -142979,7 +143185,7 @@ function estimateSystemPromptTokensFromMemoryDir(memoryDir) {
|
|
|
142979
143185
|
return out;
|
|
142980
143186
|
};
|
|
142981
143187
|
return walkMarkdownFiles(systemDir).sort().reduce((sum, filePath) => {
|
|
142982
|
-
const text =
|
|
143188
|
+
const text = readFileSync24(filePath, "utf8");
|
|
142983
143189
|
return sum + estimateSystemTokens(text);
|
|
142984
143190
|
}, 0);
|
|
142985
143191
|
}
|
|
@@ -143783,16 +143989,16 @@ __export(exports_shellAliases, {
|
|
|
143783
143989
|
expandAliases: () => expandAliases,
|
|
143784
143990
|
clearAliasCache: () => clearAliasCache
|
|
143785
143991
|
});
|
|
143786
|
-
import { existsSync as
|
|
143992
|
+
import { existsSync as existsSync42, readFileSync as readFileSync25 } from "node:fs";
|
|
143787
143993
|
import { homedir as homedir37 } from "node:os";
|
|
143788
143994
|
import { join as join50 } from "node:path";
|
|
143789
143995
|
function parseAliasesFromFile(filePath) {
|
|
143790
143996
|
const aliases = new Map;
|
|
143791
|
-
if (!
|
|
143997
|
+
if (!existsSync42(filePath)) {
|
|
143792
143998
|
return aliases;
|
|
143793
143999
|
}
|
|
143794
144000
|
try {
|
|
143795
|
-
const content =
|
|
144001
|
+
const content = readFileSync25(filePath, "utf-8");
|
|
143796
144002
|
const lines = content.split(`
|
|
143797
144003
|
`);
|
|
143798
144004
|
let inFunction = false;
|
|
@@ -144703,7 +144909,7 @@ __export(exports_App, {
|
|
|
144703
144909
|
default: () => App2
|
|
144704
144910
|
});
|
|
144705
144911
|
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
144706
|
-
import { existsSync as
|
|
144912
|
+
import { existsSync as existsSync43, readFileSync as readFileSync26, renameSync as renameSync3, writeFileSync as writeFileSync24 } from "node:fs";
|
|
144707
144913
|
import { homedir as homedir38, tmpdir as tmpdir6 } from "node:os";
|
|
144708
144914
|
import { join as join51, relative as relative18 } from "node:path";
|
|
144709
144915
|
function deriveReasoningEffort(modelSettings, llmConfig) {
|
|
@@ -144959,18 +145165,18 @@ function saveLastSessionBeforeExit(conversationId) {
|
|
|
144959
145165
|
}
|
|
144960
145166
|
function planFileExists(fallbackPlanFilePath) {
|
|
144961
145167
|
const planFilePath = permissionMode.getPlanFilePath() ?? fallbackPlanFilePath;
|
|
144962
|
-
return !!planFilePath &&
|
|
145168
|
+
return !!planFilePath && existsSync43(planFilePath);
|
|
144963
145169
|
}
|
|
144964
145170
|
function _readPlanFile(fallbackPlanFilePath) {
|
|
144965
145171
|
const planFilePath = permissionMode.getPlanFilePath() ?? fallbackPlanFilePath;
|
|
144966
145172
|
if (!planFilePath) {
|
|
144967
145173
|
return "No plan file path set.";
|
|
144968
145174
|
}
|
|
144969
|
-
if (!
|
|
145175
|
+
if (!existsSync43(planFilePath)) {
|
|
144970
145176
|
return `Plan file not found at ${planFilePath}`;
|
|
144971
145177
|
}
|
|
144972
145178
|
try {
|
|
144973
|
-
return
|
|
145179
|
+
return readFileSync26(planFilePath, "utf-8");
|
|
144974
145180
|
} catch {
|
|
144975
145181
|
return `Failed to read plan file at ${planFilePath}`;
|
|
144976
145182
|
}
|
|
@@ -146317,10 +146523,10 @@ function App2({
|
|
|
146317
146523
|
if (!planFilePath)
|
|
146318
146524
|
return;
|
|
146319
146525
|
try {
|
|
146320
|
-
const { readFileSync:
|
|
146321
|
-
if (!
|
|
146526
|
+
const { readFileSync: readFileSync27, existsSync: existsSync44 } = __require("node:fs");
|
|
146527
|
+
if (!existsSync44(planFilePath))
|
|
146322
146528
|
return;
|
|
146323
|
-
const planContent =
|
|
146529
|
+
const planContent = readFileSync27(planFilePath, "utf-8");
|
|
146324
146530
|
const previewItem = {
|
|
146325
146531
|
kind: "approval_preview",
|
|
146326
146532
|
id: `approval-preview-${toolCallId}`,
|
|
@@ -146746,9 +146952,9 @@ Memory may be stale. Try running: git -C ~/.letta/agents/${agentId}/memory pull`
|
|
|
146746
146952
|
(async () => {
|
|
146747
146953
|
try {
|
|
146748
146954
|
const { watch: watch2 } = await import("node:fs");
|
|
146749
|
-
const { existsSync:
|
|
146955
|
+
const { existsSync: existsSync44 } = await import("node:fs");
|
|
146750
146956
|
const memRoot = getMemoryFilesystemRoot(agentId);
|
|
146751
|
-
if (!
|
|
146957
|
+
if (!existsSync44(memRoot))
|
|
146752
146958
|
return;
|
|
146753
146959
|
watcher = watch2(memRoot, { recursive: true }, () => {});
|
|
146754
146960
|
memfsWatcherRef.current = watcher;
|
|
@@ -149289,9 +149495,9 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
|
|
|
149289
149495
|
join51(memoryRoot, "system", "persona.md"),
|
|
149290
149496
|
join51(memoryRoot, "memory", "system", "persona.md")
|
|
149291
149497
|
];
|
|
149292
|
-
const personaPath = personaCandidates.find((candidate) =>
|
|
149498
|
+
const personaPath = personaCandidates.find((candidate) => existsSync43(candidate));
|
|
149293
149499
|
if (personaPath) {
|
|
149294
|
-
const personaContent =
|
|
149500
|
+
const personaContent = readFileSync26(personaPath, "utf-8");
|
|
149295
149501
|
setCurrentPersonalityId(detectPersonalityFromPersonaFile(personaContent));
|
|
149296
149502
|
} else {
|
|
149297
149503
|
setCurrentPersonalityId(null);
|
|
@@ -150485,7 +150691,7 @@ Press Enter to continue, or type anything to cancel.`, false, "running");
|
|
|
150485
150691
|
fileContent.skills = skills;
|
|
150486
150692
|
}
|
|
150487
150693
|
const fileName = exportParams.conversation_id ? `${exportParams.conversation_id}.af` : `${agentId}.af`;
|
|
150488
|
-
|
|
150694
|
+
writeFileSync24(fileName, JSON.stringify(fileContent, null, 2));
|
|
150489
150695
|
let summary = `AgentFile exported to ${fileName}`;
|
|
150490
150696
|
if (skills.length > 0) {
|
|
150491
150697
|
summary += `
|
|
@@ -150575,7 +150781,7 @@ Path: ${result2.memoryDir}`, true, msg);
|
|
|
150575
150781
|
setCommandRunning(true);
|
|
150576
150782
|
try {
|
|
150577
150783
|
const memoryDir = getMemoryFilesystemRoot(agentId);
|
|
150578
|
-
if (!
|
|
150784
|
+
if (!existsSync43(memoryDir)) {
|
|
150579
150785
|
updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
|
|
150580
150786
|
return { submitted: true };
|
|
150581
150787
|
}
|
|
@@ -150607,7 +150813,7 @@ Run \`/memfs sync\` to repopulate from API.`, true, msg);
|
|
|
150607
150813
|
await removeGitMemoryTag2(agentId);
|
|
150608
150814
|
let backupInfo = "";
|
|
150609
150815
|
const memoryDir = getMemoryFilesystemRoot(agentId);
|
|
150610
|
-
if (
|
|
150816
|
+
if (existsSync43(memoryDir)) {
|
|
150611
150817
|
const backupDir = join51(tmpdir6(), `letta-memfs-disable-${agentId}-${Date.now()}`);
|
|
150612
150818
|
renameSync3(memoryDir, backupDir);
|
|
150613
150819
|
backupInfo = `
|
|
@@ -154516,13 +154722,13 @@ __export(exports_terminalKeybindingInstaller2, {
|
|
|
154516
154722
|
});
|
|
154517
154723
|
import {
|
|
154518
154724
|
copyFileSync as copyFileSync2,
|
|
154519
|
-
existsSync as
|
|
154520
|
-
mkdirSync as
|
|
154521
|
-
readFileSync as
|
|
154522
|
-
writeFileSync as
|
|
154725
|
+
existsSync as existsSync44,
|
|
154726
|
+
mkdirSync as mkdirSync30,
|
|
154727
|
+
readFileSync as readFileSync27,
|
|
154728
|
+
writeFileSync as writeFileSync25
|
|
154523
154729
|
} from "node:fs";
|
|
154524
154730
|
import { homedir as homedir39, platform as platform7 } from "node:os";
|
|
154525
|
-
import { dirname as
|
|
154731
|
+
import { dirname as dirname20, join as join52 } from "node:path";
|
|
154526
154732
|
function detectTerminalType2() {
|
|
154527
154733
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
154528
154734
|
return "cursor";
|
|
@@ -154585,10 +154791,10 @@ function parseKeybindings2(content) {
|
|
|
154585
154791
|
}
|
|
154586
154792
|
}
|
|
154587
154793
|
function keybindingExists2(keybindingsPath) {
|
|
154588
|
-
if (!
|
|
154794
|
+
if (!existsSync44(keybindingsPath))
|
|
154589
154795
|
return false;
|
|
154590
154796
|
try {
|
|
154591
|
-
const content =
|
|
154797
|
+
const content = readFileSync27(keybindingsPath, { encoding: "utf-8" });
|
|
154592
154798
|
const keybindings = parseKeybindings2(content);
|
|
154593
154799
|
if (!keybindings)
|
|
154594
154800
|
return false;
|
|
@@ -154598,7 +154804,7 @@ function keybindingExists2(keybindingsPath) {
|
|
|
154598
154804
|
}
|
|
154599
154805
|
}
|
|
154600
154806
|
function createBackup2(keybindingsPath) {
|
|
154601
|
-
if (!
|
|
154807
|
+
if (!existsSync44(keybindingsPath))
|
|
154602
154808
|
return null;
|
|
154603
154809
|
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
154604
154810
|
try {
|
|
@@ -154613,15 +154819,15 @@ function installKeybinding2(keybindingsPath) {
|
|
|
154613
154819
|
if (keybindingExists2(keybindingsPath)) {
|
|
154614
154820
|
return { success: true, alreadyExists: true };
|
|
154615
154821
|
}
|
|
154616
|
-
const parentDir =
|
|
154617
|
-
if (!
|
|
154618
|
-
|
|
154822
|
+
const parentDir = dirname20(keybindingsPath);
|
|
154823
|
+
if (!existsSync44(parentDir)) {
|
|
154824
|
+
mkdirSync30(parentDir, { recursive: true });
|
|
154619
154825
|
}
|
|
154620
154826
|
let keybindings = [];
|
|
154621
154827
|
let backupPath = null;
|
|
154622
|
-
if (
|
|
154828
|
+
if (existsSync44(keybindingsPath)) {
|
|
154623
154829
|
backupPath = createBackup2(keybindingsPath);
|
|
154624
|
-
const content =
|
|
154830
|
+
const content = readFileSync27(keybindingsPath, { encoding: "utf-8" });
|
|
154625
154831
|
const parsed = parseKeybindings2(content);
|
|
154626
154832
|
if (parsed === null) {
|
|
154627
154833
|
return {
|
|
@@ -154634,7 +154840,7 @@ function installKeybinding2(keybindingsPath) {
|
|
|
154634
154840
|
keybindings.push(SHIFT_ENTER_KEYBINDING2);
|
|
154635
154841
|
const newContent = `${JSON.stringify(keybindings, null, 2)}
|
|
154636
154842
|
`;
|
|
154637
|
-
|
|
154843
|
+
writeFileSync25(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
154638
154844
|
return {
|
|
154639
154845
|
success: true,
|
|
154640
154846
|
backupPath: backupPath ?? undefined
|
|
@@ -154649,10 +154855,10 @@ function installKeybinding2(keybindingsPath) {
|
|
|
154649
154855
|
}
|
|
154650
154856
|
function removeKeybinding2(keybindingsPath) {
|
|
154651
154857
|
try {
|
|
154652
|
-
if (!
|
|
154858
|
+
if (!existsSync44(keybindingsPath)) {
|
|
154653
154859
|
return { success: true };
|
|
154654
154860
|
}
|
|
154655
|
-
const content =
|
|
154861
|
+
const content = readFileSync27(keybindingsPath, { encoding: "utf-8" });
|
|
154656
154862
|
const keybindings = parseKeybindings2(content);
|
|
154657
154863
|
if (!keybindings) {
|
|
154658
154864
|
return {
|
|
@@ -154663,7 +154869,7 @@ function removeKeybinding2(keybindingsPath) {
|
|
|
154663
154869
|
const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
|
|
154664
154870
|
const newContent = `${JSON.stringify(filtered, null, 2)}
|
|
154665
154871
|
`;
|
|
154666
|
-
|
|
154872
|
+
writeFileSync25(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
154667
154873
|
return { success: true };
|
|
154668
154874
|
} catch (error) {
|
|
154669
154875
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -154717,19 +154923,19 @@ function getWezTermConfigPath2() {
|
|
|
154717
154923
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
154718
154924
|
if (xdgConfig) {
|
|
154719
154925
|
const xdgPath = join52(xdgConfig, "wezterm", "wezterm.lua");
|
|
154720
|
-
if (
|
|
154926
|
+
if (existsSync44(xdgPath))
|
|
154721
154927
|
return xdgPath;
|
|
154722
154928
|
}
|
|
154723
154929
|
const configPath = join52(homedir39(), ".config", "wezterm", "wezterm.lua");
|
|
154724
|
-
if (
|
|
154930
|
+
if (existsSync44(configPath))
|
|
154725
154931
|
return configPath;
|
|
154726
154932
|
return join52(homedir39(), ".wezterm.lua");
|
|
154727
154933
|
}
|
|
154728
154934
|
function wezTermDeleteFixExists2(configPath) {
|
|
154729
|
-
if (!
|
|
154935
|
+
if (!existsSync44(configPath))
|
|
154730
154936
|
return false;
|
|
154731
154937
|
try {
|
|
154732
|
-
const content =
|
|
154938
|
+
const content = readFileSync27(configPath, { encoding: "utf-8" });
|
|
154733
154939
|
return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
|
|
154734
154940
|
} catch {
|
|
154735
154941
|
return false;
|
|
@@ -154743,10 +154949,10 @@ function installWezTermDeleteFix2() {
|
|
|
154743
154949
|
}
|
|
154744
154950
|
let content = "";
|
|
154745
154951
|
let backupPath = null;
|
|
154746
|
-
if (
|
|
154952
|
+
if (existsSync44(configPath)) {
|
|
154747
154953
|
backupPath = `${configPath}.letta-backup`;
|
|
154748
154954
|
copyFileSync2(configPath, backupPath);
|
|
154749
|
-
content =
|
|
154955
|
+
content = readFileSync27(configPath, { encoding: "utf-8" });
|
|
154750
154956
|
}
|
|
154751
154957
|
if (content.includes("return {") && !content.includes("local config")) {
|
|
154752
154958
|
content = content.replace(/return\s*\{/, "local config = {");
|
|
@@ -154772,11 +154978,11 @@ return config`);
|
|
|
154772
154978
|
${WEZTERM_DELETE_FIX2}
|
|
154773
154979
|
`;
|
|
154774
154980
|
}
|
|
154775
|
-
const parentDir =
|
|
154776
|
-
if (!
|
|
154777
|
-
|
|
154981
|
+
const parentDir = dirname20(configPath);
|
|
154982
|
+
if (!existsSync44(parentDir)) {
|
|
154983
|
+
mkdirSync30(parentDir, { recursive: true });
|
|
154778
154984
|
}
|
|
154779
|
-
|
|
154985
|
+
writeFileSync25(configPath, content, { encoding: "utf-8" });
|
|
154780
154986
|
return {
|
|
154781
154987
|
success: true,
|
|
154782
154988
|
backupPath: backupPath ?? undefined
|
|
@@ -155342,7 +155548,7 @@ __export(exports_import2, {
|
|
|
155342
155548
|
});
|
|
155343
155549
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
155344
155550
|
import { chmod as chmod2, mkdir as mkdir11, readFile as readFile18, writeFile as writeFile12 } from "node:fs/promises";
|
|
155345
|
-
import { dirname as
|
|
155551
|
+
import { dirname as dirname21, resolve as resolve33 } from "node:path";
|
|
155346
155552
|
async function importAgentFromFile2(options) {
|
|
155347
155553
|
const client = await getClient();
|
|
155348
155554
|
const resolvedPath = resolve33(options.filePath);
|
|
@@ -155401,7 +155607,7 @@ async function writeSkillFiles2(skillDir, files) {
|
|
|
155401
155607
|
}
|
|
155402
155608
|
async function writeSkillFile2(skillDir, filePath, content) {
|
|
155403
155609
|
const fullPath = resolve33(skillDir, filePath);
|
|
155404
|
-
await mkdir11(
|
|
155610
|
+
await mkdir11(dirname21(fullPath), { recursive: true });
|
|
155405
155611
|
await writeFile12(fullPath, content, "utf-8");
|
|
155406
155612
|
const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
|
|
155407
155613
|
if (isScript) {
|
|
@@ -155510,7 +155716,7 @@ __export(exports_memoryFilesystem2, {
|
|
|
155510
155716
|
MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR2,
|
|
155511
155717
|
MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR2
|
|
155512
155718
|
});
|
|
155513
|
-
import { existsSync as
|
|
155719
|
+
import { existsSync as existsSync45, mkdirSync as mkdirSync31 } from "node:fs";
|
|
155514
155720
|
import { homedir as homedir41 } from "node:os";
|
|
155515
155721
|
import { join as join54 } from "node:path";
|
|
155516
155722
|
function getMemoryFilesystemRoot2(agentId, homeDir = homedir41()) {
|
|
@@ -155522,11 +155728,11 @@ function getMemorySystemDir2(agentId, homeDir = homedir41()) {
|
|
|
155522
155728
|
function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir41()) {
|
|
155523
155729
|
const root = getMemoryFilesystemRoot2(agentId, homeDir);
|
|
155524
155730
|
const systemDir = getMemorySystemDir2(agentId, homeDir);
|
|
155525
|
-
if (!
|
|
155526
|
-
|
|
155731
|
+
if (!existsSync45(root)) {
|
|
155732
|
+
mkdirSync31(root, { recursive: true });
|
|
155527
155733
|
}
|
|
155528
|
-
if (!
|
|
155529
|
-
|
|
155734
|
+
if (!existsSync45(systemDir)) {
|
|
155735
|
+
mkdirSync31(systemDir, { recursive: true });
|
|
155530
155736
|
}
|
|
155531
155737
|
}
|
|
155532
155738
|
async function isMemfsEnabledOnServer2(agentId) {
|
|
@@ -160180,8 +160386,8 @@ import { parseArgs as parseArgs7 } from "node:util";
|
|
|
160180
160386
|
// src/websocket/listen-log.ts
|
|
160181
160387
|
import {
|
|
160182
160388
|
appendFileSync as appendFileSync2,
|
|
160183
|
-
existsSync as
|
|
160184
|
-
mkdirSync as
|
|
160389
|
+
existsSync as existsSync24,
|
|
160390
|
+
mkdirSync as mkdirSync18,
|
|
160185
160391
|
readdirSync as readdirSync7,
|
|
160186
160392
|
unlinkSync as unlinkSync6
|
|
160187
160393
|
} from "node:fs";
|
|
@@ -160199,7 +160405,7 @@ function formatTimestamp2() {
|
|
|
160199
160405
|
}
|
|
160200
160406
|
function pruneOldLogs() {
|
|
160201
160407
|
try {
|
|
160202
|
-
if (!
|
|
160408
|
+
if (!existsSync24(REMOTE_LOG_DIR))
|
|
160203
160409
|
return;
|
|
160204
160410
|
const files = readdirSync7(REMOTE_LOG_DIR).filter((f) => f.endsWith(".log")).sort();
|
|
160205
160411
|
if (files.length >= MAX_LOG_FILES) {
|
|
@@ -160246,8 +160452,8 @@ class RemoteSessionLog {
|
|
|
160246
160452
|
if (this.dirCreated)
|
|
160247
160453
|
return;
|
|
160248
160454
|
try {
|
|
160249
|
-
if (!
|
|
160250
|
-
|
|
160455
|
+
if (!existsSync24(REMOTE_LOG_DIR)) {
|
|
160456
|
+
mkdirSync18(REMOTE_LOG_DIR, { recursive: true });
|
|
160251
160457
|
}
|
|
160252
160458
|
this.dirCreated = true;
|
|
160253
160459
|
} catch {}
|
|
@@ -160748,7 +160954,7 @@ async function runListenSubcommand(argv) {
|
|
|
160748
160954
|
|
|
160749
160955
|
// src/cli/subcommands/memfs.ts
|
|
160750
160956
|
init_memoryGit();
|
|
160751
|
-
import { cpSync, existsSync as
|
|
160957
|
+
import { cpSync, existsSync as existsSync27, mkdirSync as mkdirSync20, rmSync as rmSync3, statSync as statSync8 } from "node:fs";
|
|
160752
160958
|
import { readdir as readdir7 } from "node:fs/promises";
|
|
160753
160959
|
import { homedir as homedir24 } from "node:os";
|
|
160754
160960
|
import { join as join31 } from "node:path";
|
|
@@ -160813,7 +161019,7 @@ function formatBackupTimestamp(date = new Date) {
|
|
|
160813
161019
|
}
|
|
160814
161020
|
async function listBackups(agentId) {
|
|
160815
161021
|
const agentRoot = getAgentRoot(agentId);
|
|
160816
|
-
if (!
|
|
161022
|
+
if (!existsSync27(agentRoot)) {
|
|
160817
161023
|
return [];
|
|
160818
161024
|
}
|
|
160819
161025
|
const entries = await readdir7(agentRoot, { withFileTypes: true });
|
|
@@ -160900,14 +161106,14 @@ async function runMemfsSubcommand(argv) {
|
|
|
160900
161106
|
}
|
|
160901
161107
|
if (action === "backup") {
|
|
160902
161108
|
const root = getMemoryRoot(agentId);
|
|
160903
|
-
if (!
|
|
161109
|
+
if (!existsSync27(root)) {
|
|
160904
161110
|
console.error(`Memory directory not found for agent ${agentId}.`);
|
|
160905
161111
|
return 1;
|
|
160906
161112
|
}
|
|
160907
161113
|
const agentRoot = getAgentRoot(agentId);
|
|
160908
161114
|
const backupName = `memory-backup-${formatBackupTimestamp()}`;
|
|
160909
161115
|
const backupPath = join31(agentRoot, backupName);
|
|
160910
|
-
if (
|
|
161116
|
+
if (existsSync27(backupPath)) {
|
|
160911
161117
|
console.error(`Backup already exists at ${backupPath}`);
|
|
160912
161118
|
return 1;
|
|
160913
161119
|
}
|
|
@@ -160931,7 +161137,7 @@ async function runMemfsSubcommand(argv) {
|
|
|
160931
161137
|
return 1;
|
|
160932
161138
|
}
|
|
160933
161139
|
const backupPath = resolveBackupPath(agentId, from);
|
|
160934
|
-
if (!
|
|
161140
|
+
if (!existsSync27(backupPath)) {
|
|
160935
161141
|
console.error(`Backup not found: ${backupPath}`);
|
|
160936
161142
|
return 1;
|
|
160937
161143
|
}
|
|
@@ -160953,11 +161159,11 @@ async function runMemfsSubcommand(argv) {
|
|
|
160953
161159
|
return 1;
|
|
160954
161160
|
}
|
|
160955
161161
|
const root = getMemoryRoot(agentId);
|
|
160956
|
-
if (!
|
|
161162
|
+
if (!existsSync27(root)) {
|
|
160957
161163
|
console.error(`Memory directory not found for agent ${agentId}.`);
|
|
160958
161164
|
return 1;
|
|
160959
161165
|
}
|
|
160960
|
-
if (
|
|
161166
|
+
if (existsSync27(out)) {
|
|
160961
161167
|
const stat7 = statSync8(out);
|
|
160962
161168
|
if (stat7.isDirectory()) {
|
|
160963
161169
|
const contents = await readdir7(out);
|
|
@@ -160970,7 +161176,7 @@ async function runMemfsSubcommand(argv) {
|
|
|
160970
161176
|
return 1;
|
|
160971
161177
|
}
|
|
160972
161178
|
} else {
|
|
160973
|
-
|
|
161179
|
+
mkdirSync20(out, { recursive: true });
|
|
160974
161180
|
}
|
|
160975
161181
|
cpSync(root, out, { recursive: true });
|
|
160976
161182
|
console.log(JSON.stringify({ exportedFrom: root, exportedTo: out, agentId }, null, 2));
|
|
@@ -163951,9 +164157,9 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
163951
164157
|
}
|
|
163952
164158
|
} else {
|
|
163953
164159
|
const { resolve: resolve34 } = await import("path");
|
|
163954
|
-
const { existsSync:
|
|
164160
|
+
const { existsSync: existsSync46 } = await import("fs");
|
|
163955
164161
|
const resolvedPath = resolve34(fromAfFile);
|
|
163956
|
-
if (!
|
|
164162
|
+
if (!existsSync46(resolvedPath)) {
|
|
163957
164163
|
console.error(`Error: AgentFile not found: ${resolvedPath}`);
|
|
163958
164164
|
process.exit(1);
|
|
163959
164165
|
}
|
|
@@ -164832,4 +165038,4 @@ Error during initialization: ${message}`);
|
|
|
164832
165038
|
}
|
|
164833
165039
|
main();
|
|
164834
165040
|
|
|
164835
|
-
//# debugId=
|
|
165041
|
+
//# debugId=D837155EA6C28D1764756E2164756E21
|