@letta-ai/letta-code 0.34.6 → 0.34.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/letta.js CHANGED
@@ -3930,6 +3930,7 @@ var init_toolset_catalog = __esm(() => {
3930
3930
  "Wake",
3931
3931
  "TaskStop",
3932
3932
  "Skill",
3933
+ "Memory",
3933
3934
  "Workflow",
3934
3935
  "exec_command",
3935
3936
  "write_stdin",
@@ -3964,6 +3965,7 @@ var init_toolset_catalog = __esm(() => {
3964
3965
  "TaskStop",
3965
3966
  "Read",
3966
3967
  "Skill",
3968
+ "Memory",
3967
3969
  "Workflow",
3968
3970
  "Task",
3969
3971
  "SendAgentMessage",
@@ -3990,6 +3992,7 @@ var init_toolset_catalog = __esm(() => {
3990
3992
  "Wake",
3991
3993
  "TaskStop",
3992
3994
  "Skill",
3995
+ "Memory",
3993
3996
  "Workflow",
3994
3997
  "exec_command",
3995
3998
  "write_stdin",
@@ -5724,7 +5727,7 @@ var package_default;
5724
5727
  var init_package = __esm(() => {
5725
5728
  package_default = {
5726
5729
  name: "@letta-ai/letta-code",
5727
- version: "0.34.6",
5730
+ version: "0.34.8",
5728
5731
  lettaStartupLogProtocol: 1,
5729
5732
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5730
5733
  type: "module",
@@ -5999,7 +6002,7 @@ var init_package = __esm(() => {
5999
6002
  },
6000
6003
  lettaLifecycleProtocol: 1,
6001
6004
  lettaRuntimeGraphProtocol: 1,
6002
- lettaRuntimeGraphSha512: "sha512-XLLoGDBuKF5JywIzS03nqOmcuSbwY1oGBwkINW2htdSGxlMnDVGIKq6HZLoE6hDMudNN3mzVIBUhdIYIlj2zzw=="
6005
+ lettaRuntimeGraphSha512: "sha512-NkEBUY1HKUlzrKrw9Z5465jdqkp+u7tLYNly5lGlHQKUAoN/8N4gGSsIXTsc3u2Eiz9f05ryN0l5zJOf1/q1iA=="
6003
6006
  };
6004
6007
  });
6005
6008
 
@@ -120190,6 +120193,226 @@ var init_personality = __esm(() => {
120190
120193
  execFile5 = promisify6(execFileCb3);
120191
120194
  });
120192
120195
 
120196
+ // src/browser-discovery-server.ts
120197
+ import {
120198
+ createServer as createServer3
120199
+ } from "node:http";
120200
+ function startBrowserDiscoveryServer(options = {}) {
120201
+ const port = options.port ?? BROWSER_DISCOVERY_PORT;
120202
+ const retryDelayMs = options.retryDelayMs ?? DEFAULT_RETRY_DELAY_MS;
120203
+ let activeServer = null;
120204
+ let pendingServer = null;
120205
+ let retryTimer = null;
120206
+ let stopped = false;
120207
+ let readySettled = false;
120208
+ let resolveReady;
120209
+ let rejectReady;
120210
+ const ready = new Promise((resolve10, reject) => {
120211
+ resolveReady = resolve10;
120212
+ rejectReady = reject;
120213
+ });
120214
+ ready.catch(() => {
120215
+ return;
120216
+ });
120217
+ const scheduleRetry = () => {
120218
+ if (stopped || retryTimer)
120219
+ return;
120220
+ retryTimer = setTimeout(() => {
120221
+ retryTimer = null;
120222
+ attemptListen();
120223
+ }, retryDelayMs);
120224
+ retryTimer.unref();
120225
+ };
120226
+ const attemptListen = () => {
120227
+ if (stopped || activeServer || pendingServer)
120228
+ return;
120229
+ const candidate = createBrowserDiscoveryHttpServer();
120230
+ pendingServer = candidate;
120231
+ const onStartupError = (error4) => {
120232
+ pendingServer = null;
120233
+ candidate.close();
120234
+ if (error4.code === "EADDRINUSE") {
120235
+ scheduleRetry();
120236
+ return;
120237
+ }
120238
+ if (!readySettled) {
120239
+ readySettled = true;
120240
+ rejectReady(error4);
120241
+ }
120242
+ };
120243
+ candidate.once("error", onStartupError);
120244
+ candidate.listen(port, BROWSER_DISCOVERY_HOST, () => {
120245
+ candidate.off("error", onStartupError);
120246
+ if (stopped) {
120247
+ candidate.close();
120248
+ return;
120249
+ }
120250
+ pendingServer = null;
120251
+ activeServer = candidate;
120252
+ candidate.unref();
120253
+ const address = candidate.address();
120254
+ if (!address || typeof address === "string") {
120255
+ candidate.close();
120256
+ return;
120257
+ }
120258
+ if (!readySettled) {
120259
+ readySettled = true;
120260
+ resolveReady(formatDiscoveryAddress(address));
120261
+ }
120262
+ candidate.on("error", () => {
120263
+ if (activeServer !== candidate)
120264
+ return;
120265
+ activeServer = null;
120266
+ candidate.close();
120267
+ scheduleRetry();
120268
+ });
120269
+ candidate.once("close", () => {
120270
+ if (activeServer === candidate)
120271
+ activeServer = null;
120272
+ scheduleRetry();
120273
+ });
120274
+ });
120275
+ };
120276
+ attemptListen();
120277
+ return {
120278
+ ready,
120279
+ close: async () => {
120280
+ if (stopped)
120281
+ return;
120282
+ stopped = true;
120283
+ if (retryTimer) {
120284
+ clearTimeout(retryTimer);
120285
+ retryTimer = null;
120286
+ }
120287
+ if (!readySettled) {
120288
+ readySettled = true;
120289
+ rejectReady(new Error("Browser discovery server stopped before listening"));
120290
+ }
120291
+ const servers = [pendingServer, activeServer].filter((server2) => server2 !== null);
120292
+ pendingServer = null;
120293
+ activeServer = null;
120294
+ await Promise.all(servers.map(closeServer));
120295
+ }
120296
+ };
120297
+ }
120298
+ function createBrowserDiscoveryHttpServer() {
120299
+ let server2;
120300
+ server2 = createServer3((request, response) => {
120301
+ handleBrowserDiscoveryRequest(server2, request, response);
120302
+ });
120303
+ server2.headersTimeout = 5000;
120304
+ server2.requestTimeout = 5000;
120305
+ server2.keepAliveTimeout = 1000;
120306
+ server2.maxHeadersCount = 32;
120307
+ server2.on("connection", (socket) => socket.unref());
120308
+ server2.on("timeout", (socket) => socket.destroy());
120309
+ server2.on("clientError", (_error, socket) => {
120310
+ if (!socket.writable)
120311
+ return;
120312
+ socket.end(`HTTP/1.1 400 Bad Request\r
120313
+ Connection: close\r
120314
+ Content-Length: 0\r
120315
+ \r
120316
+ `);
120317
+ });
120318
+ return server2;
120319
+ }
120320
+ function handleBrowserDiscoveryRequest(server2, request, response) {
120321
+ if (!isLoopbackAddress(request.socket.remoteAddress)) {
120322
+ respond(response, 403, "Browser connection must use loopback");
120323
+ return;
120324
+ }
120325
+ const address = server2.address();
120326
+ const expectedHost = address && typeof address !== "string" ? `${BROWSER_DISCOVERY_HOST}:${address.port}` : null;
120327
+ if (!expectedHost || request.headers.host !== expectedHost) {
120328
+ respond(response, 400, "Invalid discovery host");
120329
+ return;
120330
+ }
120331
+ if (request.url !== BROWSER_DISCOVERY_PATH) {
120332
+ respond(response, 404, "Not found");
120333
+ return;
120334
+ }
120335
+ const requestOrigin = request.headers.origin;
120336
+ const origin = allowedBrowserOrigin(requestOrigin);
120337
+ if (requestOrigin && !origin) {
120338
+ respond(response, 403, "Browser origin is not allowed");
120339
+ return;
120340
+ }
120341
+ if (request.method === "OPTIONS") {
120342
+ if (!origin || request.headers["access-control-request-method"] !== "GET") {
120343
+ respond(response, 403, "Browser preflight is not allowed");
120344
+ return;
120345
+ }
120346
+ response.writeHead(204, {
120347
+ ...browserAccessHeaders(origin),
120348
+ "Content-Length": "0"
120349
+ });
120350
+ response.end();
120351
+ return;
120352
+ }
120353
+ if (request.method !== "GET") {
120354
+ response.writeHead(405, {
120355
+ ...browserAccessHeaders(origin),
120356
+ Allow: "GET, OPTIONS",
120357
+ "Content-Type": "text/plain; charset=utf-8"
120358
+ });
120359
+ response.end("Method not allowed");
120360
+ return;
120361
+ }
120362
+ response.writeHead(200, {
120363
+ ...browserAccessHeaders(origin),
120364
+ "Content-Length": String(Buffer.byteLength(STATUS_BODY)),
120365
+ "Content-Type": "application/json; charset=utf-8"
120366
+ });
120367
+ response.end(STATUS_BODY);
120368
+ }
120369
+ function allowedBrowserOrigin(value) {
120370
+ if (!value)
120371
+ return;
120372
+ return ALLOWED_BROWSER_ORIGINS.has(value) || LOCAL_BROWSER_ORIGIN.test(value) ? value : undefined;
120373
+ }
120374
+ function isLoopbackAddress(value) {
120375
+ return value === "127.0.0.1" || value === "::ffff:127.0.0.1";
120376
+ }
120377
+ function browserAccessHeaders(origin) {
120378
+ return {
120379
+ "Access-Control-Allow-Methods": "GET, OPTIONS",
120380
+ ...origin ? { "Access-Control-Allow-Origin": origin } : {},
120381
+ "Access-Control-Allow-Private-Network": "true",
120382
+ "Cache-Control": "no-store",
120383
+ Connection: "close",
120384
+ Vary: "Origin, Access-Control-Request-Method, Access-Control-Request-Private-Network"
120385
+ };
120386
+ }
120387
+ function respond(response, statusCode2, body) {
120388
+ response.writeHead(statusCode2, {
120389
+ "Content-Length": String(Buffer.byteLength(body)),
120390
+ "Content-Type": "text/plain; charset=utf-8"
120391
+ });
120392
+ response.end(body);
120393
+ }
120394
+ function formatDiscoveryAddress(address) {
120395
+ return {
120396
+ host: BROWSER_DISCOVERY_HOST,
120397
+ port: address.port,
120398
+ url: `http://${BROWSER_DISCOVERY_HOST}:${address.port}${BROWSER_DISCOVERY_PATH}`
120399
+ };
120400
+ }
120401
+ async function closeServer(server2) {
120402
+ server2.closeAllConnections();
120403
+ if (!server2.listening)
120404
+ return;
120405
+ await new Promise((resolve10) => {
120406
+ server2.close(() => resolve10());
120407
+ });
120408
+ }
120409
+ var BROWSER_DISCOVERY_HOST = "127.0.0.1", BROWSER_DISCOVERY_PORT = 32187, BROWSER_DISCOVERY_PATH = "/status", DEFAULT_RETRY_DELAY_MS = 1000, STATUS_BODY, LOCAL_BROWSER_ORIGIN, ALLOWED_BROWSER_ORIGINS;
120410
+ var init_browser_discovery_server = __esm(() => {
120411
+ STATUS_BODY = JSON.stringify({ status: "ok" });
120412
+ LOCAL_BROWSER_ORIGIN = /^https?:\/\/(?:localhost|127\.0\.0\.1)(?::\d+)?$/;
120413
+ ALLOWED_BROWSER_ORIGINS = new Set(["https://chat.letta.com"]);
120414
+ });
120415
+
120193
120416
  // src/cli/args.ts
120194
120417
  import { parseArgs } from "node:util";
120195
120418
  function formatHelpFlagLabel(flagName, definition) {
@@ -195921,6 +196144,23 @@ Lists files and directories in a given path. The path parameter must be an absol
195921
196144
  If a directory has more than 1,000 entries, only the first 1,000 will be shown.`;
195922
196145
  var init_LS = () => {};
195923
196146
 
196147
+ // src/tools/descriptions/Memory.md
196148
+ var Memory_default = `Read deferred memory from your memory filesystem.
196149
+
196150
+ Your root memory files are already in your system prompt. Everything else is deferred: the <deferred-memory> section lists directories you have not opened. Use this tool to open them progressively instead of guessing what they contain.
196151
+
196152
+ - Memory("projects") returns projects/MEMORY.md, then the files (<memory_files>) and subdirectories (<deferred-memory>) directly beneath it, with their descriptions.
196153
+ - Memory("projects/code") opens a subdirectory the same way.
196154
+ - Memory("projects/example.md") returns that file.
196155
+
196156
+ Entries are listed most recently edited first, up to 10 per directory.
196157
+
196158
+ Paths are relative to your memory directory. Before acting on a person, project, channel, or topic that your memory index points to, open the matching memory rather than working from assumptions. Open one level at a time and only what the task needs.
196159
+
196160
+ Do not use this tool for root memory files (already loaded) or skills/ (use Skill).
196161
+ `;
196162
+ var init_Memory = () => {};
196163
+
195924
196164
  // src/tools/descriptions/Monitor.md
195925
196165
  var Monitor_default = 'Start a background monitor that streams events from a long-running script. Each stdout line is an event — you keep working and notifications arrive in the chat. Events arrive on their own schedule and are not replies from the user, even if one lands while you\'re waiting for the user to answer a question.\n\nPick by how many notifications you need:\n- **One** ("tell me when the server is ready / the build finishes") → use **Bash with `run_in_background`** and a command that exits when the condition is true, e.g. `until grep -q "Ready in" dev.log; do sleep 0.5; done`. You get a single completion notification when it exits.\n- **One per occurrence, indefinitely** ("tell me every time an ERROR line appears") → Monitor with an unbounded command (`tail -f`, `inotifywait -m`, `while true`).\n- **One per occurrence, until a known end** ("emit each CI step result, stop when the run completes") → Monitor with a command that emits lines and then exits.\n\nYour script\'s stdout is the event stream. Each line becomes a notification. Exit ends the watch.\n # Each matching log line is an event\n tail -f /var/log/app.log | grep --line-buffered "ERROR"\n # Each file change is an event\n inotifywait -m --format \'%e %f\' /watched/dir\n # Node script that emits events as they arrive (e.g. WebSocket listener)\n node watch-for-events.js\n\nFor open github.com pull requests, use WatchPR instead. It covers the whole PR surface and keeps watching after CI finishes. Use Monitor only when WatchPR does not apply.\n\n**Don\'t use an unbounded command for a single notification.** `tail -f`, `inotifywait -m`, and `while true` never exit on their own, so the monitor stays armed until timeout even after the event has fired. For "tell me when X is ready," use Bash `run_in_background` with an `until` loop instead (one notification, ends in seconds). Note that `tail -f log | grep -m 1 ...` does *not* fix this: if the log goes quiet after the match, `tail` never receives SIGPIPE and the pipeline hangs anyway.\n\n- Every pipe stage must flush per line or matches sit in its buffer unseen: `grep` needs `--line-buffered`, `awk` needs `fflush()`. `head` cannot flush at all — `| head -N` delivers nothing until N matches accumulate, then ends the stream.\n- In poll loops, handle transient failures (`curl ... || true`) — one failed request shouldn\'t kill the monitor.\n- Poll intervals: 30s+ for remote APIs (rate limits), 0.5–1s for local checks.\n- Write a specific `description` — it appears in every notification ("errors in deploy.log" not "watching logs").\n- Only stdout is the event stream. Stderr goes to the output file (readable via Read) but does not trigger notifications — for a command you run directly (e.g. `python train.py 2>&1 | grep --line-buffered ...`), merge stderr with `2>&1` so its failures reach your filter. (No effect on `tail -f` of an existing log — that file only contains what its writer redirected.)\n\n**Coverage — silence is not success.** When watching a job or process for an outcome, your filter must match every terminal state, not just the happy path. A monitor that greps only for the success marker stays silent through a crashloop, a hung process, or an unexpected exit — and silence looks identical to "still running." Before arming, ask: *if this process crashed right now, would my filter emit anything?* If not, widen it.\n # Wrong — silent on crash, hang, or any non-success exit\n tail -f run.log | grep --line-buffered "elapsed_steps="\n # Right — one alternation covering progress + the failure signatures you\'d act on\n tail -f run.log | grep -E --line-buffered "elapsed_steps=|Traceback|Error|FAILED|assert|Killed|OOM"\n\nFor poll loops checking job state, emit on every terminal status (`succeeded|failed|cancelled|timeout`), not just success. If you cannot confidently enumerate the failure signatures, broaden the grep alternation rather than narrow it — some extra noise is better than missing a crashloop.\n\n**Output volume**: Every stdout line is a conversation message, so the filter should be selective — but selective means "the lines you\'d act on," not "only good news." Never pipe raw logs; filter to exactly the success and failure signals you care about. Monitors that produce too many events are automatically stopped; restart with a tighter filter if this happens.\n\nStdout lines within 200ms are batched into a single notification, so multiline output from a single event groups naturally.\n\nThe script runs in the same shell environment as Bash. Exit ends the watch (exit code is reported). Timeout → killed. Set `persistent: true` for session-length watches (log tails, long-lived event streams) — the monitor runs until you call TaskStop or the session ends. Use TaskStop to cancel early.\n\n**ws source** — open a WebSocket and stream each incoming text frame as an event. No shell, no polling: the server pushes, you get notified.\n ws: {url: \'wss://events.example.com/stream\', protocols: [\'v1\']},\n description: \'deploy events\',\n\nEach text frame becomes one notification (multiline frames stay as one event). Binary frames are reported as `[binary frame, N bytes]` rather than passed through. Socket close ends the watch with the close code surfaced; errors are surfaced before close. Same rate limiting as bash — a firehose will be suppressed and eventually stopped, so subscribe to a filtered feed where one exists.\n\nPrefer this over `command: \'websocat wss://…\'` — it avoids the extra process and line-buffering pitfalls. Use bash when you need to transform or filter frames with shell tools before they become events.\n';
195926
196166
  var init_Monitor = () => {};
@@ -196774,8 +197014,14 @@ function parseUpdateChunk(lines, startIndex, endIndex, allowMissingContext) {
196774
197014
  }
196775
197015
  const oldLines = [];
196776
197016
  const newLines = [];
197017
+ const contextLineIndices = [];
196777
197018
  let isEndOfFile = false;
196778
197019
  let parsedLineCount = 0;
197020
+ const pushContextLine = (text2) => {
197021
+ contextLineIndices.push([oldLines.length, newLines.length]);
197022
+ oldLines.push(text2);
197023
+ newLines.push(text2);
197024
+ };
196779
197025
  while (index < endIndex) {
196780
197026
  const line = lines[index] ?? "";
196781
197027
  if (line === EOF_MARKER) {
@@ -196788,17 +197034,14 @@ function parseUpdateChunk(lines, startIndex, endIndex, allowMissingContext) {
196788
197034
  break;
196789
197035
  }
196790
197036
  if (line.length === 0) {
196791
- oldLines.push("");
196792
- newLines.push("");
197037
+ pushContextLine("");
196793
197038
  parsedLineCount += 1;
196794
197039
  index += 1;
196795
197040
  continue;
196796
197041
  }
196797
197042
  const prefix = line[0];
196798
197043
  if (prefix === " ") {
196799
- const text2 = line.slice(1);
196800
- oldLines.push(text2);
196801
- newLines.push(text2);
197044
+ pushContextLine(line.slice(1));
196802
197045
  parsedLineCount += 1;
196803
197046
  index += 1;
196804
197047
  continue;
@@ -196825,6 +197068,7 @@ function parseUpdateChunk(lines, startIndex, endIndex, allowMissingContext) {
196825
197068
  changeContext,
196826
197069
  oldLines,
196827
197070
  newLines,
197071
+ contextLineIndices,
196828
197072
  isEndOfFile
196829
197073
  },
196830
197074
  nextIndex: index
@@ -196898,18 +197142,41 @@ async function deriveNewContentsFromChunks(absolutePath, filePathForErrors, chun
196898
197142
  const message = error4 instanceof Error ? error4.message : String(error4);
196899
197143
  throw new Error(`Failed to read file to update ${filePathForErrors}: ${message}`);
196900
197144
  }
196901
- const originalLines = originalContents.split(`
196902
- `);
196903
- if (originalLines[originalLines.length - 1] === "") {
196904
- originalLines.pop();
196905
- }
197145
+ const sourceFile = parseSourceFile(originalContents);
197146
+ const originalLines = sourceFile.lines.map((line) => line.text);
196906
197147
  const replacements = computeReplacements(originalLines, filePathForErrors, chunks);
196907
- const newLines = applyReplacements([...originalLines], replacements);
196908
- if (newLines[newLines.length - 1] !== "") {
196909
- newLines.push("");
197148
+ return applyReplacements(sourceFile, replacements).map((line) => `${line.text}${line.ending ?? ""}`).join("");
197149
+ }
197150
+ function parseSourceFile(contents) {
197151
+ const lines = [];
197152
+ let preferredEnding = null;
197153
+ let lineStart = 0;
197154
+ let cursor = 0;
197155
+ while (cursor < contents.length) {
197156
+ const char = contents[cursor];
197157
+ let ending;
197158
+ if (char === "\r") {
197159
+ ending = contents[cursor + 1] === `
197160
+ ` ? `\r
197161
+ ` : "\r";
197162
+ } else if (char === `
197163
+ `) {
197164
+ ending = `
197165
+ `;
197166
+ } else {
197167
+ cursor += 1;
197168
+ continue;
197169
+ }
197170
+ preferredEnding ??= ending;
197171
+ lines.push({ text: contents.slice(lineStart, cursor), ending });
197172
+ cursor += ending.length;
197173
+ lineStart = cursor;
196910
197174
  }
196911
- return newLines.join(`
196912
- `);
197175
+ if (lineStart < contents.length) {
197176
+ lines.push({ text: contents.slice(lineStart), ending: null });
197177
+ }
197178
+ return { lines, preferredEnding: preferredEnding ?? `
197179
+ ` };
196913
197180
  }
196914
197181
  function computeReplacements(originalLines, filePathForErrors, chunks) {
196915
197182
  const replacements = [];
@@ -196923,8 +197190,7 @@ function computeReplacements(originalLines, filePathForErrors, chunks) {
196923
197190
  lineIndex = contextIndex + 1;
196924
197191
  }
196925
197192
  if (chunk2.oldLines.length === 0) {
196926
- const insertionIndex = originalLines[originalLines.length - 1] === "" ? originalLines.length - 1 : originalLines.length;
196927
- replacements.push([insertionIndex, 0, [...chunk2.newLines]]);
197193
+ replacements.push([originalLines.length, 0, [...chunk2.newLines]]);
196928
197194
  continue;
196929
197195
  }
196930
197196
  let pattern4 = [...chunk2.oldLines];
@@ -196942,23 +197208,47 @@ function computeReplacements(originalLines, filePathForErrors, chunks) {
196942
197208
  ${chunk2.oldLines.join(`
196943
197209
  `)}`);
196944
197210
  }
196945
- replacements.push([found, pattern4.length, newSlice]);
197211
+ let oldStart = 0;
197212
+ let newStart = 0;
197213
+ for (const [oldContext, newContext] of chunk2.contextLineIndices) {
197214
+ if (oldContext >= pattern4.length || newContext >= newSlice.length) {
197215
+ break;
197216
+ }
197217
+ if (oldStart !== oldContext || newStart !== newContext) {
197218
+ replacements.push([
197219
+ found + oldStart,
197220
+ oldContext - oldStart,
197221
+ newSlice.slice(newStart, newContext)
197222
+ ]);
197223
+ }
197224
+ oldStart = oldContext + 1;
197225
+ newStart = newContext + 1;
197226
+ }
197227
+ if (oldStart !== pattern4.length || newStart !== newSlice.length) {
197228
+ replacements.push([
197229
+ found + oldStart,
197230
+ pattern4.length - oldStart,
197231
+ newSlice.slice(newStart)
197232
+ ]);
197233
+ }
196946
197234
  lineIndex = found + pattern4.length;
196947
197235
  }
196948
197236
  replacements.sort((left, right) => left[0] - right[0]);
196949
197237
  return replacements;
196950
197238
  }
196951
- function applyReplacements(lines, replacements) {
196952
- for (let i4 = replacements.length - 1;i4 >= 0; i4 -= 1) {
196953
- const [startIndex, oldLength, newSegment] = replacements[i4];
196954
- for (let j2 = 0;j2 < oldLength; j2 += 1) {
196955
- if (startIndex < lines.length) {
196956
- lines.splice(startIndex, 1);
196957
- }
196958
- }
196959
- lines.splice(startIndex, 0, ...newSegment);
196960
- }
196961
- return lines;
197239
+ function applyReplacements({ lines, preferredEnding }, replacements) {
197240
+ const newLines = [];
197241
+ let sourceIndex = 0;
197242
+ for (const [startIndex, oldLength, newSegment] of replacements) {
197243
+ newLines.push(...lines.slice(sourceIndex, startIndex));
197244
+ newLines.push(...newSegment.map((text2) => ({ text: text2, ending: preferredEnding })));
197245
+ sourceIndex = startIndex + oldLength;
197246
+ }
197247
+ newLines.push(...lines.slice(sourceIndex));
197248
+ return newLines.map((line) => ({
197249
+ text: line.text,
197250
+ ending: line.ending ?? preferredEnding
197251
+ }));
196962
197252
  }
196963
197253
  function seekSequence(lines, pattern4, start, eof) {
196964
197254
  if (pattern4.length === 0) {
@@ -196968,7 +197258,7 @@ function seekSequence(lines, pattern4, start, eof) {
196968
197258
  return null;
196969
197259
  }
196970
197260
  const maxStart = lines.length - pattern4.length;
196971
- const searchStart = eof && lines.length >= pattern4.length ? lines.length - pattern4.length : start;
197261
+ const searchStart = eof && lines.length >= pattern4.length ? Math.max(lines.length - pattern4.length, start) : start;
196972
197262
  const tryMatch = (matches3) => {
196973
197263
  for (let index = searchStart;index <= maxStart; index += 1) {
196974
197264
  let ok = true;
@@ -201222,6 +201512,7 @@ var init_truncation = __esm(() => {
201222
201512
  GREP_OUTPUT_CHARS: 1e4,
201223
201513
  GLOB_MAX_FILES: 2000,
201224
201514
  LS_MAX_ENTRIES: 1000,
201515
+ MEMORY_MAX_ENTRIES: 10,
201225
201516
  TOOL_RETURN_MAX_CHARS: 32000
201226
201517
  };
201227
201518
  });
@@ -204618,6 +204909,7 @@ var init_approval_execution = __esm(async () => {
204618
204909
  "Read",
204619
204910
  "ViewImage",
204620
204911
  "Grep",
204912
+ "Memory",
204621
204913
  "Glob",
204622
204914
  "conversation_search",
204623
204915
  "web_search",
@@ -206478,6 +206770,290 @@ var init_tool_name_mapping = __esm(() => {
206478
206770
  };
206479
206771
  });
206480
206772
 
206773
+ // src/tools/impl/memory.ts
206774
+ import { execFileSync as execFileSync9 } from "node:child_process";
206775
+ import {
206776
+ closeSync as closeSync5,
206777
+ existsSync as existsSync39,
206778
+ openSync as openSync5,
206779
+ readdirSync as readdirSync13,
206780
+ readFileSync as readFileSync32,
206781
+ readSync as readSync3,
206782
+ realpathSync as realpathSync6,
206783
+ statSync as statSync14
206784
+ } from "node:fs";
206785
+ import { extname as extname8, join as join51, sep as sep5 } from "node:path";
206786
+ function resolveMemoryToolDirectory(agentId) {
206787
+ try {
206788
+ const id2 = agentId === undefined ? getCurrentAgentId() : agentId;
206789
+ const memoryDir = id2 ? getActiveMemoryDirectory(id2) : undefined;
206790
+ return memoryDir && detectMemoryFormat(memoryDir, false) === "memfs-v2" ? memoryDir : null;
206791
+ } catch {
206792
+ return null;
206793
+ }
206794
+ }
206795
+ function readDescription(path19) {
206796
+ try {
206797
+ const value = parseFrontmatter(readFileSync32(path19, "utf8")).frontmatter.description;
206798
+ return typeof value === "string" ? value.trim() || undefined : undefined;
206799
+ } catch {
206800
+ return;
206801
+ }
206802
+ }
206803
+ function readIndexDescription(path19) {
206804
+ const fromFrontmatter = readDescription(path19);
206805
+ if (fromFrontmatter)
206806
+ return fromFrontmatter;
206807
+ try {
206808
+ const { body: body3 } = parseFrontmatter(readFileSync32(path19, "utf8"));
206809
+ for (const block of body3.split(/\n\s*\n/)) {
206810
+ const text2 = block.trim();
206811
+ if (!text2 || /^(#|[-*+] |\d+\. |\||```|<)/.test(text2))
206812
+ continue;
206813
+ const paragraph = text2.replace(/\s*\n\s*/g, " ").replace(/\[([^\]]+)\]\([^)]*\)/g, "$1");
206814
+ return paragraph.length > 300 ? `${paragraph.slice(0, 297)}...` : paragraph;
206815
+ }
206816
+ } catch {}
206817
+ return;
206818
+ }
206819
+ function isHidden2(name) {
206820
+ return name.startsWith(".");
206821
+ }
206822
+ function findByBasename(dir, name, root2 = dir, found = []) {
206823
+ for (const entry of readdirSync13(dir, { withFileTypes: true })) {
206824
+ if (found.length >= 5)
206825
+ break;
206826
+ if (isHidden2(entry.name) || dir === root2 && entry.name === "skills") {
206827
+ continue;
206828
+ }
206829
+ const path19 = join51(dir, entry.name);
206830
+ if (entry.isDirectory())
206831
+ findByBasename(path19, name, root2, found);
206832
+ else if (entry.isFile() && entry.name === name && dir !== root2) {
206833
+ found.push(path19.slice(root2.length + 1).split(sep5).join("/"));
206834
+ }
206835
+ }
206836
+ return found;
206837
+ }
206838
+ function escapeXmlText2(value) {
206839
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
206840
+ }
206841
+ function descriptionAttr(description) {
206842
+ return description ? ` description="${escapeXmlText2(description).replace(/"/g, "&quot;")}"` : "";
206843
+ }
206844
+ function clampContent(content, fullPath, maxChars) {
206845
+ const lines = content.split(`
206846
+ `);
206847
+ const shown = lines.slice(0, LIMITS.READ_MAX_LINES);
206848
+ let longLines = false;
206849
+ let result2 = shown.map((line) => {
206850
+ if (line.length <= LIMITS.READ_MAX_CHARS_PER_LINE)
206851
+ return line;
206852
+ longLines = true;
206853
+ return `${line.slice(0, LIMITS.READ_MAX_CHARS_PER_LINE)}... [line truncated]`;
206854
+ }).join(`
206855
+ `);
206856
+ const byTotal = result2.length > maxChars;
206857
+ if (byTotal)
206858
+ result2 = truncateByChars(result2, maxChars, "Memory").content;
206859
+ const byLines = shown.length < lines.length;
206860
+ const notices = [];
206861
+ if (byLines) {
206862
+ notices.push(`[File truncated: showing lines 1-${shown.length} of ${lines.length} total lines. Use Read with offset and limit on the full file to read other sections.]`);
206863
+ }
206864
+ if (longLines) {
206865
+ notices.push(`[Some lines exceeded ${LIMITS.READ_MAX_CHARS_PER_LINE.toLocaleString()} characters and were truncated.]`);
206866
+ }
206867
+ if (byTotal) {
206868
+ notices.push("[Use Read with offset and limit on the full file to read it in smaller sections.]");
206869
+ }
206870
+ if (notices.length)
206871
+ notices.push(`[Full file: ${fullPath}]`);
206872
+ return notices.length ? `${result2}
206873
+
206874
+ ${notices.join(`
206875
+
206876
+ `)}` : result2;
206877
+ }
206878
+ function lastEditedByChild(dir, names2) {
206879
+ const edited = new Map;
206880
+ const bump = (name, time) => {
206881
+ if (time > (edited.get(name) ?? 0))
206882
+ edited.set(name, time);
206883
+ };
206884
+ const git = (args) => execFileSync9("git", ["-C", dir, ...args], {
206885
+ encoding: "utf8",
206886
+ timeout: 5000,
206887
+ maxBuffer: 64 * 1024 * 1024,
206888
+ stdio: ["ignore", "pipe", "ignore"]
206889
+ });
206890
+ const walkMtime = (path19, name) => {
206891
+ try {
206892
+ const stat6 = statSync14(path19);
206893
+ if (stat6.isFile())
206894
+ return bump(name, stat6.mtimeMs);
206895
+ if (!stat6.isDirectory())
206896
+ return;
206897
+ for (const entry of readdirSync13(path19, { withFileTypes: true })) {
206898
+ if (!isHidden2(entry.name))
206899
+ walkMtime(join51(path19, entry.name), name);
206900
+ }
206901
+ } catch {}
206902
+ };
206903
+ let dirty;
206904
+ try {
206905
+ let commitTime = 0;
206906
+ for (const line of git([
206907
+ "log",
206908
+ "--format=%x00%ct",
206909
+ "--name-only",
206910
+ "--relative",
206911
+ "--",
206912
+ "."
206913
+ ]).split(`
206914
+ `)) {
206915
+ const child = line.split("/")[0] ?? line;
206916
+ if (line.startsWith("\x00"))
206917
+ commitTime = Number(line.slice(1)) * 1000;
206918
+ else if (line && !edited.has(child))
206919
+ edited.set(child, commitTime);
206920
+ }
206921
+ const prefix = git(["rev-parse", "--show-prefix"]).trim();
206922
+ dirty = git([
206923
+ "status",
206924
+ "--porcelain=v1",
206925
+ "-z",
206926
+ "--untracked-files=all",
206927
+ "--",
206928
+ "."
206929
+ ]).split("\x00").filter((record4) => record4.length > 3).map((record4) => record4.slice(3)).filter((path19) => path19.startsWith(prefix)).map((path19) => path19.slice(prefix.length));
206930
+ } catch {
206931
+ edited.clear();
206932
+ dirty = names2;
206933
+ }
206934
+ for (const path19 of dirty)
206935
+ walkMtime(join51(dir, path19), path19.split("/")[0] ?? path19);
206936
+ return edited;
206937
+ }
206938
+ function renderDirectory(memoryDir, relPath, fullPath) {
206939
+ const entries = readdirSync13(fullPath, { withFileTypes: true }).filter((entry) => !isHidden2(entry.name) && (entry.isDirectory() || entry.isFile() && entry.name !== INDEX));
206940
+ const edited = lastEditedByChild(fullPath, entries.map((entry) => entry.name));
206941
+ const shown = entries.sort((a2, b3) => (edited.get(b3.name) ?? 0) - (edited.get(a2.name) ?? 0) || a2.name.localeCompare(b3.name)).slice(0, LIMITS.MEMORY_MAX_ENTRIES);
206942
+ const fileLines = shown.filter((entry) => entry.isFile()).map((entry) => {
206943
+ const description = extname8(entry.name) === ".md" ? readDescription(join51(fullPath, entry.name)) : undefined;
206944
+ return ` <file${descriptionAttr(description)}>${escapeXmlText2(`${relPath}/${entry.name}`)}</file>`;
206945
+ });
206946
+ const dirLines = shown.filter((entry) => entry.isDirectory()).map((entry) => {
206947
+ const description = readIndexDescription(join51(fullPath, entry.name, INDEX));
206948
+ return ` <directory${descriptionAttr(description)}>${escapeXmlText2(`${relPath}/${entry.name}`)}</directory>`;
206949
+ });
206950
+ const tail2 = [
206951
+ `Memory directory: ${memoryDir}`,
206952
+ "Paths in this memory are relative to the memory directory."
206953
+ ];
206954
+ if (fileLines.length) {
206955
+ tail2.push("", "<memory_files>", ...fileLines, "</memory_files>");
206956
+ }
206957
+ if (dirLines.length) {
206958
+ tail2.push("", "<deferred-memory>", ...dirLines, "</deferred-memory>");
206959
+ }
206960
+ if (entries.length > LIMITS.MEMORY_MAX_ENTRIES) {
206961
+ tail2.push(`[Output truncated: showing ${LIMITS.MEMORY_MAX_ENTRIES.toLocaleString()} of ${entries.length.toLocaleString()} entries.]`, `[Full listing: ${fullPath}]`);
206962
+ }
206963
+ const tailText = tail2.join(`
206964
+ `);
206965
+ const indexPath = join51(fullPath, INDEX);
206966
+ const open4 = `<memory_content path="${escapeXmlText2(relPath).replace(/"/g, "&quot;")}">`;
206967
+ const close = "</memory_content>";
206968
+ let head4;
206969
+ if (existsSync39(indexPath)) {
206970
+ const budget = Math.max(2000, LIMITS.READ_OUTPUT_CHARS - tailText.length - open4.length - close.length - 16);
206971
+ head4 = clampContent(readFileSync32(indexPath, "utf8").trimEnd(), indexPath, budget);
206972
+ } else {
206973
+ head4 = `<note>No ${INDEX} index in this directory.</note>`;
206974
+ }
206975
+ return `${open4}
206976
+ ${head4}
206977
+
206978
+ ${tailText}
206979
+ ${close}`;
206980
+ }
206981
+ function readPrefix(path19, bytes) {
206982
+ const fd = openSync5(path19, "r");
206983
+ try {
206984
+ const buffer = Buffer.alloc(bytes);
206985
+ return buffer.subarray(0, readSync3(fd, buffer, 0, bytes, 0));
206986
+ } finally {
206987
+ closeSync5(fd);
206988
+ }
206989
+ }
206990
+ function renderFile(relPath, fullPath) {
206991
+ const content = readFileSync32(fullPath, "utf8").trimEnd();
206992
+ const open4 = `<memory_content path="${escapeXmlText2(relPath).replace(/"/g, "&quot;")}"${descriptionAttr(readDescription(fullPath))}>`;
206993
+ const close = "</memory_content>";
206994
+ return `${open4}
206995
+ ${clampContent(content, fullPath, LIMITS.READ_OUTPUT_CHARS - open4.length - close.length - 2)}
206996
+ ${close}`;
206997
+ }
206998
+ async function memory2(args) {
206999
+ validateRequiredParams(args, ["path"], "Memory");
207000
+ const memoryDir = resolveMemoryToolDirectory();
207001
+ if (!memoryDir) {
207002
+ throw new Error("Memory() is only available for agents with a MemFS v2 memory directory.");
207003
+ }
207004
+ const raw2 = String(args.path).trim();
207005
+ const relPath = raw2.replace(/\\/g, "/").replace(/^(\.\/)+/, "").replace(/\/+$/, "");
207006
+ if (!relPath || relPath === "." || relPath === INDEX) {
207007
+ throw new Error("The memory root is already in your context. Pass a directory from <deferred-memory>.");
207008
+ }
207009
+ if (raw2.startsWith("/") || /^[A-Za-z]:/.test(raw2)) {
207010
+ throw new Error('Paths are relative to the memory directory, e.g. "projects".');
207011
+ }
207012
+ const segments = relPath.split("/");
207013
+ if (segments.some((s3) => s3 === ".." || s3 === "" || isHidden2(s3))) {
207014
+ throw new Error(`Invalid memory path: ${raw2}`);
207015
+ }
207016
+ if (segments[0] === "skills") {
207017
+ throw new Error(`skills/ is reserved for skills. Use Skill("${segments[1] ?? "<name>"}").`);
207018
+ }
207019
+ const fullPath = join51(memoryDir, ...segments);
207020
+ if (!existsSync39(fullPath)) {
207021
+ const candidates2 = !relPath.endsWith(".md") && existsSync39(`${fullPath}.md`) ? [`${relPath}.md`] : findByBasename(memoryDir, segments[segments.length - 1] ?? relPath);
207022
+ const hint = candidates2.length ? ` Did you mean ${candidates2.join(" or ")}? Paths are relative to the memory directory.` : "";
207023
+ throw new Error(`No memory at ${relPath}.${hint}`);
207024
+ }
207025
+ const realRoot = realpathSync6(memoryDir);
207026
+ const realTarget = realpathSync6(fullPath);
207027
+ if (realTarget !== realRoot && !realTarget.startsWith(realRoot + sep5)) {
207028
+ throw new Error(`Invalid memory path: ${raw2}`);
207029
+ }
207030
+ const stat6 = statSync14(fullPath);
207031
+ if (segments.length === 1 && stat6.isFile()) {
207032
+ throw new Error(`${relPath} is root core memory and is already in your context.`);
207033
+ }
207034
+ if (stat6.isDirectory()) {
207035
+ return { content: renderDirectory(memoryDir, relPath, fullPath) };
207036
+ }
207037
+ if (!stat6.isFile()) {
207038
+ throw new Error(`Not a memory file or directory: ${relPath}`);
207039
+ }
207040
+ if (stat6.size > MAX_FILE_BYTES) {
207041
+ throw new Error(`${relPath} is too large: ${stat6.size} bytes (max ${MAX_FILE_BYTES} bytes).`);
207042
+ }
207043
+ if (readPrefix(fullPath, 8000).includes(0)) {
207044
+ throw new Error(`${relPath} is not a text file. Use Read on ${fullPath} instead.`);
207045
+ }
207046
+ return { content: renderFile(relPath, fullPath) };
207047
+ }
207048
+ var INDEX = "MEMORY.md", MAX_FILE_BYTES;
207049
+ var init_memory5 = __esm(() => {
207050
+ init_context();
207051
+ init_memory_format();
207052
+ init_memory_runtime();
207053
+ init_truncation();
207054
+ MAX_FILE_BYTES = 10 * 1024 * 1024;
207055
+ });
207056
+
206481
207057
  // node_modules/@isaacs/balanced-match/dist/esm/index.js
206482
207058
  var balanced = (a2, b3, str) => {
206483
207059
  const ma = a2 instanceof RegExp ? maybeMatch(a2, str) : a2;
@@ -207799,7 +208375,7 @@ var minimatch = (p2, pattern4, options = {}) => {
207799
208375
  }, qmarksTestNoExtDot = ([$0]) => {
207800
208376
  const len = $0.length;
207801
208377
  return (f4) => f4.length === len && f4 !== "." && f4 !== "..";
207802
- }, defaultPlatform, path19, sep5, GLOBSTAR, qmark2 = "[^/]", star2, twoStarDot = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?", twoStarNoDot = "(?:(?!(?:\\/|^)\\.).)*?", filter2 = (pattern4, options = {}) => (p2) => minimatch(p2, pattern4, options), ext = (a2, b3 = {}) => Object.assign({}, a2, b3), defaults5 = (def) => {
208378
+ }, defaultPlatform, path19, sep6, GLOBSTAR, qmark2 = "[^/]", star2, twoStarDot = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?", twoStarNoDot = "(?:(?!(?:\\/|^)\\.).)*?", filter2 = (pattern4, options = {}) => (p2) => minimatch(p2, pattern4, options), ext = (a2, b3 = {}) => Object.assign({}, a2, b3), defaults5 = (def) => {
207803
208379
  if (!def || typeof def !== "object" || !Object.keys(def).length) {
207804
208380
  return minimatch;
207805
208381
  }
@@ -207861,8 +208437,8 @@ var init_esm3 = __esm(() => {
207861
208437
  win32: { sep: "\\" },
207862
208438
  posix: { sep: "/" }
207863
208439
  };
207864
- sep5 = defaultPlatform === "win32" ? path19.win32.sep : path19.posix.sep;
207865
- minimatch.sep = sep5;
208440
+ sep6 = defaultPlatform === "win32" ? path19.win32.sep : path19.posix.sep;
208441
+ minimatch.sep = sep6;
207866
208442
  GLOBSTAR = Symbol("globstar **");
207867
208443
  minimatch.GLOBSTAR = GLOBSTAR;
207868
208444
  star2 = qmark2 + "*?";
@@ -209753,6 +210329,16 @@ function checkPermissionForEngine(engine4, toolName2, toolArgs, permissions, wor
209753
210329
  trace
209754
210330
  };
209755
210331
  }
210332
+ if (toolName2 === "Memory" && !isStrictMode) {
210333
+ traceEvent(trace, "memory-auto-allow", "Memory tool is always allowed");
210334
+ return {
210335
+ result: {
210336
+ decision: "allow",
210337
+ reason: "Memory tool is always allowed (reads own memory)"
210338
+ },
210339
+ trace
210340
+ };
210341
+ }
209756
210342
  if (!isStrictMode && isShellToolName(canonicalTool)) {
209757
210343
  const shellCommand = extractShellCommand(toolArgs);
209758
210344
  if (shellCommand && isReadOnlyShellCommand(shellCommand, {
@@ -210068,15 +210654,15 @@ __export(exports_loader, {
210068
210654
  getUserSettingsPaths: () => getUserSettingsPaths
210069
210655
  });
210070
210656
  import { createHash as createHash4 } from "node:crypto";
210071
- import { readFileSync as readFileSync32, statSync as statSync14, watch } from "node:fs";
210657
+ import { readFileSync as readFileSync33, statSync as statSync15, watch } from "node:fs";
210072
210658
  import { homedir as homedir26 } from "node:os";
210073
- import { dirname as dirname21, join as join51, resolve as resolve25 } from "node:path";
210659
+ import { dirname as dirname21, join as join52, resolve as resolve25 } from "node:path";
210074
210660
  function getUserSettingsPaths(options = {}) {
210075
210661
  const homeDir = options.homeDir || homedir26();
210076
- const xdgConfigHome = options.xdgConfigHome || process.env.XDG_CONFIG_HOME || join51(homeDir, ".config");
210662
+ const xdgConfigHome = options.xdgConfigHome || process.env.XDG_CONFIG_HOME || join52(homeDir, ".config");
210077
210663
  return {
210078
- canonical: join51(homeDir, ".letta", "settings.json"),
210079
- legacy: join51(xdgConfigHome, "letta", "settings.json")
210664
+ canonical: join52(homeDir, ".letta", "settings.json"),
210665
+ legacy: join52(xdgConfigHome, "letta", "settings.json")
210080
210666
  };
210081
210667
  }
210082
210668
  function getPermissionSourcePaths(workingDirectory) {
@@ -210084,13 +210670,13 @@ function getPermissionSourcePaths(workingDirectory) {
210084
210670
  return [
210085
210671
  legacyUserSettingsPath,
210086
210672
  userSettingsPath,
210087
- join51(workingDirectory, ".letta", "settings.json"),
210088
- join51(workingDirectory, ".letta", "settings.local.json")
210673
+ join52(workingDirectory, ".letta", "settings.json"),
210674
+ join52(workingDirectory, ".letta", "settings.local.json")
210089
210675
  ];
210090
210676
  }
210091
210677
  function getFileSignature(path20) {
210092
210678
  try {
210093
- const stat6 = statSync14(path20);
210679
+ const stat6 = statSync15(path20);
210094
210680
  if (!stat6.isFile()) {
210095
210681
  return { exists: false };
210096
210682
  }
@@ -210098,7 +210684,7 @@ function getFileSignature(path20) {
210098
210684
  exists: true,
210099
210685
  mtimeMs: stat6.mtimeMs,
210100
210686
  size: stat6.size,
210101
- hash: createHash4("sha256").update(readFileSync32(path20)).digest("hex")
210687
+ hash: createHash4("sha256").update(readFileSync33(path20)).digest("hex")
210102
210688
  };
210103
210689
  } catch {
210104
210690
  return { exists: false };
@@ -210279,10 +210865,10 @@ async function savePermissionRule(rule, ruleType, scope, workingDirectory = proc
210279
210865
  settingsPath = getUserSettingsPaths().canonical;
210280
210866
  break;
210281
210867
  case "project":
210282
- settingsPath = join51(normalizedWorkingDirectory, ".letta", "settings.json");
210868
+ settingsPath = join52(normalizedWorkingDirectory, ".letta", "settings.json");
210283
210869
  break;
210284
210870
  case "local":
210285
- settingsPath = join51(normalizedWorkingDirectory, ".letta", "settings.local.json");
210871
+ settingsPath = join52(normalizedWorkingDirectory, ".letta", "settings.local.json");
210286
210872
  break;
210287
210873
  }
210288
210874
  let settings3 = {};
@@ -210309,7 +210895,7 @@ async function savePermissionRule(rule, ruleType, scope, workingDirectory = proc
210309
210895
  }
210310
210896
  }
210311
210897
  async function ensureLocalSettingsIgnored(workingDirectory) {
210312
- const gitignorePath = join51(workingDirectory, ".gitignore");
210898
+ const gitignorePath = join52(workingDirectory, ".gitignore");
210313
210899
  const pattern4 = ".letta/settings.local.json";
210314
210900
  try {
210315
210901
  let content = "";
@@ -211262,19 +211848,19 @@ var init_approval_result_normalization = __esm(() => {
211262
211848
 
211263
211849
  // src/agent/client-skills-watcher.ts
211264
211850
  import {
211265
- existsSync as existsSync39,
211266
- readdirSync as readdirSync13,
211267
- realpathSync as realpathSync6,
211268
- statSync as statSync15,
211851
+ existsSync as existsSync40,
211852
+ readdirSync as readdirSync14,
211853
+ realpathSync as realpathSync7,
211854
+ statSync as statSync16,
211269
211855
  watch as watch2
211270
211856
  } from "node:fs";
211271
- import { dirname as dirname23, relative as relative6, resolve as resolve27, sep as sep6 } from "node:path";
211857
+ import { dirname as dirname23, relative as relative6, resolve as resolve27, sep as sep7 } from "node:path";
211272
211858
  function defaultWatchFunction(path20, options, listener) {
211273
211859
  return watch2(path20, options, listener);
211274
211860
  }
211275
211861
  function isDirectory(path20) {
211276
211862
  try {
211277
- return statSync15(path20).isDirectory();
211863
+ return statSync16(path20).isDirectory();
211278
211864
  } catch {
211279
211865
  return false;
211280
211866
  }
@@ -211293,7 +211879,7 @@ function findNearestExistingDirectory(path20) {
211293
211879
  function collectSymlinkDirectoryTargets(path20, targets, visited2) {
211294
211880
  let realPath;
211295
211881
  try {
211296
- realPath = realpathSync6(path20);
211882
+ realPath = realpathSync7(path20);
211297
211883
  } catch {
211298
211884
  return;
211299
211885
  }
@@ -211302,7 +211888,7 @@ function collectSymlinkDirectoryTargets(path20, targets, visited2) {
211302
211888
  }
211303
211889
  visited2.add(realPath);
211304
211890
  try {
211305
- const entries = readdirSync13(path20, {
211891
+ const entries = readdirSync14(path20, {
211306
211892
  encoding: "utf8",
211307
211893
  withFileTypes: true
211308
211894
  });
@@ -211313,7 +211899,7 @@ function collectSymlinkDirectoryTargets(path20, targets, visited2) {
211313
211899
  continue;
211314
211900
  }
211315
211901
  try {
211316
- targets.add(realpathSync6(entryPath));
211902
+ targets.add(realpathSync7(entryPath));
211317
211903
  } catch {
211318
211904
  continue;
211319
211905
  }
@@ -211362,13 +211948,13 @@ class ClientSkillsWatcher {
211362
211948
  const watchPaths = new Set;
211363
211949
  let recursive = false;
211364
211950
  let awaitedChild = null;
211365
- if (existsSync39(root2)) {
211951
+ if (existsSync40(root2)) {
211366
211952
  recursive = true;
211367
211953
  watchPaths.add(root2);
211368
211954
  collectSymlinkDirectoryTargets(root2, watchPaths, new Set);
211369
211955
  } else {
211370
211956
  watchPaths.add(existingDirectory);
211371
- awaitedChild = relative6(existingDirectory, root2).split(sep6)[0] ?? null;
211957
+ awaitedChild = relative6(existingDirectory, root2).split(sep7)[0] ?? null;
211372
211958
  }
211373
211959
  const watchers2 = [];
211374
211960
  const invalidate = () => {
@@ -211415,16 +212001,16 @@ __export(exports_skills2, {
211415
212001
  PROJECT_SKILLS_DIR: () => PROJECT_SKILLS_DIR,
211416
212002
  GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR
211417
212003
  });
211418
- import { existsSync as existsSync40 } from "node:fs";
212004
+ import { existsSync as existsSync41 } from "node:fs";
211419
212005
  import { readdir as readdir4, readFile as readFile12, realpath as realpath3, stat as stat6 } from "node:fs/promises";
211420
- import { dirname as dirname24, join as join52 } from "node:path";
212006
+ import { dirname as dirname24, join as join53 } from "node:path";
211421
212007
  import { fileURLToPath as fileURLToPath6 } from "node:url";
211422
212008
  function getBundledSkillsPath() {
211423
212009
  const thisDir = dirname24(fileURLToPath6(import.meta.url));
211424
212010
  if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
211425
- return join52(thisDir, "../skills/builtin");
212011
+ return join53(thisDir, "../skills/builtin");
211426
212012
  }
211427
- return join52(thisDir, "skills");
212013
+ return join53(thisDir, "skills");
211428
212014
  }
211429
212015
  function compareSkills(a2, b3) {
211430
212016
  return a2.id.localeCompare(b3.id) || a2.source.localeCompare(b3.source) || a2.path.localeCompare(b3.path);
@@ -211471,7 +212057,7 @@ function isSkillAvailableForAgent(skill, agentId) {
211471
212057
  return true;
211472
212058
  }
211473
212059
  function getAgentSkillsDir(agentId) {
211474
- return join52(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "memory/skills");
212060
+ return join53(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "memory/skills");
211475
212061
  }
211476
212062
  async function getBundledSkills() {
211477
212063
  const bundledPath = getBundledSkillsPath();
@@ -211480,7 +212066,7 @@ async function getBundledSkills() {
211480
212066
  }
211481
212067
  async function discoverSkillsFromDir(skillsPath, source) {
211482
212068
  const errors4 = [];
211483
- if (!existsSync40(skillsPath)) {
212069
+ if (!existsSync41(skillsPath)) {
211484
212070
  return { skills: [], errors: [] };
211485
212071
  }
211486
212072
  const skills = [];
@@ -211494,7 +212080,7 @@ async function discoverSkillsFromDir(skillsPath, source) {
211494
212080
  }
211495
212081
  return { skills, errors: errors4 };
211496
212082
  }
211497
- async function discoverSkills(projectSkillsPath = join52(process.cwd(), SKILLS_DIR), agentId, options) {
212083
+ async function discoverSkills(projectSkillsPath = join53(process.cwd(), SKILLS_DIR), agentId, options) {
211498
212084
  const allErrors = [];
211499
212085
  const skillsById = new Map;
211500
212086
  const sourceSet = new Set(options?.sources ?? ALL_SKILL_SOURCES);
@@ -211549,7 +212135,7 @@ async function findSkillFiles(currentPath, rootPath, skills, errors4, source, vi
211549
212135
  try {
211550
212136
  const entries = await readdir4(currentPath, { withFileTypes: true });
211551
212137
  for (const entry of entries) {
211552
- const fullPath = join52(currentPath, entry.name);
212138
+ const fullPath = join53(currentPath, entry.name);
211553
212139
  try {
211554
212140
  let isDirectory2 = entry.isDirectory();
211555
212141
  let isFile = entry.isFile();
@@ -211645,13 +212231,13 @@ var init_skills5 = __esm(() => {
211645
212231
  "managing-shared-memory",
211646
212232
  "working-across-computers"
211647
212233
  ]);
211648
- PROJECT_SKILLS_DIR = join52(".agents", "skills");
211649
- GLOBAL_SKILLS_DIR = join52(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
212234
+ PROJECT_SKILLS_DIR = join53(".agents", "skills");
212235
+ GLOBAL_SKILLS_DIR = join53(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
211650
212236
  });
211651
212237
 
211652
212238
  // src/agent/shared-memory-skills.ts
211653
- import { existsSync as existsSync41 } from "node:fs";
211654
- import { dirname as dirname25, join as join53 } from "node:path";
212239
+ import { existsSync as existsSync42 } from "node:fs";
212240
+ import { dirname as dirname25, join as join54 } from "node:path";
211655
212241
  function getAttachedRepositoriesCache() {
211656
212242
  const global2 = globalThis;
211657
212243
  if (!global2[ATTACHED_REPOSITORIES_CACHE_KEY]) {
@@ -211726,7 +212312,7 @@ async function resolveSharedMemorySkillsContext(options) {
211726
212312
  for (const repository of repositories.sort((a2, b3) => a2.name.localeCompare(b3.name) || a2.id.localeCompare(b3.id))) {
211727
212313
  try {
211728
212314
  const repositoryName = validateAgentRepositoryName2(repository.name);
211729
- skillsDirs.push(join53(getRepositoryMountDir2(agentId, repositoryName), "skills"));
212315
+ skillsDirs.push(join54(getRepositoryMountDir2(agentId, repositoryName), "skills"));
211730
212316
  } catch (error4) {
211731
212317
  errors4.push({
211732
212318
  path: `shared-memory:${repository.name}`,
@@ -211743,7 +212329,7 @@ async function discoverSharedMemorySkills(skillsDirs) {
211743
212329
  const repositoryMount = dirname25(dir);
211744
212330
  if (isCheckoutPending(repositoryMount))
211745
212331
  continue;
211746
- if (!existsSync41(repositoryMount)) {
212332
+ if (!existsSync42(repositoryMount)) {
211747
212333
  errors4.push({
211748
212334
  path: repositoryMount,
211749
212335
  message: "Attached repository is not mounted locally"
@@ -211789,8 +212375,8 @@ __export(exports_client_skills, {
211789
212375
  buildClientSkillsUpdateReminder: () => buildClientSkillsUpdateReminder,
211790
212376
  buildClientSkillsPayload: () => buildClientSkillsPayload
211791
212377
  });
211792
- import { existsSync as existsSync42 } from "node:fs";
211793
- import { join as join54, resolve as resolve28 } from "node:path";
212378
+ import { existsSync as existsSync43 } from "node:fs";
212379
+ import { join as join55, resolve as resolve28 } from "node:path";
211794
212380
  function getCache2() {
211795
212381
  const global2 = globalThis;
211796
212382
  if (!global2[CLIENT_SKILLS_CACHE_KEY]) {
@@ -211917,12 +212503,12 @@ function buildClientSkillsUpdateReminder(previous, current) {
211917
212503
  function getMemorySkillsDirs(agentId) {
211918
212504
  const dirs = new Set;
211919
212505
  const scopedMemoryDir = resolveScopedMemoryDir({ agentId });
211920
- if (scopedMemoryDir && scopedMemoryDir.trim().length > 0 && existsSync42(scopedMemoryDir)) {
211921
- dirs.add(join54(scopedMemoryDir.trim(), "skills"));
212506
+ if (scopedMemoryDir && scopedMemoryDir.trim().length > 0 && existsSync43(scopedMemoryDir)) {
212507
+ dirs.add(join55(scopedMemoryDir.trim(), "skills"));
211922
212508
  } else {
211923
212509
  const fallbackMemoryDir = (process.env.LETTA_MEMORY_DIR || process.env.MEMORY_DIR || "").trim();
211924
212510
  if (fallbackMemoryDir) {
211925
- dirs.add(join54(fallbackMemoryDir, "skills"));
212511
+ dirs.add(join55(fallbackMemoryDir, "skills"));
211926
212512
  }
211927
212513
  }
211928
212514
  return Array.from(dirs);
@@ -211964,8 +212550,8 @@ function toClientSkill(skill) {
211964
212550
  function resolveSkillDiscoveryContext(options) {
211965
212551
  const workingDirectory = options.workingDirectory ?? process.cwd();
211966
212552
  const configuredSkillsDirectory = options.skillsDirectory ?? getSkillsDirectory();
211967
- const legacySkillsDirectory = join54(workingDirectory, SKILLS_DIR);
211968
- const primaryProjectSkillsDirectory = join54(workingDirectory, PROJECT_SKILLS_DIR);
212553
+ const legacySkillsDirectory = join55(workingDirectory, SKILLS_DIR);
212554
+ const primaryProjectSkillsDirectory = join55(workingDirectory, PROJECT_SKILLS_DIR);
211969
212555
  const skillSources = options.skillSources ?? getSkillSources();
211970
212556
  return {
211971
212557
  workingDirectory,
@@ -212593,6 +213179,14 @@ function filterToolRegistryByClientAllowlist(registry3, clientToolAllowlist) {
212593
213179
  const allowSet = new Set(clientToolAllowlist);
212594
213180
  return new Map(Array.from(registry3.entries()).filter(([internalName]) => matchesClientToolAllowlistEntry(allowSet, getServerToolName(internalName), internalName)));
212595
213181
  }
213182
+ function filterMemoryToolByMemoryFormat(registry3, agentId) {
213183
+ if (!registry3.has("Memory") || resolveMemoryToolDirectory(agentId)) {
213184
+ return registry3;
213185
+ }
213186
+ const filtered = new Map(registry3);
213187
+ filtered.delete("Memory");
213188
+ return filtered;
213189
+ }
212596
213190
  function filterExternalToolsByRuntimeContext(externalTools, runtimeContext) {
212597
213191
  return new Map(Array.from(externalTools.entries()).filter(([, tool]) => {
212598
213192
  const matchesRuntime = !tool.runtime || (tool.runtime.agentId ?? null) === (runtimeContext.agentId ?? null) && tool.runtime.conversationId === runtimeContext.conversationId;
@@ -212809,7 +213403,7 @@ async function executeExternalTool(toolCallId, toolName2, input, executorOverrid
212809
213403
  }
212810
213404
  }
212811
213405
  function getClientToolsFromRegistry() {
212812
- return buildClientToolsFromSnapshot(toolRegistry, selectModelFacingExternalTools(filterExternalToolsByRuntimeContext(getExternalToolsRegistry(), {})), getAvailableModToolsRegistry());
213406
+ return buildClientToolsFromSnapshot(filterMemoryToolByMemoryFormat(toolRegistry, undefined), selectModelFacingExternalTools(filterExternalToolsByRuntimeContext(getExternalToolsRegistry(), {})), getAvailableModToolsRegistry());
212813
213407
  }
212814
213408
  function buildClientToolsFromSnapshot(registry3, externalTools, modTools) {
212815
213409
  return serializeClientTools(registry3, externalTools, modTools, getServerToolName);
@@ -212817,7 +213411,7 @@ function buildClientToolsFromSnapshot(registry3, externalTools, modTools) {
212817
213411
  function capturePreparedToolExecutionContext(snapshot2, options) {
212818
213412
  const runtimeContext = buildExecutionRuntimeContextSnapshot(options);
212819
213413
  const clientToolAllowlist = options?.clientToolAllowlist ?? toolFilter.getEnabledTools() ?? undefined;
212820
- const toolRegistrySnapshot = applySubagentToolPolicy(filterToolRegistryByClientAllowlist(snapshot2.toolRegistry, clientToolAllowlist), readSubagentDepth(getRuntimeExecutionEnv(process.env, runtimeContext.executionSettings)));
213414
+ const toolRegistrySnapshot = filterMemoryToolByMemoryFormat(applySubagentToolPolicy(filterToolRegistryByClientAllowlist(snapshot2.toolRegistry, clientToolAllowlist), readSubagentDepth(getRuntimeExecutionEnv(process.env, runtimeContext.executionSettings))), runtimeContext.agentId);
212821
213415
  const executionSnapshot = {
212822
213416
  toolRegistry: toolRegistrySnapshot,
212823
213417
  externalTools: selectModelFacingExternalTools(filterExternalToolsByClientAllowlist(filterExternalToolsByScopeIds(filterExternalToolsByRuntimeContext(snapshot2.externalTools, runtimeContext), options?.externalToolScopeIds), clientToolAllowlist), runtimeContext.connectionId),
@@ -213859,6 +214453,7 @@ var init_manager2 = __esm(async () => {
213859
214453
  init_subagent_tool_policy();
213860
214454
  init_task_tool_assets();
213861
214455
  init_tool_name_mapping();
214456
+ init_memory5();
213862
214457
  init_toolset_catalog();
213863
214458
  await __promiseAll([
213864
214459
  init_approval_execution(),
@@ -217290,7 +217885,7 @@ var init_LS2 = __esm(() => {
217290
217885
 
217291
217886
  // src/tools/impl/ls.ts
217292
217887
  import { readdir as readdir7, stat as stat9 } from "node:fs/promises";
217293
- import { isAbsolute as isAbsolute21, join as join55, resolve as resolve33 } from "node:path";
217888
+ import { isAbsolute as isAbsolute21, join as join56, resolve as resolve33 } from "node:path";
217294
217889
  async function ls(args) {
217295
217890
  validateRequiredParams(args, ["path"], "LS");
217296
217891
  validateParamTypes(args, LS_default2, "LS");
@@ -217301,7 +217896,7 @@ async function ls(args) {
217301
217896
  const items3 = await readdir7(dirPath);
217302
217897
  const filteredItems = items3.filter((item) => !ignore.some((pattern4) => import_picomatch.default.isMatch(item, pattern4)));
217303
217898
  const fileInfos = await Promise.all(filteredItems.map(async (item) => {
217304
- const fullPath = join55(dirPath, item);
217899
+ const fullPath = join56(dirPath, item);
217305
217900
  try {
217306
217901
  const stats = await stat9(fullPath);
217307
217902
  return {
@@ -217523,7 +218118,7 @@ var init_monitor_event_stream = __esm(() => {
217523
218118
  });
217524
218119
 
217525
218120
  // src/tools/impl/monitor.ts
217526
- import { appendFileSync as appendFileSync6, readFileSync as readFileSync33, writeFileSync as writeFileSync25 } from "node:fs";
218121
+ import { appendFileSync as appendFileSync6, readFileSync as readFileSync34, writeFileSync as writeFileSync25 } from "node:fs";
217527
218122
  import { WebSocket as WebSocket4 } from "ws";
217528
218123
  function buildMonitorResult(taskId, timeoutMs, persistent, outputFile) {
217529
218124
  const lifetime = persistent ? "persistent — runs until TaskStop or session end" : `timeout ${timeoutMs}ms`;
@@ -217579,7 +218174,7 @@ class MonitorOutputWriter {
217579
218174
  [output truncated at ${MONITOR_OUTPUT_FILE_BYTES} bytes]
217580
218175
  `, "utf8");
217581
218176
  try {
217582
- const content = validUtf8Prefix(Buffer.concat([readFileSync33(this.path), chunk2]), MONITOR_OUTPUT_FILE_BYTES - marker2.length);
218177
+ const content = validUtf8Prefix(Buffer.concat([readFileSync34(this.path), chunk2]), MONITOR_OUTPUT_FILE_BYTES - marker2.length);
217583
218178
  const truncatedOutput = Buffer.concat([content, marker2]);
217584
218179
  writeFileSync25(this.path, truncatedOutput);
217585
218180
  this.bytesWritten = truncatedOutput.length;
@@ -219852,7 +220447,7 @@ class CodexAppServerClient {
219852
220447
  await this.request("initialize", {
219853
220448
  clientInfo: {
219854
220449
  name: "letta-code",
219855
- version: "0.34.6"
220450
+ version: "0.34.8"
219856
220451
  },
219857
220452
  capabilities: null
219858
220453
  });
@@ -221261,7 +221856,7 @@ var init_engine3 = __esm(() => {
221261
221856
 
221262
221857
  // src/tools/impl/native-session-capture.ts
221263
221858
  import { createHash as createHash5, randomUUID as randomUUID32 } from "node:crypto";
221264
- import { readdirSync as readdirSync14, rmSync as rmSync14 } from "node:fs";
221859
+ import { readdirSync as readdirSync15, rmSync as rmSync14 } from "node:fs";
221265
221860
  import {
221266
221861
  mkdtemp as mkdtemp4,
221267
221862
  open as open4,
@@ -221270,7 +221865,7 @@ import {
221270
221865
  stat as stat10
221271
221866
  } from "node:fs/promises";
221272
221867
  import { homedir as homedir28, tmpdir as tmpdir12 } from "node:os";
221273
- import { join as join56 } from "node:path";
221868
+ import { join as join57 } from "node:path";
221274
221869
  async function hashNativeSessionPrefix(input, size2) {
221275
221870
  const hash3 = createHash5("sha256");
221276
221871
  const buffer = Buffer.allocUnsafe(NATIVE_SESSION_CAPTURE_CHUNK_BYTES);
@@ -221332,7 +221927,7 @@ function scavengeStaleSpoolDirectories() {
221332
221927
  staleSpoolsScavenged = true;
221333
221928
  let entries;
221334
221929
  try {
221335
- entries = readdirSync14(tmpdir12(), { withFileTypes: true });
221930
+ entries = readdirSync15(tmpdir12(), { withFileTypes: true });
221336
221931
  } catch {
221337
221932
  return;
221338
221933
  }
@@ -221355,7 +221950,7 @@ function scavengeStaleSpoolDirectories() {
221355
221950
  }
221356
221951
  }
221357
221952
  if (!ownerIsAlive)
221358
- cleanupSpoolDirectorySync(join56(tmpdir12(), entry.name));
221953
+ cleanupSpoolDirectorySync(join57(tmpdir12(), entry.name));
221359
221954
  }
221360
221955
  }
221361
221956
  function key2(source, sessionId) {
@@ -221508,9 +222103,9 @@ async function findNativeSessionPath(source, sessionId, env6 = process.env) {
221508
222103
  return;
221509
222104
  const home = env6.HOME || homedir28();
221510
222105
  if (source === "claude_code") {
221511
- const projects = join56(env6.CLAUDE_CONFIG_DIR || join56(home, ".claude"), "projects");
222106
+ const projects = join57(env6.CLAUDE_CONFIG_DIR || join57(home, ".claude"), "projects");
221512
222107
  for (const project of await entries(projects, true)) {
221513
- const path29 = join56(projects, project, `${sessionId}.jsonl`);
222108
+ const path29 = join57(projects, project, `${sessionId}.jsonl`);
221514
222109
  try {
221515
222110
  if ((await stat10(path29)).isFile())
221516
222111
  return path29;
@@ -221521,14 +222116,14 @@ async function findNativeSessionPath(source, sessionId, env6 = process.env) {
221521
222116
  }
221522
222117
  return;
221523
222118
  }
221524
- const root2 = join56(env6.CODEX_HOME || join56(home, ".codex"), "sessions");
222119
+ const root2 = join57(env6.CODEX_HOME || join57(home, ".codex"), "sessions");
221525
222120
  for (const year of (await entries(root2, true)).filter((name) => /^\d{4}$/.test(name)))
221526
- for (const month of (await entries(join56(root2, year), true)).filter((name) => /^\d{2}$/.test(name)))
221527
- for (const day of (await entries(join56(root2, year, month), true)).filter((name) => /^\d{2}$/.test(name))) {
221528
- const directory = join56(root2, year, month, day);
222121
+ for (const month of (await entries(join57(root2, year), true)).filter((name) => /^\d{2}$/.test(name)))
222122
+ for (const day of (await entries(join57(root2, year, month), true)).filter((name) => /^\d{2}$/.test(name))) {
222123
+ const directory = join57(root2, year, month, day);
221529
222124
  for (const file of await entries(directory, false))
221530
222125
  if (file.startsWith("rollout-") && file.endsWith(`-${sessionId}.jsonl`))
221531
- return join56(directory, file);
222126
+ return join57(directory, file);
221532
222127
  }
221533
222128
  return;
221534
222129
  }
@@ -221545,9 +222140,9 @@ async function seal(state2, source, sessionId, scope, env6, requestOptions) {
221545
222140
  throw new Error("Native session file disappeared before EOF capture");
221546
222141
  throw error4;
221547
222142
  }
221548
- const directory = await mkdtemp4(join56(tmpdir12(), `letta-native-session-${process.pid}-${captureProcessInstanceId}-`));
222143
+ const directory = await mkdtemp4(join57(tmpdir12(), `letta-native-session-${process.pid}-${captureProcessInstanceId}-`));
221549
222144
  spoolDirectories.add(directory);
221550
- const spoolPath = join56(directory, "segment");
222145
+ const spoolPath = join57(directory, "segment");
221551
222146
  let output;
221552
222147
  let retained = false;
221553
222148
  try {
@@ -221664,7 +222259,7 @@ async function drain(state2, source, sessionId) {
221664
222259
  await spool.close();
221665
222260
  }
221666
222261
  state2.segments.shift();
221667
- const directory = join56(segment.path, "..");
222262
+ const directory = join57(segment.path, "..");
221668
222263
  await cleanupSpoolDirectory(directory);
221669
222264
  }
221670
222265
  }
@@ -221696,7 +222291,7 @@ async function discardRejectedSegment(state2) {
221696
222291
  const segment = state2.segments.shift();
221697
222292
  if (!segment)
221698
222293
  return;
221699
- const directory = join56(segment.path, "..");
222294
+ const directory = join57(segment.path, "..");
221700
222295
  await cleanupSpoolDirectory(directory);
221701
222296
  state2.ackedOffset = segment.end;
221702
222297
  state2.retryDelayMs = INITIAL_DRAIN_RETRY_MS;
@@ -222702,20 +223297,20 @@ var init_recall_subagent_local = () => {};
222702
223297
 
222703
223298
  // src/utils/transcript-paths.ts
222704
223299
  import { homedir as homedir29 } from "node:os";
222705
- import { join as join57 } from "node:path";
223300
+ import { join as join58 } from "node:path";
222706
223301
  function getTranscriptRoot() {
222707
223302
  const envRoot = process.env[TRANSCRIPT_ROOT_ENV]?.trim();
222708
223303
  if (envRoot) {
222709
223304
  return envRoot;
222710
223305
  }
222711
- return join57(homedir29(), ".letta", "transcripts");
223306
+ return join58(homedir29(), ".letta", "transcripts");
222712
223307
  }
222713
223308
  var TRANSCRIPT_ROOT_ENV = "LETTA_TRANSCRIPT_ROOT";
222714
223309
  var init_transcript_paths = () => {};
222715
223310
 
222716
223311
  // src/agent/subagents/sandbox.ts
222717
223312
  import { mkdirSync as mkdirSync30 } from "node:fs";
222718
- import { join as join58 } from "node:path";
223313
+ import { join as join59 } from "node:path";
222719
223314
  function wrapSubagentLauncher(input) {
222720
223315
  const env6 = input.env ?? process.env;
222721
223316
  if (!isFsSandboxEnabled(env6))
@@ -222758,7 +223353,7 @@ function wrapSubagentLauncher(input) {
222758
223353
  if (!wrapped || wrapped.length === 0)
222759
223354
  return null;
222760
223355
  const [command, ...args] = wrapped;
222761
- const scratchRoot = join58(getLettaHomeRoot(), "tmp");
223356
+ const scratchRoot = join59(getLettaHomeRoot(), "tmp");
222762
223357
  mkdirSync30(scratchRoot, { recursive: true });
222763
223358
  return {
222764
223359
  command,
@@ -224065,7 +224660,7 @@ var MEMORY_WORKER_SESSION_ENV = "LETTA_MEMORY_WORKER_SESSION";
224065
224660
 
224066
224661
  // src/agent/subagents/subagent-launcher.ts
224067
224662
  import { homedir as homedir30 } from "node:os";
224068
- import { join as join59 } from "node:path";
224663
+ import { join as join60 } from "node:path";
224069
224664
  function resolveSubagentWorkingDirectory(env6 = process.env, fallbackCwd = getCurrentWorkingDirectory(), options = {}) {
224070
224665
  if (options.subagentType === "reflection" && options.launchProfile === "memory-subagent" && options.memoryScope) {
224071
224666
  return env6.USER_CWD || fallbackCwd;
@@ -224123,9 +224718,9 @@ function resolveMemorySubagentScratchpad(parentProcessEnv, subagentId) {
224123
224718
  return configuredScratchpad;
224124
224719
  }
224125
224720
  const configuredTranscriptRoot = parentProcessEnv[TRANSCRIPT_ROOT_ENV];
224126
- const transcriptRoot = configuredTranscriptRoot?.trim() || join59(parentProcessEnv.HOME?.trim() || homedir30(), ".letta", "transcripts");
224721
+ const transcriptRoot = configuredTranscriptRoot?.trim() || join60(parentProcessEnv.HOME?.trim() || homedir30(), ".letta", "transcripts");
224127
224722
  const scope = subagentId ? encodeURIComponent(subagentId) : crypto.randomUUID();
224128
- return join59(transcriptRoot, "background", scope);
224723
+ return join60(transcriptRoot, "background", scope);
224129
224724
  }
224130
224725
  function composeSubagentChildEnv(options) {
224131
224726
  const {
@@ -224695,7 +225290,7 @@ var init_manager4 = __esm(async () => {
224695
225290
  import { execFile as execFile16 } from "node:child_process";
224696
225291
  import { randomUUID as randomUUID36 } from "node:crypto";
224697
225292
  import { readFile as readFile15, rm as rm9, writeFile as writeFile13 } from "node:fs/promises";
224698
- import { join as join60 } from "node:path";
225293
+ import { join as join61 } from "node:path";
224699
225294
  import { promisify as promisify16 } from "node:util";
224700
225295
  async function readOptional(path29) {
224701
225296
  try {
@@ -224716,7 +225311,7 @@ async function describeMemoryConflict(memoryDir, gitDir) {
224716
225311
  ]);
224717
225312
  head4 = stdout.trim();
224718
225313
  } catch {}
224719
- const heads = await Promise.all(OPERATION_HEADS.map((name) => readOptional(join60(gitDir, name))));
225314
+ const heads = await Promise.all(OPERATION_HEADS.map((name) => readOptional(join61(gitDir, name))));
224720
225315
  return [head4, ...heads].join(`
224721
225316
  `);
224722
225317
  }
@@ -224736,7 +225331,7 @@ ${stdout.trim()}`;
224736
225331
  }
224737
225332
  }
224738
225333
  async function attemptPath(memoryDir) {
224739
- return join60(await getMemoryGitDir(memoryDir), ATTEMPT_FILE);
225334
+ return join61(await getMemoryGitDir(memoryDir), ATTEMPT_FILE);
224740
225335
  }
224741
225336
  async function readAttempt(path29) {
224742
225337
  try {
@@ -224770,7 +225365,7 @@ async function claimMemoryConflictRepair(memoryDir, kind = "conflict") {
224770
225365
  let signature;
224771
225366
  try {
224772
225367
  const gitDir = await getMemoryGitDir(memoryDir);
224773
- path29 = join60(gitDir, ATTEMPT_FILE);
225368
+ path29 = join61(gitDir, ATTEMPT_FILE);
224774
225369
  signature = kind === "invalid" ? await describeInvalidMemoryHistory(memoryDir) : await describeMemoryConflict(memoryDir, gitDir);
224775
225370
  } catch {
224776
225371
  return { status: "claimed", token: token2 };
@@ -224832,7 +225427,7 @@ var init_memory_conflict_repair = __esm(() => {
224832
225427
  // src/agent/subagents/memory-handoff.ts
224833
225428
  import { randomUUID as randomUUID37 } from "node:crypto";
224834
225429
  import { mkdir as mkdir11, rm as rm10, writeFile as writeFile14 } from "node:fs/promises";
224835
- import { join as join61 } from "node:path";
225430
+ import { join as join62 } from "node:path";
224836
225431
  async function withMemoryHandoff(params, run) {
224837
225432
  const handoff = await prepareMemoryHandoff(params);
224838
225433
  try {
@@ -224867,9 +225462,9 @@ async function prepareMemoryHandoff(params) {
224867
225462
  break;
224868
225463
  after2 = cursor;
224869
225464
  }
224870
- const directory = join61(getTranscriptRoot(), params.agentId, "memory-handoffs");
225465
+ const directory = join62(getTranscriptRoot(), params.agentId, "memory-handoffs");
224871
225466
  await mkdir11(directory, { recursive: true, mode: 448 });
224872
- transcriptPath = join61(directory, `${randomUUID37()}.json`);
225467
+ transcriptPath = join62(directory, `${randomUUID37()}.json`);
224873
225468
  await writeFile14(transcriptPath, JSON.stringify(messages, null, 2), {
224874
225469
  mode: 292,
224875
225470
  flag: "wx"
@@ -224932,9 +225527,9 @@ var init_memory_operation = __esm(() => {
224932
225527
  // src/agent/memory-worktree.ts
224933
225528
  import { execFile as execFileCb4 } from "node:child_process";
224934
225529
  import { randomUUID as randomUUID38 } from "node:crypto";
224935
- import { existsSync as existsSync43 } from "node:fs";
225530
+ import { existsSync as existsSync44 } from "node:fs";
224936
225531
  import { mkdir as mkdir12 } from "node:fs/promises";
224937
- import { dirname as dirname26, isAbsolute as isAbsolute23, join as join62, resolve as resolve36 } from "node:path";
225532
+ import { dirname as dirname26, isAbsolute as isAbsolute23, join as join63, resolve as resolve36 } from "node:path";
224938
225533
  import { promisify as promisify17 } from "node:util";
224939
225534
  async function runGit4(cwd2, args) {
224940
225535
  try {
@@ -224994,9 +225589,9 @@ async function buildReflectionMergeMessage(parentMemoryDir, branchName) {
224994
225589
  async function createReflectionMemoryWorktree(options) {
224995
225590
  const parentMemoryDir = resolve36(options.parentMemoryDir);
224996
225591
  const id2 = buildReflectionWorktreeId(options.now);
224997
- const worktreeBaseDir = join62(dirname26(parentMemoryDir), "memory-worktrees");
225592
+ const worktreeBaseDir = join63(dirname26(parentMemoryDir), "memory-worktrees");
224998
225593
  const label = options.label ?? "reflection";
224999
- const worktreeDir = join62(worktreeBaseDir, `${label}-${id2}`);
225594
+ const worktreeDir = join63(worktreeBaseDir, `${label}-${id2}`);
225000
225595
  const branchName = `letta/${label}/${id2}`;
225001
225596
  await mkdir12(worktreeBaseDir, { recursive: true });
225002
225597
  const { stdout: baseHeadOut } = await runGit4(parentMemoryDir, [
@@ -225124,7 +225719,7 @@ async function inspectReflectionMemoryWorktree(worktree) {
225124
225719
  };
225125
225720
  }
225126
225721
  async function cleanupWorktreeAndBranch(parentMemoryDir, worktreeDir, branchName, options = {}) {
225127
- const removedWorktree = existsSync43(worktreeDir);
225722
+ const removedWorktree = existsSync44(worktreeDir);
225128
225723
  if (removedWorktree) {
225129
225724
  await runGit4(parentMemoryDir, [
225130
225725
  "worktree",
@@ -225140,7 +225735,7 @@ async function cleanupWorktreeAndBranch(parentMemoryDir, worktreeDir, branchName
225140
225735
  ]);
225141
225736
  }
225142
225737
  async function finalizeReflectionMemoryWorktreeUnlocked(worktree, options) {
225143
- if (!existsSync43(worktree.worktreeDir) && options.knownNoChanges) {
225738
+ if (!existsSync44(worktree.worktreeDir) && options.knownNoChanges) {
225144
225739
  const branchHead = (await tryRunGit(worktree.parentMemoryDir, [
225145
225740
  "rev-parse",
225146
225741
  "--verify",
@@ -225327,7 +225922,7 @@ async function integrateMemoryWorkerWorktree(worktree, options = {}) {
225327
225922
  await cleanup(true);
225328
225923
  return { status: "no_changes" };
225329
225924
  }
225330
- if (existsSync43(worktree.worktreeDir)) {
225925
+ if (existsSync44(worktree.worktreeDir)) {
225331
225926
  await runGit4(worktree.parentMemoryDir, [
225332
225927
  "worktree",
225333
225928
  "remove",
@@ -226628,9 +227223,9 @@ __export(exports_skill, {
226628
227223
  loadRenderedSkillContent: () => loadRenderedSkillContent,
226629
227224
  getResolvedSkillsDir: () => getResolvedSkillsDir
226630
227225
  });
226631
- import { existsSync as existsSync44, readdirSync as readdirSync15 } from "node:fs";
227226
+ import { existsSync as existsSync45, readdirSync as readdirSync16 } from "node:fs";
226632
227227
  import { readFile as readFile16 } from "node:fs/promises";
226633
- import { dirname as dirname27, join as join63 } from "node:path";
227228
+ import { dirname as dirname27, join as join64 } from "node:path";
226634
227229
  async function readSkillFromRoot(skillsRoot, skillId) {
226635
227230
  const discovery = await discoverSkills(skillsRoot, undefined, {
226636
227231
  sources: ["project"],
@@ -226650,12 +227245,12 @@ async function readSkillFromRoot(skillsRoot, skillId) {
226650
227245
  function getMemorySkillsDirs2(agentId) {
226651
227246
  const dirs = new Set;
226652
227247
  const scopedMemoryDir = resolveScopedMemoryDir({ agentId });
226653
- if (scopedMemoryDir && scopedMemoryDir.trim().length > 0 && existsSync44(scopedMemoryDir)) {
226654
- dirs.add(join63(scopedMemoryDir.trim(), "skills"));
227248
+ if (scopedMemoryDir && scopedMemoryDir.trim().length > 0 && existsSync45(scopedMemoryDir)) {
227249
+ dirs.add(join64(scopedMemoryDir.trim(), "skills"));
226655
227250
  } else {
226656
227251
  const fallbackMemoryDir = (process.env.LETTA_MEMORY_DIR || process.env.MEMORY_DIR || "").trim();
226657
227252
  if (fallbackMemoryDir) {
226658
- dirs.add(join63(fallbackMemoryDir, "skills"));
227253
+ dirs.add(join64(fallbackMemoryDir, "skills"));
226659
227254
  }
226660
227255
  }
226661
227256
  return Array.from(dirs);
@@ -226667,7 +227262,7 @@ function listSkillResources(skillMdPath) {
226667
227262
  function walk3(directory, relativeDirectory) {
226668
227263
  let entries2;
226669
227264
  try {
226670
- entries2 = readdirSync15(directory, { withFileTypes: true });
227265
+ entries2 = readdirSync16(directory, { withFileTypes: true });
226671
227266
  } catch {
226672
227267
  return;
226673
227268
  }
@@ -226681,7 +227276,7 @@ function listSkillResources(skillMdPath) {
226681
227276
  return;
226682
227277
  }
226683
227278
  if (entry.isDirectory()) {
226684
- walk3(join63(directory, entry.name), relativePath);
227279
+ walk3(join64(directory, entry.name), relativePath);
226685
227280
  if (truncated) {
226686
227281
  return;
226687
227282
  }
@@ -226695,7 +227290,7 @@ function listSkillResources(skillMdPath) {
226695
227290
  }
226696
227291
  async function readSkillContent(skillId, skillsDir, agentId, options = {}) {
226697
227292
  const projectSkillsDirs = new Set([
226698
- join63(getCurrentWorkingDirectory(), PROJECT_SKILLS_DIR),
227293
+ join64(getCurrentWorkingDirectory(), PROJECT_SKILLS_DIR),
226699
227294
  skillsDir
226700
227295
  ]);
226701
227296
  for (const projectSkillsDir of projectSkillsDirs) {
@@ -226743,8 +227338,8 @@ async function readSkillContent(skillId, skillsDir, agentId, options = {}) {
226743
227338
  } catch {}
226744
227339
  }
226745
227340
  try {
226746
- const bundledSkillsDir = join63(process.cwd(), "skills", "skills");
226747
- const bundledSkillPath = join63(bundledSkillsDir, skillId, "SKILL.md");
227341
+ const bundledSkillsDir = join64(process.cwd(), "skills", "skills");
227342
+ const bundledSkillPath = join64(bundledSkillsDir, skillId, "SKILL.md");
226748
227343
  const content = await readFile16(bundledSkillPath, "utf-8");
226749
227344
  return { content, path: bundledSkillPath };
226750
227345
  } catch {
@@ -226756,7 +227351,7 @@ async function getResolvedSkillsDir() {
226756
227351
  if (skillsDir) {
226757
227352
  return skillsDir;
226758
227353
  }
226759
- return join63(getCurrentWorkingDirectory(), SKILLS_DIR);
227354
+ return join64(getCurrentWorkingDirectory(), SKILLS_DIR);
226760
227355
  }
226761
227356
  function getResolvedAgentId(args) {
226762
227357
  if (args.parentScope?.agentId) {
@@ -226776,7 +227371,7 @@ function renderSkillContent(skillName, skillContent, skillPath, options = {}) {
226776
227371
  const skillDir = dirname27(skillPath);
226777
227372
  const withSkillDir = skillContent.replace(/<SKILL_DIR>/g, skillDir).replace(/\$\{CLAUDE_SKILL_DIR\}/g, skillDir);
226778
227373
  const resources = listSkillResources(skillPath);
226779
- const resourceLines = resources.paths.map((resourcePath) => ` <file>${escapeXmlText2(resourcePath)}</file>`);
227374
+ const resourceLines = resources.paths.map((resourcePath) => ` <file>${escapeXmlText3(resourcePath)}</file>`);
226780
227375
  if (resources.truncated) {
226781
227376
  resourceLines.push(" <truncated>true</truncated>");
226782
227377
  }
@@ -226796,11 +227391,11 @@ async function loadRenderedSkillContent(skillName, options = {}) {
226796
227391
  const { content: skillContent, path: skillPath } = await readSkillContent(skillName, skillsDir, options.agentId, options);
226797
227392
  return renderSkillContent(skillName, skillContent, skillPath, options);
226798
227393
  }
226799
- function escapeXmlText2(value) {
227394
+ function escapeXmlText3(value) {
226800
227395
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
226801
227396
  }
226802
227397
  function escapeXmlAttribute3(value) {
226803
- return escapeXmlText2(value).replace(/"/g, "&quot;");
227398
+ return escapeXmlText3(value).replace(/"/g, "&quot;");
226804
227399
  }
226805
227400
  function wrapSkillContent(skillName, content) {
226806
227401
  return `<skill_content name="${escapeXmlAttribute3(skillName)}">
@@ -228740,9 +229335,9 @@ function formatWorkflowSummary(stats) {
228740
229335
  // src/tools/workflow/journal.ts
228741
229336
  import { appendFileSync as appendFileSync7, mkdirSync as mkdirSync31, writeFileSync as writeFileSync26 } from "node:fs";
228742
229337
  import { homedir as homedir32 } from "node:os";
228743
- import { join as join64 } from "node:path";
229338
+ import { join as join65 } from "node:path";
228744
229339
  function defaultExecutionsDir() {
228745
- return join64(homedir32(), ".letta", "workflows", "executions");
229340
+ return join65(homedir32(), ".letta", "workflows", "executions");
228746
229341
  }
228747
229342
  function newExecutionId() {
228748
229343
  const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
@@ -228753,17 +229348,17 @@ function newExecutionId() {
228753
229348
  return `wf-${suffix}`;
228754
229349
  }
228755
229350
  function createExecutionDir(executionsDir, executionId, script4, args) {
228756
- const executionDir = join64(executionsDir, executionId);
229351
+ const executionDir = join65(executionsDir, executionId);
228757
229352
  mkdirSync31(executionDir, { recursive: true, mode: DIR_MODE });
228758
- const scriptPath = join64(executionDir, "script.js");
229353
+ const scriptPath = join65(executionDir, "script.js");
228759
229354
  writeFileSync26(scriptPath, script4, { mode: FILE_MODE });
228760
229355
  if (args !== undefined) {
228761
- writeFileSync26(join64(executionDir, "args.json"), JSON.stringify(args, null, 2), { mode: FILE_MODE });
229356
+ writeFileSync26(join65(executionDir, "args.json"), JSON.stringify(args, null, 2), { mode: FILE_MODE });
228762
229357
  }
228763
229358
  return {
228764
229359
  executionDir,
228765
229360
  scriptPath,
228766
- journalPath: join64(executionDir, "journal.jsonl")
229361
+ journalPath: join65(executionDir, "journal.jsonl")
228767
229362
  };
228768
229363
  }
228769
229364
  function appendJournalEntry(journalPath, entry) {
@@ -228873,9 +229468,9 @@ var init_meta3 = __esm(() => {
228873
229468
  });
228874
229469
 
228875
229470
  // src/tools/workflow/sdk-loader.ts
228876
- import { existsSync as existsSync45, readFileSync as readFileSync34 } from "node:fs";
229471
+ import { existsSync as existsSync46, readFileSync as readFileSync35 } from "node:fs";
228877
229472
  import { createRequire as createRequire6 } from "node:module";
228878
- import { dirname as dirname28, join as join65 } from "node:path";
229473
+ import { dirname as dirname28, join as join66 } from "node:path";
228879
229474
  import { fileURLToPath as fileURLToPath7, pathToFileURL as pathToFileURL3 } from "node:url";
228880
229475
  function supportsPublishedResume(version2) {
228881
229476
  if (!version2 || !MIN_RESUME_SDK_VERSION)
@@ -228897,14 +229492,14 @@ function preferRunningCliForSubagents() {
228897
229492
  if (process.env.LETTA_CLI_PATH)
228898
229493
  return;
228899
229494
  const entry = process.argv[1];
228900
- if (entry && /(^|[\\/])letta\.js$/.test(entry) && existsSync45(entry)) {
229495
+ if (entry && /(^|[\\/])letta\.js$/.test(entry) && existsSync46(entry)) {
228901
229496
  process.env.LETTA_CLI_PATH = entry;
228902
229497
  }
228903
229498
  }
228904
229499
  function packageVersion(entry) {
228905
229500
  for (let dir = dirname28(entry);; dir = dirname28(dir)) {
228906
229501
  try {
228907
- const manifest = JSON.parse(readFileSync34(join65(dir, "package.json"), "utf8"));
229502
+ const manifest = JSON.parse(readFileSync35(join66(dir, "package.json"), "utf8"));
228908
229503
  if (manifest.name === SDK_PACKAGE)
228909
229504
  return manifest.version;
228910
229505
  } catch {}
@@ -228914,10 +229509,10 @@ function packageVersion(entry) {
228914
229509
  }
228915
229510
  function packageEntry(packageDir) {
228916
229511
  try {
228917
- const manifest = JSON.parse(readFileSync34(join65(packageDir, "package.json"), "utf8"));
229512
+ const manifest = JSON.parse(readFileSync35(join66(packageDir, "package.json"), "utf8"));
228918
229513
  const root2 = manifest.exports?.["."];
228919
229514
  const entry = typeof root2 === "string" ? root2 : root2?.import ?? root2?.default ?? manifest.main;
228920
- return entry ? join65(packageDir, entry) : null;
229515
+ return entry ? join66(packageDir, entry) : null;
228921
229516
  } catch {
228922
229517
  return null;
228923
229518
  }
@@ -228927,8 +229522,8 @@ function probeInstalledSdkDirs(startDirs) {
228927
229522
  for (const start of startDirs) {
228928
229523
  let dir = start;
228929
229524
  while (true) {
228930
- const candidate = join65(dir, "node_modules", ...SDK_PACKAGE.split("/"));
228931
- if (existsSync45(join65(candidate, "package.json")) && !found.includes(candidate)) {
229525
+ const candidate = join66(dir, "node_modules", ...SDK_PACKAGE.split("/"));
229526
+ if (existsSync46(join66(candidate, "package.json")) && !found.includes(candidate)) {
228932
229527
  found.push(candidate);
228933
229528
  }
228934
229529
  const parent = dirname28(dir);
@@ -228946,7 +229541,7 @@ async function loadAgentSdk() {
228946
229541
  const specifiers = [];
228947
229542
  if (envPath) {
228948
229543
  try {
228949
- const require2 = createRequire6(join65(envPath, "noop.js"));
229544
+ const require2 = createRequire6(join66(envPath, "noop.js"));
228950
229545
  specifiers.push(pathToFileURL3(require2.resolve(envPath)).href);
228951
229546
  } catch {
228952
229547
  specifiers.push(pathToFileURL3(envPath).href);
@@ -228957,7 +229552,7 @@ async function loadAgentSdk() {
228957
229552
  specifiers.push(pathToFileURL3(require2.resolve(SDK_PACKAGE)).href);
228958
229553
  } catch {}
228959
229554
  try {
228960
- const require2 = createRequire6(join65(process.cwd(), "package.json"));
229555
+ const require2 = createRequire6(join66(process.cwd(), "package.json"));
228961
229556
  specifiers.push(pathToFileURL3(require2.resolve(SDK_PACKAGE)).href);
228962
229557
  } catch {
228963
229558
  specifiers.push(SDK_PACKAGE);
@@ -246747,12 +247342,12 @@ var init_mcp_client = __esm(() => {
246747
247342
  init_streamableHttp();
246748
247343
  DEFAULT_CLIENT_INFO = {
246749
247344
  name: "letta-code",
246750
- version: "0.34.6"
247345
+ version: "0.34.8"
246751
247346
  };
246752
247347
  });
246753
247348
 
246754
247349
  // src/mcp-oauth-callback.ts
246755
- import { createServer as createServer3 } from "node:http";
247350
+ import { createServer as createServer4 } from "node:http";
246756
247351
  async function startOAuthCallbackServer2(preferredPort) {
246757
247352
  try {
246758
247353
  return await startOAuthCallbackServerOnPort(preferredPort ?? 0);
@@ -246791,7 +247386,7 @@ async function startOAuthCallbackServerOnPort(port) {
246791
247386
  codePromise.catch(() => {
246792
247387
  return;
246793
247388
  });
246794
- server2 = createServer3((request, response) => {
247389
+ server2 = createServer4((request, response) => {
246795
247390
  if (request.method !== "GET" || !request.url?.startsWith("/") || request.url.startsWith("//") || request.url.includes("\\")) {
246796
247391
  response.writeHead(400, { "Content-Type": "text/plain" });
246797
247392
  response.end("Invalid request target");
@@ -246828,7 +247423,7 @@ async function startOAuthCallbackServerOnPort(port) {
246828
247423
  response.writeHead(400, { "Content-Type": "text/html" });
246829
247424
  reject2?.(new Error(`MCP OAuth authorization failed: ${error5}`));
246830
247425
  response.end(callbackPage("Authorization failed", error5), () => {
246831
- closeServer(true);
247426
+ closeServer2(true);
246832
247427
  });
246833
247428
  return;
246834
247429
  }
@@ -246840,7 +247435,7 @@ async function startOAuthCallbackServerOnPort(port) {
246840
247435
  response.writeHead(200, { "Content-Type": "text/html" });
246841
247436
  settle3?.(code2);
246842
247437
  response.end(callbackPage("Authorization complete", "You can close this tab and return to Letta Code."), () => {
246843
- closeServer(true);
247438
+ closeServer2(true);
246844
247439
  });
246845
247440
  });
246846
247441
  server2.on("clientError", (_error, socket) => {
@@ -246853,7 +247448,7 @@ Content-Length: 0\r
246853
247448
  `);
246854
247449
  });
246855
247450
  let serverClosing = false;
246856
- const closeServer = (force = false) => {
247451
+ const closeServer2 = (force = false) => {
246857
247452
  if (serverClosing)
246858
247453
  return;
246859
247454
  serverClosing = true;
@@ -246873,7 +247468,7 @@ Content-Length: 0\r
246873
247468
  }
246874
247469
  const timeout = setTimeout(() => {
246875
247470
  reject2?.(new Error("Timed out waiting for MCP OAuth authorization"));
246876
- closeServer(true);
247471
+ closeServer2(true);
246877
247472
  }, CALLBACK_TIMEOUT_MS);
246878
247473
  timeout.unref();
246879
247474
  return {
@@ -246884,7 +247479,7 @@ Content-Length: 0\r
246884
247479
  clearTimeout(timeout);
246885
247480
  if (!completed)
246886
247481
  reject2?.(new Error("MCP OAuth flow was cancelled"));
246887
- closeServer(true);
247482
+ closeServer2(true);
246888
247483
  }
246889
247484
  };
246890
247485
  }
@@ -248538,8 +249133,8 @@ var init_mcp = __esm(() => {
248538
249133
  });
248539
249134
 
248540
249135
  // src/tools/impl/workflow.ts
248541
- import { readFileSync as readFileSync35 } from "node:fs";
248542
- import { join as join66, resolve as resolve38 } from "node:path";
249136
+ import { readFileSync as readFileSync36 } from "node:fs";
249137
+ import { join as join67, resolve as resolve38 } from "node:path";
248543
249138
  function isOwningAgentId(value) {
248544
249139
  return value?.startsWith("agent-") === true && !value.startsWith("agent-free:");
248545
249140
  }
@@ -248696,7 +249291,7 @@ function formatCompletionResult(run, executionDir) {
248696
249291
  return [
248697
249292
  payload,
248698
249293
  "",
248699
- `Per-call results: ${join66(executionDir, "journal.jsonl")} — one line per completed agent call with its full return value, plus one per decide() API attempt (retries included) with its model, cost, calibration, and tokens.`,
249294
+ `Per-call results: ${join67(executionDir, "journal.jsonl")} — one line per completed agent call with its full return value, plus one per decide() API attempt (retries included) with its model, cost, calibration, and tokens.`,
248700
249295
  "If the result above is empty or unexpected, read that file BEFORE diagnosing — do not assume agents returned non-empty results."
248701
249296
  ].join(`
248702
249297
  `);
@@ -248705,7 +249300,7 @@ async function workflow(args) {
248705
249300
  let script4 = typeof args.script === "string" ? args.script : undefined;
248706
249301
  if (typeof args.scriptPath === "string" && args.scriptPath) {
248707
249302
  try {
248708
- script4 = readFileSync35(resolve38(getCurrentWorkingDirectory(), args.scriptPath), "utf8");
249303
+ script4 = readFileSync36(resolve38(getCurrentWorkingDirectory(), args.scriptPath), "utf8");
248709
249304
  } catch (error5) {
248710
249305
  return {
248711
249306
  toolReturn: `Cannot read scriptPath ${args.scriptPath}: ${String(error5)}`,
@@ -249357,6 +249952,23 @@ var init_Grep2 = __esm(() => {
249357
249952
  };
249358
249953
  });
249359
249954
 
249955
+ // src/tools/schemas/Memory.json
249956
+ var Memory_default2;
249957
+ var init_Memory2 = __esm(() => {
249958
+ Memory_default2 = {
249959
+ type: "object",
249960
+ properties: {
249961
+ path: {
249962
+ type: "string",
249963
+ description: 'Memory directory or file relative to the memory directory, e.g. "projects", "projects/code", or "projects/example.md".'
249964
+ }
249965
+ },
249966
+ required: ["path"],
249967
+ additionalProperties: false,
249968
+ $schema: "https://json-schema.org/draft/2020-12/schema"
249969
+ };
249970
+ });
249971
+
249360
249972
  // src/tools/schemas/Monitor.json
249361
249973
  var Monitor_default2;
249362
249974
  var init_Monitor2 = __esm(() => {
@@ -249995,6 +250607,7 @@ var init_tool_definitions = __esm(async () => {
249995
250607
  init_Glob();
249996
250608
  init_Grep();
249997
250609
  init_LS();
250610
+ init_Memory();
249998
250611
  init_Monitor();
249999
250612
  init_Read();
250000
250613
  init_ReadArtifactFile();
@@ -250023,6 +250636,7 @@ var init_tool_definitions = __esm(async () => {
250023
250636
  init_glob();
250024
250637
  init_grep();
250025
250638
  init_ls();
250639
+ init_memory5();
250026
250640
  init_skill();
250027
250641
  init_task_create();
250028
250642
  init_task_get();
@@ -250041,6 +250655,7 @@ var init_tool_definitions = __esm(async () => {
250041
250655
  init_Glob2();
250042
250656
  init_Grep2();
250043
250657
  init_LS2();
250658
+ init_Memory2();
250044
250659
  init_Monitor2();
250045
250660
  init_Read2();
250046
250661
  init_ReadArtifactFile2();
@@ -250173,6 +250788,11 @@ ${WINDOWS_UNIFIED_EXEC_GUIDANCE}`;
250173
250788
  description: SetWorkingDirectory_default.trim(),
250174
250789
  impl: set_working_directory
250175
250790
  }),
250791
+ Memory: defineTool({
250792
+ schema: Memory_default2,
250793
+ description: Memory_default.trim(),
250794
+ impl: memory2
250795
+ }),
250176
250796
  Skill: defineTool({
250177
250797
  schema: Skill_default2,
250178
250798
  description: Skill_default.trim(),
@@ -250400,14 +251020,14 @@ var init_interrupted_turn_schema = __esm(async () => {
250400
251020
  // src/websocket/listener/interrupted-turn-storage.ts
250401
251021
  import { createHash as createHash7 } from "node:crypto";
250402
251022
  import {
250403
- closeSync as closeSync5,
251023
+ closeSync as closeSync6,
250404
251024
  fsyncSync as fsyncSync3,
250405
- openSync as openSync5,
251025
+ openSync as openSync6,
250406
251026
  renameSync as renameSync8,
250407
251027
  writeFileSync as writeFileSync27
250408
251028
  } from "node:fs";
250409
251029
  import { homedir as homedir33 } from "node:os";
250410
- import { join as join67 } from "node:path";
251030
+ import { join as join68 } from "node:path";
250411
251031
  function writeInterruptedTurnRecordFile(temporary, destination, directory, record6, syncDirectory) {
250412
251032
  writeFileSync27(temporary, JSON.stringify(record6), {
250413
251033
  mode: 384,
@@ -250419,11 +251039,11 @@ function writeInterruptedTurnRecordFile(temporary, destination, directory, recor
250419
251039
  function fsyncInterruptedTurnDirectory(directory, platform9 = process.platform) {
250420
251040
  if (platform9 === "win32")
250421
251041
  return;
250422
- const fd = openSync5(directory, "r");
251042
+ const fd = openSync6(directory, "r");
250423
251043
  try {
250424
251044
  fsyncSync3(fd);
250425
251045
  } finally {
250426
- closeSync5(fd);
251046
+ closeSync6(fd);
250427
251047
  }
250428
251048
  }
250429
251049
  function defaultInterruptedTurnDirectory() {
@@ -250433,7 +251053,7 @@ function defaultInterruptedTurnDirectory() {
250433
251053
  } catch {
250434
251054
  serverUrl = process.env.LETTA_BASE_URL ?? "uninitialized";
250435
251055
  }
250436
- return join67(homedir33(), ".letta", "listener-state", createHash7("sha256").update(serverUrl).digest("hex").slice(0, 24));
251056
+ return join68(homedir33(), ".letta", "listener-state", createHash7("sha256").update(serverUrl).digest("hex").slice(0, 24));
250437
251057
  }
250438
251058
  var init_interrupted_turn_storage = __esm(() => {
250439
251059
  init_server_url();
@@ -250502,23 +251122,23 @@ function createRecoveryAuthorityGuard(dependencies4) {
250502
251122
  // src/websocket/listener/recovery-lineage-sidecar.ts
250503
251123
  import { createHash as createHash8, randomUUID as randomUUID40 } from "node:crypto";
250504
251124
  import {
250505
- existsSync as existsSync46,
251125
+ existsSync as existsSync47,
250506
251126
  mkdirSync as mkdirSync32,
250507
- readdirSync as readdirSync16,
250508
- readFileSync as readFileSync36,
251127
+ readdirSync as readdirSync17,
251128
+ readFileSync as readFileSync37,
250509
251129
  renameSync as renameSync9,
250510
251130
  rmSync as rmSync17,
250511
- statSync as statSync16,
251131
+ statSync as statSync17,
250512
251132
  writeFileSync as writeFileSync28
250513
251133
  } from "node:fs";
250514
- import { join as join68 } from "node:path";
251134
+ import { join as join69 } from "node:path";
250515
251135
  function createRecoveryLineageSidecarAccess(params) {
250516
251136
  const canonicalSidecarName = /\.json\.recovery-[0-9a-f]{24}$/;
250517
251137
  const temporarySidecarName = /^(.+\.json)\.recovery-[0-9a-f]{24}\.(\d+)\.([0-9a-f-]{36})\.[0-9a-f-]{36}\.tmp$/;
250518
251138
  const legacyTemporarySidecarName = /^(.+\.json)\.recovery-[0-9a-f]{24}\.(\d+)\.[0-9a-f-]{36}\.tmp$/;
250519
251139
  const staleTemporaryAgeMs = 60000;
250520
251140
  const maximumTemporaryAgeMs = 24 * 60 * 60 * 1000;
250521
- const path32 = (agentId, conversationId, lineageId) => join68(params.directory, `${encodeURIComponent(agentId)}_${encodeURIComponent(conversationId)}.json.recovery-${createHash8("sha256").update(lineageId).digest("hex").slice(0, 24)}`);
251141
+ const path32 = (agentId, conversationId, lineageId) => join69(params.directory, `${encodeURIComponent(agentId)}_${encodeURIComponent(conversationId)}.json.recovery-${createHash8("sha256").update(lineageId).digest("hex").slice(0, 24)}`);
250522
251142
  const isSidecar = (value) => {
250523
251143
  if (!value || typeof value !== "object")
250524
251144
  return false;
@@ -250527,7 +251147,7 @@ function createRecoveryLineageSidecarAccess(params) {
250527
251147
  };
250528
251148
  const read2 = (agentId, conversationId, lineageId) => {
250529
251149
  try {
250530
- const parsed = JSON.parse(readFileSync36(path32(agentId, conversationId, lineageId), "utf8"));
251150
+ const parsed = JSON.parse(readFileSync37(path32(agentId, conversationId, lineageId), "utf8"));
250531
251151
  if (!isSidecar(parsed) || parsed.agentId !== agentId || parsed.conversationId !== conversationId || parsed.lineageId !== lineageId) {
250532
251152
  throw new Error("Invalid recovery-lineage sidecar");
250533
251153
  }
@@ -250797,15 +251417,15 @@ function createRecoveryLineageSidecarAccess(params) {
250797
251417
  const removeMalformedOrphan = (file) => {
250798
251418
  const separator = file.indexOf(".recovery-");
250799
251419
  const mainFile = separator >= 0 ? file.slice(0, separator) : "";
250800
- if (!mainFile || existsSync46(join68(params.directory, mainFile)))
251420
+ if (!mainFile || existsSync47(join69(params.directory, mainFile)))
250801
251421
  return;
250802
251422
  try {
250803
- rmSync17(join68(params.directory, file), { force: true });
251423
+ rmSync17(join69(params.directory, file), { force: true });
250804
251424
  params.syncDirectory(params.directory);
250805
251425
  } catch {}
250806
251426
  };
250807
251427
  try {
250808
- const files = readdirSync16(params.directory);
251428
+ const files = readdirSync17(params.directory);
250809
251429
  for (const file of files) {
250810
251430
  const temporaryMatch = file.match(temporarySidecarName) ?? file.match(legacyTemporarySidecarName);
250811
251431
  if (!temporaryMatch)
@@ -250827,13 +251447,13 @@ function createRecoveryLineageSidecarAccess(params) {
250827
251447
  ownerIsAlive = error5.code !== "ESRCH";
250828
251448
  }
250829
251449
  }
250830
- const ageMs = Date.now() - statSync16(join68(params.directory, file)).mtimeMs;
251450
+ const ageMs = Date.now() - statSync17(join69(params.directory, file)).mtimeMs;
250831
251451
  if (!ownerIsCurrentWriter && (!ownerIsAlive && ageMs >= staleTemporaryAgeMs || ageMs >= maximumTemporaryAgeMs)) {
250832
- const release = acquireDurableFileLock(join68(params.directory, mainFile), { waitMs: params.lockWaitMs });
251452
+ const release = acquireDurableFileLock(join69(params.directory, mainFile), { waitMs: params.lockWaitMs });
250833
251453
  try {
250834
- const currentAgeMs = Date.now() - statSync16(join68(params.directory, file)).mtimeMs;
251454
+ const currentAgeMs = Date.now() - statSync17(join69(params.directory, file)).mtimeMs;
250835
251455
  if (!ownerIsCurrentWriter && (!ownerIsAlive && currentAgeMs >= staleTemporaryAgeMs || currentAgeMs >= maximumTemporaryAgeMs)) {
250836
- rmSync17(join68(params.directory, file), { force: true });
251456
+ rmSync17(join69(params.directory, file), { force: true });
250837
251457
  params.syncDirectory(params.directory);
250838
251458
  }
250839
251459
  } finally {
@@ -250844,8 +251464,8 @@ function createRecoveryLineageSidecarAccess(params) {
250844
251464
  }
250845
251465
  return files.filter((file) => canonicalSidecarName.test(file)).flatMap((file) => {
250846
251466
  try {
250847
- const value = JSON.parse(readFileSync36(join68(params.directory, file), "utf8"));
250848
- if (isSidecar(value) && join68(params.directory, file) === path32(value.agentId, value.conversationId, value.lineageId)) {
251467
+ const value = JSON.parse(readFileSync37(join69(params.directory, file), "utf8"));
251468
+ if (isSidecar(value) && join69(params.directory, file) === path32(value.agentId, value.conversationId, value.lineageId)) {
250849
251469
  return [value];
250850
251470
  }
250851
251471
  removeMalformedOrphan(file);
@@ -250887,14 +251507,14 @@ var init_recovery_lineage_sidecar = __esm(async () => {
250887
251507
  // src/websocket/listener/interrupted-turn-record.ts
250888
251508
  import { randomUUID as randomUUID41 } from "node:crypto";
250889
251509
  import {
250890
- existsSync as existsSync47,
251510
+ existsSync as existsSync48,
250891
251511
  mkdirSync as mkdirSync33,
250892
- readFileSync as readFileSync37,
251512
+ readFileSync as readFileSync38,
250893
251513
  rmSync as rmSync18,
250894
251514
  unlinkSync as unlinkSync9,
250895
251515
  writeFileSync as writeFileSync29
250896
251516
  } from "node:fs";
250897
- import { join as join69 } from "node:path";
251517
+ import { join as join70 } from "node:path";
250898
251518
  function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(), dependencies4 = {}) {
250899
251519
  const sync = dependencies4.fsyncDirectory ?? fsyncInterruptedTurnDirectory;
250900
251520
  function persist(destination, record6) {
@@ -250906,11 +251526,11 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
250906
251526
  }
250907
251527
  }
250908
251528
  function path32(agentId, conversationId) {
250909
- return join69(directory, `${encodeURIComponent(agentId)}_${encodeURIComponent(conversationId)}.json`);
251529
+ return join70(directory, `${encodeURIComponent(agentId)}_${encodeURIComponent(conversationId)}.json`);
250910
251530
  }
250911
251531
  function readRecord2(file) {
250912
251532
  try {
250913
- const value = JSON.parse(readFileSync37(file, "utf8"));
251533
+ const value = JSON.parse(readFileSync38(file, "utf8"));
250914
251534
  if (!isInterruptedTurnRecord(value, file, path32)) {
250915
251535
  throw new Error("Invalid interrupted-turn record");
250916
251536
  }
@@ -250944,7 +251564,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
250944
251564
  const recoveryAuthority = createRecoveryAuthorityGuard({
250945
251565
  path: path32,
250946
251566
  readRecord: readRecord2,
250947
- exists: existsSync47,
251567
+ exists: existsSync48,
250948
251568
  acquire: (destination) => acquireDurableFileLock(destination, {
250949
251569
  waitMs: dependencies4.lockWaitMs
250950
251570
  }),
@@ -250978,7 +251598,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
250978
251598
  });
250979
251599
  try {
250980
251600
  const current = readRecord2(destination);
250981
- if (!existsSync47(destination)) {
251601
+ if (!existsSync48(destination)) {
250982
251602
  removeSidecar(sidecar);
250983
251603
  } else if (current && current.recoveryClaimCompletion?.lineageId !== sidecar.lineageId) {
250984
251604
  removeSidecar(sidecar);
@@ -251003,7 +251623,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
251003
251623
  },
251004
251624
  listDurableInputOwnership() {
251005
251625
  const snapshot2 = rawSnapshot();
251006
- return collectInterruptedTurnInputOwnershipWithSidecars(snapshot2.records, readMainView, listSidecars(), (agentId, conversationId) => existsSync47(path32(agentId, conversationId)), snapshot2.unreadableScopes);
251626
+ return collectInterruptedTurnInputOwnershipWithSidecars(snapshot2.records, readMainView, listSidecars(), (agentId, conversationId) => existsSync48(path32(agentId, conversationId)), snapshot2.unreadableScopes);
251007
251627
  },
251008
251628
  read(agentId, conversationId) {
251009
251629
  const current = readRecord2(path32(agentId, conversationId));
@@ -251262,7 +251882,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
251262
251882
  }
251263
251883
  if (current.revision === params.pendingRevision && !marker2.independentSuccessor) {
251264
251884
  const retiredAuthority = retireSidecar(current);
251265
- const evidence = readFileSync37(destination, "utf8");
251885
+ const evidence = readFileSync38(destination, "utf8");
251266
251886
  unlinkSync9(destination);
251267
251887
  try {
251268
251888
  sync(directory);
@@ -251317,7 +251937,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
251317
251937
  if (expectedRevision !== undefined && (current.revision ?? null) !== expectedRevision) {
251318
251938
  return false;
251319
251939
  }
251320
- evidence = readFileSync37(destination, "utf8");
251940
+ evidence = readFileSync38(destination, "utf8");
251321
251941
  unlinkSync9(destination);
251322
251942
  } catch (error5) {
251323
251943
  if (error5.code === "ENOENT")
@@ -253305,10 +253925,10 @@ var init_input_disposition_expiry = __esm(() => {
253305
253925
  // src/websocket/listener/input-disposition-path.ts
253306
253926
  import { createHash as createHash9 } from "node:crypto";
253307
253927
  import { homedir as homedir34 } from "node:os";
253308
- import { join as join70 } from "node:path";
253928
+ import { join as join71 } from "node:path";
253309
253929
  function inputDispositionPersistentPath(serverUrl) {
253310
253930
  const namespace = createHash9("sha256").update(serverUrl).digest("hex").slice(0, 24);
253311
- return join70(homedir34(), ".letta", "state", namespace, "input-dispositions-v2.json");
253931
+ return join71(homedir34(), ".letta", "state", namespace, "input-dispositions-v2.json");
253312
253932
  }
253313
253933
  var init_input_disposition_path = () => {};
253314
253934
 
@@ -253334,14 +253954,14 @@ var init_input_disposition_validation = __esm(async () => {
253334
253954
  import { randomUUID as randomUUID42 } from "node:crypto";
253335
253955
  import {
253336
253956
  chmodSync as chmodSync7,
253337
- closeSync as closeSync6,
253338
- existsSync as existsSync48,
253957
+ closeSync as closeSync7,
253958
+ existsSync as existsSync49,
253339
253959
  fsyncSync as fsyncSync4,
253340
253960
  mkdirSync as mkdirSync34,
253341
- openSync as openSync6,
253342
- readFileSync as readFileSync38,
253961
+ openSync as openSync7,
253962
+ readFileSync as readFileSync39,
253343
253963
  renameSync as renameSync10,
253344
- statSync as statSync17,
253964
+ statSync as statSync18,
253345
253965
  unlinkSync as unlinkSync10,
253346
253966
  writeFileSync as writeFileSync30
253347
253967
  } from "node:fs";
@@ -253479,13 +254099,13 @@ function validateDurableStore(value) {
253479
254099
  return value;
253480
254100
  }
253481
254101
  function readDurableStore(path32) {
253482
- if (!existsSync48(path32))
254102
+ if (!existsSync49(path32))
253483
254103
  return emptyDurableStore();
253484
- const size2 = statSync17(path32).size;
254104
+ const size2 = statSync18(path32).size;
253485
254105
  if (size2 > MAX_INPUT_DISPOSITION_STORE_BYTES) {
253486
254106
  throw new Error("Accepted-input disposition store exceeds its size limit");
253487
254107
  }
253488
- return validateDurableStore(JSON.parse(readFileSync38(path32, "utf8")));
254108
+ return validateDurableStore(JSON.parse(readFileSync39(path32, "utf8")));
253489
254109
  }
253490
254110
  function prepareStateDirectory(path32) {
253491
254111
  const dir = dirname30(path32);
@@ -253501,11 +254121,11 @@ function writeDurableStore(path32, store3) {
253501
254121
  const temporaryPath = `${path32}.${process.pid}.${randomUUID42()}.tmp`;
253502
254122
  try {
253503
254123
  writeFileSync30(temporaryPath, serialized, { mode: 384, flag: "wx" });
253504
- const fd = openSync6(temporaryPath, "r+");
254124
+ const fd = openSync7(temporaryPath, "r+");
253505
254125
  try {
253506
254126
  fsyncSync4(fd);
253507
254127
  } finally {
253508
- closeSync6(fd);
254128
+ closeSync7(fd);
253509
254129
  }
253510
254130
  renameSync10(temporaryPath, path32);
253511
254131
  fsyncDirectory(dirname30(path32));
@@ -253927,18 +254547,18 @@ var init_input_disposition = __esm(async () => {
253927
254547
  // src/websocket/listener/turn-finished-replay.ts
253928
254548
  import { randomUUID as randomUUID43 } from "node:crypto";
253929
254549
  import {
253930
- closeSync as closeSync7,
254550
+ closeSync as closeSync8,
253931
254551
  fsyncSync as fsyncSync5,
253932
254552
  mkdirSync as mkdirSync35,
253933
- openSync as openSync7,
253934
- readdirSync as readdirSync17,
253935
- readFileSync as readFileSync39,
254553
+ openSync as openSync8,
254554
+ readdirSync as readdirSync18,
254555
+ readFileSync as readFileSync40,
253936
254556
  renameSync as renameSync11,
253937
254557
  rmSync as rmSync19,
253938
254558
  writeFileSync as writeFileSync31
253939
254559
  } from "node:fs";
253940
254560
  import { homedir as homedir35 } from "node:os";
253941
- import { join as join71 } from "node:path";
254561
+ import { join as join72 } from "node:path";
253942
254562
  function terminalAuthorityStatus(runtime, terminal, terminals, interruptedStore = createInterruptedTurnStore()) {
253943
254563
  const { owner } = terminal;
253944
254564
  if (!owner.recoveryLineageId)
@@ -253978,7 +254598,7 @@ function defaultDirectory() {
253978
254598
  } catch {
253979
254599
  serverUrl = process.env.LETTA_BASE_URL ?? "uninitialized";
253980
254600
  }
253981
- return join71(homedir35(), ".letta", "listener-terminal-state", Buffer.from(serverUrl).toString("base64url"));
254601
+ return join72(homedir35(), ".letta", "listener-terminal-state", Buffer.from(serverUrl).toString("base64url"));
253982
254602
  }
253983
254603
  function encodeTurnFinishedScope(agentId, conversationId) {
253984
254604
  return Buffer.from(JSON.stringify([agentId, conversationId])).toString("base64url");
@@ -253997,19 +254617,19 @@ function decodeTurnFinishedScope(encoded) {
253997
254617
  function fsyncDirectory2(directory) {
253998
254618
  if (process.platform === "win32")
253999
254619
  return;
254000
- const fd = openSync7(directory, "r");
254620
+ const fd = openSync8(directory, "r");
254001
254621
  try {
254002
254622
  fsyncSync5(fd);
254003
254623
  } finally {
254004
- closeSync7(fd);
254624
+ closeSync8(fd);
254005
254625
  }
254006
254626
  }
254007
254627
  function createTurnFinishedStore(directory = defaultDirectory(), options = {}) {
254008
254628
  const claimantToken = randomUUID43();
254009
- const path32 = (agentId, conversationId) => join71(directory, `${encodeTurnFinishedScope(agentId, conversationId)}.json`);
254629
+ const path32 = (agentId, conversationId) => join72(directory, `${encodeTurnFinishedScope(agentId, conversationId)}.json`);
254010
254630
  const readRecord2 = (agentId, conversationId) => {
254011
254631
  try {
254012
- const record6 = JSON.parse(readFileSync39(path32(agentId, conversationId), "utf8"));
254632
+ const record6 = JSON.parse(readFileSync40(path32(agentId, conversationId), "utf8"));
254013
254633
  if (record6.agentId !== agentId || record6.conversationId !== conversationId || !Array.isArray(record6.terminals) || !record6.terminals.every((terminal) => typeof terminal.id === "string" && Number.isFinite(terminal.createdAt) && terminal.message?.type === "turn_finished" && typeof terminal.message.turn_id === "string" && Array.isArray(terminal.requiredConsumerIds) && terminal.requiredConsumerIds.every((id2) => typeof id2 === "string") && Array.isArray(terminal.acknowledgedConsumerIds) && terminal.acknowledgedConsumerIds.every((id2) => typeof id2 === "string") && !!terminal.owner && (terminal.owner.connectionId === null || typeof terminal.owner.connectionId === "string") && typeof terminal.owner.canRotate === "boolean" && (terminal.owner.terminalIdentity === undefined || typeof terminal.owner.terminalIdentity === "string") && (terminal.owner.interruptedRevision === undefined || typeof terminal.owner.interruptedRevision === "string") && (terminal.owner.recoveryLineageId === undefined || typeof terminal.owner.recoveryLineageId === "string") && (terminal.owner.interruptedAuthorityRevision === undefined || typeof terminal.owner.interruptedAuthorityRevision === "string") && (terminal.owner.preparationSequence === undefined || Number.isSafeInteger(terminal.owner.preparationSequence) && terminal.owner.preparationSequence >= 0))) {
254014
254634
  throw new Error("Invalid turn-finished record");
254015
254635
  }
@@ -254075,7 +254695,7 @@ function createTurnFinishedStore(directory = defaultDirectory(), options = {}) {
254075
254695
  const sweepExpiredRecords = () => {
254076
254696
  let entries2;
254077
254697
  try {
254078
- entries2 = readdirSync17(directory, { withFileTypes: true });
254698
+ entries2 = readdirSync18(directory, { withFileTypes: true });
254079
254699
  } catch (error5) {
254080
254700
  if (error5.code === "ENOENT")
254081
254701
  return;
@@ -259315,7 +259935,7 @@ function printListenUsage() {
259315
259935
  }
259316
259936
 
259317
259937
  // src/cli/subcommands/listener-readiness.ts
259318
- async function completeListenerConnectionStartup(expectedConnection, readiness) {
259938
+ async function completeListenerConnectionStartup(expectedConnection, readiness, startGateway = async () => {}) {
259319
259939
  const { getActiveRuntime: getActiveRuntime2 } = await init_runtime6().then(() => exports_runtime);
259320
259940
  const runtime = getActiveRuntime2();
259321
259941
  const connection = runtime?.connections.get(expectedConnection.id);
@@ -259325,8 +259945,11 @@ async function completeListenerConnectionStartup(expectedConnection, readiness)
259325
259945
  const { isListenerTransportOpen: isListenerTransportOpen2 } = await Promise.resolve().then(() => (init_transport(), exports_transport));
259326
259946
  if (!isListenerTransportOpen2(connection.writer))
259327
259947
  return false;
259948
+ await startGateway();
259328
259949
  if (getActiveRuntime2()?.connections.get(connection.id) !== connection)
259329
259950
  return false;
259951
+ if (!connection.initialized || !connection.ingressReady || connection.cancellation.signal.aborted || !isListenerTransportOpen2(connection.writer))
259952
+ return false;
259330
259953
  readiness.completeCloudStartup(epoch);
259331
259954
  return true;
259332
259955
  }
@@ -259448,13 +260071,13 @@ var init_service_protocol = __esm(() => {
259448
260071
  // src/websocket/listen-log.ts
259449
260072
  import {
259450
260073
  appendFileSync as appendFileSync8,
259451
- existsSync as existsSync49,
260074
+ existsSync as existsSync50,
259452
260075
  mkdirSync as mkdirSync36,
259453
- readdirSync as readdirSync18,
260076
+ readdirSync as readdirSync19,
259454
260077
  unlinkSync as unlinkSync11
259455
260078
  } from "node:fs";
259456
260079
  import { homedir as homedir36 } from "node:os";
259457
- import { join as join72 } from "node:path";
260080
+ import { join as join73 } from "node:path";
259458
260081
  function formatTimestamp2() {
259459
260082
  const now2 = new Date;
259460
260083
  const h3 = String(now2.getHours()).padStart(2, "0");
@@ -259468,14 +260091,14 @@ function formatFileTimestamp(now2) {
259468
260091
  }
259469
260092
  function pruneOldLogs(dir, maxFiles) {
259470
260093
  try {
259471
- if (!existsSync49(dir))
260094
+ if (!existsSync50(dir))
259472
260095
  return;
259473
- const files = readdirSync18(dir).filter((f4) => f4.endsWith(".log")).sort();
260096
+ const files = readdirSync19(dir).filter((f4) => f4.endsWith(".log")).sort();
259474
260097
  if (files.length >= maxFiles) {
259475
260098
  const toDelete = files.slice(0, files.length - maxFiles + 1);
259476
260099
  for (const file of toDelete) {
259477
260100
  try {
259478
- unlinkSync11(join72(dir, file));
260101
+ unlinkSync11(join73(dir, file));
259479
260102
  } catch {}
259480
260103
  }
259481
260104
  }
@@ -259514,13 +260137,13 @@ class RemoteSessionLog {
259514
260137
  freshPath() {
259515
260138
  const stamp = formatFileTimestamp(new Date);
259516
260139
  const suffix = this.rotation > 0 ? `.${this.rotation}` : "";
259517
- return join72(this.dir, `${stamp}${suffix}.log`);
260140
+ return join73(this.dir, `${stamp}${suffix}.log`);
259518
260141
  }
259519
260142
  rotate() {
259520
260143
  const previous = this.path;
259521
260144
  this.rotation += 1;
259522
260145
  this.path = this.freshPath();
259523
- while (existsSync49(this.path)) {
260146
+ while (existsSync50(this.path)) {
259524
260147
  this.rotation += 1;
259525
260148
  this.path = this.freshPath();
259526
260149
  }
@@ -259544,7 +260167,7 @@ class RemoteSessionLog {
259544
260167
  if (this.dirCreated)
259545
260168
  return;
259546
260169
  try {
259547
- if (!existsSync49(this.dir)) {
260170
+ if (!existsSync50(this.dir)) {
259548
260171
  mkdirSync36(this.dir, { recursive: true });
259549
260172
  }
259550
260173
  this.dirCreated = true;
@@ -259553,7 +260176,7 @@ class RemoteSessionLog {
259553
260176
  }
259554
260177
  var REMOTE_LOG_DIR, MAX_LOG_FILES = 10, MAX_LOG_BYTES2;
259555
260178
  var init_listen_log = __esm(() => {
259556
- REMOTE_LOG_DIR = join72(homedir36(), ".letta", "logs", "remote");
260179
+ REMOTE_LOG_DIR = join73(homedir36(), ".letta", "logs", "remote");
259557
260180
  MAX_LOG_BYTES2 = 10 * 1024 * 1024;
259558
260181
  });
259559
260182
 
@@ -262296,28 +262919,28 @@ __export(exports_memory_scanner, {
262296
262919
  readFileContent: () => readFileContent,
262297
262920
  getFileNodes: () => getFileNodes
262298
262921
  });
262299
- import { readdirSync as readdirSync19, readFileSync as readFileSync40, statSync as statSync18 } from "node:fs";
262300
- import { join as join73, relative as relative7 } from "node:path";
262922
+ import { readdirSync as readdirSync20, readFileSync as readFileSync41, statSync as statSync19 } from "node:fs";
262923
+ import { join as join74, relative as relative7 } from "node:path";
262301
262924
  function scanMemoryFilesystem(memoryRoot) {
262302
262925
  const nodes = [];
262303
262926
  const scanDir = (dir, depth, parentIsLast) => {
262304
262927
  let entries2;
262305
262928
  try {
262306
- entries2 = readdirSync19(dir);
262929
+ entries2 = readdirSync20(dir);
262307
262930
  } catch {
262308
262931
  return;
262309
262932
  }
262310
262933
  const filtered = entries2.filter((name) => !name.startsWith("."));
262311
262934
  const sorted = filtered.sort((a2, b3) => {
262312
- const aPath = join73(dir, a2);
262313
- const bPath = join73(dir, b3);
262935
+ const aPath = join74(dir, a2);
262936
+ const bPath = join74(dir, b3);
262314
262937
  let aIsDir = false;
262315
262938
  let bIsDir = false;
262316
262939
  try {
262317
- aIsDir = statSync18(aPath).isDirectory();
262940
+ aIsDir = statSync19(aPath).isDirectory();
262318
262941
  } catch {}
262319
262942
  try {
262320
- bIsDir = statSync18(bPath).isDirectory();
262943
+ bIsDir = statSync19(bPath).isDirectory();
262321
262944
  } catch {}
262322
262945
  if (aIsDir !== bIsDir)
262323
262946
  return aIsDir ? -1 : 1;
@@ -262330,10 +262953,10 @@ function scanMemoryFilesystem(memoryRoot) {
262330
262953
  return a2.localeCompare(b3);
262331
262954
  });
262332
262955
  sorted.forEach((name, index) => {
262333
- const fullPath = join73(dir, name);
262956
+ const fullPath = join74(dir, name);
262334
262957
  let isDir = false;
262335
262958
  try {
262336
- isDir = statSync18(fullPath).isDirectory();
262959
+ isDir = statSync19(fullPath).isDirectory();
262337
262960
  } catch {
262338
262961
  return;
262339
262962
  }
@@ -262361,7 +262984,7 @@ function getFileNodes(nodes) {
262361
262984
  }
262362
262985
  function readFileContent(fullPath) {
262363
262986
  try {
262364
- return readFileSync40(fullPath, "utf-8");
262987
+ return readFileSync41(fullPath, "utf-8");
262365
262988
  } catch {
262366
262989
  return "(unable to read file)";
262367
262990
  }
@@ -262432,10 +263055,10 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
262432
263055
  const isMemfsEnabledOnServer2 = overrides.isMemfsEnabledOnServer ?? actualIsMemfsEnabledOnServer;
262433
263056
  const { scanMemoryFilesystem: scanMemoryFilesystem2, getFileNodes: getFileNodes2, readFileContent: readFileContent2 } = await Promise.resolve().then(() => (init_memory_scanner(), exports_memory_scanner));
262434
263057
  const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => exports_frontmatter);
262435
- const { existsSync: existsSync50, statSync: statSync19 } = await import("node:fs");
262436
- const { join: join74, posix: posix3 } = await import("node:path");
263058
+ const { existsSync: existsSync51, statSync: statSync20 } = await import("node:fs");
263059
+ const { join: join75, posix: posix3 } = await import("node:path");
262437
263060
  const memoryRoot = getMemoryFilesystemRoot2(parsed.agent_id);
262438
- let memfsInitialized = existsSync50(join74(memoryRoot, ".git"));
263061
+ let memfsInitialized = existsSync51(join75(memoryRoot, ".git"));
262439
263062
  const memfsEnabled = memfsInitialized ? true : await isMemfsEnabledOnServer2(parsed.agent_id);
262440
263063
  if (!memfsEnabled) {
262441
263064
  safeSocketSend(socket, {
@@ -262453,7 +263076,7 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
262453
263076
  await ensureLocalMemfsCheckout2(parsed.agent_id, {
262454
263077
  pullOnExistingRepo: true
262455
263078
  });
262456
- memfsInitialized = existsSync50(join74(memoryRoot, ".git"));
263079
+ memfsInitialized = existsSync51(join75(memoryRoot, ".git"));
262457
263080
  if (!memfsInitialized) {
262458
263081
  throw new Error("MemFS is enabled, but the local memory checkout could not be initialized.");
262459
263082
  }
@@ -262529,7 +263152,7 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
262529
263152
  if (imageMimeType) {
262530
263153
  let size2 = 0;
262531
263154
  try {
262532
- size2 = statSync19(node.fullPath).size;
263155
+ size2 = statSync20(node.fullPath).size;
262533
263156
  } catch {}
262534
263157
  return {
262535
263158
  relative_path: node.relativePath,
@@ -262753,34 +263376,34 @@ function handleMemoryProtocolCommand(parsed, context3) {
262753
263376
  isMemfsEnabledOnServer: isMemfsEnabledOnServer2
262754
263377
  } = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
262755
263378
  const { readFile: readFile20 } = await import("node:fs/promises");
262756
- const { existsSync: existsSync50 } = await import("node:fs");
262757
- const { isAbsolute: isAbsolute25, join: join74, normalize: normalize4, relative: relative8, sep: sep7 } = await import("node:path");
263379
+ const { existsSync: existsSync51 } = await import("node:fs");
263380
+ const { isAbsolute: isAbsolute25, join: join75, normalize: normalize4, relative: relative8, sep: sep8 } = await import("node:path");
262758
263381
  if (isAbsolute25(parsed.path) || parsed.path.length === 0) {
262759
263382
  sendFailure("path must be a non-empty relative path");
262760
263383
  return;
262761
263384
  }
262762
263385
  const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
262763
- const absolutePath = normalize4(join74(memoryRoot, parsed.path));
263386
+ const absolutePath = normalize4(join75(memoryRoot, parsed.path));
262764
263387
  const rel = relative8(memoryRoot, absolutePath);
262765
- if (rel.startsWith("..") || rel === "" || isAbsolute25(rel) || rel.split(sep7).includes("..")) {
263388
+ if (rel.startsWith("..") || rel === "" || isAbsolute25(rel) || rel.split(sep8).includes("..")) {
262766
263389
  sendFailure("path must resolve inside the memory root");
262767
263390
  return;
262768
263391
  }
262769
- if (!existsSync50(join74(memoryRoot, ".git"))) {
263392
+ if (!existsSync51(join75(memoryRoot, ".git"))) {
262770
263393
  const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
262771
263394
  if (!enabled) {
262772
263395
  sendFailure("memfs is not enabled for this agent");
262773
263396
  return;
262774
263397
  }
262775
263398
  await ensureLocalMemfsCheckout2(parsed.agent_id);
262776
- if (!existsSync50(join74(memoryRoot, ".git"))) {
263399
+ if (!existsSync51(join75(memoryRoot, ".git"))) {
262777
263400
  sendFailure("failed to initialize local memory checkout");
262778
263401
  return;
262779
263402
  }
262780
263403
  }
262781
263404
  const buffer = await readFile20(absolutePath);
262782
263405
  const content = encoding === "base64" ? buffer.toString("base64") : buffer.toString("utf-8");
262783
- const pathspec = rel.split(sep7).join("/");
263406
+ const pathspec = rel.split(sep8).join("/");
262784
263407
  safeSocketSend(socket, {
262785
263408
  type: "read_memory_file_response",
262786
263409
  request_id: parsed.request_id,
@@ -262819,27 +263442,27 @@ function handleMemoryProtocolCommand(parsed, context3) {
262819
263442
  } = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
262820
263443
  const { commitMemoryWrite: commitMemoryWrite2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
262821
263444
  const { writeFile: writeFile16, mkdir: mkdir14 } = await import("node:fs/promises");
262822
- const { existsSync: existsSync50 } = await import("node:fs");
262823
- const { dirname: dirname31, isAbsolute: isAbsolute25, join: join74, normalize: normalize4, relative: relative8, sep: sep7 } = await import("node:path");
263445
+ const { existsSync: existsSync51 } = await import("node:fs");
263446
+ const { dirname: dirname31, isAbsolute: isAbsolute25, join: join75, normalize: normalize4, relative: relative8, sep: sep8 } = await import("node:path");
262824
263447
  if (isAbsolute25(parsed.path) || parsed.path.length === 0) {
262825
263448
  sendFailure("write_memory_file: path must be a non-empty relative path");
262826
263449
  return;
262827
263450
  }
262828
263451
  const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
262829
- const absolutePath = normalize4(join74(memoryRoot, parsed.path));
263452
+ const absolutePath = normalize4(join75(memoryRoot, parsed.path));
262830
263453
  const rel = relative8(memoryRoot, absolutePath);
262831
- if (rel.startsWith("..") || rel === "" || isAbsolute25(rel) || rel.split(sep7).includes("..")) {
263454
+ if (rel.startsWith("..") || rel === "" || isAbsolute25(rel) || rel.split(sep8).includes("..")) {
262832
263455
  sendFailure("write_memory_file: path must resolve inside the memory root");
262833
263456
  return;
262834
263457
  }
262835
- if (!existsSync50(join74(memoryRoot, ".git"))) {
263458
+ if (!existsSync51(join75(memoryRoot, ".git"))) {
262836
263459
  const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
262837
263460
  if (!enabled) {
262838
263461
  sendFailure("write_memory_file: memfs is not enabled for this agent");
262839
263462
  return;
262840
263463
  }
262841
263464
  await ensureLocalMemfsCheckout2(parsed.agent_id);
262842
- if (!existsSync50(join74(memoryRoot, ".git"))) {
263465
+ if (!existsSync51(join75(memoryRoot, ".git"))) {
262843
263466
  sendFailure("write_memory_file: failed to initialize local memory checkout");
262844
263467
  return;
262845
263468
  }
@@ -262857,7 +263480,7 @@ function handleMemoryProtocolCommand(parsed, context3) {
262857
263480
  agentName = agent.name.trim();
262858
263481
  }
262859
263482
  } catch {}
262860
- const pathspec = rel.split(sep7).join("/");
263483
+ const pathspec = rel.split(sep8).join("/");
262861
263484
  const reason = parsed.commit_message?.trim() || `Update memory file ${pathspec}`;
262862
263485
  const commitResult = await commitMemoryWrite2({
262863
263486
  memoryDir: memoryRoot,
@@ -262917,34 +263540,34 @@ function handleMemoryProtocolCommand(parsed, context3) {
262917
263540
  } = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
262918
263541
  const { commitMemoryWrite: commitMemoryWrite2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
262919
263542
  const { unlink: unlink4 } = await import("node:fs/promises");
262920
- const { existsSync: existsSync50 } = await import("node:fs");
262921
- const { isAbsolute: isAbsolute25, join: join74, normalize: normalize4, relative: relative8, sep: sep7 } = await import("node:path");
263543
+ const { existsSync: existsSync51 } = await import("node:fs");
263544
+ const { isAbsolute: isAbsolute25, join: join75, normalize: normalize4, relative: relative8, sep: sep8 } = await import("node:path");
262922
263545
  if (isAbsolute25(parsed.path) || parsed.path.length === 0) {
262923
263546
  sendFailure("delete_memory_file: path must be a non-empty relative path");
262924
263547
  return;
262925
263548
  }
262926
263549
  const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
262927
- const absolutePath = normalize4(join74(memoryRoot, parsed.path));
263550
+ const absolutePath = normalize4(join75(memoryRoot, parsed.path));
262928
263551
  const rel = relative8(memoryRoot, absolutePath);
262929
- if (rel.startsWith("..") || rel === "" || isAbsolute25(rel) || rel.split(sep7).includes("..")) {
263552
+ if (rel.startsWith("..") || rel === "" || isAbsolute25(rel) || rel.split(sep8).includes("..")) {
262930
263553
  sendFailure("delete_memory_file: path must resolve inside the memory root");
262931
263554
  return;
262932
263555
  }
262933
- if (!existsSync50(join74(memoryRoot, ".git"))) {
263556
+ if (!existsSync51(join75(memoryRoot, ".git"))) {
262934
263557
  const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
262935
263558
  if (!enabled) {
262936
263559
  sendFailure("delete_memory_file: memfs is not enabled for this agent");
262937
263560
  return;
262938
263561
  }
262939
263562
  await ensureLocalMemfsCheckout2(parsed.agent_id);
262940
- if (!existsSync50(join74(memoryRoot, ".git"))) {
263563
+ if (!existsSync51(join75(memoryRoot, ".git"))) {
262941
263564
  sendFailure("delete_memory_file: failed to initialize local memory checkout");
262942
263565
  return;
262943
263566
  }
262944
263567
  }
262945
- const pathspec = rel.split(sep7).join("/");
263568
+ const pathspec = rel.split(sep8).join("/");
262946
263569
  const removeIfPresent = async () => {
262947
- if (!existsSync50(absolutePath))
263570
+ if (!existsSync51(absolutePath))
262948
263571
  return false;
262949
263572
  await unlink4(absolutePath);
262950
263573
  return true;
@@ -263013,7 +263636,7 @@ function handleMemoryProtocolCommand(parsed, context3) {
263013
263636
  return false;
263014
263637
  }
263015
263638
  var warnMemoryCommand, WIKI_LINK_REGEX, IMAGE_MIME_BY_EXTENSION, MEMORY_PUSH_AWAIT_CAP_MS = 8000;
263016
- var init_memory5 = __esm(async () => {
263639
+ var init_memory6 = __esm(async () => {
263017
263640
  init_error_reporting();
263018
263641
  init_debug();
263019
263642
  await init_protocol_inbound();
@@ -263118,12 +263741,12 @@ __export(exports_remote_model_catalog, {
263118
263741
  applyCatalogModels: () => applyCatalogModels,
263119
263742
  __testResetRemoteModelCatalog: () => __testResetRemoteModelCatalog
263120
263743
  });
263121
- import { existsSync as existsSync50, mkdirSync as mkdirSync37, readFileSync as readFileSync41, writeFileSync as writeFileSync32 } from "node:fs";
263744
+ import { existsSync as existsSync51, mkdirSync as mkdirSync37, readFileSync as readFileSync42, writeFileSync as writeFileSync32 } from "node:fs";
263122
263745
  import { homedir as homedir38 } from "node:os";
263123
- import { dirname as dirname31, join as join74 } from "node:path";
263746
+ import { dirname as dirname31, join as join75 } from "node:path";
263124
263747
  function catalogCachePath() {
263125
- const dir = process.env.LETTA_MODEL_CATALOG_CACHE_DIR || join74(homedir38(), ".letta", "cache");
263126
- return join74(dir, "model-catalog.json");
263748
+ const dir = process.env.LETTA_MODEL_CATALOG_CACHE_DIR || join75(homedir38(), ".letta", "cache");
263749
+ return join75(dir, "model-catalog.json");
263127
263750
  }
263128
263751
  function normalizeCatalogSource(source) {
263129
263752
  try {
@@ -263222,10 +263845,10 @@ function persistCatalogCache(entries2, source) {
263222
263845
  function loadPersistedModelCatalog(source) {
263223
263846
  try {
263224
263847
  const path33 = catalogCachePath();
263225
- if (!existsSync50(path33)) {
263848
+ if (!existsSync51(path33)) {
263226
263849
  return false;
263227
263850
  }
263228
- const parsed = JSON.parse(readFileSync41(path33, "utf-8"));
263851
+ const parsed = JSON.parse(readFileSync42(path33, "utf-8"));
263229
263852
  if (parsed.schemaVersion !== CACHE_SCHEMA_VERSION || parsed.source !== normalizeCatalogSource(source) || !Array.isArray(parsed.models)) {
263230
263853
  return false;
263231
263854
  }
@@ -263911,7 +264534,7 @@ function recordStaleHandleUse(collector, owner, capability, onDiagnostic) {
263911
264534
  var MOD_DIAGNOSTICS_MAX_COUNT = 200, MOD_DIAGNOSTICS_RESET_COUNT = 50, MOD_DYNAMIC_CONTEXT_MIGRATION_HINT = "Dynamic context is now passed as ctx to commands, tools, events, permissions, and UI renderers. Use ctx.agent, ctx.cwd, ctx.conversation, ctx.model, etc.", MOD_LETTA_GET_CONTEXT_MIGRATION_HINT = "letta.getContext has been removed. Activation has no dynamic invocation context. Move dynamic work into a command, tool, event, permission, status, or statusline callback that receives ctx, or use explicit/global state such as process.cwd() for activation-time background work.", MOD_CTX_GET_CONTEXT_MIGRATION_HINT = "ctx.getContext has been removed. Use ctx directly; scoped fields are available as ctx.agent, ctx.cwd, ctx.conversation, ctx.model, etc.", MOD_GENERIC_GET_CONTEXT_MIGRATION_HINT = "getContext helpers have been removed. If this is callback ctx, use ctx directly; if activation/background code needs runtime state, move it into a callback that receives ctx or use explicit/global state such as process.cwd().";
263912
264535
 
263913
264536
  // src/mods/paths.ts
263914
- import { existsSync as existsSync51 } from "node:fs";
264537
+ import { existsSync as existsSync52 } from "node:fs";
263915
264538
  import { homedir as homedir39 } from "node:os";
263916
264539
  import path33 from "node:path";
263917
264540
  function getGlobalModsDirectory(homeDirectory = homedir39()) {
@@ -263925,10 +264548,10 @@ function resolveDefaultGlobalModsDirectory(homeDirectory = homedir39(), env6 = p
263925
264548
  if (environmentDirectory)
263926
264549
  return environmentDirectory;
263927
264550
  const modsDirectory = getGlobalModsDirectory(homeDirectory);
263928
- if (existsSync51(modsDirectory))
264551
+ if (existsSync52(modsDirectory))
263929
264552
  return modsDirectory;
263930
264553
  const legacyDirectory = getLegacyGlobalExtensionsDirectory(homeDirectory);
263931
- if (existsSync51(legacyDirectory))
264554
+ if (existsSync52(legacyDirectory))
263932
264555
  return legacyDirectory;
263933
264556
  return modsDirectory;
263934
264557
  }
@@ -272078,7 +272701,7 @@ ${lanes.join(`
272078
272701
  return process.memoryUsage().heapUsed;
272079
272702
  },
272080
272703
  getFileSize(path35) {
272081
- const stat12 = statSync19(path35);
272704
+ const stat12 = statSync20(path35);
272082
272705
  if (stat12 == null ? undefined : stat12.isFile()) {
272083
272706
  return stat12.size;
272084
272707
  }
@@ -272121,7 +272744,7 @@ ${lanes.join(`
272121
272744
  }
272122
272745
  };
272123
272746
  return nodeSystem;
272124
- function statSync19(path35) {
272747
+ function statSync20(path35) {
272125
272748
  try {
272126
272749
  return _fs.statSync(path35, statSyncOptions);
272127
272750
  } catch {
@@ -272173,7 +272796,7 @@ ${lanes.join(`
272173
272796
  activeSession.post("Profiler.stop", (err, { profile }) => {
272174
272797
  var _a10;
272175
272798
  if (!err) {
272176
- if ((_a10 = statSync19(profilePath)) == null ? undefined : _a10.isDirectory()) {
272799
+ if ((_a10 = statSync20(profilePath)) == null ? undefined : _a10.isDirectory()) {
272177
272800
  profilePath = _path.join(profilePath, `${(/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-")}+P${process.pid}.cpuprofile`);
272178
272801
  }
272179
272802
  try {
@@ -272282,7 +272905,7 @@ ${lanes.join(`
272282
272905
  let stat12;
272283
272906
  if (typeof dirent === "string" || dirent.isSymbolicLink()) {
272284
272907
  const name = combinePaths(path35, entry);
272285
- stat12 = statSync19(name);
272908
+ stat12 = statSync20(name);
272286
272909
  if (!stat12) {
272287
272910
  continue;
272288
272911
  }
@@ -272306,7 +272929,7 @@ ${lanes.join(`
272306
272929
  return matchFiles(path35, extensions, excludes, includes2, useCaseSensitiveFileNames2, process.cwd(), depth, getAccessibleFileSystemEntries, realpath6);
272307
272930
  }
272308
272931
  function fileSystemEntryExists(path35, entryKind) {
272309
- const stat12 = statSync19(path35);
272932
+ const stat12 = statSync20(path35);
272310
272933
  if (!stat12) {
272311
272934
  return false;
272312
272935
  }
@@ -272340,7 +272963,7 @@ ${lanes.join(`
272340
272963
  }
272341
272964
  function getModifiedTime3(path35) {
272342
272965
  var _a10;
272343
- return (_a10 = statSync19(path35)) == null ? undefined : _a10.mtime;
272966
+ return (_a10 = statSync20(path35)) == null ? undefined : _a10.mtime;
272344
272967
  }
272345
272968
  function setModifiedTime(path35, time3) {
272346
272969
  try {
@@ -295182,7 +295805,7 @@ ${lanes.join(`
295182
295805
  var contextFlags;
295183
295806
  var topLevel = true;
295184
295807
  var parseErrorBeforeNextFinishedNode = false;
295185
- function parseSourceFile(fileName2, sourceText2, languageVersion2, syntaxCursor2, setParentNodes = false, scriptKind2, setExternalModuleIndicatorOverride, jsDocParsingMode = 0) {
295808
+ function parseSourceFile2(fileName2, sourceText2, languageVersion2, syntaxCursor2, setParentNodes = false, scriptKind2, setExternalModuleIndicatorOverride, jsDocParsingMode = 0) {
295186
295809
  var _a10;
295187
295810
  scriptKind2 = ensureScriptKind(fileName2, scriptKind2);
295188
295811
  if (scriptKind2 === 6) {
@@ -295201,7 +295824,7 @@ ${lanes.join(`
295201
295824
  clearState();
295202
295825
  return result3;
295203
295826
  }
295204
- Parser22.parseSourceFile = parseSourceFile;
295827
+ Parser22.parseSourceFile = parseSourceFile2;
295205
295828
  function parseIsolatedEntityName2(content, languageVersion2) {
295206
295829
  initializeState("", content, languageVersion2, undefined, 1, 0);
295207
295830
  nextToken();
@@ -305466,11 +306089,11 @@ ${lanes.join(`
305466
306089
  if (i4 < rootLength) {
305467
306090
  return;
305468
306091
  }
305469
- const sep7 = directory.lastIndexOf(directorySeparator, i4 - 1);
305470
- if (sep7 === -1) {
306092
+ const sep8 = directory.lastIndexOf(directorySeparator, i4 - 1);
306093
+ if (sep8 === -1) {
305471
306094
  return;
305472
306095
  }
305473
- return directory.substr(0, Math.max(sep7, rootLength));
306096
+ return directory.substr(0, Math.max(sep8, rootLength));
305474
306097
  }
305475
306098
  }
305476
306099
  }
@@ -432746,7 +433369,7 @@ function createModChangeBatcher(onChange) {
432746
433369
  }
432747
433370
 
432748
433371
  // src/mods/package-manifest.ts
432749
- import { readFileSync as readFileSync42 } from "node:fs";
433372
+ import { readFileSync as readFileSync43 } from "node:fs";
432750
433373
  import path35 from "node:path";
432751
433374
  function isRecord15(value) {
432752
433375
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -432956,7 +433579,7 @@ function parseLettaPackageManifest(packageJson) {
432956
433579
  }
432957
433580
  function readLettaPackageManifest(packageJsonPath) {
432958
433581
  try {
432959
- const packageJson = JSON.parse(readFileSync42(packageJsonPath, "utf8"));
433582
+ const packageJson = JSON.parse(readFileSync43(packageJsonPath, "utf8"));
432960
433583
  return parseLettaPackageManifest(packageJson);
432961
433584
  } catch (error5) {
432962
433585
  return {
@@ -432986,9 +433609,9 @@ var init_package_manifest = __esm(() => {
432986
433609
 
432987
433610
  // src/mods/package-registry.ts
432988
433611
  import {
432989
- existsSync as existsSync52,
433612
+ existsSync as existsSync53,
432990
433613
  mkdirSync as mkdirSync39,
432991
- readFileSync as readFileSync43,
433614
+ readFileSync as readFileSync44,
432992
433615
  rmSync as rmSync20,
432993
433616
  writeFileSync as writeFileSync34
432994
433617
  } from "node:fs";
@@ -433044,7 +433667,7 @@ function parseJsonFile(filePath) {
433044
433667
  try {
433045
433668
  return {
433046
433669
  ok: true,
433047
- value: JSON.parse(readFileSync43(filePath, "utf8"))
433670
+ value: JSON.parse(readFileSync44(filePath, "utf8"))
433048
433671
  };
433049
433672
  } catch (error5) {
433050
433673
  return {
@@ -433058,7 +433681,7 @@ function getRegistryPath(modsRoot) {
433058
433681
  }
433059
433682
  function readRegistryObject(modsRoot) {
433060
433683
  const registryPath = getRegistryPath(modsRoot);
433061
- if (!existsSync52(registryPath)) {
433684
+ if (!existsSync53(registryPath)) {
433062
433685
  return { diagnostics: [], ok: false, registryExists: false, registryPath };
433063
433686
  }
433064
433687
  const registryResult = parseJsonFile(registryPath);
@@ -433490,7 +434113,7 @@ function writePackageRegistry(registryPath, registry4) {
433490
434113
  }
433491
434114
  function validateManagedModPackageRegistryForMutation(modsRoot) {
433492
434115
  const registryPath = getRegistryPath(modsRoot);
433493
- const contents = existsSync52(registryPath) ? readFileSync43(registryPath, "utf8") : null;
434116
+ const contents = existsSync53(registryPath) ? readFileSync44(registryPath, "utf8") : null;
433494
434117
  const registry4 = readMutablePackageRegistry(modsRoot, {
433495
434118
  createIfMissing: true
433496
434119
  });
@@ -433613,12 +434236,12 @@ var init_package_registry = __esm(() => {
433613
434236
  });
433614
434237
 
433615
434238
  // src/mods/mod-sources.ts
433616
- import { existsSync as existsSync53, readdirSync as readdirSync20 } from "node:fs";
434239
+ import { existsSync as existsSync54, readdirSync as readdirSync21 } from "node:fs";
433617
434240
  import path37 from "node:path";
433618
434241
  function listModFiles(directory) {
433619
- if (!existsSync53(directory))
434242
+ if (!existsSync54(directory))
433620
434243
  return [];
433621
- return readdirSync20(directory, { withFileTypes: true }).filter((entry) => {
434244
+ return readdirSync21(directory, { withFileTypes: true }).filter((entry) => {
433622
434245
  if (!entry.isFile())
433623
434246
  return false;
433624
434247
  if (entry.name.startsWith("."))
@@ -433632,7 +434255,7 @@ function resolveLocalModSources(options = {}) {
433632
434255
  const includeGlobalMods = options.includeGlobalMods !== false;
433633
434256
  const managedPackages = includeGlobalMods ? resolveManagedModPackages(globalModsDirectory) : { diagnostics: [], files: [], packages: [] };
433634
434257
  const sources = [];
433635
- if (includeGlobalMods && legacyGlobalExtensionsDirectory && path37.resolve(legacyGlobalExtensionsDirectory) !== path37.resolve(globalModsDirectory) && existsSync53(legacyGlobalExtensionsDirectory)) {
434258
+ if (includeGlobalMods && legacyGlobalExtensionsDirectory && path37.resolve(legacyGlobalExtensionsDirectory) !== path37.resolve(globalModsDirectory) && existsSync54(legacyGlobalExtensionsDirectory)) {
433636
434259
  sources.push({
433637
434260
  files: listModFiles(legacyGlobalExtensionsDirectory),
433638
434261
  legacyMigrationTargetRoot: globalModsDirectory,
@@ -433811,11 +434434,11 @@ function createNoopModPanelHandle() {
433811
434434
  // src/mods/mod-engine.ts
433812
434435
  import { createHash as createHash12 } from "node:crypto";
433813
434436
  import {
433814
- existsSync as existsSync54,
434437
+ existsSync as existsSync55,
433815
434438
  mkdirSync as mkdirSync41,
433816
- readdirSync as readdirSync21,
433817
- readFileSync as readFileSync44,
433818
- statSync as statSync19,
434439
+ readdirSync as readdirSync22,
434440
+ readFileSync as readFileSync45,
434441
+ statSync as statSync20,
433819
434442
  unlinkSync as unlinkSync13,
433820
434443
  writeFileSync as writeFileSync35
433821
434444
  } from "node:fs";
@@ -433990,7 +434613,7 @@ function prepareModForImport(modPath, source) {
433990
434613
  }
433991
434614
  function createImportableModPath(modPath, cacheDirectory, source) {
433992
434615
  const importCacheDirectory = getManagedPackageImportCacheDirectory(modPath, source) ?? cacheDirectory;
433993
- const sourceText = readFileSync44(modPath, "utf8");
434616
+ const sourceText = readFileSync45(modPath, "utf8");
433994
434617
  const hash3 = createHash12("sha256").update(sourceText).digest("hex").slice(0, 16);
433995
434618
  const fileExtension = path39.extname(modPath);
433996
434619
  const importableSource = prepareModForImport(modPath, sourceText);
@@ -434001,11 +434624,11 @@ function createImportableModPath(modPath, cacheDirectory, source) {
434001
434624
  }
434002
434625
  const baseName = path39.basename(modPath, fileExtension).replace(/[^a-zA-Z0-9_-]/g, "-");
434003
434626
  const importPath = path39.join(importCacheDirectory, `.letta-mod-${baseName}-${hash3}.mjs`);
434004
- if (!existsSync54(importPath)) {
434627
+ if (!existsSync55(importPath)) {
434005
434628
  writeFileSync35(importPath, importableSource, "utf8");
434006
434629
  }
434007
434630
  try {
434008
- for (const entry of readdirSync21(importCacheDirectory)) {
434631
+ for (const entry of readdirSync22(importCacheDirectory)) {
434009
434632
  if (entry.startsWith(`.letta-mod-${baseName}-`) && entry !== path39.basename(importPath)) {
434010
434633
  unlinkSync13(path39.join(importCacheDirectory, entry));
434011
434634
  }
@@ -434644,8 +435267,8 @@ async function loadLocalMods(options) {
434644
435267
  recordLegacyExtensionLoadedDiagnostic(registry4, owner, source, options.onDiagnostic);
434645
435268
  }
434646
435269
  try {
434647
- const mtimeMs = statSync19(modPath).mtimeMs;
434648
- const sourceText = readFileSync44(modPath, "utf8");
435270
+ const mtimeMs = statSync20(modPath).mtimeMs;
435271
+ const sourceText = readFileSync45(modPath, "utf8");
434649
435272
  recordDeprecatedContextApiSourceDiagnostics(sourceText, (diagnostic) => {
434650
435273
  recordModDiagnostic(registry4, {
434651
435274
  ...diagnostic,
@@ -435167,7 +435790,7 @@ var init_memfs_sync = __esm(() => {
435167
435790
 
435168
435791
  // src/websocket/listener/mod-adapter.ts
435169
435792
  import { createHash as createHash13 } from "node:crypto";
435170
- import { join as join75 } from "node:path";
435793
+ import { join as join76 } from "node:path";
435171
435794
  async function getUnavailableListenerClient() {
435172
435795
  throw new Error("letta.client is not available in listener mods");
435173
435796
  }
@@ -435243,14 +435866,14 @@ function ensureListenerModAdapter(runtime) {
435243
435866
  }
435244
435867
  function resolveListenerAgentModsDirectory(agentId) {
435245
435868
  try {
435246
- return settingsManager.isMemfsEnabled(agentId) ? join75(getScopedMemoryFilesystemRoot(agentId), "mods") : null;
435869
+ return settingsManager.isMemfsEnabled(agentId) ? join76(getScopedMemoryFilesystemRoot(agentId), "mods") : null;
435247
435870
  } catch {
435248
435871
  return null;
435249
435872
  }
435250
435873
  }
435251
435874
  function resolveListenerAgentModCacheDirectory(agentId) {
435252
435875
  const cacheKey = createHash13("sha256").update(agentId).digest("hex");
435253
- return join75(getModCacheDirectory(), "listener-agents", cacheKey);
435876
+ return join76(getModCacheDirectory(), "listener-agents", cacheKey);
435254
435877
  }
435255
435878
  async function ensureListenerAgentModAdapter(runtime, agentId) {
435256
435879
  runtime.agentModAdapters ??= new Map;
@@ -436790,7 +437413,8 @@ function finishClaimedTeleport(runtime, pending, commit, options = {}) {
436790
437413
  agentId: pending.agentId,
436791
437414
  conversationId: pending.conversationId,
436792
437415
  persistTerminalWithoutConsumers: intentRevision !== undefined,
436793
- expectedInterruptedRevision: intentRevision
437416
+ expectedInterruptedRevision: intentRevision,
437417
+ teleportHandoff: pending.activeTurn
436794
437418
  });
436795
437419
  } catch (error5) {
436796
437420
  abandonTeleportIntent(runtime.listener, pending, intentRevision);
@@ -437407,19 +438031,19 @@ function emitSkillsUpdated(socket, safeSocketSend) {
437407
438031
  }
437408
438032
  async function handleSkillCommand(parsed, socket, safeSocketSend) {
437409
438033
  const {
437410
- existsSync: existsSync55,
438034
+ existsSync: existsSync56,
437411
438035
  lstatSync: lstatSync3,
437412
438036
  mkdirSync: mkdirSync42,
437413
438037
  rmdirSync: rmdirSync2,
437414
438038
  symlinkSync: symlinkSync2,
437415
438039
  unlinkSync: unlinkSync14
437416
438040
  } = await import("node:fs");
437417
- const { basename: basename21, join: join76 } = await import("node:path");
437418
- const lettaHome = process.env.LETTA_HOME || join76(process.env.HOME || process.env.USERPROFILE || "~", ".letta");
437419
- const globalSkillsDir = join76(lettaHome, "skills");
438041
+ const { basename: basename21, join: join77 } = await import("node:path");
438042
+ const lettaHome = process.env.LETTA_HOME || join77(process.env.HOME || process.env.USERPROFILE || "~", ".letta");
438043
+ const globalSkillsDir = join77(lettaHome, "skills");
437420
438044
  if (parsed.type === "skill_enable") {
437421
438045
  try {
437422
- if (!existsSync55(parsed.skill_path)) {
438046
+ if (!existsSync56(parsed.skill_path)) {
437423
438047
  safeSocketSend(socket, {
437424
438048
  type: "skill_enable_response",
437425
438049
  request_id: parsed.request_id,
@@ -437428,8 +438052,8 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
437428
438052
  }, "listener_skill_send_failed", "listener_skill_command");
437429
438053
  return true;
437430
438054
  }
437431
- const skillMdPath = join76(parsed.skill_path, "SKILL.md");
437432
- if (!existsSync55(skillMdPath)) {
438055
+ const skillMdPath = join77(parsed.skill_path, "SKILL.md");
438056
+ if (!existsSync56(skillMdPath)) {
437433
438057
  safeSocketSend(socket, {
437434
438058
  type: "skill_enable_response",
437435
438059
  request_id: parsed.request_id,
@@ -437439,9 +438063,9 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
437439
438063
  return true;
437440
438064
  }
437441
438065
  const linkName = basename21(parsed.skill_path);
437442
- const linkPath = join76(globalSkillsDir, linkName);
438066
+ const linkPath = join77(globalSkillsDir, linkName);
437443
438067
  mkdirSync42(globalSkillsDir, { recursive: true });
437444
- if (existsSync55(linkPath)) {
438068
+ if (existsSync56(linkPath)) {
437445
438069
  const stat12 = lstatSync3(linkPath);
437446
438070
  if (stat12.isSymbolicLink()) {
437447
438071
  if (process.platform === "win32") {
@@ -437482,8 +438106,8 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
437482
438106
  }
437483
438107
  if (parsed.type === "skill_disable") {
437484
438108
  try {
437485
- const linkPath = join76(globalSkillsDir, parsed.name);
437486
- if (!existsSync55(linkPath)) {
438109
+ const linkPath = join77(globalSkillsDir, parsed.name);
438110
+ if (!existsSync56(linkPath)) {
437487
438111
  safeSocketSend(socket, {
437488
438112
  type: "skill_disable_response",
437489
438113
  request_id: parsed.request_id,
@@ -438403,7 +439027,7 @@ var init_control_inputs = __esm(async () => {
438403
439027
  });
438404
439028
 
438405
439029
  // src/websocket/terminal-handler.ts
438406
- import { existsSync as existsSync55 } from "node:fs";
439030
+ import { existsSync as existsSync56 } from "node:fs";
438407
439031
  import * as os7 from "node:os";
438408
439032
  import WebSocket6 from "ws";
438409
439033
  function getTerminalKey(connectionId, terminalId) {
@@ -438419,7 +439043,7 @@ function getDefaultShell() {
438419
439043
  "/bin/bash"
438420
439044
  ];
438421
439045
  for (const candidate of candidates2) {
438422
- if (candidate && existsSync55(candidate)) {
439046
+ if (candidate && existsSync56(candidate)) {
438423
439047
  return candidate;
438424
439048
  }
438425
439049
  }
@@ -440373,14 +440997,14 @@ var init_tui_perf = __esm(() => {
440373
440997
 
440374
440998
  // src/cli/helpers/chunk-log.ts
440375
440999
  import {
440376
- existsSync as existsSync56,
441000
+ existsSync as existsSync57,
440377
441001
  mkdirSync as mkdirSync43,
440378
- readdirSync as readdirSync22,
441002
+ readdirSync as readdirSync23,
440379
441003
  unlinkSync as unlinkSync14,
440380
441004
  writeFileSync as writeFileSync36
440381
441005
  } from "node:fs";
440382
441006
  import { homedir as homedir41 } from "node:os";
440383
- import { join as join76 } from "node:path";
441007
+ import { join as join77 } from "node:path";
440384
441008
  function truncateStr(value, maxLen) {
440385
441009
  if (value === null || value === undefined)
440386
441010
  return "";
@@ -440444,8 +441068,8 @@ class ChunkLog {
440444
441068
  agentDir = null;
440445
441069
  dirCreated = false;
440446
441070
  init(agentId, sessionId) {
440447
- this.agentDir = join76(LOG_BASE_DIR, agentId);
440448
- this.logPath = join76(this.agentDir, `${sessionId}.jsonl`);
441071
+ this.agentDir = join77(LOG_BASE_DIR, agentId);
441072
+ this.logPath = join77(this.agentDir, `${sessionId}.jsonl`);
440449
441073
  this.buffer = [];
440450
441074
  this.dirty = false;
440451
441075
  this.dirCreated = false;
@@ -440474,7 +441098,7 @@ class ChunkLog {
440474
441098
  if (this.dirCreated || !this.agentDir)
440475
441099
  return;
440476
441100
  try {
440477
- if (!existsSync56(this.agentDir)) {
441101
+ if (!existsSync57(this.agentDir)) {
440478
441102
  mkdirSync43(this.agentDir, { recursive: true });
440479
441103
  }
440480
441104
  this.dirCreated = true;
@@ -440499,14 +441123,14 @@ class ChunkLog {
440499
441123
  if (!this.agentDir)
440500
441124
  return;
440501
441125
  try {
440502
- if (!existsSync56(this.agentDir))
441126
+ if (!existsSync57(this.agentDir))
440503
441127
  return;
440504
- const files = readdirSync22(this.agentDir).filter((f4) => f4.endsWith(".jsonl")).sort();
441128
+ const files = readdirSync23(this.agentDir).filter((f4) => f4.endsWith(".jsonl")).sort();
440505
441129
  if (files.length >= MAX_SESSION_FILES2) {
440506
441130
  const toDelete = files.slice(0, files.length - MAX_SESSION_FILES2 + 1);
440507
441131
  for (const file of toDelete) {
440508
441132
  try {
440509
- unlinkSync14(join76(this.agentDir, file));
441133
+ unlinkSync14(join77(this.agentDir, file));
440510
441134
  } catch (e2) {
440511
441135
  debugWarn("chunkLog", `Failed to delete old session log ${file}: ${e2 instanceof Error ? e2.message : String(e2)}`);
440512
441136
  }
@@ -440520,7 +441144,7 @@ class ChunkLog {
440520
441144
  var MAX_ENTRIES = 100, CONTENT_TRUNCATE_LEN = 200, MAX_SESSION_FILES2 = 5, LOG_BASE_DIR, chunkLog;
440521
441145
  var init_chunk_log = __esm(() => {
440522
441146
  init_debug();
440523
- LOG_BASE_DIR = join76(homedir41(), ".letta", "logs", "chunk-logs");
441147
+ LOG_BASE_DIR = join77(homedir41(), ".letta", "logs", "chunk-logs");
440524
441148
  chunkLog = new ChunkLog;
440525
441149
  });
440526
441150
 
@@ -441904,7 +442528,7 @@ function finishListenerTurn(runtime, lease, options) {
441904
442528
  type: "turn_finished",
441905
442529
  turn_id: options.turnId,
441906
442530
  stop_reason: options.stopReason,
441907
- ...options.terminalConsumerIds?.length ? {
442531
+ ...options.terminalConsumerIds?.length && !options.teleportHandoff ? {
441908
442532
  terminal_consumer_ids: [
441909
442533
  ...new Set(options.terminalConsumerIds)
441910
442534
  ]
@@ -442029,7 +442653,7 @@ function finishListenerTurn(runtime, lease, options) {
442029
442653
  conversation_id: options.conversationId
442030
442654
  });
442031
442655
  }
442032
- if (mayEmit && options.socket && turnFinishedMessage && preparedTurnFinished) {
442656
+ if (mayEmit && options.socket && turnFinishedMessage && preparedTurnFinished && !options.teleportHandoff) {
442033
442657
  emitDurableTurnFinished(options.socket, runtime, turnFinishedMessage, TO_SUBSCRIBERS, options.turnFinishedStore, preparedTurnFinished);
442034
442658
  }
442035
442659
  if (options.stopReason === "end_turn" || options.stopReason === "cancelled" && transition2.interruptionCause !== "transport") {
@@ -446547,8 +447171,8 @@ var init_turn_approval = __esm(async () => {
446547
447171
  });
446548
447172
 
446549
447173
  // src/agent/attached-repository-git-sync.ts
446550
- import { existsSync as existsSync57 } from "node:fs";
446551
- import { join as join77 } from "node:path";
447174
+ import { existsSync as existsSync58 } from "node:fs";
447175
+ import { join as join78 } from "node:path";
446552
447176
  async function getPendingCommitCount(path42) {
446553
447177
  const divergence = await getMemoryAheadBehind(path42);
446554
447178
  if (divergence) {
@@ -446578,7 +447202,7 @@ async function syncPendingAttachedRepositoryCommitsUnlocked(params) {
446578
447202
  path: path42,
446579
447203
  permissions: params.repository.permissions ?? "unknown"
446580
447204
  };
446581
- if (!existsSync57(join77(path42, ".git"))) {
447205
+ if (!existsSync58(join78(path42, ".git"))) {
446582
447206
  return {
446583
447207
  ...resultBase,
446584
447208
  status: "skipped",
@@ -446748,8 +447372,8 @@ var init_attached_repository_git_sync = __esm(() => {
446748
447372
  });
446749
447373
 
446750
447374
  // src/reminders/memory-git-sync.ts
446751
- import { existsSync as existsSync58 } from "node:fs";
446752
- import { join as join78 } from "node:path";
447375
+ import { existsSync as existsSync59 } from "node:fs";
447376
+ import { join as join79 } from "node:path";
446753
447377
  function formatMemoryRepairInProgressReminder(result3) {
446754
447378
  return `${SYSTEM_REMINDER_OPEN}
446755
447379
  MEMORY REPAIR RUNNING: A background worker is repairing the memory repository.
@@ -446859,7 +447483,7 @@ async function runPostTurnMemorySync(params, dependencies4 = {}) {
446859
447483
  if (memorySyncEnabled) {
446860
447484
  try {
446861
447485
  const memoryDir = getScopedMemoryFilesystemRoot(params.agentId);
446862
- const release = existsSync58(join78(memoryDir, ".git")) ? await (dependencies4.claimOperation ?? claimMemoryOperation)(memoryDir) : undefined;
447486
+ const release = existsSync59(join79(memoryDir, ".git")) ? await (dependencies4.claimOperation ?? claimMemoryOperation)(memoryDir) : undefined;
446863
447487
  if (release !== null) {
446864
447488
  try {
446865
447489
  const result3 = await syncMemory(params.agentId);
@@ -449098,7 +449722,7 @@ var init_core5 = __esm(() => {
449098
449722
  import { spawn as spawn10 } from "node:child_process";
449099
449723
  import { accessSync as accessSync2, constants as constants6 } from "node:fs";
449100
449724
  import { homedir as homedir42 } from "node:os";
449101
- import { join as join79 } from "node:path";
449725
+ import { join as join80 } from "node:path";
449102
449726
  import { fileURLToPath as fileURLToPath8 } from "node:url";
449103
449727
  async function normalizeCheckpoint(input) {
449104
449728
  const { decoded, bounds, filters } = await decodeCheckpoint(input);
@@ -449122,7 +449746,7 @@ async function decodeCheckpoint(input) {
449122
449746
  }
449123
449747
  async function loadDeepAgentsCheckpoint(checkpoint) {
449124
449748
  validateLocation(checkpoint);
449125
- const path42 = checkpoint.path ?? join79(homedir42(), ".deepagents", "sessions.db");
449749
+ const path42 = checkpoint.path ?? join80(homedir42(), ".deepagents", "sessions.db");
449126
449750
  const python = checkpoint.pythonExecutable ?? process.env.PYTHON ?? "python3";
449127
449751
  const helper = resolveHelperPath();
449128
449752
  return await new Promise((resolve39, reject2) => {
@@ -449341,8 +449965,8 @@ var init_deepagents = __esm(() => {
449341
449965
  });
449342
449966
 
449343
449967
  // node_modules/@letta-ai/trajectory/dist/adapters/listing-shared.js
449344
- import { readdirSync as readdirSync23, statSync as statSync20 } from "node:fs";
449345
- import { join as join80 } from "node:path";
449968
+ import { readdirSync as readdirSync24, statSync as statSync21 } from "node:fs";
449969
+ import { join as join81 } from "node:path";
449346
449970
  function sortListings(items3) {
449347
449971
  return items3.sort((left, right) => {
449348
449972
  const l3 = left.updatedAt ?? "";
@@ -449354,7 +449978,7 @@ function sortListings(items3) {
449354
449978
  }
449355
449979
  function safeReadDir(path42) {
449356
449980
  try {
449357
- return readdirSync23(path42, { withFileTypes: true }).map((entry) => ({
449981
+ return readdirSync24(path42, { withFileTypes: true }).map((entry) => ({
449358
449982
  name: entry.name,
449359
449983
  isDirectory: entry.isDirectory(),
449360
449984
  isFile: entry.isFile()
@@ -449365,7 +449989,7 @@ function safeReadDir(path42) {
449365
449989
  }
449366
449990
  function safeStat(path42) {
449367
449991
  try {
449368
- const stats = statSync20(path42);
449992
+ const stats = statSync21(path42);
449369
449993
  return { mtimeMs: stats.mtimeMs, sizeBytes: stats.size };
449370
449994
  } catch {
449371
449995
  return;
@@ -449387,7 +450011,7 @@ function collectFiles(root2, extension, depth) {
449387
450011
  return [];
449388
450012
  const collected = [];
449389
450013
  for (const entry of safeReadDir(root2)) {
449390
- const full = join80(root2, entry.name);
450014
+ const full = join81(root2, entry.name);
449391
450015
  if (entry.isFile && entry.name.endsWith(extension)) {
449392
450016
  collected.push(full);
449393
450017
  } else if (entry.isDirectory) {
@@ -449472,18 +450096,18 @@ var init_listing_shared = __esm(() => {
449472
450096
 
449473
450097
  // node_modules/@letta-ai/trajectory/dist/adapters/claude-code/list.js
449474
450098
  import { homedir as homedir43 } from "node:os";
449475
- import { basename as basename23, join as join81 } from "node:path";
450099
+ import { basename as basename23, join as join82 } from "node:path";
449476
450100
  async function listClaudeCodeTrajectories(root2) {
449477
- const base2 = root2 ?? join81(homedir43(), ".claude", "projects");
450101
+ const base2 = root2 ?? join82(homedir43(), ".claude", "projects");
449478
450102
  const items3 = [];
449479
450103
  for (const project of safeReadDir(base2)) {
449480
450104
  if (!project.isDirectory)
449481
450105
  continue;
449482
- const projectPath = join81(base2, project.name);
450106
+ const projectPath = join82(base2, project.name);
449483
450107
  for (const entry of safeReadDir(projectPath)) {
449484
450108
  if (!entry.isFile || !entry.name.endsWith(".jsonl"))
449485
450109
  continue;
449486
- const path42 = join81(projectPath, entry.name);
450110
+ const path42 = join82(projectPath, entry.name);
449487
450111
  const listing = listingFromFile(basename23(entry.name, ".jsonl"), path42);
449488
450112
  if (listing)
449489
450113
  items3.push(listing);
@@ -449497,9 +450121,9 @@ var init_list = __esm(() => {
449497
450121
 
449498
450122
  // node_modules/@letta-ai/trajectory/dist/adapters/codex/list.js
449499
450123
  import { homedir as homedir44 } from "node:os";
449500
- import { basename as basename24, join as join82 } from "node:path";
450124
+ import { basename as basename24, join as join83 } from "node:path";
449501
450125
  async function listCodexTrajectories(root2) {
449502
- const base2 = root2 ?? join82(homedir44(), ".codex", "sessions");
450126
+ const base2 = root2 ?? join83(homedir44(), ".codex", "sessions");
449503
450127
  const items3 = [];
449504
450128
  for (const path42 of collectFiles(base2, ".jsonl", 4)) {
449505
450129
  const listing = listingFromFile(basename24(path42, ".jsonl"), path42);
@@ -449514,7 +450138,7 @@ var init_list2 = __esm(() => {
449514
450138
 
449515
450139
  // node_modules/@letta-ai/trajectory/dist/adapters/deepagents/list.js
449516
450140
  import { homedir as homedir45 } from "node:os";
449517
- import { join as join83 } from "node:path";
450141
+ import { join as join84 } from "node:path";
449518
450142
  async function listDeepAgentsTrajectories(root2) {
449519
450143
  const path42 = resolveStorePath(root2);
449520
450144
  if (!safeStat(path42))
@@ -449535,8 +450159,8 @@ async function listDeepAgentsTrajectories(root2) {
449535
450159
  }
449536
450160
  function resolveStorePath(root2) {
449537
450161
  if (root2 === undefined)
449538
- return join83(homedir45(), ".deepagents", "sessions.db");
449539
- return root2.endsWith(".db") ? root2 : join83(root2, "sessions.db");
450162
+ return join84(homedir45(), ".deepagents", "sessions.db");
450163
+ return root2.endsWith(".db") ? root2 : join84(root2, "sessions.db");
449540
450164
  }
449541
450165
  var init_list3 = __esm(() => {
449542
450166
  init_listing_shared();
@@ -449544,7 +450168,7 @@ var init_list3 = __esm(() => {
449544
450168
 
449545
450169
  // node_modules/@letta-ai/trajectory/dist/adapters/hermes/list.js
449546
450170
  import { homedir as homedir46 } from "node:os";
449547
- import { join as join84 } from "node:path";
450171
+ import { join as join85 } from "node:path";
449548
450172
  async function listHermesTrajectories(root2) {
449549
450173
  const path42 = resolveStorePath2(root2);
449550
450174
  if (!safeStat(path42))
@@ -449571,8 +450195,8 @@ async function listHermesTrajectories(root2) {
449571
450195
  }
449572
450196
  function resolveStorePath2(root2) {
449573
450197
  if (root2 === undefined)
449574
- return join84(homedir46(), ".hermes", "state.db");
449575
- return root2.endsWith(".db") ? root2 : join84(root2, "state.db");
450198
+ return join85(homedir46(), ".hermes", "state.db");
450199
+ return root2.endsWith(".db") ? root2 : join85(root2, "state.db");
449576
450200
  }
449577
450201
  function numeric2(value) {
449578
450202
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : undefined;
@@ -449583,18 +450207,18 @@ var init_list4 = __esm(() => {
449583
450207
 
449584
450208
  // node_modules/@letta-ai/trajectory/dist/adapters/letta-code/list.js
449585
450209
  import { homedir as homedir47 } from "node:os";
449586
- import { join as join85 } from "node:path";
450210
+ import { join as join86 } from "node:path";
449587
450211
  async function listLettaCodeTrajectories(root2) {
449588
- const base2 = root2 ?? join85(homedir47(), ".letta", "transcripts");
450212
+ const base2 = root2 ?? join86(homedir47(), ".letta", "transcripts");
449589
450213
  const items3 = [];
449590
450214
  for (const agent of safeReadDir(base2)) {
449591
450215
  if (!agent.isDirectory)
449592
450216
  continue;
449593
- const agentPath2 = join85(base2, agent.name);
450217
+ const agentPath2 = join86(base2, agent.name);
449594
450218
  for (const conversation of safeReadDir(agentPath2)) {
449595
450219
  if (!conversation.isDirectory)
449596
450220
  continue;
449597
- const path42 = join85(agentPath2, conversation.name, "transcript.jsonl");
450221
+ const path42 = join86(agentPath2, conversation.name, "transcript.jsonl");
449598
450222
  const listing = listingFromFile(`${agent.name}/${conversation.name}`, path42);
449599
450223
  if (listing && (listing.sizeBytes ?? 0) > 0)
449600
450224
  items3.push(listing);
@@ -449607,21 +450231,21 @@ var init_list5 = __esm(() => {
449607
450231
  });
449608
450232
 
449609
450233
  // node_modules/@letta-ai/trajectory/dist/adapters/openclaw/list.js
449610
- import { existsSync as existsSync59 } from "node:fs";
450234
+ import { existsSync as existsSync60 } from "node:fs";
449611
450235
  import { homedir as homedir48 } from "node:os";
449612
- import { basename as basename25, join as join86 } from "node:path";
450236
+ import { basename as basename25, join as join87 } from "node:path";
449613
450237
  async function listOpenClawTrajectories(root2) {
449614
450238
  const base2 = root2 ?? defaultStateDir();
449615
450239
  const items3 = [];
449616
- const agentsPath = join86(base2, "agents");
450240
+ const agentsPath = join87(base2, "agents");
449617
450241
  for (const agent of safeReadDir(agentsPath)) {
449618
450242
  if (!agent.isDirectory)
449619
450243
  continue;
449620
- const sessionsPath = join86(agentsPath, agent.name, "sessions");
450244
+ const sessionsPath = join87(agentsPath, agent.name, "sessions");
449621
450245
  for (const entry of safeReadDir(sessionsPath)) {
449622
450246
  if (!entry.isFile || !entry.name.endsWith(".jsonl"))
449623
450247
  continue;
449624
- const path42 = join86(sessionsPath, entry.name);
450248
+ const path42 = join87(sessionsPath, entry.name);
449625
450249
  const listing = listingFromFile(basename25(entry.name, ".jsonl"), path42);
449626
450250
  if (listing)
449627
450251
  items3.push(listing);
@@ -449633,10 +450257,10 @@ function defaultStateDir() {
449633
450257
  const override = process.env.OPENCLAW_STATE_DIR?.trim() || process.env.CLAWDBOT_STATE_DIR?.trim();
449634
450258
  if (override)
449635
450259
  return override;
449636
- const current = join86(homedir48(), ".openclaw");
449637
- if (existsSync59(current))
450260
+ const current = join87(homedir48(), ".openclaw");
450261
+ if (existsSync60(current))
449638
450262
  return current;
449639
- return join86(homedir48(), ".clawdbot");
450263
+ return join87(homedir48(), ".clawdbot");
449640
450264
  }
449641
450265
  var init_list6 = __esm(() => {
449642
450266
  init_listing_shared();
@@ -449644,14 +450268,14 @@ var init_list6 = __esm(() => {
449644
450268
 
449645
450269
  // node_modules/@letta-ai/trajectory/dist/adapters/openhands/list.js
449646
450270
  import { homedir as homedir49 } from "node:os";
449647
- import { join as join87 } from "node:path";
450271
+ import { join as join88 } from "node:path";
449648
450272
  async function listOpenHandsTrajectories(root2) {
449649
- const base2 = root2 ?? join87(homedir49(), ".openhands", "sessions");
450273
+ const base2 = root2 ?? join88(homedir49(), ".openhands", "sessions");
449650
450274
  const items3 = [];
449651
450275
  for (const entry of safeReadDir(base2)) {
449652
450276
  if (!entry.isDirectory)
449653
450277
  continue;
449654
- const path42 = join87(base2, entry.name);
450278
+ const path42 = join88(base2, entry.name);
449655
450279
  const facts = safeStat(path42);
449656
450280
  items3.push({
449657
450281
  id: entry.name,
@@ -449897,7 +450521,7 @@ import {
449897
450521
  stat as stat13,
449898
450522
  writeFile as writeFile16
449899
450523
  } from "node:fs/promises";
449900
- import { join as join88 } from "node:path";
450524
+ import { join as join89 } from "node:path";
449901
450525
  function buildReflectionSelectorPrompt(options) {
449902
450526
  const lines = [
449903
450527
  'You are selecting conversation transcripts for memory reflection. The transcript candidates path is available as the `$TRANSCRIPT_PATH` env var — read it via Bash (e.g. `wc -c "$TRANSCRIPT_PATH"`). Note: `$TRANSCRIPT_PATH` only expands in shell commands; Edit file_path is literal and does NOT expand env vars.',
@@ -449931,7 +450555,7 @@ async function collectParentMemoryFiles(memoryDir) {
449931
450555
  return a2.name.localeCompare(b3.name);
449932
450556
  });
449933
450557
  for (const entry of sortedEntries) {
449934
- const entryPath = join88(currentDir, entry.name);
450558
+ const entryPath = join89(currentDir, entry.name);
449935
450559
  const relativePath = relativeDir ? `${relativeDir}/${entry.name}` : entry.name;
449936
450560
  if (entry.isDirectory()) {
449937
450561
  await walk3(entryPath, relativePath);
@@ -450347,17 +450971,17 @@ async function writeState(paths, state2) {
450347
450971
  }
450348
450972
  function buildPayloadPath(rootDir, kind) {
450349
450973
  const nonce = Math.random().toString(36).slice(2, 8);
450350
- return join88(rootDir, `payload-${kind}-${nonce}.json`);
450974
+ return join89(rootDir, `payload-${kind}-${nonce}.json`);
450351
450975
  }
450352
450976
  function getAgentTranscriptRoot(agentId) {
450353
- return join88(getTranscriptRoot(), sanitizePathSegment2(agentId));
450977
+ return join89(getTranscriptRoot(), sanitizePathSegment2(agentId));
450354
450978
  }
450355
450979
  function getReflectionTranscriptPaths(agentId, conversationId) {
450356
- const rootDir = join88(getTranscriptRoot(), sanitizePathSegment2(agentId), sanitizePathSegment2(conversationId));
450980
+ const rootDir = join89(getTranscriptRoot(), sanitizePathSegment2(agentId), sanitizePathSegment2(conversationId));
450357
450981
  return {
450358
450982
  rootDir,
450359
- transcriptPath: join88(rootDir, "transcript.jsonl"),
450360
- statePath: join88(rootDir, "state.json")
450983
+ transcriptPath: join89(rootDir, "transcript.jsonl"),
450984
+ statePath: join89(rootDir, "state.json")
450361
450985
  };
450362
450986
  }
450363
450987
  async function appendTranscriptDeltaJsonl(agentId, conversationId, lines) {
@@ -450447,7 +451071,7 @@ async function getTranscriptLastUpdatedAt(paths) {
450447
451071
  }
450448
451072
  }
450449
451073
  async function ensureAgentPayloadRoot(agentId) {
450450
- const root2 = join88(getAgentTranscriptRoot(agentId), "multi-reflection-payloads");
451074
+ const root2 = join89(getAgentTranscriptRoot(agentId), "multi-reflection-payloads");
450451
451075
  await mkdir14(root2, { recursive: true });
450452
451076
  return root2;
450453
451077
  }
@@ -455229,9 +455853,9 @@ __export(exports_custom, {
455229
455853
  GLOBAL_COMMANDS_DIR: () => GLOBAL_COMMANDS_DIR,
455230
455854
  COMMANDS_DIR: () => COMMANDS_DIR
455231
455855
  });
455232
- import { existsSync as existsSync60 } from "node:fs";
455856
+ import { existsSync as existsSync61 } from "node:fs";
455233
455857
  import { readdir as readdir11, readFile as readFile24 } from "node:fs/promises";
455234
- import { basename as basename27, dirname as dirname33, join as join89 } from "node:path";
455858
+ import { basename as basename27, dirname as dirname33, join as join90 } from "node:path";
455235
455859
  async function getCustomCommands() {
455236
455860
  if (cachedCommands !== null) {
455237
455861
  return cachedCommands;
@@ -455242,7 +455866,7 @@ async function getCustomCommands() {
455242
455866
  function refreshCustomCommands() {
455243
455867
  cachedCommands = null;
455244
455868
  }
455245
- async function discoverCustomCommands(projectPath = join89(process.cwd(), COMMANDS_DIR)) {
455869
+ async function discoverCustomCommands(projectPath = join90(process.cwd(), COMMANDS_DIR)) {
455246
455870
  const commandsById = new Map;
455247
455871
  const userCommands = await discoverFromDirectory(GLOBAL_COMMANDS_DIR, "user");
455248
455872
  for (const cmd of userCommands) {
@@ -455263,7 +455887,7 @@ async function discoverCustomCommands(projectPath = join89(process.cwd(), COMMAN
455263
455887
  return result3;
455264
455888
  }
455265
455889
  async function discoverFromDirectory(dirPath, source) {
455266
- if (!existsSync60(dirPath)) {
455890
+ if (!existsSync61(dirPath)) {
455267
455891
  return [];
455268
455892
  }
455269
455893
  const commands = [];
@@ -455274,7 +455898,7 @@ async function findCommandFiles(currentPath, rootPath, commands, source) {
455274
455898
  try {
455275
455899
  const entries2 = await readdir11(currentPath, { withFileTypes: true });
455276
455900
  for (const entry of entries2) {
455277
- const fullPath = join89(currentPath, entry.name);
455901
+ const fullPath = join90(currentPath, entry.name);
455278
455902
  if (entry.isDirectory()) {
455279
455903
  await findCommandFiles(fullPath, rootPath, commands, source);
455280
455904
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
@@ -455359,7 +455983,7 @@ async function findCustomCommand(commandName) {
455359
455983
  }
455360
455984
  var COMMANDS_DIR = ".commands", GLOBAL_COMMANDS_DIR, cachedCommands = null;
455361
455985
  var init_custom = __esm(() => {
455362
- GLOBAL_COMMANDS_DIR = join89(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
455986
+ GLOBAL_COMMANDS_DIR = join90(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
455363
455987
  });
455364
455988
 
455365
455989
  // src/cli/helpers/doctor-command.ts
@@ -457001,7 +457625,7 @@ function handleMemfsSyncedMemoryProtocolCommand(parsed, context3) {
457001
457625
  }
457002
457626
  var init_memory_command_sync = __esm(async () => {
457003
457627
  init_memfs_sync();
457004
- await init_memory5();
457628
+ await init_memory6();
457005
457629
  });
457006
457630
 
457007
457631
  // src/websocket/listener/commands/queue.ts
@@ -458052,7 +458676,7 @@ function createListenerMessageHandler(params) {
458052
458676
  return;
458053
458677
  }
458054
458678
  if (parsed.type === "runtime_external_tools_update") {
458055
- const respond = (success, error5) => {
458679
+ const respond2 = (success, error5) => {
458056
458680
  safeSocketSend(socket, {
458057
458681
  type: "runtime_external_tools_update_response",
458058
458682
  request_id: parsed.request_id,
@@ -458061,11 +458685,11 @@ function createListenerMessageHandler(params) {
458061
458685
  }, "runtime_external_tools_update_response", "runtime_external_tools_update");
458062
458686
  };
458063
458687
  if (runtime !== getActiveRuntime() || runtime.intentionallyClosed) {
458064
- respond(false, "Runtime is no longer active");
458688
+ respond2(false, "Runtime is no longer active");
458065
458689
  return;
458066
458690
  }
458067
458691
  updateRuntimeExternalTools(runtime, connectionId, parsed.updates);
458068
- respond(true);
458692
+ respond2(true);
458069
458693
  return;
458070
458694
  }
458071
458695
  if (parsed.type === "sync") {
@@ -460613,7 +461237,7 @@ var init_client9 = __esm(async () => {
460613
461237
  init_approval(),
460614
461238
  init_agents_conversations(),
460615
461239
  init_cron3(),
460616
- init_memory5(),
461240
+ init_memory6(),
460617
461241
  init_model_toolset(),
460618
461242
  init_runtime_start(),
460619
461243
  init_settings3(),
@@ -462543,7 +463167,7 @@ __export(exports_app_server, {
462543
463167
  startAppServer: () => startAppServer,
462544
463168
  parseAppServerListenUrl: () => parseAppServerListenUrl
462545
463169
  });
462546
- import { createServer as createServer4 } from "node:http";
463170
+ import { createServer as createServer5 } from "node:http";
462547
463171
  import { hostname as hostname4 } from "node:os";
462548
463172
  import WebSocket11, { WebSocketServer } from "ws";
462549
463173
  function getRequiredAddressInfo(server2) {
@@ -462676,7 +463300,7 @@ async function startAppServer(options = {}) {
462676
463300
  closeSocket(socket, 1011, "failed to start connection");
462677
463301
  });
462678
463302
  };
462679
- const server2 = createServer4((request, response) => {
463303
+ const server2 = createServer5((request, response) => {
462680
463304
  const requestUrl = getRequestUrl(request, listen.host);
462681
463305
  if (request.headers.origin) {
462682
463306
  options.onLog?.(`Rejecting app-server request with Origin header: ${request.url ?? "/"}`);
@@ -463601,11 +464225,9 @@ async function runListenSubcommand(argv) {
463601
464225
  console.log(`[${formatTimestamp3()}] status: ${status}`);
463602
464226
  }
463603
464227
  },
463604
- onConnected: async () => {
463605
- await startChannelGateway();
463606
- },
464228
+ onConnected: () => {},
463607
464229
  onConnectionReady: async (connectedId) => {
463608
- const ready = await completeListenerConnectionStartup(connectedId, readiness);
464230
+ const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway);
463609
464231
  if (!ready)
463610
464232
  return;
463611
464233
  sessionLog.log("Local channel listener ready.");
@@ -463708,11 +464330,9 @@ async function runListenSubcommand(argv) {
463708
464330
  }
463709
464331
  },
463710
464332
  onLog: logListenerMessage,
463711
- onConnected: async () => {
463712
- await startChannelGateway();
463713
- },
464333
+ onConnected: () => {},
463714
464334
  onConnectionReady: async (connectedId) => {
463715
- const ready = await completeListenerConnectionStartup(connectedId, readiness);
464335
+ const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway);
463716
464336
  if (!ready)
463717
464337
  return;
463718
464338
  sessionLog.log("Connected. Awaiting instructions.");
@@ -463789,9 +464409,12 @@ async function runListenSubcommand(argv) {
463789
464409
  updateStatusCallback?.(status);
463790
464410
  },
463791
464411
  onLog: logListenerMessage,
463792
- onConnected: async () => {
464412
+ onConnected: () => {},
464413
+ onConnectionReady: async (connectedId) => {
464414
+ const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway);
464415
+ if (!ready)
464416
+ return;
463793
464417
  sessionLog.log("Connected. Awaiting instructions.");
463794
- await startChannelGateway();
463795
464418
  clearRetryStatusCallback?.();
463796
464419
  updateStatusCallback?.("idle");
463797
464420
  },
@@ -463888,17 +464511,17 @@ var init_listen = __esm(async () => {
463888
464511
  import { randomUUID as randomUUID51 } from "node:crypto";
463889
464512
  import {
463890
464513
  copyFileSync as copyFileSync3,
463891
- existsSync as existsSync61,
464514
+ existsSync as existsSync62,
463892
464515
  mkdirSync as mkdirSync44,
463893
- readdirSync as readdirSync24,
463894
- readFileSync as readFileSync45,
464516
+ readdirSync as readdirSync25,
464517
+ readFileSync as readFileSync46,
463895
464518
  writeFileSync as writeFileSync37
463896
464519
  } from "node:fs";
463897
- import { join as join90 } from "node:path";
464520
+ import { join as join91 } from "node:path";
463898
464521
  function readJsonl(path45) {
463899
- if (!existsSync61(path45))
464522
+ if (!existsSync62(path45))
463900
464523
  return [];
463901
- return readFileSync45(path45, "utf8").split(`
464524
+ return readFileSync46(path45, "utf8").split(`
463902
464525
  `).filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
463903
464526
  }
463904
464527
  function isLegacyUiMessage(value) {
@@ -464177,23 +464800,23 @@ function convertMessages4(messages, mode, nextId2) {
464177
464800
  }
464178
464801
  function migrateLocalBackendTranscripts(input) {
464179
464802
  const storageDir = input.storageDir;
464180
- const conversationsDir = join90(storageDir, "conversations");
464803
+ const conversationsDir = join91(storageDir, "conversations");
464181
464804
  const result3 = {
464182
464805
  storageDir,
464183
464806
  converted: [],
464184
464807
  skipped: [],
464185
464808
  dryRun: input.dryRun === true
464186
464809
  };
464187
- if (!existsSync61(conversationsDir))
464810
+ if (!existsSync62(conversationsDir))
464188
464811
  return result3;
464189
- for (const name of readdirSync24(conversationsDir)) {
464190
- const conversationDir = join90(conversationsDir, name);
464191
- const messagesPath = join90(conversationDir, "messages.jsonl");
464192
- const manifestPath = join90(conversationDir, "manifest.json");
464193
- const hasManifest = existsSync61(manifestPath);
464812
+ for (const name of readdirSync25(conversationsDir)) {
464813
+ const conversationDir = join91(conversationsDir, name);
464814
+ const messagesPath = join91(conversationDir, "messages.jsonl");
464815
+ const manifestPath = join91(conversationDir, "manifest.json");
464816
+ const hasManifest = existsSync62(manifestPath);
464194
464817
  const existingManifest = hasManifest ? (() => {
464195
464818
  try {
464196
- return JSON.parse(readFileSync45(manifestPath, "utf8"));
464819
+ return JSON.parse(readFileSync46(manifestPath, "utf8"));
464197
464820
  } catch {
464198
464821
  return;
464199
464822
  }
@@ -464232,11 +464855,11 @@ function migrateLocalBackendTranscripts(input) {
464232
464855
  const backupPath = `${messagesPath}.pre-pi-backup-${timestampSuffix()}`;
464233
464856
  if (!input.dryRun) {
464234
464857
  copyFileSync3(messagesPath, backupPath);
464235
- const conversationPath = join90(conversationDir, "conversation.json");
464858
+ const conversationPath = join91(conversationDir, "conversation.json");
464236
464859
  let conversation;
464237
- if (existsSync61(conversationPath)) {
464860
+ if (existsSync62(conversationPath)) {
464238
464861
  try {
464239
- conversation = JSON.parse(readFileSync45(conversationPath, "utf8"));
464862
+ conversation = JSON.parse(readFileSync46(conversationPath, "utf8"));
464240
464863
  } catch {
464241
464864
  conversation = undefined;
464242
464865
  }
@@ -464428,9 +465051,9 @@ var init_memory_tokens = __esm(() => {
464428
465051
  });
464429
465052
 
464430
465053
  // src/cli/subcommands/memory.ts
464431
- import { cpSync, existsSync as existsSync62, mkdirSync as mkdirSync45, rmSync as rmSync21, statSync as statSync21 } from "node:fs";
465054
+ import { cpSync, existsSync as existsSync63, mkdirSync as mkdirSync45, rmSync as rmSync21, statSync as statSync22 } from "node:fs";
464432
465055
  import { readdir as readdir12 } from "node:fs/promises";
464433
- import { dirname as dirname34, join as join91 } from "node:path";
465056
+ import { dirname as dirname34, join as join92 } from "node:path";
464434
465057
  import { parseArgs as parseArgs11 } from "node:util";
464435
465058
  function printUsage8() {
464436
465059
  console.log(`
@@ -464490,7 +465113,7 @@ function formatBackupTimestamp(date5 = new Date) {
464490
465113
  }
464491
465114
  async function listBackups(agentId) {
464492
465115
  const agentRoot = getAgentRoot(agentId);
464493
- if (!existsSync62(agentRoot)) {
465116
+ if (!existsSync63(agentRoot)) {
464494
465117
  return [];
464495
465118
  }
464496
465119
  const entries2 = await readdir12(agentRoot, { withFileTypes: true });
@@ -464500,10 +465123,10 @@ async function listBackups(agentId) {
464500
465123
  continue;
464501
465124
  if (!entry.name.startsWith("memory-backup-"))
464502
465125
  continue;
464503
- const path45 = join91(agentRoot, entry.name);
465126
+ const path45 = join92(agentRoot, entry.name);
464504
465127
  let createdAt = null;
464505
465128
  try {
464506
- const stat15 = statSync21(path45);
465129
+ const stat15 = statSync22(path45);
464507
465130
  createdAt = stat15.mtime.toISOString();
464508
465131
  } catch {
464509
465132
  createdAt = null;
@@ -464517,7 +465140,7 @@ function resolveBackupPath(agentId, from) {
464517
465140
  if (from.startsWith("/") || /^[A-Za-z]:[/\\]/.test(from)) {
464518
465141
  return from;
464519
465142
  }
464520
- return join91(getAgentRoot(agentId), from);
465143
+ return join92(getAgentRoot(agentId), from);
464521
465144
  }
464522
465145
  async function runMemorySubcommand(argv, deps = {}) {
464523
465146
  let parsed;
@@ -464595,14 +465218,14 @@ async function runMemorySubcommand(argv, deps = {}) {
464595
465218
  }
464596
465219
  if (action3 === "backup") {
464597
465220
  const root2 = getMemoryRoot(agentId);
464598
- if (!existsSync62(root2)) {
465221
+ if (!existsSync63(root2)) {
464599
465222
  console.error(`Memory directory not found for agent ${agentId}.`);
464600
465223
  return 1;
464601
465224
  }
464602
465225
  const agentRoot = getAgentRoot(agentId);
464603
465226
  const backupName = `memory-backup-${formatBackupTimestamp()}`;
464604
- const backupPath = join91(agentRoot, backupName);
464605
- if (existsSync62(backupPath)) {
465227
+ const backupPath = join92(agentRoot, backupName);
465228
+ if (existsSync63(backupPath)) {
464606
465229
  console.error(`Backup already exists at ${backupPath}`);
464607
465230
  return 1;
464608
465231
  }
@@ -464626,11 +465249,11 @@ async function runMemorySubcommand(argv, deps = {}) {
464626
465249
  return 1;
464627
465250
  }
464628
465251
  const backupPath = resolveBackupPath(agentId, from);
464629
- if (!existsSync62(backupPath)) {
465252
+ if (!existsSync63(backupPath)) {
464630
465253
  console.error(`Backup not found: ${backupPath}`);
464631
465254
  return 1;
464632
465255
  }
464633
- const stat15 = statSync21(backupPath);
465256
+ const stat15 = statSync22(backupPath);
464634
465257
  if (!stat15.isDirectory()) {
464635
465258
  console.error(`Backup path is not a directory: ${backupPath}`);
464636
465259
  return 1;
@@ -464648,12 +465271,12 @@ async function runMemorySubcommand(argv, deps = {}) {
464648
465271
  return 1;
464649
465272
  }
464650
465273
  const root2 = getMemoryRoot(agentId);
464651
- if (!existsSync62(root2)) {
465274
+ if (!existsSync63(root2)) {
464652
465275
  console.error(`Memory directory not found for agent ${agentId}.`);
464653
465276
  return 1;
464654
465277
  }
464655
- if (existsSync62(out)) {
464656
- const stat15 = statSync21(out);
465278
+ if (existsSync63(out)) {
465279
+ const stat15 = statSync22(out);
464657
465280
  if (stat15.isDirectory()) {
464658
465281
  const contents = await readdir12(out);
464659
465282
  if (contents.length > 0) {
@@ -464680,7 +465303,7 @@ async function runMemorySubcommand(argv, deps = {}) {
464680
465303
  return 1;
464681
465304
  }
464682
465305
  var MEMORY_OPTIONS;
464683
- var init_memory6 = __esm(() => {
465306
+ var init_memory7 = __esm(() => {
464684
465307
  init_memory_filesystem2();
464685
465308
  init_memory_git();
464686
465309
  init_paths();
@@ -464701,22 +465324,22 @@ var init_memory6 = __esm(() => {
464701
465324
  });
464702
465325
 
464703
465326
  // src/backend/local/transcript-search.ts
464704
- import { existsSync as existsSync63, readdirSync as readdirSync25, readFileSync as readFileSync46, statSync as statSync22 } from "node:fs";
464705
- import { join as join92 } from "node:path";
465327
+ import { existsSync as existsSync64, readdirSync as readdirSync26, readFileSync as readFileSync47, statSync as statSync23 } from "node:fs";
465328
+ import { join as join93 } from "node:path";
464706
465329
  function readJsonFile3(path45) {
464707
- if (!existsSync63(path45))
465330
+ if (!existsSync64(path45))
464708
465331
  return;
464709
465332
  try {
464710
- return JSON.parse(readFileSync46(path45, "utf8"));
465333
+ return JSON.parse(readFileSync47(path45, "utf8"));
464711
465334
  } catch {
464712
465335
  return;
464713
465336
  }
464714
465337
  }
464715
465338
  function readJsonlFile2(path45) {
464716
- if (!existsSync63(path45))
465339
+ if (!existsSync64(path45))
464717
465340
  return [];
464718
465341
  try {
464719
- return readFileSync46(path45, "utf8").split(`
465342
+ return readFileSync47(path45, "utf8").split(`
464720
465343
  `).filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
464721
465344
  } catch {
464722
465345
  return [];
@@ -464957,11 +465580,11 @@ function collectConversationMessages(input) {
464957
465580
  return [];
464958
465581
  if (input.conversationId && conversation.id !== input.conversationId)
464959
465582
  return [];
464960
- const messagesPath = join92(conversationDir, "messages.jsonl");
465583
+ const messagesPath = join93(conversationDir, "messages.jsonl");
464961
465584
  const rows = readJsonlFile2(messagesPath);
464962
465585
  if (rows.length === 0)
464963
465586
  return [];
464964
- const manifest2 = readJsonFile3(join92(conversationDir, "manifest.json"));
465587
+ const manifest2 = readJsonFile3(join93(conversationDir, "manifest.json"));
464965
465588
  const format5 = transcriptFormat(manifest2, rows);
464966
465589
  if (!format5)
464967
465590
  return [];
@@ -464990,11 +465613,11 @@ function collectConversationMessages(input) {
464990
465613
  }).filter((record6) => record6.tokens.length > 0);
464991
465614
  }
464992
465615
  function conversationDirectories(storageDir) {
464993
- const conversationsDir = join92(storageDir, "conversations");
464994
- if (!existsSync63(conversationsDir))
465616
+ const conversationsDir = join93(storageDir, "conversations");
465617
+ if (!existsSync64(conversationsDir))
464995
465618
  return [];
464996
465619
  try {
464997
- return readdirSync25(conversationsDir).map((entry) => join92(conversationsDir, entry)).filter((entryPath) => statSync22(entryPath).isDirectory());
465620
+ return readdirSync26(conversationsDir).map((entry) => join93(conversationsDir, entry)).filter((entryPath) => statSync23(entryPath).isDirectory());
464998
465621
  } catch {
464999
465622
  return [];
465000
465623
  }
@@ -465021,7 +465644,7 @@ function searchLocalTranscriptMessages(storageDir, body3, options = {}) {
465021
465644
  const endDate = typeof body3.end_date === "string" ? body3.end_date : undefined;
465022
465645
  const includeHidden = body3.include_hidden === true;
465023
465646
  const records2 = conversationDirectories(storageDir).flatMap((conversationDir) => {
465024
- const conversation = conversationSearchRecord(readJsonFile3(join92(conversationDir, "conversation.json")));
465647
+ const conversation = conversationSearchRecord(readJsonFile3(join93(conversationDir, "conversation.json")));
465025
465648
  if (!conversation)
465026
465649
  return [];
465027
465650
  if (conversation.hidden && !includeHidden)
@@ -465905,12 +466528,12 @@ var init_model2 = __esm(() => {
465905
466528
  import { spawn as spawn13 } from "node:child_process";
465906
466529
  import {
465907
466530
  copyFileSync as copyFileSync4,
465908
- existsSync as existsSync64,
466531
+ existsSync as existsSync65,
465909
466532
  lstatSync as lstatSync3,
465910
466533
  mkdirSync as mkdirSync46,
465911
466534
  mkdtempSync as mkdtempSync5,
465912
- readdirSync as readdirSync26,
465913
- readFileSync as readFileSync47,
466535
+ readdirSync as readdirSync27,
466536
+ readFileSync as readFileSync48,
465914
466537
  renameSync as renameSync12,
465915
466538
  rmSync as rmSync22,
465916
466539
  writeFileSync as writeFileSync38
@@ -465929,7 +466552,7 @@ function isPathInsideOrEqual2(childPath, parentPath) {
465929
466552
  function readPackageJson(packageJsonPath) {
465930
466553
  let parsed;
465931
466554
  try {
465932
- parsed = JSON.parse(readFileSync47(packageJsonPath, "utf8"));
466555
+ parsed = JSON.parse(readFileSync48(packageJsonPath, "utf8"));
465933
466556
  } catch (error5) {
465934
466557
  throw new Error(`Could not read package.json: ${error5 instanceof Error ? error5.message : String(error5)}`);
465935
466558
  }
@@ -466050,7 +466673,7 @@ function validatePackageSource(packageDirectory) {
466050
466673
  }
466051
466674
  function copyPackageDirectory(sourceRoot, targetRoot) {
466052
466675
  mkdirSync46(targetRoot, { recursive: true });
466053
- for (const entry of readdirSync26(sourceRoot, { withFileTypes: true })) {
466676
+ for (const entry of readdirSync27(sourceRoot, { withFileTypes: true })) {
466054
466677
  if (SKIPPED_PACKAGE_COPY_NAMES.has(entry.name))
466055
466678
  continue;
466056
466679
  const sourcePath = path45.join(sourceRoot, entry.name);
@@ -466082,7 +466705,7 @@ function shouldSkipDependencyPath(relativeParts, installedPackageName) {
466082
466705
  function copyDependencyDirectoryFiltered(params) {
466083
466706
  let copied = false;
466084
466707
  const relativeParts = params.relativeParts ?? [];
466085
- for (const entry of readdirSync26(params.sourceRoot, { withFileTypes: true })) {
466708
+ for (const entry of readdirSync27(params.sourceRoot, { withFileTypes: true })) {
466086
466709
  const nextRelativeParts = [...relativeParts, entry.name];
466087
466710
  if (shouldSkipDependencyPath(nextRelativeParts, params.installedPackageName)) {
466088
466711
  continue;
@@ -466114,7 +466737,7 @@ function copyDependencyDirectoryFiltered(params) {
466114
466737
  return copied;
466115
466738
  }
466116
466739
  function copyDependencyNodeModules(params) {
466117
- if (!existsSync64(params.sourceNodeModulesDirectory))
466740
+ if (!existsSync65(params.sourceNodeModulesDirectory))
466118
466741
  return;
466119
466742
  copyDependencyDirectoryFiltered({
466120
466743
  installedPackageName: params.installedPackageName,
@@ -466124,7 +466747,7 @@ function copyDependencyNodeModules(params) {
466124
466747
  }
466125
466748
  function copyPackageInternalNodeModules(params) {
466126
466749
  const sourceNodeModulesDirectory = path45.join(params.packageDirectory, "node_modules");
466127
- if (!existsSync64(sourceNodeModulesDirectory))
466750
+ if (!existsSync65(sourceNodeModulesDirectory))
466128
466751
  return;
466129
466752
  copyDependencyDirectoryFiltered({
466130
466753
  sourceRoot: sourceNodeModulesDirectory,
@@ -466146,12 +466769,12 @@ function removeIfExists(targetPath) {
466146
466769
  }
466147
466770
  function restoreDestination(params) {
466148
466771
  rmSync22(params.destinationRoot, { force: true, recursive: true });
466149
- if (params.backupRoot && existsSync64(params.backupRoot)) {
466772
+ if (params.backupRoot && existsSync65(params.backupRoot)) {
466150
466773
  renameSync12(params.backupRoot, params.destinationRoot);
466151
466774
  }
466152
466775
  }
466153
466776
  function restoreDestinationIfNeeded(params) {
466154
- if (!params.backupRoot || !existsSync64(params.backupRoot)) {
466777
+ if (!params.backupRoot || !existsSync65(params.backupRoot)) {
466155
466778
  rmSync22(params.destinationRoot, { force: true, recursive: true });
466156
466779
  return;
466157
466780
  }
@@ -466192,7 +466815,7 @@ function installPreparedManagedModPackage(params) {
466192
466815
  targetPackageRoot: stagingRoot
466193
466816
  });
466194
466817
  }
466195
- if (existsSync64(destinationRoot)) {
466818
+ if (existsSync65(destinationRoot)) {
466196
466819
  backupRoot = makeSiblingTempDirectory(destinationRoot, "backup");
466197
466820
  rmSync22(backupRoot, { force: true, recursive: true });
466198
466821
  renameSync12(destinationRoot, backupRoot);
@@ -466477,7 +467100,7 @@ function hasRuntimeDependencies(packageJson) {
466477
467100
  }
466478
467101
  function readPackageJsonIfExists(packageDirectory) {
466479
467102
  const packageJsonPath = path45.join(packageDirectory, "package.json");
466480
- if (!existsSync64(packageJsonPath))
467103
+ if (!existsSync65(packageJsonPath))
466481
467104
  return null;
466482
467105
  return readPackageJson(packageJsonPath);
466483
467106
  }
@@ -466491,13 +467114,13 @@ function isRegularModFile(filePath) {
466491
467114
  }
466492
467115
  function inferCompatibilityModEntries(packageDirectory) {
466493
467116
  const modsDirectory = path45.join(packageDirectory, "mods");
466494
- if (existsSync64(modsDirectory)) {
467117
+ if (existsSync65(modsDirectory)) {
466495
467118
  const stats = lstatSync3(modsDirectory);
466496
467119
  if (stats.isSymbolicLink()) {
466497
467120
  throw new Error(`Package mods directory must not be a symlink: mods`);
466498
467121
  }
466499
467122
  if (stats.isDirectory()) {
466500
- const entries2 = readdirSync26(modsDirectory, { withFileTypes: true }).filter((entry) => entry.isFile() && isModFileExtension(path45.extname(entry.name))).map((entry) => `mods/${entry.name}`).sort();
467123
+ const entries2 = readdirSync27(modsDirectory, { withFileTypes: true }).filter((entry) => entry.isFile() && isModFileExtension(path45.extname(entry.name))).map((entry) => `mods/${entry.name}`).sort();
466501
467124
  if (entries2.length > 0)
466502
467125
  return entries2;
466503
467126
  }
@@ -466766,7 +467389,7 @@ var init_package_installer = __esm(() => {
466766
467389
  // src/mods/package-scaffolder.ts
466767
467390
  import {
466768
467391
  copyFileSync as copyFileSync5,
466769
- existsSync as existsSync65,
467392
+ existsSync as existsSync66,
466770
467393
  lstatSync as lstatSync4,
466771
467394
  mkdirSync as mkdirSync47,
466772
467395
  rmSync as rmSync23,
@@ -466859,7 +467482,7 @@ function scaffoldLocalModPackage(options) {
466859
467482
  const sourceFile = readSourceFile(options.sourceFile);
466860
467483
  const packageName = assertValidPackageName(options.packageName);
466861
467484
  const outputDirectory = path46.resolve(options.outputDirectory ?? defaultOutputDirectory(sourceFile, packageName));
466862
- if (existsSync65(outputDirectory)) {
467485
+ if (existsSync66(outputDirectory)) {
466863
467486
  throw new Error(`Output directory already exists: ${outputDirectory}`);
466864
467487
  }
466865
467488
  const modFileName = path46.basename(sourceFile);
@@ -466901,7 +467524,7 @@ var init_package_scaffolder = __esm(() => {
466901
467524
  });
466902
467525
 
466903
467526
  // src/cli/subcommands/mods.ts
466904
- import { dirname as dirname35, join as join93 } from "node:path";
467527
+ import { dirname as dirname35, join as join94 } from "node:path";
466905
467528
  import { parseArgs as parseArgs14 } from "node:util";
466906
467529
  function printUsage11() {
466907
467530
  console.log(`
@@ -466940,7 +467563,7 @@ function getExplicitAgentId(values4) {
466940
467563
  return typeof explicitAgent === "string" && explicitAgent.trim() ? explicitAgent.trim() : null;
466941
467564
  }
466942
467565
  function getAgentModsDirectory(agentId) {
466943
- return join93(getScopedMemoryFilesystemRoot(agentId), "mods");
467566
+ return join94(getScopedMemoryFilesystemRoot(agentId), "mods");
466944
467567
  }
466945
467568
  function directFilesForSource(source) {
466946
467569
  return source.files.filter((file) => dirname35(file) === source.root);
@@ -468480,8 +469103,8 @@ var init_setup7 = __esm(async () => {
468480
469103
  });
468481
469104
 
468482
469105
  // src/cli/subcommands/shared-memory.ts
468483
- import { existsSync as existsSync66 } from "node:fs";
468484
- import { join as join94 } from "node:path";
469106
+ import { existsSync as existsSync67 } from "node:fs";
469107
+ import { join as join95 } from "node:path";
468485
469108
  import { parseArgs as parseArgs19 } from "node:util";
468486
469109
  function printUsage16() {
468487
469110
  console.log(`
@@ -468673,7 +469296,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
468673
469296
  invalidateClientSkills(agentId);
468674
469297
  const recompileError = await recompileAndReportFailure(recompileAgent, agentId);
468675
469298
  const mountDir = getRepositoryMountDir(agentId, repository.name);
468676
- const mounted = existsSync66(join94(mountDir, ".git"));
469299
+ const mounted = existsSync67(join95(mountDir, ".git"));
468677
469300
  console.log(JSON.stringify({
468678
469301
  attached: true,
468679
469302
  repository: { id: repository.id, name: repository.name },
@@ -470202,16 +470825,16 @@ var init_AgentSelector = __esm(async () => {
470202
470825
  // src/cli/subcommands/skills.ts
470203
470826
  import {
470204
470827
  cpSync as cpSync2,
470205
- existsSync as existsSync67,
470828
+ existsSync as existsSync68,
470206
470829
  mkdtempSync as mkdtempSync6,
470207
- readFileSync as readFileSync48,
470830
+ readFileSync as readFileSync49,
470208
470831
  rmSync as rmSync24,
470209
- statSync as statSync23,
470832
+ statSync as statSync24,
470210
470833
  writeFileSync as writeFileSync40
470211
470834
  } from "node:fs";
470212
470835
  import { mkdir as mkdir15, readdir as readdir13 } from "node:fs/promises";
470213
470836
  import { tmpdir as tmpdir14 } from "node:os";
470214
- import { basename as basename29, dirname as dirname36, join as join95, normalize as normalize4, resolve as resolve41, sep as sep7 } from "node:path";
470837
+ import { basename as basename29, dirname as dirname36, join as join96, normalize as normalize4, resolve as resolve41, sep as sep8 } from "node:path";
470215
470838
  import { parseArgs as parseArgs20, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
470216
470839
  function printUsage17() {
470217
470840
  console.log(`
@@ -470503,14 +471126,14 @@ async function resolveBranchAndSubdir(location) {
470503
471126
  }
470504
471127
  async function cloneSkillSource(location) {
470505
471128
  const resolvedLocation = await resolveBranchAndSubdir(location);
470506
- const tmpDir = mkdtempSync6(join95(tmpdir14(), "letta-skill-install-"));
471129
+ const tmpDir = mkdtempSync6(join96(tmpdir14(), "letta-skill-install-"));
470507
471130
  const args = ["clone", "--depth", "1"];
470508
471131
  if (resolvedLocation.branch) {
470509
471132
  args.push("--branch", resolvedLocation.branch);
470510
471133
  }
470511
471134
  args.push(resolvedLocation.repoUrl, tmpDir);
470512
471135
  await execFile22("git", args, { timeout: 120000 });
470513
- const sourceDir = resolvedLocation.subdir ? join95(tmpDir, resolvedLocation.subdir) : tmpDir;
471136
+ const sourceDir = resolvedLocation.subdir ? join96(tmpDir, resolvedLocation.subdir) : tmpDir;
470514
471137
  return { tmpDir, sourceDir };
470515
471138
  }
470516
471139
  function assertDirectSkillFileSize(receivedBytes, maxBytes) {
@@ -470565,11 +471188,11 @@ async function downloadDirectSkillFileSource(location, options = {}) {
470565
471188
  throw new Error(`Direct skill file download failed for ${location.url}: ${response.status}`);
470566
471189
  }
470567
471190
  const skillText = await readResponseTextWithLimit(response, MAX_DIRECT_SKILL_FILE_BYTES);
470568
- const tmpDir = mkdtempSync6(join95(tmpdir14(), "letta-direct-skill-"));
471191
+ const tmpDir = mkdtempSync6(join96(tmpdir14(), "letta-direct-skill-"));
470569
471192
  try {
470570
- const sourceDir = join95(tmpDir, "skill");
471193
+ const sourceDir = join96(tmpDir, "skill");
470571
471194
  await mkdir15(sourceDir, { recursive: true });
470572
- writeFileSync40(join95(sourceDir, "SKILL.md"), skillText, "utf8");
471195
+ writeFileSync40(join96(sourceDir, "SKILL.md"), skillText, "utf8");
470573
471196
  return { tmpDir, sourceDir };
470574
471197
  } catch (error5) {
470575
471198
  rmSync24(tmpDir, { recursive: true, force: true });
@@ -470610,9 +471233,9 @@ function assertSafeZipMember(name) {
470610
471233
  }
470611
471234
  async function downloadClawHubSkillSource(location) {
470612
471235
  const version3 = await resolveClawHubVersion(location);
470613
- const tmpDir = mkdtempSync6(join95(tmpdir14(), "letta-clawhub-skill-"));
470614
- const zipPath = join95(tmpDir, "skill.zip");
470615
- const sourceDir = join95(tmpDir, "skill");
471236
+ const tmpDir = mkdtempSync6(join96(tmpdir14(), "letta-clawhub-skill-"));
471237
+ const zipPath = join96(tmpDir, "skill.zip");
471238
+ const sourceDir = join96(tmpDir, "skill");
470616
471239
  await mkdir15(sourceDir, { recursive: true });
470617
471240
  const url2 = new URL(`${CLAWHUB_API_BASE_URL}/download`);
470618
471241
  url2.searchParams.set("slug", location.slug);
@@ -470639,7 +471262,7 @@ async function downloadClawHubSkillSource(location) {
470639
471262
  function assertInside(parent, child) {
470640
471263
  const parentPath = resolve41(parent);
470641
471264
  const childPath = resolve41(child);
470642
- if (childPath !== parentPath && !childPath.startsWith(`${parentPath}${sep7}`)) {
471265
+ if (childPath !== parentPath && !childPath.startsWith(`${parentPath}${sep8}`)) {
470643
471266
  throw new Error(`Resolved path is outside target directory: ${child}`);
470644
471267
  }
470645
471268
  }
@@ -470651,7 +471274,7 @@ function sanitizeSkillName(name) {
470651
471274
  return trimmed;
470652
471275
  }
470653
471276
  function getSkillName(sourceDir) {
470654
- const skillMd = readFileSync48(join95(sourceDir, "SKILL.md"), "utf8");
471277
+ const skillMd = readFileSync49(join96(sourceDir, "SKILL.md"), "utf8");
470655
471278
  const { frontmatter } = parseFrontmatter(skillMd);
470656
471279
  const frontmatterName = frontmatter.name;
470657
471280
  const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName : basename29(sourceDir);
@@ -470660,18 +471283,18 @@ function getSkillName(sourceDir) {
470660
471283
  async function installSkillDirectory(params) {
470661
471284
  const sourceDir = resolve41(params.sourceDir);
470662
471285
  const memoryDir = resolve41(params.memoryDir);
470663
- const skillMdPath = join95(sourceDir, "SKILL.md");
470664
- if (!existsSync67(skillMdPath)) {
471286
+ const skillMdPath = join96(sourceDir, "SKILL.md");
471287
+ if (!existsSync68(skillMdPath)) {
470665
471288
  throw new Error("No SKILL.md found in the skill directory.");
470666
471289
  }
470667
- if (!statSync23(sourceDir).isDirectory()) {
471290
+ if (!statSync24(sourceDir).isDirectory()) {
470668
471291
  throw new Error(`Skill source is not a directory: ${sourceDir}`);
470669
471292
  }
470670
471293
  const name = getSkillName(sourceDir);
470671
- const skillsDir = join95(memoryDir, "skills");
470672
- const targetPath = join95(skillsDir, name);
471294
+ const skillsDir = join96(memoryDir, "skills");
471295
+ const targetPath = join96(skillsDir, name);
470673
471296
  assertInside(skillsDir, targetPath);
470674
- if (existsSync67(targetPath)) {
471297
+ if (existsSync68(targetPath)) {
470675
471298
  if (!params.force) {
470676
471299
  throw new Error(`Skill "${name}" already exists at ${targetPath}. Re-run with --force to replace it.`);
470677
471300
  }
@@ -470686,22 +471309,22 @@ async function installSkillDirectory(params) {
470686
471309
  }
470687
471310
  async function listSkillDirectories(params) {
470688
471311
  const memoryDir = resolve41(params.memoryDir);
470689
- const skillsDir = join95(memoryDir, "skills");
470690
- if (!existsSync67(skillsDir))
471312
+ const skillsDir = join96(memoryDir, "skills");
471313
+ if (!existsSync68(skillsDir))
470691
471314
  return [];
470692
471315
  const entries2 = await readdir13(skillsDir, { withFileTypes: true });
470693
471316
  const skills = [];
470694
471317
  for (const entry of entries2) {
470695
471318
  if (!entry.isDirectory())
470696
471319
  continue;
470697
- const skillDir = join95(skillsDir, entry.name);
470698
- const skillMdPath = join95(skillDir, "SKILL.md");
470699
- if (!existsSync67(skillMdPath))
471320
+ const skillDir = join96(skillsDir, entry.name);
471321
+ const skillMdPath = join96(skillDir, "SKILL.md");
471322
+ if (!existsSync68(skillMdPath))
470700
471323
  continue;
470701
471324
  let name = entry.name;
470702
471325
  let description;
470703
471326
  try {
470704
- const skillMd = readFileSync48(skillMdPath, "utf8");
471327
+ const skillMd = readFileSync49(skillMdPath, "utf8");
470705
471328
  const { frontmatter } = parseFrontmatter(skillMd);
470706
471329
  if (typeof frontmatter.name === "string" && frontmatter.name.trim()) {
470707
471330
  name = frontmatter.name.trim();
@@ -470716,14 +471339,14 @@ async function listSkillDirectories(params) {
470716
471339
  }
470717
471340
  async function deleteSkillDirectory(params) {
470718
471341
  const memoryDir = resolve41(params.memoryDir);
470719
- const skillsDir = join95(memoryDir, "skills");
471342
+ const skillsDir = join96(memoryDir, "skills");
470720
471343
  const name = sanitizeSkillName(params.name);
470721
- const targetPath = join95(skillsDir, name);
471344
+ const targetPath = join96(skillsDir, name);
470722
471345
  assertInside(skillsDir, targetPath);
470723
- if (!existsSync67(targetPath)) {
471346
+ if (!existsSync68(targetPath)) {
470724
471347
  throw new Error(`Skill "${name}" is not installed at ${targetPath}.`);
470725
471348
  }
470726
- if (!statSync23(targetPath).isDirectory()) {
471349
+ if (!statSync24(targetPath).isDirectory()) {
470727
471350
  throw new Error(`Skill path is not a directory: ${targetPath}`);
470728
471351
  }
470729
471352
  rmSync24(targetPath, { recursive: true, force: true });
@@ -470769,7 +471392,7 @@ async function installSkill(specifier, agentId, force) {
470769
471392
  tmpDir = downloaded.tmpDir;
470770
471393
  const sourceDir = resolve41(downloaded.sourceDir);
470771
471394
  assertInside(tmpDir, sourceDir);
470772
- if (!existsSync67(sourceDir)) {
471395
+ if (!existsSync68(sourceDir)) {
470773
471396
  const missingPath = source.type === "git" ? source.location.subdir ?? "." : source.type === "direct-file" ? source.location.url : source.location.slug;
470774
471397
  throw new Error(`Skill path not found: ${missingPath}`);
470775
471398
  }
@@ -471304,7 +471927,7 @@ var init_teleport2 = __esm(() => {
471304
471927
 
471305
471928
  // src/cli/subcommands/trajectories/readers.ts
471306
471929
  import { readdir as readdir14, readFile as readFile27, stat as stat16 } from "node:fs/promises";
471307
- import { join as join96 } from "node:path";
471930
+ import { join as join97 } from "node:path";
471308
471931
  async function loadSessionTranscript(item) {
471309
471932
  const stats = await stat16(item.path);
471310
471933
  if (stats.isDirectory()) {
@@ -471316,13 +471939,13 @@ async function loadSessionTranscript(item) {
471316
471939
  return readFile27(item.path, "utf-8");
471317
471940
  }
471318
471941
  async function assembleEventDirectory(sessionDir) {
471319
- const eventsSubdir = join96(sessionDir, "events");
471942
+ const eventsSubdir = join97(sessionDir, "events");
471320
471943
  const eventsDir = (await stat16(eventsSubdir).catch(() => null))?.isDirectory() ? eventsSubdir : sessionDir;
471321
471944
  const names2 = (await readdir14(eventsDir, { withFileTypes: true })).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a2, b3) => Number.parseInt(a2, 10) - Number.parseInt(b3, 10) || a2.localeCompare(b3));
471322
471945
  if (names2.length === 0) {
471323
471946
  throw new Error(`No event files found in ${eventsDir}`);
471324
471947
  }
471325
- const events = await Promise.all(names2.map(async (name) => JSON.parse(await readFile27(join96(eventsDir, name), "utf-8"))));
471948
+ const events = await Promise.all(names2.map(async (name) => JSON.parse(await readFile27(join97(eventsDir, name), "utf-8"))));
471326
471949
  return JSON.stringify(events);
471327
471950
  }
471328
471951
  async function openReadOnlyDatabase(path47) {
@@ -471400,7 +472023,7 @@ import {
471400
472023
  stat as stat17,
471401
472024
  writeFile as writeFile19
471402
472025
  } from "node:fs/promises";
471403
- import { basename as basename30, join as join97 } from "node:path";
472026
+ import { basename as basename30, join as join98 } from "node:path";
471404
472027
  function fileTimestamp(startedAt) {
471405
472028
  if (!startedAt)
471406
472029
  return "unknown-date";
@@ -471470,7 +472093,7 @@ async function prepareOutDir(outDir) {
471470
472093
  throw new Error(`--out ${outDir} is not empty and has no ${MANIFEST_NAME}; refusing to overwrite a directory this tool did not create`);
471471
472094
  }
471472
472095
  for (const entry of entries2) {
471473
- await rm12(join97(outDir, entry), { recursive: true, force: true });
472096
+ await rm12(join98(outDir, entry), { recursive: true, force: true });
471474
472097
  }
471475
472098
  } catch (error5) {
471476
472099
  if (error5.code !== "ENOENT")
@@ -471513,14 +472136,14 @@ async function runTrajectoryExport(options) {
471513
472136
  }
471514
472137
  const sessionId = sessionHash(source, id2);
471515
472138
  const base2 = `${fileTimestamp(stats.startedAt)}_${sessionId}`;
471516
- let file = join97(source, `${base2}.json`);
472139
+ let file = join98(source, `${base2}.json`);
471517
472140
  for (let suffix = 2;usedFiles.has(file); suffix += 1) {
471518
- file = join97(source, `${base2}-${suffix}.json`);
472141
+ file = join98(source, `${base2}-${suffix}.json`);
471519
472142
  }
471520
472143
  usedFiles.add(file);
471521
472144
  const body3 = JSON.stringify(records2);
471522
- await mkdir16(join97(options.outDir, source), { recursive: true });
471523
- await writeFile19(join97(options.outDir, file), body3, "utf-8");
472145
+ await mkdir16(join98(options.outDir, source), { recursive: true });
472146
+ await writeFile19(join98(options.outDir, file), body3, "utf-8");
471524
472147
  counts.exported += 1;
471525
472148
  manifest2.sessions.push({
471526
472149
  source,
@@ -471574,7 +472197,7 @@ async function runTrajectoryExport(options) {
471574
472197
  await exportCheckpoint(checkpoint, `${basename30(checkpoint.path)}-${checkpoint.threadId}`);
471575
472198
  }
471576
472199
  manifest2.sessions.sort((a2, b3) => (a2.startedAt ?? "").localeCompare(b3.startedAt ?? ""));
471577
- await writeFile19(join97(options.outDir, MANIFEST_NAME), JSON.stringify(manifest2, null, 2), "utf-8");
472200
+ await writeFile19(join98(options.outDir, MANIFEST_NAME), JSON.stringify(manifest2, null, 2), "utf-8");
471578
472201
  return manifest2;
471579
472202
  }
471580
472203
  var MANIFEST_NAME = "manifest.json", FIRST_PROMPT_MAX_CHARS = 200, LIST_PAGE_LIMIT = 1000;
@@ -471586,13 +472209,13 @@ var init_export = __esm(() => {
471586
472209
 
471587
472210
  // src/cli/subcommands/trajectories/review.ts
471588
472211
  import { readFile as readFile29 } from "node:fs/promises";
471589
- import { isAbsolute as isAbsolute26, join as join98 } from "node:path";
472212
+ import { isAbsolute as isAbsolute26, join as join99 } from "node:path";
471590
472213
  async function readManifest(dir) {
471591
472214
  let raw2;
471592
472215
  try {
471593
- raw2 = await readFile29(join98(dir, "manifest.json"), "utf-8");
472216
+ raw2 = await readFile29(join99(dir, "manifest.json"), "utf-8");
471594
472217
  } catch {
471595
- throw new Error(`No manifest at ${join98(dir, "manifest.json")}. Run: letta trajectories export --out ${dir}`);
472218
+ throw new Error(`No manifest at ${join99(dir, "manifest.json")}. Run: letta trajectories export --out ${dir}`);
471596
472219
  }
471597
472220
  return JSON.parse(raw2);
471598
472221
  }
@@ -471601,7 +472224,7 @@ function filterSessions(sessions3, filter3) {
471601
472224
  }
471602
472225
  async function resolveSessionFile(dir, target2) {
471603
472226
  if (target2.endsWith(".json")) {
471604
- const direct = isAbsolute26(target2) ? target2 : join98(dir, target2);
472227
+ const direct = isAbsolute26(target2) ? target2 : join99(dir, target2);
471605
472228
  try {
471606
472229
  await readFile29(direct, "utf-8");
471607
472230
  return direct;
@@ -471612,7 +472235,7 @@ async function resolveSessionFile(dir, target2) {
471612
472235
  if (!entry) {
471613
472236
  throw new Error(`No session "${target2}" in ${dir} (pass a file path, a manifest-relative file, or a sessionId)`);
471614
472237
  }
471615
- return join98(dir, entry.file);
472238
+ return join99(dir, entry.file);
471616
472239
  }
471617
472240
  function stamp(timestamp) {
471618
472241
  return (timestamp ?? "").slice(0, 19);
@@ -471655,7 +472278,7 @@ async function searchSessions(dir, keyword, options = {}) {
471655
472278
  for (const session2 of filterSessions(manifest2.sessions, options)) {
471656
472279
  let records2;
471657
472280
  try {
471658
- records2 = JSON.parse(await readFile29(join98(dir, session2.file), "utf-8"));
472281
+ records2 = JSON.parse(await readFile29(join99(dir, session2.file), "utf-8"));
471659
472282
  } catch {
471660
472283
  continue;
471661
472284
  }
@@ -475019,7 +475642,7 @@ var init_message_channel_gateway_tool = __esm(() => {
475019
475642
  });
475020
475643
 
475021
475644
  // src/channels/custom/scaffolding.ts
475022
- import { existsSync as existsSync68, mkdirSync as mkdirSync48, rmSync as rmSync25, writeFileSync as writeFileSync41 } from "node:fs";
475645
+ import { existsSync as existsSync69, mkdirSync as mkdirSync48, rmSync as rmSync25, writeFileSync as writeFileSync41 } from "node:fs";
475023
475646
  function removeUserPlugin(channelId) {
475024
475647
  if (FIRST_PARTY_SET.has(channelId)) {
475025
475648
  return;
@@ -475028,7 +475651,7 @@ function removeUserPlugin(channelId) {
475028
475651
  return;
475029
475652
  }
475030
475653
  const channelDir = getChannelDir(channelId);
475031
- if (!existsSync68(channelDir)) {
475654
+ if (!existsSync69(channelDir)) {
475032
475655
  return;
475033
475656
  }
475034
475657
  try {
@@ -476770,7 +477393,7 @@ var init_router = __esm(async () => {
476770
477393
  init_feedback3();
476771
477394
  init_local_backend2();
476772
477395
  init_mcp();
476773
- init_memory6();
477396
+ init_memory7();
476774
477397
  init_messages10();
476775
477398
  init_model2();
476776
477399
  init_permissions2();
@@ -477908,7 +478531,7 @@ function resolveHeadlessMemfsPolicy(options) {
477908
478531
  }
477909
478532
 
477910
478533
  // src/headless-mod-adapter.ts
477911
- import { join as join99 } from "node:path";
478534
+ import { join as join100 } from "node:path";
477912
478535
  function isHeadlessMemfsEnabled(agentId) {
477913
478536
  try {
477914
478537
  return settingsManager.isMemfsEnabled(agentId);
@@ -477979,7 +478602,7 @@ function createHeadlessModContext(options) {
477979
478602
  };
477980
478603
  }
477981
478604
  function createHeadlessModAdapter(options) {
477982
- const agentModsDirectory = isHeadlessMemfsEnabled(options.agent.id) ? join99(getScopedMemoryFilesystemRoot(options.agent.id), "mods") : undefined;
478605
+ const agentModsDirectory = isHeadlessMemfsEnabled(options.agent.id) ? join100(getScopedMemoryFilesystemRoot(options.agent.id), "mods") : undefined;
477983
478606
  return createModAdapter({
477984
478607
  ...agentModsDirectory ? { agentModsDirectory } : {},
477985
478608
  ...options.cacheDirectory ? { cacheDirectory: options.cacheDirectory } : {},
@@ -482649,10 +483272,10 @@ var init_cli_mod_context = __esm(() => {
482649
483272
 
482650
483273
  // src/cli/helpers/reflection-arena-hf-upload.ts
482651
483274
  import { execFile as execFileCb5 } from "node:child_process";
482652
- import { existsSync as existsSync70 } from "node:fs";
483275
+ import { existsSync as existsSync71 } from "node:fs";
482653
483276
  import { appendFile as appendFile2, chmod, mkdir as mkdir17, writeFile as writeFile20 } from "node:fs/promises";
482654
483277
  import { homedir as homedir53 } from "node:os";
482655
- import { join as join101 } from "node:path";
483278
+ import { join as join102 } from "node:path";
482656
483279
  import { promisify as promisify20 } from "node:util";
482657
483280
  function buildGitEnv(token2, askpassPath) {
482658
483281
  return {
@@ -482688,7 +483311,7 @@ async function runGit6(cwd2, args, env6) {
482688
483311
  }
482689
483312
  }
482690
483313
  async function writeGitAskpass(repoRoot) {
482691
- const askpassPath = join101(repoRoot, "hf-askpass.sh");
483314
+ const askpassPath = join102(repoRoot, "hf-askpass.sh");
482692
483315
  await writeFile20(askpassPath, [
482693
483316
  "#!/bin/sh",
482694
483317
  'case "$1" in',
@@ -482703,7 +483326,7 @@ async function writeGitAskpass(repoRoot) {
482703
483326
  }
482704
483327
  async function prepareHfRepo(env6) {
482705
483328
  await mkdir17(HF_CACHE_ROOT, { recursive: true });
482706
- if (!existsSync70(join101(HF_REPO_DIR, ".git"))) {
483329
+ if (!existsSync71(join102(HF_REPO_DIR, ".git"))) {
482707
483330
  await runGit6(HF_CACHE_ROOT, ["clone", "--depth", "1", HF_REPO_URL, HF_REPO_DIR], env6);
482708
483331
  return HF_REPO_DIR;
482709
483332
  }
@@ -482738,8 +483361,8 @@ async function maybeUploadReflectionArenaChoiceToHf(row) {
482738
483361
  const env6 = buildGitEnv(token2, askpassPath);
482739
483362
  try {
482740
483363
  const repoDir = await prepareHfRepo(env6);
482741
- await mkdir17(join101(repoDir, "data"), { recursive: true });
482742
- await appendFile2(join101(repoDir, HF_DATASET_PATH), `${JSON.stringify(row)}
483364
+ await mkdir17(join102(repoDir, "data"), { recursive: true });
483365
+ await appendFile2(join102(repoDir, HF_DATASET_PATH), `${JSON.stringify(row)}
482743
483366
  `, {
482744
483367
  encoding: "utf-8"
482745
483368
  });
@@ -482767,8 +483390,8 @@ var init_reflection_arena_hf_upload = __esm(() => {
482767
483390
  init_version();
482768
483391
  execFile23 = promisify20(execFileCb5);
482769
483392
  HF_REPO_URL = `https://huggingface.co/datasets/${HF_REPO_ID}`;
482770
- HF_CACHE_ROOT = join101(homedir53(), ".letta", "reflection-arena", "hf-upload");
482771
- HF_REPO_DIR = join101(HF_CACHE_ROOT, "repo");
483393
+ HF_CACHE_ROOT = join102(homedir53(), ".letta", "reflection-arena", "hf-upload");
483394
+ HF_REPO_DIR = join102(HF_CACHE_ROOT, "repo");
482772
483395
  });
482773
483396
 
482774
483397
  // src/cli/helpers/reflection-arena.ts
@@ -482776,7 +483399,7 @@ import { execFile as execFileCb6 } from "node:child_process";
482776
483399
  import { randomInt as randomInt2, randomUUID as randomUUID57 } from "node:crypto";
482777
483400
  import { appendFile as appendFile3, mkdir as mkdir18, readFile as readFile31, writeFile as writeFile21 } from "node:fs/promises";
482778
483401
  import { homedir as homedir54 } from "node:os";
482779
- import { join as join102 } from "node:path";
483402
+ import { join as join103 } from "node:path";
482780
483403
  import { promisify as promisify21 } from "node:util";
482781
483404
  function sampleReflectionArenaComparisonModel(excludedModels = []) {
482782
483405
  const excluded = new Set(excludedModels);
@@ -482825,16 +483448,16 @@ function candidateIsConfirmedNoOp(candidate) {
482825
483448
  return candidate.result?.success === true && candidate.result.memoryNoChanges === true && candidate.result.memoryHead === candidate.worktree.baseHead;
482826
483449
  }
482827
483450
  function getReflectionArenaRoot() {
482828
- return join102(homedir54(), ".letta", "reflection-arena");
483451
+ return join103(homedir54(), ".letta", "reflection-arena");
482829
483452
  }
482830
483453
  function getReflectionArenaRunsDir() {
482831
- return join102(getReflectionArenaRoot(), "runs");
483454
+ return join103(getReflectionArenaRoot(), "runs");
482832
483455
  }
482833
483456
  function getReflectionArenaChoiceLogPath() {
482834
- return join102(getReflectionArenaRoot(), "choices.jsonl");
483457
+ return join103(getReflectionArenaRoot(), "choices.jsonl");
482835
483458
  }
482836
483459
  function getReflectionArenaRunPath(runId) {
482837
- return join102(getReflectionArenaRunsDir(), `${runId}.json`);
483460
+ return join103(getReflectionArenaRunsDir(), `${runId}.json`);
482838
483461
  }
482839
483462
  async function saveReflectionArenaRun(run) {
482840
483463
  await mkdir18(getReflectionArenaRunsDir(), { recursive: true });
@@ -484262,13 +484885,13 @@ __export(exports_terminal_keybinding_installer, {
484262
484885
  });
484263
484886
  import {
484264
484887
  copyFileSync as copyFileSync6,
484265
- existsSync as existsSync71,
484888
+ existsSync as existsSync72,
484266
484889
  mkdirSync as mkdirSync50,
484267
- readFileSync as readFileSync50,
484890
+ readFileSync as readFileSync51,
484268
484891
  writeFileSync as writeFileSync43
484269
484892
  } from "node:fs";
484270
484893
  import { homedir as homedir55, platform as platform10 } from "node:os";
484271
- import { dirname as dirname37, join as join103 } from "node:path";
484894
+ import { dirname as dirname37, join as join104 } from "node:path";
484272
484895
  function detectTerminalType() {
484273
484896
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
484274
484897
  return "cursor";
@@ -484300,16 +484923,16 @@ function getKeybindingsPath(terminal) {
484300
484923
  }[terminal];
484301
484924
  const os9 = platform10();
484302
484925
  if (os9 === "darwin") {
484303
- return join103(homedir55(), "Library", "Application Support", appName, "User", "keybindings.json");
484926
+ return join104(homedir55(), "Library", "Application Support", appName, "User", "keybindings.json");
484304
484927
  }
484305
484928
  if (os9 === "win32") {
484306
484929
  const appData = process.env.APPDATA;
484307
484930
  if (!appData)
484308
484931
  return null;
484309
- return join103(appData, appName, "User", "keybindings.json");
484932
+ return join104(appData, appName, "User", "keybindings.json");
484310
484933
  }
484311
484934
  if (os9 === "linux") {
484312
- return join103(homedir55(), ".config", appName, "User", "keybindings.json");
484935
+ return join104(homedir55(), ".config", appName, "User", "keybindings.json");
484313
484936
  }
484314
484937
  return null;
484315
484938
  }
@@ -484331,10 +484954,10 @@ function parseKeybindings(content) {
484331
484954
  }
484332
484955
  }
484333
484956
  function keybindingExists(keybindingsPath) {
484334
- if (!existsSync71(keybindingsPath))
484957
+ if (!existsSync72(keybindingsPath))
484335
484958
  return false;
484336
484959
  try {
484337
- const content = readFileSync50(keybindingsPath, { encoding: "utf-8" });
484960
+ const content = readFileSync51(keybindingsPath, { encoding: "utf-8" });
484338
484961
  const keybindings = parseKeybindings(content);
484339
484962
  if (!keybindings)
484340
484963
  return false;
@@ -484344,7 +484967,7 @@ function keybindingExists(keybindingsPath) {
484344
484967
  }
484345
484968
  }
484346
484969
  function createBackup(keybindingsPath) {
484347
- if (!existsSync71(keybindingsPath))
484970
+ if (!existsSync72(keybindingsPath))
484348
484971
  return null;
484349
484972
  const backupPath = `${keybindingsPath}.letta-backup`;
484350
484973
  try {
@@ -484360,14 +484983,14 @@ function installKeybinding(keybindingsPath) {
484360
484983
  return { success: true, alreadyExists: true };
484361
484984
  }
484362
484985
  const parentDir = dirname37(keybindingsPath);
484363
- if (!existsSync71(parentDir)) {
484986
+ if (!existsSync72(parentDir)) {
484364
484987
  mkdirSync50(parentDir, { recursive: true });
484365
484988
  }
484366
484989
  let keybindings = [];
484367
484990
  let backupPath = null;
484368
- if (existsSync71(keybindingsPath)) {
484991
+ if (existsSync72(keybindingsPath)) {
484369
484992
  backupPath = createBackup(keybindingsPath);
484370
- const content = readFileSync50(keybindingsPath, { encoding: "utf-8" });
484993
+ const content = readFileSync51(keybindingsPath, { encoding: "utf-8" });
484371
484994
  const parsed = parseKeybindings(content);
484372
484995
  if (parsed === null) {
484373
484996
  return {
@@ -484395,10 +485018,10 @@ function installKeybinding(keybindingsPath) {
484395
485018
  }
484396
485019
  function removeKeybinding(keybindingsPath) {
484397
485020
  try {
484398
- if (!existsSync71(keybindingsPath)) {
485021
+ if (!existsSync72(keybindingsPath)) {
484399
485022
  return { success: true };
484400
485023
  }
484401
- const content = readFileSync50(keybindingsPath, { encoding: "utf-8" });
485024
+ const content = readFileSync51(keybindingsPath, { encoding: "utf-8" });
484402
485025
  const keybindings = parseKeybindings(content);
484403
485026
  if (!keybindings) {
484404
485027
  return {
@@ -484462,14 +485085,14 @@ function getWezTermConfigPath() {
484462
485085
  }
484463
485086
  const xdgConfig = process.env.XDG_CONFIG_HOME;
484464
485087
  if (xdgConfig) {
484465
- const xdgPath = join103(xdgConfig, "wezterm", "wezterm.lua");
484466
- if (existsSync71(xdgPath))
485088
+ const xdgPath = join104(xdgConfig, "wezterm", "wezterm.lua");
485089
+ if (existsSync72(xdgPath))
484467
485090
  return xdgPath;
484468
485091
  }
484469
- const configPath = join103(homedir55(), ".config", "wezterm", "wezterm.lua");
484470
- if (existsSync71(configPath))
485092
+ const configPath = join104(homedir55(), ".config", "wezterm", "wezterm.lua");
485093
+ if (existsSync72(configPath))
484471
485094
  return configPath;
484472
- return join103(homedir55(), ".wezterm.lua");
485095
+ return join104(homedir55(), ".wezterm.lua");
484473
485096
  }
484474
485097
  function stripLuaCommentsFromLine(line, blockCommentEnd) {
484475
485098
  let code2 = "";
@@ -484572,10 +485195,10 @@ ${WEZTERM_DELETE_FIX}
484572
485195
  `;
484573
485196
  }
484574
485197
  function wezTermDeleteFixExists(configPath) {
484575
- if (!existsSync71(configPath))
485198
+ if (!existsSync72(configPath))
484576
485199
  return false;
484577
485200
  try {
484578
- const content = readFileSync50(configPath, { encoding: "utf-8" });
485201
+ const content = readFileSync51(configPath, { encoding: "utf-8" });
484579
485202
  return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
484580
485203
  } catch {
484581
485204
  return false;
@@ -484589,14 +485212,14 @@ function installWezTermDeleteFix() {
484589
485212
  }
484590
485213
  let content = "";
484591
485214
  let backupPath = null;
484592
- if (existsSync71(configPath)) {
485215
+ if (existsSync72(configPath)) {
484593
485216
  backupPath = `${configPath}.letta-backup`;
484594
485217
  copyFileSync6(configPath, backupPath);
484595
- content = readFileSync50(configPath, { encoding: "utf-8" });
485218
+ content = readFileSync51(configPath, { encoding: "utf-8" });
484596
485219
  }
484597
485220
  content = injectWezTermDeleteFix(content);
484598
485221
  const parentDir = dirname37(configPath);
484599
- if (!existsSync71(parentDir)) {
485222
+ if (!existsSync72(parentDir)) {
484600
485223
  mkdirSync50(parentDir, { recursive: true });
484601
485224
  }
484602
485225
  writeFileSync43(configPath, content, { encoding: "utf-8" });
@@ -484648,9 +485271,9 @@ __export(exports_settings2, {
484648
485271
  getSetting: () => getSetting
484649
485272
  });
484650
485273
  import { homedir as homedir56 } from "node:os";
484651
- import { join as join104 } from "node:path";
485274
+ import { join as join105 } from "node:path";
484652
485275
  function getSettingsPath() {
484653
- return join104(homedir56(), ".letta", "settings.json");
485276
+ return join105(homedir56(), ".letta", "settings.json");
484654
485277
  }
484655
485278
  async function loadSettings() {
484656
485279
  const settingsPath = getSettingsPath();
@@ -484687,7 +485310,7 @@ async function getSetting(key3) {
484687
485310
  return settings3[key3];
484688
485311
  }
484689
485312
  function getProjectSettingsPath() {
484690
- return join104(process.cwd(), ".letta", "settings.local.json");
485313
+ return join105(process.cwd(), ".letta", "settings.local.json");
484691
485314
  }
484692
485315
  async function loadProjectSettings() {
484693
485316
  const settingsPath = getProjectSettingsPath();
@@ -484705,7 +485328,7 @@ async function loadProjectSettings() {
484705
485328
  }
484706
485329
  async function saveProjectSettings(settings3) {
484707
485330
  const settingsPath = getProjectSettingsPath();
484708
- const dirPath = join104(process.cwd(), ".letta");
485331
+ const dirPath = join105(process.cwd(), ".letta");
484709
485332
  try {
484710
485333
  if (!exists(dirPath)) {
484711
485334
  await mkdir(dirPath, { recursive: true });
@@ -486593,9 +487216,9 @@ function getHeaderText(fileEdit) {
486593
487216
  const relPath = relative13(cwd2, fileEdit.filePath);
486594
487217
  const displayPath = relPath.startsWith("..") ? fileEdit.filePath : relPath;
486595
487218
  if (t2 === "write") {
486596
- const { existsSync: existsSync72 } = __require("node:fs");
487219
+ const { existsSync: existsSync73 } = __require("node:fs");
486597
487220
  try {
486598
- if (existsSync72(fileEdit.filePath)) {
487221
+ if (existsSync73(fileEdit.filePath)) {
486599
487222
  return `Overwrite ${displayPath}?`;
486600
487223
  }
486601
487224
  } catch {}
@@ -495512,20 +496135,20 @@ var init_InputRich = __esm(async () => {
495512
496135
  });
495513
496136
 
495514
496137
  // src/cli/commands/install-github-app.ts
495515
- import { execFileSync as execFileSync9 } from "node:child_process";
496138
+ import { execFileSync as execFileSync10 } from "node:child_process";
495516
496139
  import {
495517
- existsSync as existsSync72,
496140
+ existsSync as existsSync73,
495518
496141
  mkdirSync as mkdirSync51,
495519
496142
  mkdtempSync as mkdtempSync7,
495520
- readFileSync as readFileSync51,
496143
+ readFileSync as readFileSync52,
495521
496144
  rmSync as rmSync26,
495522
496145
  writeFileSync as writeFileSync44
495523
496146
  } from "node:fs";
495524
496147
  import { tmpdir as tmpdir15 } from "node:os";
495525
- import { dirname as dirname38, join as join105 } from "node:path";
496148
+ import { dirname as dirname38, join as join106 } from "node:path";
495526
496149
  function runCommand(command, args, cwd2, input) {
495527
496150
  try {
495528
- return execFileSync9(command, args, {
496151
+ return execFileSync10(command, args, {
495529
496152
  cwd: cwd2,
495530
496153
  encoding: "utf8",
495531
496154
  stdio: [input ? "pipe" : "ignore", "pipe", "pipe"],
@@ -495743,8 +496366,8 @@ async function createLettaAgent(apiKey, name) {
495743
496366
  return createMinimalAgent(apiKey, name);
495744
496367
  }
495745
496368
  function cloneRepoToTemp(repo) {
495746
- const tempDir = mkdtempSync7(join105(tmpdir15(), "letta-install-github-app-"));
495747
- const repoDir = join105(tempDir, "repo");
496369
+ const tempDir = mkdtempSync7(join106(tmpdir15(), "letta-install-github-app-"));
496370
+ const repoDir = join106(tempDir, "repo");
495748
496371
  runCommand("gh", ["repo", "clone", repo, repoDir, "--", "--depth=1"]);
495749
496372
  return { tempDir, repoDir };
495750
496373
  }
@@ -495755,14 +496378,14 @@ function runGit7(args, cwd2) {
495755
496378
  return runCommand("git", args, cwd2);
495756
496379
  }
495757
496380
  function writeWorkflow(repoDir, workflowPath, content) {
495758
- const absolutePath = join105(repoDir, workflowPath);
495759
- if (!existsSync72(dirname38(absolutePath))) {
496381
+ const absolutePath = join106(repoDir, workflowPath);
496382
+ if (!existsSync73(dirname38(absolutePath))) {
495760
496383
  mkdirSync51(dirname38(absolutePath), { recursive: true });
495761
496384
  }
495762
496385
  const next = `${content.trimEnd()}
495763
496386
  `;
495764
- if (existsSync72(absolutePath)) {
495765
- const previous = readFileSync51(absolutePath, "utf8");
496387
+ if (existsSync73(absolutePath)) {
496388
+ const previous = readFileSync52(absolutePath, "utf8");
495766
496389
  if (previous === next) {
495767
496390
  return false;
495768
496391
  }
@@ -499651,9 +500274,9 @@ __export(exports_generate_memory_viewer, {
499651
500274
  generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
499652
500275
  });
499653
500276
  import { execFile as execFileCb7 } from "node:child_process";
499654
- import { chmodSync as chmodSync8, existsSync as existsSync73, mkdirSync as mkdirSync52, writeFileSync as writeFileSync45 } from "node:fs";
500277
+ import { chmodSync as chmodSync8, existsSync as existsSync74, mkdirSync as mkdirSync52, writeFileSync as writeFileSync45 } from "node:fs";
499655
500278
  import { homedir as homedir58 } from "node:os";
499656
- import { join as join106 } from "node:path";
500279
+ import { join as join107 } from "node:path";
499657
500280
  import { promisify as promisify22 } from "node:util";
499658
500281
  function messagesFromOverview(overview) {
499659
500282
  return overview.messages?.map((message) => ({
@@ -499962,7 +500585,7 @@ ${m4.body}` : m4.subject;
499962
500585
  async function generateAndOpenMemoryViewer(agentId, options) {
499963
500586
  const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
499964
500587
  const repoDir = memoryRoot;
499965
- if (!existsSync73(join106(repoDir, ".git"))) {
500588
+ if (!existsSync74(join107(repoDir, ".git"))) {
499966
500589
  throw new Error("Memory viewer requires memfs. Run /memfs enable first.");
499967
500590
  }
499968
500591
  const data = await collectMemoryData(agentId, repoDir, memoryRoot, options?.conversationId);
@@ -499972,13 +500595,13 @@ async function generateAndOpenMemoryViewer(agentId, options) {
499972
500595
  data.context = applyContextUsageSnapshot(data.context, options?.contextUsage);
499973
500596
  const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
499974
500597
  const html5 = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
499975
- if (!existsSync73(VIEWERS_DIR)) {
500598
+ if (!existsSync74(VIEWERS_DIR)) {
499976
500599
  mkdirSync52(VIEWERS_DIR, { recursive: true, mode: 448 });
499977
500600
  }
499978
500601
  try {
499979
500602
  chmodSync8(VIEWERS_DIR, 448);
499980
500603
  } catch {}
499981
- const filePath = join106(VIEWERS_DIR, `memory-${encodeURIComponent(agentId)}.html`);
500604
+ const filePath = join107(VIEWERS_DIR, `memory-${encodeURIComponent(agentId)}.html`);
499982
500605
  writeFileSync45(filePath, html5);
499983
500606
  chmodSync8(filePath, 384);
499984
500607
  const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
@@ -500004,13 +500627,13 @@ var init_generate_memory_viewer = __esm(() => {
500004
500627
  init_local_memory_context();
500005
500628
  init_memory_viewer_template();
500006
500629
  execFile25 = promisify22(execFileCb7);
500007
- VIEWERS_DIR = join106(homedir58(), ".letta", "viewers");
500630
+ VIEWERS_DIR = join107(homedir58(), ".letta", "viewers");
500008
500631
  REFLECTION_PATTERN = /\(reflection\)|🔮|reflection:/i;
500009
500632
  });
500010
500633
 
500011
500634
  // src/cli/components/MemfsTreeViewer.tsx
500012
- import { existsSync as existsSync74 } from "node:fs";
500013
- import { join as join107 } from "node:path";
500635
+ import { existsSync as existsSync75 } from "node:fs";
500636
+ import { join as join108 } from "node:path";
500014
500637
  function renderTreePrefix(node) {
500015
500638
  let prefix = "";
500016
500639
  for (let i4 = 0;i4 < node.depth; i4++) {
@@ -500038,8 +500661,8 @@ function MemfsTreeViewer({
500038
500661
  const [status, setStatus] = import_react88.useState(null);
500039
500662
  const statusTimerRef = import_react88.useRef(null);
500040
500663
  const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
500041
- const memoryExists = existsSync74(memoryRoot);
500042
- const hasGitRepo = import_react88.useMemo(() => existsSync74(join107(memoryRoot, ".git")), [memoryRoot]);
500664
+ const memoryExists = existsSync75(memoryRoot);
500665
+ const hasGitRepo = import_react88.useMemo(() => existsSync75(join108(memoryRoot, ".git")), [memoryRoot]);
500043
500666
  function showStatus(msg, durationMs) {
500044
500667
  if (statusTimerRef.current)
500045
500668
  clearTimeout(statusTimerRef.current);
@@ -502415,10 +503038,10 @@ var init_PersonalitySelector = __esm(async () => {
502415
503038
  // src/utils/aws-credentials.ts
502416
503039
  import { readFile as readFile32 } from "node:fs/promises";
502417
503040
  import { homedir as homedir59 } from "node:os";
502418
- import { join as join108 } from "node:path";
503041
+ import { join as join109 } from "node:path";
502419
503042
  async function parseAwsCredentials() {
502420
- const credentialsPath = join108(homedir59(), ".aws", "credentials");
502421
- const configPath = join108(homedir59(), ".aws", "config");
503043
+ const credentialsPath = join109(homedir59(), ".aws", "credentials");
503044
+ const configPath = join109(homedir59(), ".aws", "config");
502422
503045
  const profiles = new Map;
502423
503046
  try {
502424
503047
  const content = await readFile32(credentialsPath, "utf-8");
@@ -504083,8 +504706,8 @@ function SkillsDialog({ onClose, agentId }) {
504083
504706
  try {
504084
504707
  const { discoverSkills: discoverSkills2, SKILLS_DIR: SKILLS_DIR2 } = await Promise.resolve().then(() => (init_skills5(), exports_skills2));
504085
504708
  const { getSkillsDirectory: getSkillsDirectory2, getSkillSources: getSkillSources2 } = await Promise.resolve().then(() => (init_context(), exports_context));
504086
- const { join: join109 } = await import("node:path");
504087
- const skillsDir = getSkillsDirectory2() || join109(process.cwd(), SKILLS_DIR2);
504709
+ const { join: join110 } = await import("node:path");
504710
+ const skillsDir = getSkillsDirectory2() || join110(process.cwd(), SKILLS_DIR2);
504088
504711
  const result3 = await discoverSkills2(skillsDir, agentId, {
504089
504712
  sources: getSkillSources2()
504090
504713
  });
@@ -508407,9 +509030,9 @@ function getFileEditHeader(toolName2, toolArgs) {
508407
509030
  const relPath = relative13(cwd2, filePath);
508408
509031
  const displayPath = relPath.startsWith("..") ? filePath : relPath;
508409
509032
  if (t2 === "write") {
508410
- const { existsSync: existsSync75 } = __require("node:fs");
509033
+ const { existsSync: existsSync76 } = __require("node:fs");
508411
509034
  try {
508412
- if (existsSync75(filePath)) {
509035
+ if (existsSync76(filePath)) {
508413
509036
  return `Overwrite ${displayPath}?`;
508414
509037
  }
508415
509038
  } catch {}
@@ -510177,9 +510800,9 @@ __export(exports_generate_diff_viewer, {
510177
510800
  generateAndOpenDiffViewer: () => generateAndOpenDiffViewer
510178
510801
  });
510179
510802
  import { execFile as execFileCb8 } from "node:child_process";
510180
- import { chmodSync as chmodSync9, existsSync as existsSync75, mkdirSync as mkdirSync53, writeFileSync as writeFileSync46 } from "node:fs";
510803
+ import { chmodSync as chmodSync9, existsSync as existsSync76, mkdirSync as mkdirSync53, writeFileSync as writeFileSync46 } from "node:fs";
510181
510804
  import { homedir as homedir60 } from "node:os";
510182
- import { isAbsolute as isAbsolute27, join as join109, resolve as resolve44 } from "node:path";
510805
+ import { isAbsolute as isAbsolute27, join as join110, resolve as resolve44 } from "node:path";
510183
510806
  import { promisify as promisify23 } from "node:util";
510184
510807
  async function runGit8(cwd2, args) {
510185
510808
  try {
@@ -510402,13 +511025,13 @@ async function generateAndOpenDiffViewer(targetPath) {
510402
511025
  };
510403
511026
  const jsonPayload = JSON.stringify(payload).replace(/</g, "\\u003c");
510404
511027
  const html5 = diff_viewer_template_default.replace("<!--LETTA_DIFF_DATA_PLACEHOLDER-->", () => jsonPayload);
510405
- if (!existsSync75(VIEWERS_DIR2)) {
511028
+ if (!existsSync76(VIEWERS_DIR2)) {
510406
511029
  mkdirSync53(VIEWERS_DIR2, { recursive: true, mode: 448 });
510407
511030
  }
510408
511031
  try {
510409
511032
  chmodSync9(VIEWERS_DIR2, 448);
510410
511033
  } catch {}
510411
- const filePath = join109(VIEWERS_DIR2, `diff-${encodeURIComponent(worktreePath)}.html`);
511034
+ const filePath = join110(VIEWERS_DIR2, `diff-${encodeURIComponent(worktreePath)}.html`);
510412
511035
  writeFileSync46(filePath, html5);
510413
511036
  chmodSync9(filePath, 384);
510414
511037
  const skipOpen = shouldSkipOpen();
@@ -510477,7 +511100,7 @@ var execFile26, VIEWERS_DIR2, GIT_TIMEOUT_MS3 = 60000, GIT_MAX_BUFFER, MAX_RENDE
510477
511100
  var init_generate_diff_viewer = __esm(() => {
510478
511101
  init_diff_viewer_template();
510479
511102
  execFile26 = promisify23(execFileCb8);
510480
- VIEWERS_DIR2 = join109(homedir60(), ".letta", "viewers");
511103
+ VIEWERS_DIR2 = join110(homedir60(), ".letta", "viewers");
510481
511104
  GIT_MAX_BUFFER = 50 * 1024 * 1024;
510482
511105
  });
510483
511106
 
@@ -512422,16 +513045,16 @@ __export(exports_shell_aliases, {
512422
513045
  expandAliases: () => expandAliases,
512423
513046
  clearAliasCache: () => clearAliasCache
512424
513047
  });
512425
- import { existsSync as existsSync76, readFileSync as readFileSync52 } from "node:fs";
513048
+ import { existsSync as existsSync77, readFileSync as readFileSync53 } from "node:fs";
512426
513049
  import { homedir as homedir61 } from "node:os";
512427
- import { join as join110 } from "node:path";
513050
+ import { join as join111 } from "node:path";
512428
513051
  function parseAliasesFromFile(filePath) {
512429
513052
  const aliases = new Map;
512430
- if (!existsSync76(filePath)) {
513053
+ if (!existsSync77(filePath)) {
512431
513054
  return aliases;
512432
513055
  }
512433
513056
  try {
512434
- const content = readFileSync52(filePath, "utf-8");
513057
+ const content = readFileSync53(filePath, "utf-8");
512435
513058
  const lines = content.split(`
512436
513059
  `);
512437
513060
  let inFunction = false;
@@ -512496,7 +513119,7 @@ function loadAliases(forceReload = false) {
512496
513119
  const home = homedir61();
512497
513120
  const allAliases = new Map;
512498
513121
  for (const file of ALIAS_FILES) {
512499
- const filePath = join110(home, file);
513122
+ const filePath = join111(home, file);
512500
513123
  const fileAliases = parseAliasesFromFile(filePath);
512501
513124
  for (const [name, value] of fileAliases) {
512502
513125
  allAliases.set(name, value);
@@ -520696,9 +521319,9 @@ var init_conversation_switch_alert = __esm(() => {
520696
521319
 
520697
521320
  // src/cli/app/use-submit-handler.ts
520698
521321
  import { randomUUID as randomUUID62 } from "node:crypto";
520699
- import { existsSync as existsSync77, readFileSync as readFileSync53, renameSync as renameSync13 } from "node:fs";
521322
+ import { existsSync as existsSync78, readFileSync as readFileSync54, renameSync as renameSync13 } from "node:fs";
520700
521323
  import { tmpdir as tmpdir16 } from "node:os";
520701
- import { join as join111 } from "node:path";
521324
+ import { join as join112 } from "node:path";
520702
521325
  async function findCustomCommandByName(commandName) {
520703
521326
  const { findCustomCommand: findCustomCommand2 } = await Promise.resolve().then(() => (init_custom(), exports_custom));
520704
521327
  return findCustomCommand2(commandName);
@@ -521306,12 +521929,12 @@ ${SYSTEM_REMINDER_CLOSE}`),
521306
521929
  try {
521307
521930
  const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
521308
521931
  const personaCandidates = [
521309
- join111(memoryRoot, "system", "persona.md"),
521310
- join111(memoryRoot, "memory", "system", "persona.md")
521932
+ join112(memoryRoot, "system", "persona.md"),
521933
+ join112(memoryRoot, "memory", "system", "persona.md")
521311
521934
  ];
521312
- const personaPath = personaCandidates.find((candidate) => existsSync77(candidate));
521935
+ const personaPath = personaCandidates.find((candidate) => existsSync78(candidate));
521313
521936
  if (personaPath) {
521314
- const personaContent = readFileSync53(personaPath, "utf-8");
521937
+ const personaContent = readFileSync54(personaPath, "utf-8");
521315
521938
  setCurrentPersonalityId(detectPersonalityFromPersonaFile(personaContent));
521316
521939
  } else {
521317
521940
  setCurrentPersonalityId(null);
@@ -522155,11 +522778,11 @@ Path: ${memoryDir}`, true);
522155
522778
  setCommandRunning(true);
522156
522779
  try {
522157
522780
  const memoryDir = getScopedMemoryFilesystemRoot(agentId);
522158
- if (!existsSync77(memoryDir)) {
522781
+ if (!existsSync78(memoryDir)) {
522159
522782
  updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
522160
522783
  return { submitted: true };
522161
522784
  }
522162
- const backupDir = join111(tmpdir16(), `letta-memfs-reset-${agentId}-${Date.now()}`);
522785
+ const backupDir = join112(tmpdir16(), `letta-memfs-reset-${agentId}-${Date.now()}`);
522163
522786
  renameSync13(memoryDir, backupDir);
522164
522787
  if (getBackend().capabilities.localMemfs) {
522165
522788
  const { initializeLocalMemoryRepo: initializeLocalMemoryRepo2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
@@ -523074,7 +523697,7 @@ var init_use_submit_handler = __esm(async () => {
523074
523697
  });
523075
523698
 
523076
523699
  // src/cli/app/AppCoordinator.tsx
523077
- import { join as join112 } from "node:path";
523700
+ import { join as join113 } from "node:path";
523078
523701
  function buildStartupCommandHints(options) {
523079
523702
  const {
523080
523703
  isResumingConversation,
@@ -524356,7 +524979,7 @@ function App2({
524356
524979
  agentId: a2.agentId ?? null
524357
524980
  }))
524358
524981
  });
524359
- const agentModsDirectory = modContext.memfs.enabled && modContext.memfs.memoryDir ? join112(modContext.memfs.memoryDir, "mods") : null;
524982
+ const agentModsDirectory = modContext.memfs.enabled && modContext.memfs.memoryDir ? join113(modContext.memfs.memoryDir, "mods") : null;
524360
524983
  const modAdapter = useLocalModAdapter(modContext, {
524361
524984
  agentModsDirectory,
524362
524985
  disabled: modsDisabled,
@@ -525112,9 +525735,9 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
525112
525735
  (async () => {
525113
525736
  try {
525114
525737
  const { watch: watch4 } = await import("node:fs");
525115
- const { existsSync: existsSync78 } = await import("node:fs");
525738
+ const { existsSync: existsSync79 } = await import("node:fs");
525116
525739
  const memRoot = getScopedMemoryFilesystemRoot(agentId);
525117
- if (!existsSync78(memRoot))
525740
+ if (!existsSync79(memRoot))
525118
525741
  return;
525119
525742
  watcher2 = watch4(memRoot, { recursive: true }, () => {});
525120
525743
  memfsWatcherRef.current = watcher2;
@@ -526684,12 +527307,12 @@ EXAMPLES
526684
527307
  console.log(usage);
526685
527308
  }
526686
527309
  async function printInfo() {
526687
- const { join: join113 } = await import("node:path");
527310
+ const { join: join114 } = await import("node:path");
526688
527311
  const { getVersion: getVersion2 } = await Promise.resolve().then(() => (init_version(), exports_version));
526689
527312
  const { SKILLS_DIR: SKILLS_DIR2 } = await Promise.resolve().then(() => (init_skills5(), exports_skills2));
526690
527313
  const { exists: exists2 } = await Promise.resolve().then(() => (init_fs(), exports_fs));
526691
527314
  const cwd2 = process.cwd();
526692
- const skillsDir = join113(cwd2, SKILLS_DIR2);
527315
+ const skillsDir = join114(cwd2, SKILLS_DIR2);
526693
527316
  const skillsExist = exists2(skillsDir);
526694
527317
  await settingsManager.loadLocalProjectSettings(cwd2);
526695
527318
  const pinned = settingsManager.getPinnedAgents();
@@ -528129,6 +528752,7 @@ var init_src5 = __esm(async () => {
528129
528752
  init_backend2();
528130
528753
  init_metadata();
528131
528754
  init_paths();
528755
+ init_browser_discovery_server();
528132
528756
  init_args();
528133
528757
  init_app_urls();
528134
528758
  init_error_formatter();
@@ -528152,6 +528776,9 @@ var init_src5 = __esm(async () => {
528152
528776
  EMPTY_APPROVAL_ARRAY = [];
528153
528777
  EMPTY_MESSAGE_ARRAY = [];
528154
528778
  assertSupportedBunRuntime();
528779
+ startBrowserDiscoveryServer().ready.catch(() => {
528780
+ return;
528781
+ });
528155
528782
  main();
528156
528783
  });
528157
528784
 
@@ -530516,4 +531143,4 @@ function registerBunOAuthFlows() {
530516
531143
  registerBunOAuthFlows();
530517
531144
  await init_src5().then(() => exports_src2);
530518
531145
 
530519
- //# debugId=9CF03C78F5A48E9A64756E2164756E21
531146
+ //# debugId=F46164B649518D8764756E2164756E21