@letta-ai/letta-code 0.22.1 → 0.22.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/letta.js +464 -293
- package/package.json +1 -1
package/letta.js
CHANGED
|
@@ -3269,7 +3269,7 @@ var package_default;
|
|
|
3269
3269
|
var init_package = __esm(() => {
|
|
3270
3270
|
package_default = {
|
|
3271
3271
|
name: "@letta-ai/letta-code",
|
|
3272
|
-
version: "0.22.
|
|
3272
|
+
version: "0.22.2",
|
|
3273
3273
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3274
3274
|
type: "module",
|
|
3275
3275
|
bin: {
|
|
@@ -5153,19 +5153,86 @@ __export(exports_oauth, {
|
|
|
5153
5153
|
OAUTH_CONFIG: () => OAUTH_CONFIG,
|
|
5154
5154
|
LETTA_CLOUD_API_URL: () => LETTA_CLOUD_API_URL
|
|
5155
5155
|
});
|
|
5156
|
+
function getOAuthAuthHost() {
|
|
5157
|
+
try {
|
|
5158
|
+
return new URL(OAUTH_CONFIG.authBaseUrl).host;
|
|
5159
|
+
} catch {
|
|
5160
|
+
return OAUTH_CONFIG.authBaseUrl;
|
|
5161
|
+
}
|
|
5162
|
+
}
|
|
5163
|
+
function getErrorLikeMessage(value) {
|
|
5164
|
+
if (value instanceof Error) {
|
|
5165
|
+
return value.message.trim() || null;
|
|
5166
|
+
}
|
|
5167
|
+
if (!value || typeof value !== "object") {
|
|
5168
|
+
return null;
|
|
5169
|
+
}
|
|
5170
|
+
const message = value.message;
|
|
5171
|
+
return typeof message === "string" && message.trim().length > 0 ? message.trim() : null;
|
|
5172
|
+
}
|
|
5173
|
+
function getErrorLikeCode(value) {
|
|
5174
|
+
if (!value || typeof value !== "object") {
|
|
5175
|
+
return null;
|
|
5176
|
+
}
|
|
5177
|
+
const code = value.code;
|
|
5178
|
+
return typeof code === "string" && code.trim().length > 0 ? code.trim() : null;
|
|
5179
|
+
}
|
|
5180
|
+
function isGenericFetchFailureMessage(message) {
|
|
5181
|
+
const normalized = message.trim().toLowerCase();
|
|
5182
|
+
return normalized === "fetch failed" || normalized === "network request failed";
|
|
5183
|
+
}
|
|
5184
|
+
function isOAuthTransportError(error) {
|
|
5185
|
+
if (!(error instanceof Error)) {
|
|
5186
|
+
return false;
|
|
5187
|
+
}
|
|
5188
|
+
if (isGenericFetchFailureMessage(error.message)) {
|
|
5189
|
+
return true;
|
|
5190
|
+
}
|
|
5191
|
+
return error.name === "TypeError" && error.cause !== undefined;
|
|
5192
|
+
}
|
|
5193
|
+
function extractOAuthTransportDetail(error) {
|
|
5194
|
+
const directMessage = isGenericFetchFailureMessage(error.message) ? null : error.message.trim() || null;
|
|
5195
|
+
const causeMessage = getErrorLikeMessage(error.cause);
|
|
5196
|
+
const causeCode = getErrorLikeCode(error.cause);
|
|
5197
|
+
let detail = causeMessage ?? directMessage;
|
|
5198
|
+
if (!detail && causeCode) {
|
|
5199
|
+
detail = causeCode;
|
|
5200
|
+
}
|
|
5201
|
+
if (detail && causeCode && !detail.includes(causeCode)) {
|
|
5202
|
+
detail = `${detail} (${causeCode})`;
|
|
5203
|
+
}
|
|
5204
|
+
return detail;
|
|
5205
|
+
}
|
|
5206
|
+
function toOAuthActionError(action, error, options) {
|
|
5207
|
+
if (isOAuthTransportError(error)) {
|
|
5208
|
+
const host = getOAuthAuthHost();
|
|
5209
|
+
const detail = extractOAuthTransportDetail(error);
|
|
5210
|
+
const reachabilityHint = options?.browserHint ? "Browser authorization may have succeeded, but the CLI could not reach Letta auth servers from this machine." : "The CLI could not reach Letta auth servers from this machine.";
|
|
5211
|
+
return new Error(`Failed to ${action} from ${host}${detail ? `: ${detail}` : ""}. ${reachabilityHint} Check your network, DNS, proxy, VPN, or TLS settings.`);
|
|
5212
|
+
}
|
|
5213
|
+
if (error instanceof Error) {
|
|
5214
|
+
return error;
|
|
5215
|
+
}
|
|
5216
|
+
return new Error(`Failed to ${action}: ${String(error)}`);
|
|
5217
|
+
}
|
|
5156
5218
|
async function requestDeviceCode() {
|
|
5157
|
-
const
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5219
|
+
const authHost = getOAuthAuthHost();
|
|
5220
|
+
try {
|
|
5221
|
+
const response = await fetch(`${OAUTH_CONFIG.authBaseUrl}/api/oauth/device/code`, {
|
|
5222
|
+
method: "POST",
|
|
5223
|
+
headers: { "Content-Type": "application/json" },
|
|
5224
|
+
body: JSON.stringify({
|
|
5225
|
+
client_id: OAUTH_CONFIG.clientId
|
|
5226
|
+
})
|
|
5227
|
+
});
|
|
5228
|
+
if (!response.ok) {
|
|
5229
|
+
const error = await response.json();
|
|
5230
|
+
throw new Error(`Failed to request device code from ${authHost}: ${error.error_description || error.error}`);
|
|
5231
|
+
}
|
|
5232
|
+
return await response.json();
|
|
5233
|
+
} catch (error) {
|
|
5234
|
+
throw toOAuthActionError("request device code", error);
|
|
5167
5235
|
}
|
|
5168
|
-
return await response.json();
|
|
5169
5236
|
}
|
|
5170
5237
|
async function pollForToken(deviceCode, interval = 5, expiresIn = 900, deviceId, deviceName) {
|
|
5171
5238
|
const startTime = Date.now();
|
|
@@ -5211,7 +5278,9 @@ async function pollForToken(deviceCode, interval = 5, expiresIn = 900, deviceId,
|
|
|
5211
5278
|
context: "auth_oauth_token_poll"
|
|
5212
5279
|
});
|
|
5213
5280
|
if (error instanceof Error) {
|
|
5214
|
-
throw error
|
|
5281
|
+
throw toOAuthActionError("poll for OAuth token", error, {
|
|
5282
|
+
browserHint: true
|
|
5283
|
+
});
|
|
5215
5284
|
}
|
|
5216
5285
|
throw new Error(`Failed to poll for token: ${String(error)}`);
|
|
5217
5286
|
}
|
|
@@ -5219,23 +5288,28 @@ async function pollForToken(deviceCode, interval = 5, expiresIn = 900, deviceId,
|
|
|
5219
5288
|
throw new Error("Timeout waiting for authorization (15 minutes)");
|
|
5220
5289
|
}
|
|
5221
5290
|
async function refreshAccessToken(refreshToken, deviceId, deviceName) {
|
|
5222
|
-
const
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5291
|
+
const authHost = getOAuthAuthHost();
|
|
5292
|
+
try {
|
|
5293
|
+
const response = await fetch(`${OAUTH_CONFIG.authBaseUrl}/api/oauth/token`, {
|
|
5294
|
+
method: "POST",
|
|
5295
|
+
headers: { "Content-Type": "application/json" },
|
|
5296
|
+
body: JSON.stringify({
|
|
5297
|
+
grant_type: "refresh_token",
|
|
5298
|
+
client_id: OAUTH_CONFIG.clientId,
|
|
5299
|
+
refresh_token: refreshToken,
|
|
5300
|
+
refresh_token_mode: "new",
|
|
5301
|
+
device_id: deviceId,
|
|
5302
|
+
...deviceName && { device_name: deviceName }
|
|
5303
|
+
})
|
|
5304
|
+
});
|
|
5305
|
+
if (!response.ok) {
|
|
5306
|
+
const error = await response.json();
|
|
5307
|
+
throw new Error(`Failed to refresh access token from ${authHost}: ${error.error_description || error.error}`);
|
|
5308
|
+
}
|
|
5309
|
+
return await response.json();
|
|
5310
|
+
} catch (error) {
|
|
5311
|
+
throw toOAuthActionError("refresh access token", error);
|
|
5237
5312
|
}
|
|
5238
|
-
return await response.json();
|
|
5239
5313
|
}
|
|
5240
5314
|
async function revokeToken(refreshToken) {
|
|
5241
5315
|
try {
|
|
@@ -10364,19 +10438,86 @@ __export(exports_oauth2, {
|
|
|
10364
10438
|
OAUTH_CONFIG: () => OAUTH_CONFIG2,
|
|
10365
10439
|
LETTA_CLOUD_API_URL: () => LETTA_CLOUD_API_URL2
|
|
10366
10440
|
});
|
|
10441
|
+
function getOAuthAuthHost2() {
|
|
10442
|
+
try {
|
|
10443
|
+
return new URL(OAUTH_CONFIG2.authBaseUrl).host;
|
|
10444
|
+
} catch {
|
|
10445
|
+
return OAUTH_CONFIG2.authBaseUrl;
|
|
10446
|
+
}
|
|
10447
|
+
}
|
|
10448
|
+
function getErrorLikeMessage2(value) {
|
|
10449
|
+
if (value instanceof Error) {
|
|
10450
|
+
return value.message.trim() || null;
|
|
10451
|
+
}
|
|
10452
|
+
if (!value || typeof value !== "object") {
|
|
10453
|
+
return null;
|
|
10454
|
+
}
|
|
10455
|
+
const message = value.message;
|
|
10456
|
+
return typeof message === "string" && message.trim().length > 0 ? message.trim() : null;
|
|
10457
|
+
}
|
|
10458
|
+
function getErrorLikeCode2(value) {
|
|
10459
|
+
if (!value || typeof value !== "object") {
|
|
10460
|
+
return null;
|
|
10461
|
+
}
|
|
10462
|
+
const code = value.code;
|
|
10463
|
+
return typeof code === "string" && code.trim().length > 0 ? code.trim() : null;
|
|
10464
|
+
}
|
|
10465
|
+
function isGenericFetchFailureMessage2(message) {
|
|
10466
|
+
const normalized = message.trim().toLowerCase();
|
|
10467
|
+
return normalized === "fetch failed" || normalized === "network request failed";
|
|
10468
|
+
}
|
|
10469
|
+
function isOAuthTransportError2(error) {
|
|
10470
|
+
if (!(error instanceof Error)) {
|
|
10471
|
+
return false;
|
|
10472
|
+
}
|
|
10473
|
+
if (isGenericFetchFailureMessage2(error.message)) {
|
|
10474
|
+
return true;
|
|
10475
|
+
}
|
|
10476
|
+
return error.name === "TypeError" && error.cause !== undefined;
|
|
10477
|
+
}
|
|
10478
|
+
function extractOAuthTransportDetail2(error) {
|
|
10479
|
+
const directMessage = isGenericFetchFailureMessage2(error.message) ? null : error.message.trim() || null;
|
|
10480
|
+
const causeMessage = getErrorLikeMessage2(error.cause);
|
|
10481
|
+
const causeCode = getErrorLikeCode2(error.cause);
|
|
10482
|
+
let detail = causeMessage ?? directMessage;
|
|
10483
|
+
if (!detail && causeCode) {
|
|
10484
|
+
detail = causeCode;
|
|
10485
|
+
}
|
|
10486
|
+
if (detail && causeCode && !detail.includes(causeCode)) {
|
|
10487
|
+
detail = `${detail} (${causeCode})`;
|
|
10488
|
+
}
|
|
10489
|
+
return detail;
|
|
10490
|
+
}
|
|
10491
|
+
function toOAuthActionError2(action, error, options) {
|
|
10492
|
+
if (isOAuthTransportError2(error)) {
|
|
10493
|
+
const host = getOAuthAuthHost2();
|
|
10494
|
+
const detail = extractOAuthTransportDetail2(error);
|
|
10495
|
+
const reachabilityHint = options?.browserHint ? "Browser authorization may have succeeded, but the CLI could not reach Letta auth servers from this machine." : "The CLI could not reach Letta auth servers from this machine.";
|
|
10496
|
+
return new Error(`Failed to ${action} from ${host}${detail ? `: ${detail}` : ""}. ${reachabilityHint} Check your network, DNS, proxy, VPN, or TLS settings.`);
|
|
10497
|
+
}
|
|
10498
|
+
if (error instanceof Error) {
|
|
10499
|
+
return error;
|
|
10500
|
+
}
|
|
10501
|
+
return new Error(`Failed to ${action}: ${String(error)}`);
|
|
10502
|
+
}
|
|
10367
10503
|
async function requestDeviceCode2() {
|
|
10368
|
-
const
|
|
10369
|
-
|
|
10370
|
-
|
|
10371
|
-
|
|
10372
|
-
|
|
10373
|
-
|
|
10374
|
-
|
|
10375
|
-
|
|
10376
|
-
|
|
10377
|
-
|
|
10504
|
+
const authHost = getOAuthAuthHost2();
|
|
10505
|
+
try {
|
|
10506
|
+
const response = await fetch(`${OAUTH_CONFIG2.authBaseUrl}/api/oauth/device/code`, {
|
|
10507
|
+
method: "POST",
|
|
10508
|
+
headers: { "Content-Type": "application/json" },
|
|
10509
|
+
body: JSON.stringify({
|
|
10510
|
+
client_id: OAUTH_CONFIG2.clientId
|
|
10511
|
+
})
|
|
10512
|
+
});
|
|
10513
|
+
if (!response.ok) {
|
|
10514
|
+
const error = await response.json();
|
|
10515
|
+
throw new Error(`Failed to request device code from ${authHost}: ${error.error_description || error.error}`);
|
|
10516
|
+
}
|
|
10517
|
+
return await response.json();
|
|
10518
|
+
} catch (error) {
|
|
10519
|
+
throw toOAuthActionError2("request device code", error);
|
|
10378
10520
|
}
|
|
10379
|
-
return await response.json();
|
|
10380
10521
|
}
|
|
10381
10522
|
async function pollForToken2(deviceCode, interval = 5, expiresIn = 900, deviceId, deviceName) {
|
|
10382
10523
|
const startTime = Date.now();
|
|
@@ -10422,7 +10563,9 @@ async function pollForToken2(deviceCode, interval = 5, expiresIn = 900, deviceId
|
|
|
10422
10563
|
context: "auth_oauth_token_poll"
|
|
10423
10564
|
});
|
|
10424
10565
|
if (error instanceof Error) {
|
|
10425
|
-
throw error
|
|
10566
|
+
throw toOAuthActionError2("poll for OAuth token", error, {
|
|
10567
|
+
browserHint: true
|
|
10568
|
+
});
|
|
10426
10569
|
}
|
|
10427
10570
|
throw new Error(`Failed to poll for token: ${String(error)}`);
|
|
10428
10571
|
}
|
|
@@ -10430,23 +10573,28 @@ async function pollForToken2(deviceCode, interval = 5, expiresIn = 900, deviceId
|
|
|
10430
10573
|
throw new Error("Timeout waiting for authorization (15 minutes)");
|
|
10431
10574
|
}
|
|
10432
10575
|
async function refreshAccessToken2(refreshToken, deviceId, deviceName) {
|
|
10433
|
-
const
|
|
10434
|
-
|
|
10435
|
-
|
|
10436
|
-
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
|
|
10440
|
-
|
|
10441
|
-
|
|
10442
|
-
|
|
10443
|
-
|
|
10444
|
-
|
|
10445
|
-
|
|
10446
|
-
|
|
10447
|
-
|
|
10576
|
+
const authHost = getOAuthAuthHost2();
|
|
10577
|
+
try {
|
|
10578
|
+
const response = await fetch(`${OAUTH_CONFIG2.authBaseUrl}/api/oauth/token`, {
|
|
10579
|
+
method: "POST",
|
|
10580
|
+
headers: { "Content-Type": "application/json" },
|
|
10581
|
+
body: JSON.stringify({
|
|
10582
|
+
grant_type: "refresh_token",
|
|
10583
|
+
client_id: OAUTH_CONFIG2.clientId,
|
|
10584
|
+
refresh_token: refreshToken,
|
|
10585
|
+
refresh_token_mode: "new",
|
|
10586
|
+
device_id: deviceId,
|
|
10587
|
+
...deviceName && { device_name: deviceName }
|
|
10588
|
+
})
|
|
10589
|
+
});
|
|
10590
|
+
if (!response.ok) {
|
|
10591
|
+
const error = await response.json();
|
|
10592
|
+
throw new Error(`Failed to refresh access token from ${authHost}: ${error.error_description || error.error}`);
|
|
10593
|
+
}
|
|
10594
|
+
return await response.json();
|
|
10595
|
+
} catch (error) {
|
|
10596
|
+
throw toOAuthActionError2("refresh access token", error);
|
|
10448
10597
|
}
|
|
10449
|
-
return await response.json();
|
|
10450
10598
|
}
|
|
10451
10599
|
async function revokeToken2(refreshToken) {
|
|
10452
10600
|
try {
|
|
@@ -38922,6 +39070,10 @@ for file in $(git diff --cached --name-only --diff-filter=ACM | grep -E '^(memor
|
|
|
38922
39070
|
# Validate each line
|
|
38923
39071
|
while IFS= read -r line; do
|
|
38924
39072
|
[ -z "$line" ] && continue
|
|
39073
|
+
# Skip YAML multiline continuation lines (indented lines that continue a previous value)
|
|
39074
|
+
case "$line" in
|
|
39075
|
+
" "*|$' '*) continue ;;
|
|
39076
|
+
esac
|
|
38925
39077
|
|
|
38926
39078
|
key=$(echo "$line" | cut -d: -f1 | tr -d ' ')
|
|
38927
39079
|
value=$(echo "$line" | cut -d: -f2- | sed 's/^ *//;s/ *$//')
|
|
@@ -39842,11 +39994,227 @@ var init_routing = __esm(() => {
|
|
|
39842
39994
|
routesByKey = new Map;
|
|
39843
39995
|
});
|
|
39844
39996
|
|
|
39997
|
+
// src/cli/helpers/gitContext.ts
|
|
39998
|
+
import { execFileSync } from "node:child_process";
|
|
39999
|
+
function runGit3(args, cwd2) {
|
|
40000
|
+
try {
|
|
40001
|
+
return execFileSync("git", args, {
|
|
40002
|
+
cwd: cwd2,
|
|
40003
|
+
encoding: "utf-8",
|
|
40004
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
40005
|
+
}).trim();
|
|
40006
|
+
} catch {
|
|
40007
|
+
return null;
|
|
40008
|
+
}
|
|
40009
|
+
}
|
|
40010
|
+
function truncateLines(value, maxLines) {
|
|
40011
|
+
const lines = value.split(`
|
|
40012
|
+
`);
|
|
40013
|
+
if (lines.length <= maxLines) {
|
|
40014
|
+
return value;
|
|
40015
|
+
}
|
|
40016
|
+
return lines.slice(0, maxLines).join(`
|
|
40017
|
+
`) + `
|
|
40018
|
+
... and ${lines.length - maxLines} more changes`;
|
|
40019
|
+
}
|
|
40020
|
+
function formatGitUser(name, email) {
|
|
40021
|
+
if (!name && !email) {
|
|
40022
|
+
return null;
|
|
40023
|
+
}
|
|
40024
|
+
if (name && email) {
|
|
40025
|
+
return `${name} <${email}>`;
|
|
40026
|
+
}
|
|
40027
|
+
return name || email;
|
|
40028
|
+
}
|
|
40029
|
+
function gatherGitContextSnapshot(options = {}) {
|
|
40030
|
+
const cwd2 = options.cwd ?? process.cwd();
|
|
40031
|
+
const recentCommitLimit = options.recentCommitLimit ?? 3;
|
|
40032
|
+
if (!runGit3(["rev-parse", "--git-dir"], cwd2)) {
|
|
40033
|
+
return {
|
|
40034
|
+
isGitRepo: false,
|
|
40035
|
+
branch: null,
|
|
40036
|
+
status: null,
|
|
40037
|
+
recentCommits: null,
|
|
40038
|
+
gitUser: null
|
|
40039
|
+
};
|
|
40040
|
+
}
|
|
40041
|
+
const branch = runGit3(["branch", "--show-current"], cwd2);
|
|
40042
|
+
const fullStatus = runGit3(["status", "--short"], cwd2);
|
|
40043
|
+
const status = typeof fullStatus === "string" && options.statusLineLimit ? truncateLines(fullStatus, options.statusLineLimit) : fullStatus;
|
|
40044
|
+
const recentCommits = options.recentCommitFormat ? runGit3([
|
|
40045
|
+
"log",
|
|
40046
|
+
`--format=${options.recentCommitFormat}`,
|
|
40047
|
+
"-n",
|
|
40048
|
+
String(recentCommitLimit)
|
|
40049
|
+
], cwd2) : runGit3(["log", "--oneline", "-n", String(recentCommitLimit)], cwd2);
|
|
40050
|
+
const userConfig = runGit3(["config", "--get-regexp", "^user\\.(name|email)$"], cwd2);
|
|
40051
|
+
let userName = null;
|
|
40052
|
+
let userEmail = null;
|
|
40053
|
+
if (userConfig) {
|
|
40054
|
+
for (const line of userConfig.split(`
|
|
40055
|
+
`)) {
|
|
40056
|
+
if (line.startsWith("user.name "))
|
|
40057
|
+
userName = line.slice("user.name ".length);
|
|
40058
|
+
else if (line.startsWith("user.email "))
|
|
40059
|
+
userEmail = line.slice("user.email ".length);
|
|
40060
|
+
}
|
|
40061
|
+
}
|
|
40062
|
+
const gitUser = formatGitUser(userName, userEmail);
|
|
40063
|
+
return {
|
|
40064
|
+
isGitRepo: true,
|
|
40065
|
+
branch,
|
|
40066
|
+
status,
|
|
40067
|
+
recentCommits,
|
|
40068
|
+
gitUser
|
|
40069
|
+
};
|
|
40070
|
+
}
|
|
40071
|
+
function getGitContext(cwd2) {
|
|
40072
|
+
if (!runGit3(["rev-parse", "--git-dir"], cwd2)) {
|
|
40073
|
+
return null;
|
|
40074
|
+
}
|
|
40075
|
+
const branch = runGit3(["branch", "--show-current"], cwd2);
|
|
40076
|
+
const branchList = runGit3([
|
|
40077
|
+
"branch",
|
|
40078
|
+
"--sort=-committerdate",
|
|
40079
|
+
"--format=%(refname:short)",
|
|
40080
|
+
"--no-color"
|
|
40081
|
+
], cwd2);
|
|
40082
|
+
const recentBranches = branchList ? branchList.split(`
|
|
40083
|
+
`).map((b) => b.trim()).filter((b) => b.length > 0 && b !== branch).slice(0, 10) : [];
|
|
40084
|
+
return { branch, recent_branches: recentBranches };
|
|
40085
|
+
}
|
|
40086
|
+
var init_gitContext = () => {};
|
|
40087
|
+
|
|
40088
|
+
// src/cli/helpers/sessionContext.ts
|
|
40089
|
+
import { platform as platform3 } from "node:os";
|
|
40090
|
+
function getLocalTime() {
|
|
40091
|
+
const now = new Date;
|
|
40092
|
+
return now.toLocaleString(undefined, {
|
|
40093
|
+
weekday: "long",
|
|
40094
|
+
year: "numeric",
|
|
40095
|
+
month: "long",
|
|
40096
|
+
day: "numeric",
|
|
40097
|
+
hour: "2-digit",
|
|
40098
|
+
minute: "2-digit",
|
|
40099
|
+
timeZoneName: "short"
|
|
40100
|
+
});
|
|
40101
|
+
}
|
|
40102
|
+
function getDeviceType() {
|
|
40103
|
+
const p = platform3();
|
|
40104
|
+
switch (p) {
|
|
40105
|
+
case "darwin":
|
|
40106
|
+
return "macOS";
|
|
40107
|
+
case "win32":
|
|
40108
|
+
return "Windows";
|
|
40109
|
+
case "linux":
|
|
40110
|
+
return "Linux";
|
|
40111
|
+
default:
|
|
40112
|
+
return p;
|
|
40113
|
+
}
|
|
40114
|
+
}
|
|
40115
|
+
function getGitInfo(cwd2) {
|
|
40116
|
+
const git = gatherGitContextSnapshot({
|
|
40117
|
+
cwd: cwd2,
|
|
40118
|
+
recentCommitLimit: 3,
|
|
40119
|
+
recentCommitFormat: "%h %s (%an)",
|
|
40120
|
+
statusLineLimit: 20
|
|
40121
|
+
});
|
|
40122
|
+
if (!git.isGitRepo) {
|
|
40123
|
+
return { isGitRepo: false };
|
|
40124
|
+
}
|
|
40125
|
+
return {
|
|
40126
|
+
isGitRepo: true,
|
|
40127
|
+
branch: git.branch ?? "(unknown)",
|
|
40128
|
+
recentCommits: git.recentCommits ?? "(failed to get commits)",
|
|
40129
|
+
status: git.status || "(clean working tree)",
|
|
40130
|
+
gitUser: git.gitUser ?? "(not configured)"
|
|
40131
|
+
};
|
|
40132
|
+
}
|
|
40133
|
+
function getIntroText(source, reason) {
|
|
40134
|
+
if (reason === "cwd_changed") {
|
|
40135
|
+
return "The working directory for this conversation has changed. Updated environment context follows.";
|
|
40136
|
+
}
|
|
40137
|
+
switch (source) {
|
|
40138
|
+
case "listen":
|
|
40139
|
+
return "This conversation is now connected to a Letta Code execution environment.";
|
|
40140
|
+
case "headless":
|
|
40141
|
+
return "The user has just initiated a new connection via the Letta Code headless client.";
|
|
40142
|
+
default:
|
|
40143
|
+
return "The user has just initiated a new connection via the [Letta Code CLI client](https://docs.letta.com/letta-code/index.md).";
|
|
40144
|
+
}
|
|
40145
|
+
}
|
|
40146
|
+
function buildSessionContext(options) {
|
|
40147
|
+
try {
|
|
40148
|
+
const cwd2 = options?.cwd ?? process.cwd();
|
|
40149
|
+
const source = options?.source ?? "interactive-cli";
|
|
40150
|
+
const reason = options?.reason ?? "initial_attach";
|
|
40151
|
+
let version = "unknown";
|
|
40152
|
+
try {
|
|
40153
|
+
version = getVersion();
|
|
40154
|
+
} catch {}
|
|
40155
|
+
let deviceType = "unknown";
|
|
40156
|
+
try {
|
|
40157
|
+
deviceType = getDeviceType();
|
|
40158
|
+
} catch {}
|
|
40159
|
+
let localTime = "unknown";
|
|
40160
|
+
try {
|
|
40161
|
+
localTime = getLocalTime();
|
|
40162
|
+
} catch {}
|
|
40163
|
+
const gitInfo = getGitInfo(cwd2);
|
|
40164
|
+
let context2 = `${SYSTEM_REMINDER_OPEN}
|
|
40165
|
+
This is an automated message providing context about the user's environment.
|
|
40166
|
+
${getIntroText(source, reason)}
|
|
40167
|
+
|
|
40168
|
+
## Device Information
|
|
40169
|
+
- **Local time**: ${localTime}
|
|
40170
|
+
- **Device type**: ${deviceType}
|
|
40171
|
+
- **Letta Code version**: ${version}
|
|
40172
|
+
- **Current working directory**: ${cwd2}
|
|
40173
|
+
`;
|
|
40174
|
+
if (gitInfo.isGitRepo) {
|
|
40175
|
+
context2 += `- **Git repository**: Yes (branch: ${gitInfo.branch})
|
|
40176
|
+
- **Git user**: ${gitInfo.gitUser}
|
|
40177
|
+
|
|
40178
|
+
### Recent Commits
|
|
40179
|
+
\`\`\`
|
|
40180
|
+
${gitInfo.recentCommits}
|
|
40181
|
+
\`\`\`
|
|
40182
|
+
|
|
40183
|
+
### Git Status
|
|
40184
|
+
\`\`\`
|
|
40185
|
+
${gitInfo.status}
|
|
40186
|
+
\`\`\`
|
|
40187
|
+
`;
|
|
40188
|
+
} else {
|
|
40189
|
+
context2 += `- **Git repository**: No
|
|
40190
|
+
`;
|
|
40191
|
+
}
|
|
40192
|
+
if (platform3() === "win32") {
|
|
40193
|
+
context2 += `
|
|
40194
|
+
## Windows Shell Notes
|
|
40195
|
+
- The Bash tool uses PowerShell or cmd.exe on Windows
|
|
40196
|
+
- HEREDOC syntax (e.g., \`$(cat <<'EOF'...EOF)\`) does NOT work on Windows
|
|
40197
|
+
- For multiline strings (git commits, PR bodies), use simple quoted strings instead
|
|
40198
|
+
`;
|
|
40199
|
+
}
|
|
40200
|
+
context2 += SYSTEM_REMINDER_CLOSE;
|
|
40201
|
+
return context2;
|
|
40202
|
+
} catch {
|
|
40203
|
+
return "";
|
|
40204
|
+
}
|
|
40205
|
+
}
|
|
40206
|
+
var init_sessionContext = __esm(() => {
|
|
40207
|
+
init_constants();
|
|
40208
|
+
init_version();
|
|
40209
|
+
init_gitContext();
|
|
40210
|
+
});
|
|
40211
|
+
|
|
39845
40212
|
// src/channels/xml.ts
|
|
39846
40213
|
function escapeXml(text) {
|
|
39847
40214
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
39848
40215
|
}
|
|
39849
40216
|
function formatChannelNotification(msg) {
|
|
40217
|
+
const localTime = escapeXml(getLocalTime());
|
|
39850
40218
|
const attrs = [
|
|
39851
40219
|
`source="${escapeXml(msg.channel)}"`,
|
|
39852
40220
|
`chat_id="${escapeXml(msg.chatId)}"`,
|
|
@@ -39860,10 +40228,27 @@ function formatChannelNotification(msg) {
|
|
|
39860
40228
|
}
|
|
39861
40229
|
const attrString = attrs.join(" ");
|
|
39862
40230
|
const escapedText = escapeXml(msg.text);
|
|
39863
|
-
|
|
40231
|
+
const escapedChannel = escapeXml(msg.channel);
|
|
40232
|
+
const escapedChatId = escapeXml(msg.chatId);
|
|
40233
|
+
const reminder = [
|
|
40234
|
+
SYSTEM_REMINDER_OPEN,
|
|
40235
|
+
`This message originated from an external ${escapedChannel} channel.`,
|
|
40236
|
+
`If you want the ensure the user on ${escapedChannel} will see your reply, you must call the MessageChannel tool to send a message back on the same channel.`,
|
|
40237
|
+
`Use channel="${escapedChannel}" and chat_id="${escapedChatId}" when calling MessageChannel.`,
|
|
40238
|
+
"Only pass reply_to_message_id if you intentionally want the platform's quote/reply UI.",
|
|
40239
|
+
`Current local time on this device: ${localTime}`,
|
|
40240
|
+
SYSTEM_REMINDER_CLOSE
|
|
40241
|
+
].join(`
|
|
40242
|
+
`);
|
|
40243
|
+
return `${reminder}
|
|
40244
|
+
<channel-notification ${attrString}>
|
|
39864
40245
|
${escapedText}
|
|
39865
40246
|
</channel-notification>`;
|
|
39866
40247
|
}
|
|
40248
|
+
var init_xml = __esm(() => {
|
|
40249
|
+
init_sessionContext();
|
|
40250
|
+
init_constants();
|
|
40251
|
+
});
|
|
39867
40252
|
|
|
39868
40253
|
// node_modules/grammy/out/filter.js
|
|
39869
40254
|
var require_filter = __commonJS((exports) => {
|
|
@@ -48863,6 +49248,7 @@ var init_registry = __esm(() => {
|
|
|
48863
49248
|
init_config();
|
|
48864
49249
|
init_pairing();
|
|
48865
49250
|
init_routing();
|
|
49251
|
+
init_xml();
|
|
48866
49252
|
});
|
|
48867
49253
|
|
|
48868
49254
|
// src/channels/telegram/setup.ts
|
|
@@ -49650,7 +50036,7 @@ var init_default_browser_id = __esm(() => {
|
|
|
49650
50036
|
// node_modules/run-applescript/index.js
|
|
49651
50037
|
import process17 from "node:process";
|
|
49652
50038
|
import { promisify as promisify4 } from "node:util";
|
|
49653
|
-
import { execFile as execFile4, execFileSync } from "node:child_process";
|
|
50039
|
+
import { execFile as execFile4, execFileSync as execFileSync2 } from "node:child_process";
|
|
49654
50040
|
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
49655
50041
|
if (process17.platform !== "darwin") {
|
|
49656
50042
|
throw new Error("macOS only");
|
|
@@ -49790,16 +50176,16 @@ function detectArchBinary(binary) {
|
|
|
49790
50176
|
}
|
|
49791
50177
|
return archBinary;
|
|
49792
50178
|
}
|
|
49793
|
-
function detectPlatformBinary({ [
|
|
50179
|
+
function detectPlatformBinary({ [platform4]: platformBinary }, { wsl }) {
|
|
49794
50180
|
if (wsl && is_wsl_default) {
|
|
49795
50181
|
return detectArchBinary(wsl);
|
|
49796
50182
|
}
|
|
49797
50183
|
if (!platformBinary) {
|
|
49798
|
-
throw new Error(`${
|
|
50184
|
+
throw new Error(`${platform4} is not supported`);
|
|
49799
50185
|
}
|
|
49800
50186
|
return detectArchBinary(platformBinary);
|
|
49801
50187
|
}
|
|
49802
|
-
var execFile7, __dirname2, localXdgOpenPath,
|
|
50188
|
+
var execFile7, __dirname2, localXdgOpenPath, platform4, arch, pTryEach = async (array, mapper) => {
|
|
49803
50189
|
let latestError;
|
|
49804
50190
|
for (const item of array) {
|
|
49805
50191
|
try {
|
|
@@ -49871,7 +50257,7 @@ var execFile7, __dirname2, localXdgOpenPath, platform3, arch, pTryEach = async (
|
|
|
49871
50257
|
let command;
|
|
49872
50258
|
const cliArguments = [];
|
|
49873
50259
|
const childProcessOptions = {};
|
|
49874
|
-
if (
|
|
50260
|
+
if (platform4 === "darwin") {
|
|
49875
50261
|
command = "open";
|
|
49876
50262
|
if (options.wait) {
|
|
49877
50263
|
cliArguments.push("--wait-apps");
|
|
@@ -49885,7 +50271,7 @@ var execFile7, __dirname2, localXdgOpenPath, platform3, arch, pTryEach = async (
|
|
|
49885
50271
|
if (app) {
|
|
49886
50272
|
cliArguments.push("-a", app);
|
|
49887
50273
|
}
|
|
49888
|
-
} else if (
|
|
50274
|
+
} else if (platform4 === "win32" || is_wsl_default && !isInsideContainer() && !app) {
|
|
49889
50275
|
command = await powerShellPath();
|
|
49890
50276
|
cliArguments.push("-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-EncodedCommand");
|
|
49891
50277
|
if (!is_wsl_default) {
|
|
@@ -49918,7 +50304,7 @@ var execFile7, __dirname2, localXdgOpenPath, platform3, arch, pTryEach = async (
|
|
|
49918
50304
|
await fs6.access(localXdgOpenPath, fsConstants2.X_OK);
|
|
49919
50305
|
exeLocalXdgOpen = true;
|
|
49920
50306
|
} catch {}
|
|
49921
|
-
const useSystemXdgOpen = process19.versions.electron ?? (
|
|
50307
|
+
const useSystemXdgOpen = process19.versions.electron ?? (platform4 === "android" || isBundled || !exeLocalXdgOpen);
|
|
49922
50308
|
command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
|
|
49923
50309
|
}
|
|
49924
50310
|
if (appArguments.length > 0) {
|
|
@@ -49929,7 +50315,7 @@ var execFile7, __dirname2, localXdgOpenPath, platform3, arch, pTryEach = async (
|
|
|
49929
50315
|
childProcessOptions.detached = true;
|
|
49930
50316
|
}
|
|
49931
50317
|
}
|
|
49932
|
-
if (
|
|
50318
|
+
if (platform4 === "darwin" && appArguments.length > 0) {
|
|
49933
50319
|
cliArguments.push("--args", ...appArguments);
|
|
49934
50320
|
}
|
|
49935
50321
|
if (options.target) {
|
|
@@ -49981,7 +50367,7 @@ var init_open = __esm(() => {
|
|
|
49981
50367
|
execFile7 = promisify7(childProcess.execFile);
|
|
49982
50368
|
__dirname2 = path2.dirname(fileURLToPath(import.meta.url));
|
|
49983
50369
|
localXdgOpenPath = path2.join(__dirname2, "xdg-open");
|
|
49984
|
-
({ platform:
|
|
50370
|
+
({ platform: platform4, arch } = process19);
|
|
49985
50371
|
apps = {};
|
|
49986
50372
|
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
|
|
49987
50373
|
darwin: "google chrome",
|
|
@@ -53098,97 +53484,6 @@ var init_fileIndex = __esm(() => {
|
|
|
53098
53484
|
indexRoot2 = process.cwd();
|
|
53099
53485
|
});
|
|
53100
53486
|
|
|
53101
|
-
// src/cli/helpers/gitContext.ts
|
|
53102
|
-
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
53103
|
-
function runGit3(args, cwd2) {
|
|
53104
|
-
try {
|
|
53105
|
-
return execFileSync2("git", args, {
|
|
53106
|
-
cwd: cwd2,
|
|
53107
|
-
encoding: "utf-8",
|
|
53108
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
53109
|
-
}).trim();
|
|
53110
|
-
} catch {
|
|
53111
|
-
return null;
|
|
53112
|
-
}
|
|
53113
|
-
}
|
|
53114
|
-
function truncateLines(value, maxLines) {
|
|
53115
|
-
const lines = value.split(`
|
|
53116
|
-
`);
|
|
53117
|
-
if (lines.length <= maxLines) {
|
|
53118
|
-
return value;
|
|
53119
|
-
}
|
|
53120
|
-
return lines.slice(0, maxLines).join(`
|
|
53121
|
-
`) + `
|
|
53122
|
-
... and ${lines.length - maxLines} more changes`;
|
|
53123
|
-
}
|
|
53124
|
-
function formatGitUser(name, email) {
|
|
53125
|
-
if (!name && !email) {
|
|
53126
|
-
return null;
|
|
53127
|
-
}
|
|
53128
|
-
if (name && email) {
|
|
53129
|
-
return `${name} <${email}>`;
|
|
53130
|
-
}
|
|
53131
|
-
return name || email;
|
|
53132
|
-
}
|
|
53133
|
-
function gatherGitContextSnapshot(options = {}) {
|
|
53134
|
-
const cwd2 = options.cwd ?? process.cwd();
|
|
53135
|
-
const recentCommitLimit = options.recentCommitLimit ?? 3;
|
|
53136
|
-
if (!runGit3(["rev-parse", "--git-dir"], cwd2)) {
|
|
53137
|
-
return {
|
|
53138
|
-
isGitRepo: false,
|
|
53139
|
-
branch: null,
|
|
53140
|
-
status: null,
|
|
53141
|
-
recentCommits: null,
|
|
53142
|
-
gitUser: null
|
|
53143
|
-
};
|
|
53144
|
-
}
|
|
53145
|
-
const branch = runGit3(["branch", "--show-current"], cwd2);
|
|
53146
|
-
const fullStatus = runGit3(["status", "--short"], cwd2);
|
|
53147
|
-
const status = typeof fullStatus === "string" && options.statusLineLimit ? truncateLines(fullStatus, options.statusLineLimit) : fullStatus;
|
|
53148
|
-
const recentCommits = options.recentCommitFormat ? runGit3([
|
|
53149
|
-
"log",
|
|
53150
|
-
`--format=${options.recentCommitFormat}`,
|
|
53151
|
-
"-n",
|
|
53152
|
-
String(recentCommitLimit)
|
|
53153
|
-
], cwd2) : runGit3(["log", "--oneline", "-n", String(recentCommitLimit)], cwd2);
|
|
53154
|
-
const userConfig = runGit3(["config", "--get-regexp", "^user\\.(name|email)$"], cwd2);
|
|
53155
|
-
let userName = null;
|
|
53156
|
-
let userEmail = null;
|
|
53157
|
-
if (userConfig) {
|
|
53158
|
-
for (const line of userConfig.split(`
|
|
53159
|
-
`)) {
|
|
53160
|
-
if (line.startsWith("user.name "))
|
|
53161
|
-
userName = line.slice("user.name ".length);
|
|
53162
|
-
else if (line.startsWith("user.email "))
|
|
53163
|
-
userEmail = line.slice("user.email ".length);
|
|
53164
|
-
}
|
|
53165
|
-
}
|
|
53166
|
-
const gitUser = formatGitUser(userName, userEmail);
|
|
53167
|
-
return {
|
|
53168
|
-
isGitRepo: true,
|
|
53169
|
-
branch,
|
|
53170
|
-
status,
|
|
53171
|
-
recentCommits,
|
|
53172
|
-
gitUser
|
|
53173
|
-
};
|
|
53174
|
-
}
|
|
53175
|
-
function getGitContext(cwd2) {
|
|
53176
|
-
if (!runGit3(["rev-parse", "--git-dir"], cwd2)) {
|
|
53177
|
-
return null;
|
|
53178
|
-
}
|
|
53179
|
-
const branch = runGit3(["branch", "--show-current"], cwd2);
|
|
53180
|
-
const branchList = runGit3([
|
|
53181
|
-
"branch",
|
|
53182
|
-
"--sort=-committerdate",
|
|
53183
|
-
"--format=%(refname:short)",
|
|
53184
|
-
"--no-color"
|
|
53185
|
-
], cwd2);
|
|
53186
|
-
const recentBranches = branchList ? branchList.split(`
|
|
53187
|
-
`).map((b) => b.trim()).filter((b) => b.length > 0 && b !== branch).slice(0, 10) : [];
|
|
53188
|
-
return { branch, recent_branches: recentBranches };
|
|
53189
|
-
}
|
|
53190
|
-
var init_gitContext = () => {};
|
|
53191
|
-
|
|
53192
53487
|
// src/cli/helpers/memoryReminder.ts
|
|
53193
53488
|
function isValidStepCount(value) {
|
|
53194
53489
|
return typeof value === "number" && Number.isFinite(value) && Number.isInteger(value) && value > 0;
|
|
@@ -64366,7 +64661,7 @@ var MemoryApplyPatch_default = "Apply a codex-style patch to memory files in `$M
|
|
|
64366
64661
|
var init_MemoryApplyPatch = () => {};
|
|
64367
64662
|
|
|
64368
64663
|
// src/tools/descriptions/MessageChannel.md
|
|
64369
|
-
var MessageChannel_default = "# MessageChannel\n\nSend a message to an external channel (Telegram, Slack, etc.) in response to a channel notification.\n\nWhen you receive a `<channel-notification>`, use this tool to reply. Extract the `source` and `chat_id` from the notification attributes and pass them as `channel` and `chat_id`.\n\nParameters:\n- `channel`: The platform to send to (matches the `source` attribute)\n- `chat_id`: The chat ID to send to (matches the `chat_id` attribute)\n- `text`: The message text to send\n- `reply_to_message_id`: (Optional) Reply to a specific message by its `message_id
|
|
64664
|
+
var MessageChannel_default = "# MessageChannel\n\nSend a message to an external channel (Telegram, Slack, etc.) in response to a channel notification.\n\nWhen you receive a `<channel-notification>`, use this tool to reply directly to the user on the same external channel (a normal assistant response is not delivered back to Telegram/Slack/etc). Extract the `source` and `chat_id` from the notification attributes and pass them as `channel` and `chat_id`.\n\nParameters:\n- `channel`: The platform to send to (matches the `source` attribute)\n- `chat_id`: The chat ID to send to (matches the `chat_id` attribute)\n- `text`: The message text to send\n- `reply_to_message_id`: (Optional) Reply to a specific message by its `message_id`. Omit this unless you intentionally want the platform's quote/reply UI.\n";
|
|
64370
64665
|
var init_MessageChannel = () => {};
|
|
64371
64666
|
|
|
64372
64667
|
// src/tools/descriptions/MultiEdit.md
|
|
@@ -74509,7 +74804,7 @@ class Pattern {
|
|
|
74509
74804
|
#isUNC;
|
|
74510
74805
|
#isAbsolute;
|
|
74511
74806
|
#followGlobstar = true;
|
|
74512
|
-
constructor(patternList, globList, index,
|
|
74807
|
+
constructor(patternList, globList, index, platform5) {
|
|
74513
74808
|
if (!isPatternList(patternList)) {
|
|
74514
74809
|
throw new TypeError("empty pattern list");
|
|
74515
74810
|
}
|
|
@@ -74526,7 +74821,7 @@ class Pattern {
|
|
|
74526
74821
|
this.#patternList = patternList;
|
|
74527
74822
|
this.#globList = globList;
|
|
74528
74823
|
this.#index = index;
|
|
74529
|
-
this.#platform =
|
|
74824
|
+
this.#platform = platform5;
|
|
74530
74825
|
if (this.#index === 0) {
|
|
74531
74826
|
if (this.isUNC()) {
|
|
74532
74827
|
const [p0, p1, p2, p3, ...prest] = this.#patternList;
|
|
@@ -74623,12 +74918,12 @@ class Ignore {
|
|
|
74623
74918
|
absoluteChildren;
|
|
74624
74919
|
platform;
|
|
74625
74920
|
mmopts;
|
|
74626
|
-
constructor(ignored, { nobrace, nocase, noext, noglobstar, platform:
|
|
74921
|
+
constructor(ignored, { nobrace, nocase, noext, noglobstar, platform: platform5 = defaultPlatform2 }) {
|
|
74627
74922
|
this.relative = [];
|
|
74628
74923
|
this.absolute = [];
|
|
74629
74924
|
this.relativeChildren = [];
|
|
74630
74925
|
this.absoluteChildren = [];
|
|
74631
|
-
this.platform =
|
|
74926
|
+
this.platform = platform5;
|
|
74632
74927
|
this.mmopts = {
|
|
74633
74928
|
dot: true,
|
|
74634
74929
|
nobrace,
|
|
@@ -74636,7 +74931,7 @@ class Ignore {
|
|
|
74636
74931
|
noext,
|
|
74637
74932
|
noglobstar,
|
|
74638
74933
|
optimizationLevel: 2,
|
|
74639
|
-
platform:
|
|
74934
|
+
platform: platform5,
|
|
74640
74935
|
nocomment: true,
|
|
74641
74936
|
nonegate: true
|
|
74642
74937
|
};
|
|
@@ -76721,7 +77016,7 @@ function resolveSubagentLauncher(cliArgs, options = {}) {
|
|
|
76721
77016
|
const env4 = options.env ?? process.env;
|
|
76722
77017
|
const argv = options.argv ?? process.argv;
|
|
76723
77018
|
const execPath = options.execPath ?? process.execPath;
|
|
76724
|
-
const
|
|
77019
|
+
const platform5 = options.platform ?? process.platform;
|
|
76725
77020
|
const invocation = resolveLettaInvocation(env4, argv, execPath);
|
|
76726
77021
|
if (invocation) {
|
|
76727
77022
|
return {
|
|
@@ -76736,7 +77031,7 @@ function resolveSubagentLauncher(cliArgs, options = {}) {
|
|
|
76736
77031
|
args: [currentScript, ...cliArgs]
|
|
76737
77032
|
};
|
|
76738
77033
|
}
|
|
76739
|
-
if (currentScript.endsWith(".js") &&
|
|
77034
|
+
if (currentScript.endsWith(".js") && platform5 === "win32") {
|
|
76740
77035
|
return {
|
|
76741
77036
|
command: execPath,
|
|
76742
77037
|
args: [currentScript, ...cliArgs]
|
|
@@ -87302,130 +87597,6 @@ var init_agentInfo = __esm(async () => {
|
|
|
87302
87597
|
await init_settings_manager();
|
|
87303
87598
|
});
|
|
87304
87599
|
|
|
87305
|
-
// src/cli/helpers/sessionContext.ts
|
|
87306
|
-
import { platform as platform4 } from "node:os";
|
|
87307
|
-
function getLocalTime() {
|
|
87308
|
-
const now = new Date;
|
|
87309
|
-
return now.toLocaleString(undefined, {
|
|
87310
|
-
weekday: "long",
|
|
87311
|
-
year: "numeric",
|
|
87312
|
-
month: "long",
|
|
87313
|
-
day: "numeric",
|
|
87314
|
-
hour: "2-digit",
|
|
87315
|
-
minute: "2-digit",
|
|
87316
|
-
timeZoneName: "short"
|
|
87317
|
-
});
|
|
87318
|
-
}
|
|
87319
|
-
function getDeviceType() {
|
|
87320
|
-
const p = platform4();
|
|
87321
|
-
switch (p) {
|
|
87322
|
-
case "darwin":
|
|
87323
|
-
return "macOS";
|
|
87324
|
-
case "win32":
|
|
87325
|
-
return "Windows";
|
|
87326
|
-
case "linux":
|
|
87327
|
-
return "Linux";
|
|
87328
|
-
default:
|
|
87329
|
-
return p;
|
|
87330
|
-
}
|
|
87331
|
-
}
|
|
87332
|
-
function getGitInfo(cwd2) {
|
|
87333
|
-
const git = gatherGitContextSnapshot({
|
|
87334
|
-
cwd: cwd2,
|
|
87335
|
-
recentCommitLimit: 3,
|
|
87336
|
-
recentCommitFormat: "%h %s (%an)",
|
|
87337
|
-
statusLineLimit: 20
|
|
87338
|
-
});
|
|
87339
|
-
if (!git.isGitRepo) {
|
|
87340
|
-
return { isGitRepo: false };
|
|
87341
|
-
}
|
|
87342
|
-
return {
|
|
87343
|
-
isGitRepo: true,
|
|
87344
|
-
branch: git.branch ?? "(unknown)",
|
|
87345
|
-
recentCommits: git.recentCommits ?? "(failed to get commits)",
|
|
87346
|
-
status: git.status || "(clean working tree)",
|
|
87347
|
-
gitUser: git.gitUser ?? "(not configured)"
|
|
87348
|
-
};
|
|
87349
|
-
}
|
|
87350
|
-
function getIntroText(source, reason) {
|
|
87351
|
-
if (reason === "cwd_changed") {
|
|
87352
|
-
return "The working directory for this conversation has changed. Updated environment context follows.";
|
|
87353
|
-
}
|
|
87354
|
-
switch (source) {
|
|
87355
|
-
case "listen":
|
|
87356
|
-
return "This conversation is now connected to a Letta Code execution environment.";
|
|
87357
|
-
case "headless":
|
|
87358
|
-
return "The user has just initiated a new connection via the Letta Code headless client.";
|
|
87359
|
-
default:
|
|
87360
|
-
return "The user has just initiated a new connection via the [Letta Code CLI client](https://docs.letta.com/letta-code/index.md).";
|
|
87361
|
-
}
|
|
87362
|
-
}
|
|
87363
|
-
function buildSessionContext(options) {
|
|
87364
|
-
try {
|
|
87365
|
-
const cwd2 = options?.cwd ?? process.cwd();
|
|
87366
|
-
const source = options?.source ?? "interactive-cli";
|
|
87367
|
-
const reason = options?.reason ?? "initial_attach";
|
|
87368
|
-
let version = "unknown";
|
|
87369
|
-
try {
|
|
87370
|
-
version = getVersion();
|
|
87371
|
-
} catch {}
|
|
87372
|
-
let deviceType = "unknown";
|
|
87373
|
-
try {
|
|
87374
|
-
deviceType = getDeviceType();
|
|
87375
|
-
} catch {}
|
|
87376
|
-
let localTime = "unknown";
|
|
87377
|
-
try {
|
|
87378
|
-
localTime = getLocalTime();
|
|
87379
|
-
} catch {}
|
|
87380
|
-
const gitInfo = getGitInfo(cwd2);
|
|
87381
|
-
let context3 = `${SYSTEM_REMINDER_OPEN}
|
|
87382
|
-
This is an automated message providing context about the user's environment.
|
|
87383
|
-
${getIntroText(source, reason)}
|
|
87384
|
-
|
|
87385
|
-
## Device Information
|
|
87386
|
-
- **Local time**: ${localTime}
|
|
87387
|
-
- **Device type**: ${deviceType}
|
|
87388
|
-
- **Letta Code version**: ${version}
|
|
87389
|
-
- **Current working directory**: ${cwd2}
|
|
87390
|
-
`;
|
|
87391
|
-
if (gitInfo.isGitRepo) {
|
|
87392
|
-
context3 += `- **Git repository**: Yes (branch: ${gitInfo.branch})
|
|
87393
|
-
- **Git user**: ${gitInfo.gitUser}
|
|
87394
|
-
|
|
87395
|
-
### Recent Commits
|
|
87396
|
-
\`\`\`
|
|
87397
|
-
${gitInfo.recentCommits}
|
|
87398
|
-
\`\`\`
|
|
87399
|
-
|
|
87400
|
-
### Git Status
|
|
87401
|
-
\`\`\`
|
|
87402
|
-
${gitInfo.status}
|
|
87403
|
-
\`\`\`
|
|
87404
|
-
`;
|
|
87405
|
-
} else {
|
|
87406
|
-
context3 += `- **Git repository**: No
|
|
87407
|
-
`;
|
|
87408
|
-
}
|
|
87409
|
-
if (platform4() === "win32") {
|
|
87410
|
-
context3 += `
|
|
87411
|
-
## Windows Shell Notes
|
|
87412
|
-
- The Bash tool uses PowerShell or cmd.exe on Windows
|
|
87413
|
-
- HEREDOC syntax (e.g., \`$(cat <<'EOF'...EOF)\`) does NOT work on Windows
|
|
87414
|
-
- For multiline strings (git commits, PR bodies), use simple quoted strings instead
|
|
87415
|
-
`;
|
|
87416
|
-
}
|
|
87417
|
-
context3 += SYSTEM_REMINDER_CLOSE;
|
|
87418
|
-
return context3;
|
|
87419
|
-
} catch {
|
|
87420
|
-
return "";
|
|
87421
|
-
}
|
|
87422
|
-
}
|
|
87423
|
-
var init_sessionContext = __esm(() => {
|
|
87424
|
-
init_constants();
|
|
87425
|
-
init_version();
|
|
87426
|
-
init_gitContext();
|
|
87427
|
-
});
|
|
87428
|
-
|
|
87429
87600
|
// src/reminders/catalog.ts
|
|
87430
87601
|
var SHARED_REMINDER_CATALOG, SHARED_REMINDER_IDS, SHARED_REMINDER_BY_ID;
|
|
87431
87602
|
var init_catalog = __esm(() => {
|
|
@@ -116503,7 +116674,7 @@ function xml(hljs) {
|
|
|
116503
116674
|
]
|
|
116504
116675
|
};
|
|
116505
116676
|
}
|
|
116506
|
-
var
|
|
116677
|
+
var init_xml2 = () => {};
|
|
116507
116678
|
|
|
116508
116679
|
// node_modules/highlight.js/es/languages/yaml.js
|
|
116509
116680
|
function yaml(hljs) {
|
|
@@ -116723,7 +116894,7 @@ var init_common = __esm(() => {
|
|
|
116723
116894
|
init_typescript2();
|
|
116724
116895
|
init_vbnet();
|
|
116725
116896
|
init_wasm();
|
|
116726
|
-
|
|
116897
|
+
init_xml2();
|
|
116727
116898
|
init_yaml();
|
|
116728
116899
|
grammars = {
|
|
116729
116900
|
arduino,
|
|
@@ -165814,4 +165985,4 @@ Error during initialization: ${message}`);
|
|
|
165814
165985
|
}
|
|
165815
165986
|
main();
|
|
165816
165987
|
|
|
165817
|
-
//# debugId=
|
|
165988
|
+
//# debugId=177C3FD8089A6F3E64756E2164756E21
|