lovecode-ai 0.1.5 → 0.1.6

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/dist/index.js CHANGED
@@ -1,8 +1,33 @@
1
+ import {
2
+ formatConfig,
3
+ getDefaults,
4
+ loadConfig,
5
+ saveConfig
6
+ } from "./chunk-LJ7HTOIK.js";
7
+ import {
8
+ KNOWN_ENV_VARS,
9
+ formatEnvStatus,
10
+ loadEnv,
11
+ saveEnv,
12
+ saveEnvExample
13
+ } from "./chunk-3AHNSXQX.js";
1
14
  import {
2
15
  getTheme,
3
16
  getThemeNames,
4
17
  setTheme
5
18
  } from "./chunk-FMT77EJQ.js";
19
+ import {
20
+ appendToSession,
21
+ createSession,
22
+ ensureDirs,
23
+ listSessions,
24
+ loadSession,
25
+ searchSessions
26
+ } from "./chunk-OTEQ6CQ7.js";
27
+ import {
28
+ listChatLogs,
29
+ writeChatLog
30
+ } from "./chunk-4IPMBDCG.js";
6
31
  import {
7
32
  cleanupMergedBranches,
8
33
  commit,
@@ -54,19 +79,6 @@ import {
54
79
  listPlugins,
55
80
  loadBuiltinPlugins
56
81
  } from "./chunk-MOZHR2QY.js";
57
- import {
58
- formatConfig,
59
- getDefaults,
60
- loadConfig,
61
- saveConfig
62
- } from "./chunk-LJ7HTOIK.js";
63
- import {
64
- KNOWN_ENV_VARS,
65
- formatEnvStatus,
66
- loadEnv,
67
- saveEnv,
68
- saveEnvExample
69
- } from "./chunk-3AHNSXQX.js";
70
82
 
71
83
  // src/index.ts
72
84
  import { Command as Command17 } from "commander";
@@ -1090,109 +1102,27 @@ function createSimpleInput(prompt = "") {
1090
1102
  });
1091
1103
  }
1092
1104
 
1093
- // src/memory/session.ts
1105
+ // src/memory/memory.ts
1094
1106
  import * as fs2 from "fs";
1095
1107
  import * as path2 from "path";
1096
- var LOVE_CODE_DIR = ".lovecode";
1097
- var SESSIONS_DIR = "sessions";
1098
- function getSessionsDir(rootDir) {
1099
- const base = rootDir || process.cwd();
1100
- return path2.join(base, LOVE_CODE_DIR, SESSIONS_DIR);
1101
- }
1102
- function ensureDirs(rootDir) {
1103
- const base = rootDir || process.cwd();
1104
- const sessionsDir = getSessionsDir(base);
1105
- const chatsDir = path2.join(base, LOVE_CODE_DIR, "chats");
1106
- const memoryDir = path2.join(base, LOVE_CODE_DIR, "memory");
1107
- for (const dir of [sessionsDir, chatsDir, memoryDir]) {
1108
- if (!fs2.existsSync(dir)) {
1109
- fs2.mkdirSync(dir, { recursive: true });
1110
- }
1111
- }
1112
- }
1113
- function createSession(title, options) {
1114
- ensureDirs(options?.workingDir);
1115
- const session = {
1116
- id: Date.now().toString(36) + Math.random().toString(36).slice(2, 6),
1117
- title,
1118
- created: Date.now(),
1119
- updated: Date.now(),
1120
- model: options?.model || "unknown",
1121
- provider: options?.provider || "unknown",
1122
- workingDir: options?.workingDir || process.cwd(),
1123
- entries: [],
1124
- context: {}
1125
- };
1126
- saveSession(session);
1127
- return session;
1128
- }
1129
- function saveSession(session) {
1130
- const dir = getSessionsDir(session.workingDir);
1131
- if (!fs2.existsSync(dir)) {
1132
- fs2.mkdirSync(dir, { recursive: true });
1133
- }
1134
- const filePath = path2.join(dir, `${session.id}.json`);
1135
- fs2.writeFileSync(filePath, JSON.stringify(session, null, 2), "utf-8");
1136
- }
1137
- function loadSession(id, rootDir) {
1138
- const dir = getSessionsDir(rootDir);
1139
- const filePath = path2.join(dir, `${id}.json`);
1140
- if (!fs2.existsSync(filePath)) return null;
1141
- try {
1142
- const raw = fs2.readFileSync(filePath, "utf-8");
1143
- return JSON.parse(raw);
1144
- } catch {
1145
- return null;
1146
- }
1147
- }
1148
- function listSessions(rootDir) {
1149
- const dir = getSessionsDir(rootDir);
1150
- if (!fs2.existsSync(dir)) return [];
1151
- const sessions = [];
1152
- for (const file of fs2.readdirSync(dir)) {
1153
- if (!file.endsWith(".json")) continue;
1154
- try {
1155
- const raw = fs2.readFileSync(path2.join(dir, file), "utf-8");
1156
- sessions.push(JSON.parse(raw));
1157
- } catch {
1158
- }
1159
- }
1160
- sessions.sort((a, b) => b.updated - a.updated);
1161
- return sessions;
1162
- }
1163
- function appendToSession(session, role, content) {
1164
- session.entries.push({ role, content, timestamp: Date.now() });
1165
- session.updated = Date.now();
1166
- saveSession(session);
1167
- }
1168
- function searchSessions(query, rootDir) {
1169
- const lower = query.toLowerCase();
1170
- return listSessions(rootDir).filter(
1171
- (s) => s.title.toLowerCase().includes(lower) || s.entries.some((e) => e.content.toLowerCase().includes(lower))
1172
- );
1173
- }
1174
-
1175
- // src/memory/memory.ts
1176
- import * as fs3 from "fs";
1177
- import * as path3 from "path";
1178
1108
  function getMemoryDir(rootDir) {
1179
1109
  const base = rootDir || process.cwd();
1180
- return path3.join(base, ".lovecode", "memory");
1110
+ return path2.join(base, ".lovecode", "memory");
1181
1111
  }
1182
1112
  function getMemoryFilePath(key, rootDir) {
1183
- return path3.join(getMemoryDir(rootDir), `${key}.json`);
1113
+ return path2.join(getMemoryDir(rootDir), `${key}.json`);
1184
1114
  }
1185
1115
  function ensureMemoryDir(rootDir) {
1186
1116
  const dir = getMemoryDir(rootDir);
1187
- if (!fs3.existsSync(dir)) {
1188
- fs3.mkdirSync(dir, { recursive: true });
1117
+ if (!fs2.existsSync(dir)) {
1118
+ fs2.mkdirSync(dir, { recursive: true });
1189
1119
  }
1190
1120
  }
1191
1121
  function readMemory(key, fallback, rootDir) {
1192
1122
  const filePath = getMemoryFilePath(key, rootDir);
1193
- if (!fs3.existsSync(filePath)) return fallback;
1123
+ if (!fs2.existsSync(filePath)) return fallback;
1194
1124
  try {
1195
- const raw = fs3.readFileSync(filePath, "utf-8");
1125
+ const raw = fs2.readFileSync(filePath, "utf-8");
1196
1126
  return JSON.parse(raw);
1197
1127
  } catch {
1198
1128
  return fallback;
@@ -1201,7 +1131,7 @@ function readMemory(key, fallback, rootDir) {
1201
1131
  function writeMemory(key, data, rootDir) {
1202
1132
  ensureMemoryDir(rootDir);
1203
1133
  const filePath = getMemoryFilePath(key, rootDir);
1204
- fs3.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
1134
+ fs2.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
1205
1135
  }
1206
1136
  var DEFAULT_PREFERENCES = {
1207
1137
  indentStyle: "spaces",
@@ -1274,10 +1204,10 @@ function addRepoNote(note, rootDir) {
1274
1204
  }
1275
1205
  function clearAllMemory(rootDir) {
1276
1206
  const dir = getMemoryDir(rootDir);
1277
- if (fs3.existsSync(dir)) {
1278
- for (const file of fs3.readdirSync(dir)) {
1207
+ if (fs2.existsSync(dir)) {
1208
+ for (const file of fs2.readdirSync(dir)) {
1279
1209
  if (file.endsWith(".json")) {
1280
- fs3.unlinkSync(path3.join(dir, file));
1210
+ fs2.unlinkSync(path2.join(dir, file));
1281
1211
  }
1282
1212
  }
1283
1213
  }
@@ -1317,8 +1247,8 @@ function formatRepoMemory(mem) {
1317
1247
  }
1318
1248
 
1319
1249
  // src/memory/vector.ts
1320
- import * as fs4 from "fs";
1321
- import * as path4 from "path";
1250
+ import * as fs3 from "fs";
1251
+ import * as path3 from "path";
1322
1252
 
1323
1253
  // src/ai/embeddings.ts
1324
1254
  import { execSync } from "child_process";
@@ -1387,22 +1317,22 @@ function cosineSimilarity(a, b) {
1387
1317
  // src/memory/vector.ts
1388
1318
  function getVectorDir(rootDir) {
1389
1319
  const base = rootDir || process.cwd();
1390
- return path4.join(base, ".lovecode", "memory");
1320
+ return path3.join(base, ".lovecode", "memory");
1391
1321
  }
1392
1322
  function getVectorFilePath(rootDir) {
1393
- return path4.join(getVectorDir(rootDir), "vectors.json");
1323
+ return path3.join(getVectorDir(rootDir), "vectors.json");
1394
1324
  }
1395
1325
  function ensureDir(rootDir) {
1396
1326
  const dir = getVectorDir(rootDir);
1397
- if (!fs4.existsSync(dir)) {
1398
- fs4.mkdirSync(dir, { recursive: true });
1327
+ if (!fs3.existsSync(dir)) {
1328
+ fs3.mkdirSync(dir, { recursive: true });
1399
1329
  }
1400
1330
  }
1401
1331
  function loadVectors(rootDir) {
1402
1332
  const filePath = getVectorFilePath(rootDir);
1403
- if (!fs4.existsSync(filePath)) return [];
1333
+ if (!fs3.existsSync(filePath)) return [];
1404
1334
  try {
1405
- const raw = fs4.readFileSync(filePath, "utf-8");
1335
+ const raw = fs3.readFileSync(filePath, "utf-8");
1406
1336
  return JSON.parse(raw);
1407
1337
  } catch {
1408
1338
  return [];
@@ -1411,7 +1341,7 @@ function loadVectors(rootDir) {
1411
1341
  function saveVectors(entries, rootDir) {
1412
1342
  ensureDir(rootDir);
1413
1343
  const filePath = getVectorFilePath(rootDir);
1414
- fs4.writeFileSync(filePath, JSON.stringify(entries, null, 2), "utf-8");
1344
+ fs3.writeFileSync(filePath, JSON.stringify(entries, null, 2), "utf-8");
1415
1345
  }
1416
1346
  async function storeVector(text, metadata, rootDir) {
1417
1347
  const result = await getEmbedding(text);
@@ -1452,8 +1382,8 @@ async function searchVectors(query, options, rootDir) {
1452
1382
  }
1453
1383
  function clearVectors(rootDir) {
1454
1384
  const filePath = getVectorFilePath(rootDir);
1455
- if (fs4.existsSync(filePath)) {
1456
- fs4.unlinkSync(filePath);
1385
+ if (fs3.existsSync(filePath)) {
1386
+ fs3.unlinkSync(filePath);
1457
1387
  }
1458
1388
  }
1459
1389
  function getVectorCount(rootDir) {
@@ -1474,63 +1404,6 @@ function chalkDim(s) {
1474
1404
  return `\x1B[2m${s}\x1B[22m`;
1475
1405
  }
1476
1406
 
1477
- // src/memory/chatlog.ts
1478
- import * as fs5 from "fs";
1479
- import * as path5 from "path";
1480
- function getChatLogDir(rootDir) {
1481
- const base = rootDir || process.cwd();
1482
- return path5.join(base, ".lovecode", "chats");
1483
- }
1484
- function ensureDir2(rootDir) {
1485
- const dir = getChatLogDir(rootDir);
1486
- if (!fs5.existsSync(dir)) {
1487
- fs5.mkdirSync(dir, { recursive: true });
1488
- }
1489
- }
1490
- function writeChatLog(sessionId, title, entries, rootDir) {
1491
- ensureDir2(rootDir);
1492
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
1493
- const safeTitle = title.replace(/[^a-zA-Z0-9 _-]/g, "").slice(0, 40) || "chat";
1494
- const fileName = `${timestamp}_${safeTitle}_${sessionId.slice(0, 8)}.txt`;
1495
- const filePath = path5.join(getChatLogDir(rootDir), fileName);
1496
- const lines = [
1497
- `\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557`,
1498
- `\u2551 LoveCode AI - Chat Log \u2551`,
1499
- `\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D`,
1500
- `Session: ${sessionId}`,
1501
- `Title: ${title}`,
1502
- `Date: ${(/* @__PURE__ */ new Date()).toISOString()}`,
1503
- `\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`,
1504
- ""
1505
- ];
1506
- for (const entry of entries) {
1507
- const role = entry.role === "user" ? "You" : entry.role === "assistant" ? "LoveCode" : "System";
1508
- lines.push(`\u2500\u2500 ${role} \u2500\u2500 [${new Date(entry.timestamp).toISOString()}]`);
1509
- lines.push(entry.content);
1510
- lines.push("");
1511
- }
1512
- lines.push(`\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
1513
- lines.push(`End of chat log \u2014 ${entries.length} messages`);
1514
- fs5.writeFileSync(filePath, lines.join("\n"), "utf-8");
1515
- return filePath;
1516
- }
1517
- function listChatLogs(rootDir) {
1518
- const dir = getChatLogDir(rootDir);
1519
- if (!fs5.existsSync(dir)) return [];
1520
- const logs = [];
1521
- for (const file of fs5.readdirSync(dir)) {
1522
- if (!file.endsWith(".txt")) continue;
1523
- const filePath = path5.join(dir, file);
1524
- try {
1525
- const stat = fs5.statSync(filePath);
1526
- logs.push({ path: filePath, name: file, size: stat.size, modified: stat.mtime });
1527
- } catch {
1528
- }
1529
- }
1530
- logs.sort((a, b) => b.modified.getTime() - a.modified.getTime());
1531
- return logs;
1532
- }
1533
-
1534
1407
  // src/commands/chat.ts
1535
1408
  function renderHeader() {
1536
1409
  console.log(chalk4.bold.cyan("\n \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
@@ -1575,9 +1448,9 @@ var chatCommand = new Command("chat").alias("c").description("Start an interacti
1575
1448
  const saveLog = () => {
1576
1449
  if (!dirty) return;
1577
1450
  try {
1578
- const path23 = writeChatLog(session.id, session.title, session.entries);
1451
+ const path21 = writeChatLog(session.id, session.title, session.entries);
1579
1452
  console.log(chalk4.dim(`
1580
- Chat log saved: ${path23}`));
1453
+ Chat log saved: ${path21}`));
1581
1454
  } catch {
1582
1455
  }
1583
1456
  };
@@ -1823,19 +1696,19 @@ async function getApproval(mode, toolName, description, args) {
1823
1696
  }
1824
1697
 
1825
1698
  // src/core/tools.ts
1826
- import * as fs17 from "fs";
1827
- import * as path16 from "path";
1699
+ import * as fs15 from "fs";
1700
+ import * as path14 from "path";
1828
1701
  import { execSync as execSync3 } from "child_process";
1829
1702
  import chalk17 from "chalk";
1830
1703
 
1831
1704
  // src/fs/scanner.ts
1832
- import * as fs7 from "fs";
1833
- import * as path7 from "path";
1705
+ import * as fs5 from "fs";
1706
+ import * as path5 from "path";
1834
1707
  import chalk7 from "chalk";
1835
1708
 
1836
1709
  // src/fs/ignore.ts
1837
- import * as fs6 from "fs";
1838
- import * as path6 from "path";
1710
+ import * as fs4 from "fs";
1711
+ import * as path4 from "path";
1839
1712
  function parseGitignore(content) {
1840
1713
  const patterns = [];
1841
1714
  const negations = [];
@@ -1851,9 +1724,9 @@ function parseGitignore(content) {
1851
1724
  return { patterns, negations };
1852
1725
  }
1853
1726
  function loadFile(dir, filename) {
1854
- const filePath = path6.join(dir, filename);
1727
+ const filePath = path4.join(dir, filename);
1855
1728
  try {
1856
- const content = fs6.readFileSync(filePath, "utf-8");
1729
+ const content = fs4.readFileSync(filePath, "utf-8");
1857
1730
  return parseGitignore(content);
1858
1731
  } catch {
1859
1732
  return null;
@@ -1892,7 +1765,7 @@ function matchPattern(filePath, pattern) {
1892
1765
  return matchSimple(filePath, pattern.slice(1));
1893
1766
  }
1894
1767
  if (matchSimple(filePath, pattern)) return true;
1895
- const basename6 = path6.basename(filePath);
1768
+ const basename6 = path4.basename(filePath);
1896
1769
  if (isGlobless(pattern) && basename6 === pattern) return true;
1897
1770
  return false;
1898
1771
  }
@@ -1997,13 +1870,13 @@ function scanDirectory(options) {
1997
1870
  if (depth > maxDepth || results.length >= maxFiles) return;
1998
1871
  let entries;
1999
1872
  try {
2000
- entries = fs7.readdirSync(dir, { withFileTypes: true });
1873
+ entries = fs5.readdirSync(dir, { withFileTypes: true });
2001
1874
  } catch {
2002
1875
  return;
2003
1876
  }
2004
1877
  for (const entry of entries) {
2005
- const fullPath = path7.join(dir, entry.name);
2006
- const relativePath = path7.relative(rootDir, fullPath);
1878
+ const fullPath = path5.join(dir, entry.name);
1879
+ const relativePath = path5.relative(rootDir, fullPath);
2007
1880
  if (relativePath.startsWith("..")) continue;
2008
1881
  const isHidden = entry.name.startsWith(".") && entry.name !== "." && entry.name !== "..";
2009
1882
  if (isHidden && !includeHidden) {
@@ -2015,8 +1888,8 @@ function scanDirectory(options) {
2015
1888
  if (entry.isDirectory()) {
2016
1889
  walk(fullPath, depth + 1);
2017
1890
  } else if (entry.isFile()) {
2018
- const ext = path7.extname(entry.name).toLowerCase();
2019
- const stats = fs7.statSync(fullPath);
1891
+ const ext = path5.extname(entry.name).toLowerCase();
1892
+ const stats = fs5.statSync(fullPath);
2020
1893
  const relative6 = relativePath.replace(/\\/g, "/");
2021
1894
  results.push({
2022
1895
  path: fullPath,
@@ -2072,15 +1945,15 @@ function printScanSummary(files) {
2072
1945
  }
2073
1946
 
2074
1947
  // src/fs/operations.ts
2075
- import * as fs8 from "fs";
2076
- import * as path8 from "path";
1948
+ import * as fs6 from "fs";
1949
+ import * as path6 from "path";
2077
1950
  function renameFile(oldPath, newPath) {
2078
1951
  try {
2079
- const dir = path8.dirname(newPath);
2080
- if (!fs8.existsSync(dir)) {
2081
- fs8.mkdirSync(dir, { recursive: true });
1952
+ const dir = path6.dirname(newPath);
1953
+ if (!fs6.existsSync(dir)) {
1954
+ fs6.mkdirSync(dir, { recursive: true });
2082
1955
  }
2083
- fs8.renameSync(oldPath, newPath);
1956
+ fs6.renameSync(oldPath, newPath);
2084
1957
  return { success: true, message: `Renamed to ${newPath}` };
2085
1958
  } catch (err) {
2086
1959
  return { success: false, message: "", error: String(err) };
@@ -2088,11 +1961,11 @@ function renameFile(oldPath, newPath) {
2088
1961
  }
2089
1962
  function duplicateFile(sourcePath, destPath) {
2090
1963
  try {
2091
- const dir = path8.dirname(destPath);
2092
- if (!fs8.existsSync(dir)) {
2093
- fs8.mkdirSync(dir, { recursive: true });
1964
+ const dir = path6.dirname(destPath);
1965
+ if (!fs6.existsSync(dir)) {
1966
+ fs6.mkdirSync(dir, { recursive: true });
2094
1967
  }
2095
- fs8.copyFileSync(sourcePath, destPath);
1968
+ fs6.copyFileSync(sourcePath, destPath);
2096
1969
  return { success: true, message: `Duplicated to ${destPath}` };
2097
1970
  } catch (err) {
2098
1971
  return { success: false, message: "", error: String(err) };
@@ -2104,7 +1977,7 @@ function getDirectoryTree(dirPath, prefix = "", maxDepth = 3, currentDepth = 0)
2104
1977
  let result = "";
2105
1978
  let entries;
2106
1979
  try {
2107
- entries = fs8.readdirSync(dirPath, { withFileTypes: true });
1980
+ entries = fs6.readdirSync(dirPath, { withFileTypes: true });
2108
1981
  } catch {
2109
1982
  return `${prefix} (error reading)
2110
1983
  `;
@@ -2124,13 +1997,13 @@ function getDirectoryTree(dirPath, prefix = "", maxDepth = 3, currentDepth = 0)
2124
1997
  result += `${prefix}${connector}${entry.name}/
2125
1998
  `;
2126
1999
  result += getDirectoryTree(
2127
- path8.join(dirPath, entry.name),
2000
+ path6.join(dirPath, entry.name),
2128
2001
  prefix + nextPrefix,
2129
2002
  maxDepth,
2130
2003
  currentDepth + 1
2131
2004
  );
2132
2005
  } else {
2133
- const stats = fs8.statSync(path8.join(dirPath, entry.name));
2006
+ const stats = fs6.statSync(path6.join(dirPath, entry.name));
2134
2007
  const size = formatSize(stats.size);
2135
2008
  result += `${prefix}${connector}${entry.name} ${size}
2136
2009
  `;
@@ -2150,8 +2023,8 @@ function formatSize(bytes) {
2150
2023
  }
2151
2024
 
2152
2025
  // src/fs/search.ts
2153
- import * as fs9 from "fs";
2154
- import * as path9 from "path";
2026
+ import * as fs7 from "fs";
2027
+ import * as path7 from "path";
2155
2028
  import { execSync as execSync2 } from "child_process";
2156
2029
  function normalizeQuery(query) {
2157
2030
  return query.toLowerCase().split(/[\s_-]+/).filter((w) => w.length > 0);
@@ -2180,14 +2053,14 @@ function collectAllFiles(dir, maxFiles = 5e3) {
2180
2053
  if (results.length >= maxFiles) return;
2181
2054
  let entries;
2182
2055
  try {
2183
- entries = fs9.readdirSync(dir2, { withFileTypes: true });
2056
+ entries = fs7.readdirSync(dir2, { withFileTypes: true });
2184
2057
  } catch {
2185
2058
  return;
2186
2059
  }
2187
2060
  for (const entry of entries) {
2188
2061
  if (results.length >= maxFiles) return;
2189
2062
  if (entry.name.startsWith(".") && entry.name !== ".gitignore") continue;
2190
- const fullPath = path9.join(dir2, entry.name);
2063
+ const fullPath = path7.join(dir2, entry.name);
2191
2064
  if (entry.isDirectory()) {
2192
2065
  if (entry.name === "node_modules" || entry.name === ".git") continue;
2193
2066
  walk(fullPath);
@@ -2204,8 +2077,8 @@ function findFiles(options) {
2204
2077
  const allFiles = collectAllFiles(rootDir);
2205
2078
  const scored = [];
2206
2079
  for (const filePath of allFiles) {
2207
- const relativePath = path9.relative(rootDir, filePath).replace(/\\/g, "/");
2208
- const basename6 = path9.basename(filePath);
2080
+ const relativePath = path7.relative(rootDir, filePath).replace(/\\/g, "/");
2081
+ const basename6 = path7.basename(filePath);
2209
2082
  const score = scoreByName(basename6, query) + scoreByName(relativePath, query) * 0.5;
2210
2083
  if (score > 0) {
2211
2084
  scored.push({
@@ -2226,7 +2099,7 @@ function findFiles(options) {
2226
2099
  }
2227
2100
  function searchFileContent(filePath, query) {
2228
2101
  try {
2229
- const content = fs9.readFileSync(filePath, "utf-8");
2102
+ const content = fs7.readFileSync(filePath, "utf-8");
2230
2103
  const lines = content.split("\n");
2231
2104
  const matches = [];
2232
2105
  const lowerQuery = query.toLowerCase();
@@ -2247,7 +2120,7 @@ function findWithRipgrep(query, rootDir) {
2247
2120
  const output = execSync2(cmd, { cwd: rootDir, encoding: "utf-8", maxBuffer: 1024 * 1024 });
2248
2121
  const files = output.trim().split("\n").filter(Boolean);
2249
2122
  return files.slice(0, 30).map((filePath) => ({
2250
- filePath: path9.join(rootDir, filePath),
2123
+ filePath: path7.join(rootDir, filePath),
2251
2124
  relativePath: filePath,
2252
2125
  score: 50
2253
2126
  }));
@@ -2263,11 +2136,11 @@ function semanticSearch(query, rootDir) {
2263
2136
  contentResults = findWithRipgrep(query, rootDir);
2264
2137
  } catch {
2265
2138
  const textFiles = collectAllFiles(rootDir, 2e3).filter((f) => {
2266
- const ext = path9.extname(f);
2139
+ const ext = path7.extname(f);
2267
2140
  return [".ts", ".js", ".py", ".rs", ".go", ".md", ".json", ".txt", ".yaml", ".yml"].includes(ext);
2268
2141
  });
2269
2142
  for (const filePath of textFiles.slice(0, 100)) {
2270
- const relativePath = path9.relative(rootDir, filePath).replace(/\\/g, "/");
2143
+ const relativePath = path7.relative(rootDir, filePath).replace(/\\/g, "/");
2271
2144
  if (namePaths.has(relativePath)) continue;
2272
2145
  const matches = searchFileContent(filePath, query);
2273
2146
  if (matches.length > 0) {
@@ -2291,7 +2164,7 @@ function semanticSearch(query, rootDir) {
2291
2164
  }
2292
2165
 
2293
2166
  // src/fs/rank.ts
2294
- import * as path10 from "path";
2167
+ import * as path8 from "path";
2295
2168
  import chalk8 from "chalk";
2296
2169
  var CATEGORY_WEIGHTS = {
2297
2170
  source: 100,
@@ -2348,7 +2221,7 @@ function rankFiles(files, taskDescription, options = {}) {
2348
2221
  const results = files.map((file) => {
2349
2222
  let score = 0;
2350
2223
  const reasons = [];
2351
- const basename6 = path10.basename(file.path);
2224
+ const basename6 = path8.basename(file.path);
2352
2225
  score += CATEGORY_WEIGHTS[file.category] || 10;
2353
2226
  reasons.push(`category:${file.category}=${CATEGORY_WEIGHTS[file.category] || 10}`);
2354
2227
  if (boostSource && file.category === "source") {
@@ -2419,7 +2292,7 @@ function printRankedFiles(ranked) {
2419
2292
  }
2420
2293
 
2421
2294
  // src/editor/patch.ts
2422
- import * as fs10 from "fs";
2295
+ import * as fs8 from "fs";
2423
2296
  import chalk9 from "chalk";
2424
2297
  function generateDiff(oldLines, newLines) {
2425
2298
  const result = [];
@@ -2445,10 +2318,10 @@ function generateDiff(oldLines, newLines) {
2445
2318
  }
2446
2319
  function applyInlinePatch(filePath, searchBlock, replaceBlock) {
2447
2320
  try {
2448
- if (!fs10.existsSync(filePath)) {
2321
+ if (!fs8.existsSync(filePath)) {
2449
2322
  return { success: false, applied: false, output: "", error: `File not found: ${filePath}` };
2450
2323
  }
2451
- const content = fs10.readFileSync(filePath, "utf-8");
2324
+ const content = fs8.readFileSync(filePath, "utf-8");
2452
2325
  const searchNormalized = searchBlock.trim();
2453
2326
  const contentNormalized = content;
2454
2327
  const idx = contentNormalized.indexOf(searchNormalized);
@@ -2466,7 +2339,7 @@ function applyInlinePatch(filePath, searchBlock, replaceBlock) {
2466
2339
  const oldLines = searchBlock.split("\n");
2467
2340
  const newLines = replaceBlock.split("\n");
2468
2341
  const diff = generateDiff(oldLines, newLines);
2469
- fs10.writeFileSync(filePath, newContent, "utf-8");
2342
+ fs8.writeFileSync(filePath, newContent, "utf-8");
2470
2343
  return { success: true, applied: true, output: `Patch applied:
2471
2344
  ${diff}` };
2472
2345
  } catch (err) {
@@ -2594,28 +2467,28 @@ function detectLanguage(filePath) {
2594
2467
  }
2595
2468
 
2596
2469
  // src/editor/undo.ts
2597
- import * as fs11 from "fs";
2598
- import * as path11 from "path";
2470
+ import * as fs9 from "fs";
2471
+ import * as path9 from "path";
2599
2472
  var UNDO_DIR = ".lovecode/undo";
2600
2473
  function getUndoDir(rootDir) {
2601
- return path11.join(rootDir, UNDO_DIR);
2474
+ return path9.join(rootDir, UNDO_DIR);
2602
2475
  }
2603
2476
  function ensureUndoDir(rootDir) {
2604
2477
  const dir = getUndoDir(rootDir);
2605
- fs11.mkdirSync(dir, { recursive: true });
2478
+ fs9.mkdirSync(dir, { recursive: true });
2606
2479
  return dir;
2607
2480
  }
2608
2481
  function getUndoFilePath(rootDir, id) {
2609
- return path11.join(getUndoDir(rootDir), `${id}.json`);
2482
+ return path9.join(getUndoDir(rootDir), `${id}.json`);
2610
2483
  }
2611
2484
  function getIndexPath(rootDir) {
2612
- return path11.join(getUndoDir(rootDir), "index.json");
2485
+ return path9.join(getUndoDir(rootDir), "index.json");
2613
2486
  }
2614
2487
  function saveUndoPoint(rootDir, filePath, label = "edit") {
2615
2488
  try {
2616
- if (!fs11.existsSync(filePath)) return null;
2489
+ if (!fs9.existsSync(filePath)) return null;
2617
2490
  const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
2618
- const content = fs11.readFileSync(filePath, "utf-8");
2491
+ const content = fs9.readFileSync(filePath, "utf-8");
2619
2492
  const entry = {
2620
2493
  id,
2621
2494
  filePath,
@@ -2625,19 +2498,19 @@ function saveUndoPoint(rootDir, filePath, label = "edit") {
2625
2498
  };
2626
2499
  ensureUndoDir(rootDir);
2627
2500
  const entryFile = getUndoFilePath(rootDir, id);
2628
- fs11.writeFileSync(entryFile, JSON.stringify(entry, null, 2), "utf-8");
2501
+ fs9.writeFileSync(entryFile, JSON.stringify(entry, null, 2), "utf-8");
2629
2502
  const indexPath = getIndexPath(rootDir);
2630
2503
  let index = [];
2631
- if (fs11.existsSync(indexPath)) {
2504
+ if (fs9.existsSync(indexPath)) {
2632
2505
  try {
2633
- index = JSON.parse(fs11.readFileSync(indexPath, "utf-8"));
2506
+ index = JSON.parse(fs9.readFileSync(indexPath, "utf-8"));
2634
2507
  } catch {
2635
2508
  index = [];
2636
2509
  }
2637
2510
  }
2638
2511
  index.unshift(entry);
2639
2512
  if (index.length > 100) index = index.slice(0, 100);
2640
- fs11.writeFileSync(indexPath, JSON.stringify(index, null, 2), "utf-8");
2513
+ fs9.writeFileSync(indexPath, JSON.stringify(index, null, 2), "utf-8");
2641
2514
  return entry;
2642
2515
  } catch {
2643
2516
  return null;
@@ -2646,21 +2519,21 @@ function saveUndoPoint(rootDir, filePath, label = "edit") {
2646
2519
  function undoLast(rootDir, filePath) {
2647
2520
  try {
2648
2521
  const indexPath = getIndexPath(rootDir);
2649
- if (!fs11.existsSync(indexPath)) return null;
2650
- const index = JSON.parse(fs11.readFileSync(indexPath, "utf-8"));
2522
+ if (!fs9.existsSync(indexPath)) return null;
2523
+ const index = JSON.parse(fs9.readFileSync(indexPath, "utf-8"));
2651
2524
  const targetIdx = filePath ? index.findIndex((e) => e.filePath === filePath) : 0;
2652
2525
  if (targetIdx === -1) return null;
2653
2526
  const entry = index[targetIdx];
2654
- if (!fs11.existsSync(entry.filePath)) {
2527
+ if (!fs9.existsSync(entry.filePath)) {
2655
2528
  index.splice(targetIdx, 1);
2656
- fs11.writeFileSync(indexPath, JSON.stringify(index, null, 2), "utf-8");
2529
+ fs9.writeFileSync(indexPath, JSON.stringify(index, null, 2), "utf-8");
2657
2530
  return null;
2658
2531
  }
2659
- fs11.writeFileSync(entry.filePath, entry.originalContent, "utf-8");
2532
+ fs9.writeFileSync(entry.filePath, entry.originalContent, "utf-8");
2660
2533
  index.splice(targetIdx, 1);
2661
- fs11.writeFileSync(indexPath, JSON.stringify(index, null, 2), "utf-8");
2534
+ fs9.writeFileSync(indexPath, JSON.stringify(index, null, 2), "utf-8");
2662
2535
  const entryFile = getUndoFilePath(rootDir, entry.id);
2663
- if (fs11.existsSync(entryFile)) fs11.unlinkSync(entryFile);
2536
+ if (fs9.existsSync(entryFile)) fs9.unlinkSync(entryFile);
2664
2537
  return entry;
2665
2538
  } catch {
2666
2539
  return null;
@@ -2669,8 +2542,8 @@ function undoLast(rootDir, filePath) {
2669
2542
  function getUndoHistory(rootDir) {
2670
2543
  try {
2671
2544
  const indexPath = getIndexPath(rootDir);
2672
- if (!fs11.existsSync(indexPath)) return [];
2673
- return JSON.parse(fs11.readFileSync(indexPath, "utf-8"));
2545
+ if (!fs9.existsSync(indexPath)) return [];
2546
+ return JSON.parse(fs9.readFileSync(indexPath, "utf-8"));
2674
2547
  } catch {
2675
2548
  return [];
2676
2549
  }
@@ -2680,22 +2553,22 @@ function undoForFile(rootDir, filePath) {
2680
2553
  }
2681
2554
 
2682
2555
  // src/editor/snapshot.ts
2683
- import * as fs12 from "fs";
2684
- import * as path12 from "path";
2556
+ import * as fs10 from "fs";
2557
+ import * as path10 from "path";
2685
2558
  var SNAPSHOT_DIR = ".lovecode/snapshots";
2686
2559
  function getSnapshotDir(rootDir) {
2687
- return path12.join(rootDir, SNAPSHOT_DIR);
2560
+ return path10.join(rootDir, SNAPSHOT_DIR);
2688
2561
  }
2689
2562
  function ensureSnapshotDir(rootDir) {
2690
2563
  const dir = getSnapshotDir(rootDir);
2691
- fs12.mkdirSync(dir, { recursive: true });
2564
+ fs10.mkdirSync(dir, { recursive: true });
2692
2565
  return dir;
2693
2566
  }
2694
2567
  function createSnapshot(rootDir, filePath, label = "") {
2695
2568
  try {
2696
- if (!fs12.existsSync(filePath)) return null;
2697
- const content = fs12.readFileSync(filePath, "utf-8");
2698
- const relativePath = path12.relative(rootDir, filePath).replace(/\\/g, "/");
2569
+ if (!fs10.existsSync(filePath)) return null;
2570
+ const content = fs10.readFileSync(filePath, "utf-8");
2571
+ const relativePath = path10.relative(rootDir, filePath).replace(/\\/g, "/");
2699
2572
  const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
2700
2573
  const snapshotDir = ensureSnapshotDir(rootDir);
2701
2574
  const snapshot = {
@@ -2706,8 +2579,8 @@ function createSnapshot(rootDir, filePath, label = "") {
2706
2579
  label,
2707
2580
  size: content.length
2708
2581
  };
2709
- fs12.writeFileSync(path12.join(snapshotDir, `${id}.snap`), content, "utf-8");
2710
- fs12.writeFileSync(path12.join(snapshotDir, `${id}.meta`), JSON.stringify(snapshot, null, 2), "utf-8");
2582
+ fs10.writeFileSync(path10.join(snapshotDir, `${id}.snap`), content, "utf-8");
2583
+ fs10.writeFileSync(path10.join(snapshotDir, `${id}.meta`), JSON.stringify(snapshot, null, 2), "utf-8");
2711
2584
  return snapshot;
2712
2585
  } catch {
2713
2586
  return null;
@@ -2716,13 +2589,13 @@ function createSnapshot(rootDir, filePath, label = "") {
2716
2589
  function restoreSnapshot(rootDir, id) {
2717
2590
  try {
2718
2591
  const snapshotDir = getSnapshotDir(rootDir);
2719
- const metaPath = path12.join(snapshotDir, `${id}.meta`);
2720
- const snapPath = path12.join(snapshotDir, `${id}.snap`);
2721
- if (!fs12.existsSync(metaPath) || !fs12.existsSync(snapPath)) return false;
2722
- const meta = JSON.parse(fs12.readFileSync(metaPath, "utf-8"));
2723
- const content = fs12.readFileSync(snapPath, "utf-8");
2724
- if (fs12.existsSync(meta.filePath)) {
2725
- fs12.writeFileSync(meta.filePath, content, "utf-8");
2592
+ const metaPath = path10.join(snapshotDir, `${id}.meta`);
2593
+ const snapPath = path10.join(snapshotDir, `${id}.snap`);
2594
+ if (!fs10.existsSync(metaPath) || !fs10.existsSync(snapPath)) return false;
2595
+ const meta = JSON.parse(fs10.readFileSync(metaPath, "utf-8"));
2596
+ const content = fs10.readFileSync(snapPath, "utf-8");
2597
+ if (fs10.existsSync(meta.filePath)) {
2598
+ fs10.writeFileSync(meta.filePath, content, "utf-8");
2726
2599
  }
2727
2600
  return true;
2728
2601
  } catch {
@@ -2732,13 +2605,13 @@ function restoreSnapshot(rootDir, id) {
2732
2605
  function listSnapshots(rootDir) {
2733
2606
  try {
2734
2607
  const snapshotDir = getSnapshotDir(rootDir);
2735
- if (!fs12.existsSync(snapshotDir)) return [];
2736
- const files = fs12.readdirSync(snapshotDir);
2608
+ if (!fs10.existsSync(snapshotDir)) return [];
2609
+ const files = fs10.readdirSync(snapshotDir);
2737
2610
  const metaFiles = files.filter((f) => f.endsWith(".meta"));
2738
2611
  const snapshots = [];
2739
2612
  for (const metaFile of metaFiles) {
2740
2613
  try {
2741
- const meta = JSON.parse(fs12.readFileSync(path12.join(snapshotDir, metaFile), "utf-8"));
2614
+ const meta = JSON.parse(fs10.readFileSync(path10.join(snapshotDir, metaFile), "utf-8"));
2742
2615
  snapshots.push(meta);
2743
2616
  } catch {
2744
2617
  }
@@ -2759,7 +2632,7 @@ function createBatchSnapshot(rootDir, filePaths, label = "batch") {
2759
2632
  }
2760
2633
 
2761
2634
  // src/editor/refactor.ts
2762
- import * as fs13 from "fs";
2635
+ import * as fs11 from "fs";
2763
2636
  import chalk10 from "chalk";
2764
2637
  async function executeRefactor(plan) {
2765
2638
  const snapshots = [];
@@ -2773,7 +2646,7 @@ async function executeRefactor(plan) {
2773
2646
  if (result.success && result.applied) {
2774
2647
  if (plan.validateSyntax) {
2775
2648
  try {
2776
- const content = fs13.readFileSync(edit.filePath, "utf-8");
2649
+ const content = fs11.readFileSync(edit.filePath, "utf-8");
2777
2650
  const lang = detectLanguage(edit.filePath);
2778
2651
  if (!hasValidSyntax(content, lang)) {
2779
2652
  errors.push({
@@ -3113,8 +2986,8 @@ function printSandboxVerdict(verdict) {
3113
2986
  }
3114
2987
 
3115
2988
  // src/repo/detect.ts
3116
- import * as fs14 from "fs";
3117
- import * as path13 from "path";
2989
+ import * as fs12 from "fs";
2990
+ import * as path11 from "path";
3118
2991
  import chalk14 from "chalk";
3119
2992
  var rules = [
3120
2993
  {
@@ -3123,10 +2996,10 @@ var rules = [
3123
2996
  language: "TypeScript",
3124
2997
  check: (dir) => {
3125
2998
  const evidence = [];
3126
- if (fs14.existsSync(path13.join(dir, "next.config.js")) || fs14.existsSync(path13.join(dir, "next.config.mjs"))) {
2999
+ if (fs12.existsSync(path11.join(dir, "next.config.js")) || fs12.existsSync(path11.join(dir, "next.config.mjs"))) {
3127
3000
  evidence.push("next.config.{js,mjs}");
3128
3001
  }
3129
- const pkg2 = readJson(path13.join(dir, "package.json"));
3002
+ const pkg2 = readJson(path11.join(dir, "package.json"));
3130
3003
  if (pkg2?.dependencies?.next || pkg2?.devDependencies?.next) {
3131
3004
  evidence.push("package.json: next dependency");
3132
3005
  }
@@ -3139,9 +3012,9 @@ var rules = [
3139
3012
  language: "TypeScript/JavaScript",
3140
3013
  check: (dir) => {
3141
3014
  const evidence = [];
3142
- const pkg2 = readJson(path13.join(dir, "package.json"));
3015
+ const pkg2 = readJson(path11.join(dir, "package.json"));
3143
3016
  if (pkg2?.dependencies?.react) evidence.push("package.json: react dependency");
3144
- if (fs14.existsSync(path13.join(dir, "jsconfig.json"))) evidence.push("jsconfig.json");
3017
+ if (fs12.existsSync(path11.join(dir, "jsconfig.json"))) evidence.push("jsconfig.json");
3145
3018
  if (findFiles2(dir, ".jsx", 3).length > 0) evidence.push(".jsx files found");
3146
3019
  if (findFiles2(dir, ".tsx", 3).length > 0) evidence.push(".tsx files found");
3147
3020
  return { detected: evidence.length > 0, confidence: Math.min(evidence.length * 30, 95), evidence };
@@ -3153,9 +3026,9 @@ var rules = [
3153
3026
  language: "JavaScript",
3154
3027
  check: (dir) => {
3155
3028
  const evidence = [];
3156
- if (fs14.existsSync(path13.join(dir, "package.json"))) evidence.push("package.json");
3157
- if (fs14.existsSync(path13.join(dir, "package-lock.json"))) evidence.push("package-lock.json");
3158
- const pkg2 = readJson(path13.join(dir, "package.json"));
3029
+ if (fs12.existsSync(path11.join(dir, "package.json"))) evidence.push("package.json");
3030
+ if (fs12.existsSync(path11.join(dir, "package-lock.json"))) evidence.push("package-lock.json");
3031
+ const pkg2 = readJson(path11.join(dir, "package.json"));
3159
3032
  if (pkg2 && !pkg2?.dependencies?.react && !pkg2?.dependencies?.next) {
3160
3033
  evidence.push("Node.js package (no React/Next)");
3161
3034
  }
@@ -3168,8 +3041,8 @@ var rules = [
3168
3041
  language: "Go",
3169
3042
  check: (dir) => {
3170
3043
  const evidence = [];
3171
- if (fs14.existsSync(path13.join(dir, "go.mod"))) evidence.push("go.mod");
3172
- if (fs14.existsSync(path13.join(dir, "go.sum"))) evidence.push("go.sum");
3044
+ if (fs12.existsSync(path11.join(dir, "go.mod"))) evidence.push("go.mod");
3045
+ if (fs12.existsSync(path11.join(dir, "go.sum"))) evidence.push("go.sum");
3173
3046
  if (findFiles2(dir, ".go", 3).length > 0) evidence.push(".go files found");
3174
3047
  return { detected: evidence.length > 0, confidence: evidence.includes("go.mod") ? 98 : 60, evidence };
3175
3048
  }
@@ -3180,11 +3053,11 @@ var rules = [
3180
3053
  language: "Python",
3181
3054
  check: (dir) => {
3182
3055
  const evidence = [];
3183
- if (fs14.existsSync(path13.join(dir, "manage.py"))) evidence.push("manage.py");
3056
+ if (fs12.existsSync(path11.join(dir, "manage.py"))) evidence.push("manage.py");
3184
3057
  if (findFiles2(dir, "settings.py", 5).length > 0) evidence.push("settings.py found");
3185
- const cfg = readFile(path13.join(dir, "requirements.txt"));
3058
+ const cfg = readFile(path11.join(dir, "requirements.txt"));
3186
3059
  if (cfg?.includes("django")) evidence.push("requirements.txt: django");
3187
- const pipfile = readFile(path13.join(dir, "Pipfile"));
3060
+ const pipfile = readFile(path11.join(dir, "Pipfile"));
3188
3061
  if (pipfile?.includes("django")) evidence.push("Pipfile: django");
3189
3062
  return { detected: evidence.length > 0, confidence: evidence.includes("manage.py") ? 95 : 50, evidence };
3190
3063
  }
@@ -3195,9 +3068,9 @@ var rules = [
3195
3068
  language: "Dart",
3196
3069
  check: (dir) => {
3197
3070
  const evidence = [];
3198
- if (fs14.existsSync(path13.join(dir, "pubspec.yaml"))) evidence.push("pubspec.yaml");
3071
+ if (fs12.existsSync(path11.join(dir, "pubspec.yaml"))) evidence.push("pubspec.yaml");
3199
3072
  if (findFiles2(dir, ".dart", 3).length > 0) evidence.push(".dart files found");
3200
- if (fs14.existsSync(path13.join(dir, "android")) && fs14.existsSync(path13.join(dir, "ios"))) {
3073
+ if (fs12.existsSync(path11.join(dir, "android")) && fs12.existsSync(path11.join(dir, "ios"))) {
3201
3074
  evidence.push("android/ & ios/ directories");
3202
3075
  }
3203
3076
  return { detected: evidence.length > 0, confidence: evidence.includes("pubspec.yaml") ? 95 : 50, evidence };
@@ -3209,9 +3082,9 @@ var rules = [
3209
3082
  language: "Python",
3210
3083
  check: (dir) => {
3211
3084
  const evidence = [];
3212
- if (fs14.existsSync(path13.join(dir, "requirements.txt"))) evidence.push("requirements.txt");
3213
- if (fs14.existsSync(path13.join(dir, "setup.py"))) evidence.push("setup.py");
3214
- if (fs14.existsSync(path13.join(dir, "pyproject.toml"))) evidence.push("pyproject.toml");
3085
+ if (fs12.existsSync(path11.join(dir, "requirements.txt"))) evidence.push("requirements.txt");
3086
+ if (fs12.existsSync(path11.join(dir, "setup.py"))) evidence.push("setup.py");
3087
+ if (fs12.existsSync(path11.join(dir, "pyproject.toml"))) evidence.push("pyproject.toml");
3215
3088
  if (findFiles2(dir, ".py", 5).length > 0) evidence.push(".py files found");
3216
3089
  return { detected: evidence.length > 0, confidence: Math.min(evidence.length * 25, 90), evidence };
3217
3090
  }
@@ -3222,8 +3095,8 @@ var rules = [
3222
3095
  language: "Rust",
3223
3096
  check: (dir) => {
3224
3097
  const evidence = [];
3225
- if (fs14.existsSync(path13.join(dir, "Cargo.toml"))) evidence.push("Cargo.toml");
3226
- if (fs14.existsSync(path13.join(dir, "Cargo.lock"))) evidence.push("Cargo.lock");
3098
+ if (fs12.existsSync(path11.join(dir, "Cargo.toml"))) evidence.push("Cargo.toml");
3099
+ if (fs12.existsSync(path11.join(dir, "Cargo.lock"))) evidence.push("Cargo.lock");
3227
3100
  if (findFiles2(dir, ".rs", 3).length > 0) evidence.push(".rs files found");
3228
3101
  return { detected: evidence.length > 0, confidence: evidence.includes("Cargo.toml") ? 98 : 60, evidence };
3229
3102
  }
@@ -3234,7 +3107,7 @@ var rules = [
3234
3107
  language: "JavaScript",
3235
3108
  check: (dir) => {
3236
3109
  const evidence = [];
3237
- const pkg2 = readJson(path13.join(dir, "package.json"));
3110
+ const pkg2 = readJson(path11.join(dir, "package.json"));
3238
3111
  if (pkg2?.dependencies?.vue) evidence.push("package.json: vue");
3239
3112
  if (findFiles2(dir, ".vue", 3).length > 0) evidence.push(".vue files found");
3240
3113
  return { detected: evidence.length > 0, confidence: Math.min(evidence.length * 40, 90), evidence };
@@ -3246,8 +3119,8 @@ var rules = [
3246
3119
  language: "TypeScript",
3247
3120
  check: (dir) => {
3248
3121
  const evidence = [];
3249
- if (fs14.existsSync(path13.join(dir, "angular.json"))) evidence.push("angular.json");
3250
- const pkg2 = readJson(path13.join(dir, "package.json"));
3122
+ if (fs12.existsSync(path11.join(dir, "angular.json"))) evidence.push("angular.json");
3123
+ const pkg2 = readJson(path11.join(dir, "package.json"));
3251
3124
  if (pkg2?.dependencies?.["@angular/core"]) evidence.push("package.json: @angular/core");
3252
3125
  return { detected: evidence.length > 0, confidence: Math.min(evidence.length * 40, 95), evidence };
3253
3126
  }
@@ -3255,7 +3128,7 @@ var rules = [
3255
3128
  ];
3256
3129
  function readJson(filePath) {
3257
3130
  try {
3258
- const content = fs14.readFileSync(filePath, "utf-8");
3131
+ const content = fs12.readFileSync(filePath, "utf-8");
3259
3132
  return JSON.parse(content);
3260
3133
  } catch {
3261
3134
  return null;
@@ -3263,7 +3136,7 @@ function readJson(filePath) {
3263
3136
  }
3264
3137
  function readFile(filePath) {
3265
3138
  try {
3266
- return fs14.readFileSync(filePath, "utf-8");
3139
+ return fs12.readFileSync(filePath, "utf-8");
3267
3140
  } catch {
3268
3141
  return null;
3269
3142
  }
@@ -3271,11 +3144,11 @@ function readFile(filePath) {
3271
3144
  function findFiles2(dir, ext, max) {
3272
3145
  const results = [];
3273
3146
  try {
3274
- const entries = fs14.readdirSync(dir, { withFileTypes: true });
3147
+ const entries = fs12.readdirSync(dir, { withFileTypes: true });
3275
3148
  for (const entry of entries) {
3276
3149
  if (results.length >= max) break;
3277
3150
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
3278
- const fullPath = path13.join(dir, entry.name);
3151
+ const fullPath = path11.join(dir, entry.name);
3279
3152
  if (entry.isDirectory()) {
3280
3153
  results.push(...findFiles2(fullPath, ext, max - results.length));
3281
3154
  } else if (entry.name.endsWith(ext)) {
@@ -3304,12 +3177,12 @@ function detectProject(rootDir) {
3304
3177
  types.sort((a, b) => b.confidence - a.confidence);
3305
3178
  const languages = [...new Set(types.map((t) => t.language))];
3306
3179
  const primary = types[0] || null;
3307
- const pkg2 = readJson(path13.join(rootDir, "package.json"));
3180
+ const pkg2 = readJson(path11.join(rootDir, "package.json"));
3308
3181
  let packageManager = null;
3309
- if (fs14.existsSync(path13.join(rootDir, "yarn.lock"))) packageManager = "yarn";
3310
- else if (fs14.existsSync(path13.join(rootDir, "pnpm-lock.yaml"))) packageManager = "pnpm";
3311
- else if (fs14.existsSync(path13.join(rootDir, "package-lock.json"))) packageManager = "npm";
3312
- else if (fs14.existsSync(path13.join(rootDir, "bun.lockb"))) packageManager = "bun";
3182
+ if (fs12.existsSync(path11.join(rootDir, "yarn.lock"))) packageManager = "yarn";
3183
+ else if (fs12.existsSync(path11.join(rootDir, "pnpm-lock.yaml"))) packageManager = "pnpm";
3184
+ else if (fs12.existsSync(path11.join(rootDir, "package-lock.json"))) packageManager = "npm";
3185
+ else if (fs12.existsSync(path11.join(rootDir, "bun.lockb"))) packageManager = "bun";
3313
3186
  let buildTool = null;
3314
3187
  if (pkg2?.scripts) {
3315
3188
  const scripts = pkg2.scripts;
@@ -3321,9 +3194,9 @@ function detectProject(rootDir) {
3321
3194
  else buildTool = "custom";
3322
3195
  }
3323
3196
  }
3324
- if (!buildTool && fs14.existsSync(path13.join(rootDir, "webpack.config.js"))) buildTool = "webpack";
3325
- if (!buildTool && fs14.existsSync(path13.join(rootDir, "vite.config.ts"))) buildTool = "vite";
3326
- if (!buildTool && fs14.existsSync(path13.join(rootDir, "tsconfig.json"))) buildTool = "tsc";
3197
+ if (!buildTool && fs12.existsSync(path11.join(rootDir, "webpack.config.js"))) buildTool = "webpack";
3198
+ if (!buildTool && fs12.existsSync(path11.join(rootDir, "vite.config.ts"))) buildTool = "vite";
3199
+ if (!buildTool && fs12.existsSync(path11.join(rootDir, "tsconfig.json"))) buildTool = "tsc";
3327
3200
  return { types, primary, languages, packageManager, buildTool };
3328
3201
  }
3329
3202
  function printProjectInfo(info) {
@@ -3358,8 +3231,8 @@ function confidenceBar(pct) {
3358
3231
  }
3359
3232
 
3360
3233
  // src/repo/deps.ts
3361
- import * as fs15 from "fs";
3362
- import * as path14 from "path";
3234
+ import * as fs13 from "fs";
3235
+ import * as path12 from "path";
3363
3236
  import chalk15 from "chalk";
3364
3237
  var IMPORT_PATTERNS = [
3365
3238
  { regex: /import\s+(?:\*\s+as\s+\w+\s+from\s+)?['"]([^'"]+)['"]/g, type: "import" },
@@ -3386,8 +3259,8 @@ function analyzeDependencies(rootDir) {
3386
3259
  const edges = [];
3387
3260
  const sourceFiles = collectSourceFiles(rootDir);
3388
3261
  for (const filePath of sourceFiles) {
3389
- const relativePath = path14.relative(rootDir, filePath).replace(/\\/g, "/");
3390
- const ext = path14.extname(filePath).toLowerCase();
3262
+ const relativePath = path12.relative(rootDir, filePath).replace(/\\/g, "/");
3263
+ const ext = path12.extname(filePath).toLowerCase();
3391
3264
  let patterns = IMPORT_PATTERNS;
3392
3265
  if (ext === ".py") patterns = PYTHON_PATTERNS;
3393
3266
  else if (ext === ".go") patterns = GO_PATTERNS;
@@ -3402,14 +3275,14 @@ function analyzeDependencies(rootDir) {
3402
3275
  });
3403
3276
  }
3404
3277
  try {
3405
- const content = fs15.readFileSync(filePath, "utf-8");
3278
+ const content = fs13.readFileSync(filePath, "utf-8");
3406
3279
  const imports = extractImports(content, patterns);
3407
3280
  for (const imp of imports) {
3408
3281
  const resolved = resolveImport(imp, relativePath, rootDir, sourceFiles);
3409
3282
  edges.push({ source: relativePath, target: resolved, type: "import" });
3410
3283
  nodes.get(relativePath).imports.push(imp);
3411
3284
  if (!nodes.has(resolved)) {
3412
- const isExternal = !sourceFiles.includes(resolved) && !fs15.existsSync(resolved);
3285
+ const isExternal = !sourceFiles.includes(resolved) && !fs13.existsSync(resolved);
3413
3286
  nodes.set(resolved, {
3414
3287
  name: resolved,
3415
3288
  filePath: resolved,
@@ -3432,14 +3305,14 @@ function collectSourceFiles(rootDir) {
3432
3305
  const skipDirs = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "build", ".next", "__pycache__", "target", "vendor"]);
3433
3306
  function walk(dir) {
3434
3307
  try {
3435
- const entries = fs15.readdirSync(dir, { withFileTypes: true });
3308
+ const entries = fs13.readdirSync(dir, { withFileTypes: true });
3436
3309
  for (const entry of entries) {
3437
3310
  if (entry.name.startsWith(".") || skipDirs.has(entry.name)) continue;
3438
- const fullPath = path14.join(dir, entry.name);
3311
+ const fullPath = path12.join(dir, entry.name);
3439
3312
  if (entry.isDirectory()) {
3440
3313
  walk(fullPath);
3441
3314
  } else {
3442
- const ext = path14.extname(entry.name).toLowerCase();
3315
+ const ext = path12.extname(entry.name).toLowerCase();
3443
3316
  if ([".ts", ".tsx", ".js", ".jsx", ".mjs", ".py", ".go", ".rs", ".rb", ".java"].includes(ext)) {
3444
3317
  results.push(fullPath);
3445
3318
  }
@@ -3469,12 +3342,12 @@ function extractImports(content, patterns) {
3469
3342
  }
3470
3343
  function resolveImport(imp, relativeFrom, rootDir, allFiles) {
3471
3344
  if (imp.startsWith(".")) {
3472
- const dir = path14.dirname(path14.join(rootDir, relativeFrom));
3473
- const resolved = path14.resolve(dir, imp);
3345
+ const dir = path12.dirname(path12.join(rootDir, relativeFrom));
3346
+ const resolved = path12.resolve(dir, imp);
3474
3347
  const extensions = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".py", ".go", ".rs", "/index.ts", "/index.js"];
3475
3348
  for (const ext of extensions) {
3476
3349
  const candidate = resolved + ext;
3477
- if (allFiles.includes(candidate)) return path14.relative(rootDir, candidate).replace(/\\/g, "/");
3350
+ if (allFiles.includes(candidate)) return path12.relative(rootDir, candidate).replace(/\\/g, "/");
3478
3351
  }
3479
3352
  return imp;
3480
3353
  }
@@ -3484,15 +3357,15 @@ function detectEntryPoints(rootDir, files) {
3484
3357
  const entries = [];
3485
3358
  const entryNames = ["index.ts", "index.js", "main.ts", "main.js", "app.ts", "app.js", "server.ts", "server.js"];
3486
3359
  for (const name of entryNames) {
3487
- const fp = path14.join(rootDir, name);
3360
+ const fp = path12.join(rootDir, name);
3488
3361
  if (files.includes(fp)) entries.push(name);
3489
3362
  }
3490
- if (fs15.existsSync(path14.join(rootDir, "package.json"))) {
3363
+ if (fs13.existsSync(path12.join(rootDir, "package.json"))) {
3491
3364
  try {
3492
- const pkg2 = JSON.parse(fs15.readFileSync(path14.join(rootDir, "package.json"), "utf-8"));
3365
+ const pkg2 = JSON.parse(fs13.readFileSync(path12.join(rootDir, "package.json"), "utf-8"));
3493
3366
  if (pkg2.main) {
3494
- const mainPath = path14.join(rootDir, pkg2.main);
3495
- const relative6 = path14.relative(rootDir, mainPath).replace(/\\/g, "/");
3367
+ const mainPath = path12.join(rootDir, pkg2.main);
3368
+ const relative6 = path12.relative(rootDir, mainPath).replace(/\\/g, "/");
3496
3369
  if (!entries.includes(relative6)) entries.push(relative6);
3497
3370
  }
3498
3371
  } catch {
@@ -3538,7 +3411,7 @@ function findCircularDeps(graph) {
3538
3411
  const visited = /* @__PURE__ */ new Set();
3539
3412
  const recursionStack = /* @__PURE__ */ new Set();
3540
3413
  const circles = [];
3541
- function dfs(node, path23) {
3414
+ function dfs(node, path21) {
3542
3415
  visited.add(node);
3543
3416
  recursionStack.add(node);
3544
3417
  const nodeData = graph.nodes.get(node);
@@ -3550,9 +3423,9 @@ function findCircularDeps(graph) {
3550
3423
  const target = resolveImportInGraph(imp, node, graph);
3551
3424
  if (target && graph.nodes.has(target)) {
3552
3425
  if (!visited.has(target)) {
3553
- dfs(target, [...path23, target]);
3426
+ dfs(target, [...path21, target]);
3554
3427
  } else if (recursionStack.has(target)) {
3555
- const cycle = [...path23.slice(path23.indexOf(target)), target];
3428
+ const cycle = [...path21.slice(path21.indexOf(target)), target];
3556
3429
  circles.push(cycle);
3557
3430
  }
3558
3431
  }
@@ -3568,14 +3441,14 @@ function findCircularDeps(graph) {
3568
3441
  }
3569
3442
  function resolveImportInGraph(imp, from, _graph) {
3570
3443
  if (!imp.startsWith(".")) return null;
3571
- const dir = path14.dirname(from);
3572
- const resolved = path14.normalize(path14.join(dir, imp)).replace(/\\/g, "/");
3444
+ const dir = path12.dirname(from);
3445
+ const resolved = path12.normalize(path12.join(dir, imp)).replace(/\\/g, "/");
3573
3446
  return resolved;
3574
3447
  }
3575
3448
 
3576
3449
  // src/repo/summary.ts
3577
- import * as fs16 from "fs";
3578
- import * as path15 from "path";
3450
+ import * as fs14 from "fs";
3451
+ import * as path13 from "path";
3579
3452
  import chalk16 from "chalk";
3580
3453
  function countDirStats(dir) {
3581
3454
  let files = 0;
@@ -3586,20 +3459,20 @@ function countDirStats(dir) {
3586
3459
  const skipDirs = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "build", ".next", "__pycache__", "target", "vendor", "coverage"]);
3587
3460
  function walk(dir2) {
3588
3461
  try {
3589
- const entries = fs16.readdirSync(dir2, { withFileTypes: true });
3462
+ const entries = fs14.readdirSync(dir2, { withFileTypes: true });
3590
3463
  for (const entry of entries) {
3591
3464
  if (entry.name.startsWith(".") || skipDirs.has(entry.name)) continue;
3592
- const fullPath = path15.join(dir2, entry.name);
3465
+ const fullPath = path13.join(dir2, entry.name);
3593
3466
  if (entry.isDirectory()) {
3594
3467
  dirs++;
3595
3468
  walk(fullPath);
3596
3469
  } else {
3597
3470
  files++;
3598
- const ext = path15.extname(entry.name).toLowerCase() || entry.name;
3599
- const stats = fs16.statSync(fullPath);
3471
+ const ext = path13.extname(entry.name).toLowerCase() || entry.name;
3472
+ const stats = fs14.statSync(fullPath);
3600
3473
  let lineCount = 0;
3601
3474
  try {
3602
- const content = fs16.readFileSync(fullPath, "utf-8");
3475
+ const content = fs14.readFileSync(fullPath, "utf-8");
3603
3476
  lineCount = content.split("\n").length;
3604
3477
  totalLines += lineCount;
3605
3478
  } catch {
@@ -3624,7 +3497,7 @@ function buildDirectoryTree(rootDir, maxDepth = 4) {
3624
3497
  function walk(dir, prefix, depth) {
3625
3498
  if (depth > maxDepth) return;
3626
3499
  try {
3627
- const entries = fs16.readdirSync(dir, { withFileTypes: true });
3500
+ const entries = fs14.readdirSync(dir, { withFileTypes: true });
3628
3501
  const filtered = entries.filter((e) => !e.name.startsWith(".") && !skipDirs.has(e.name));
3629
3502
  const sorted = filtered.sort((a, b) => {
3630
3503
  if (a.isDirectory() && !b.isDirectory()) return -1;
@@ -3638,9 +3511,9 @@ function buildDirectoryTree(rootDir, maxDepth = 4) {
3638
3511
  const nextPrefix = isLast ? " " : "\u2502 ";
3639
3512
  if (entry.isDirectory()) {
3640
3513
  result.push(`${prefix}${connector}${chalk16.cyan(entry.name)}/`);
3641
- walk(path15.join(dir, entry.name), prefix + nextPrefix, depth + 1);
3514
+ walk(path13.join(dir, entry.name), prefix + nextPrefix, depth + 1);
3642
3515
  } else {
3643
- const stats = fs16.statSync(path15.join(dir, entry.name));
3516
+ const stats = fs14.statSync(path13.join(dir, entry.name));
3644
3517
  const size = stats.size > 1024 ? `${(stats.size / 1024).toFixed(1)} KB` : `${stats.size} B`;
3645
3518
  result.push(`${prefix}${connector}${entry.name} ${chalk16.dim(size)}`);
3646
3519
  }
@@ -3648,7 +3521,7 @@ function buildDirectoryTree(rootDir, maxDepth = 4) {
3648
3521
  } catch {
3649
3522
  }
3650
3523
  }
3651
- result.push(chalk16.bold(`${path15.basename(rootDir)}/`));
3524
+ result.push(chalk16.bold(`${path13.basename(rootDir)}/`));
3652
3525
  walk(rootDir, "", 1);
3653
3526
  return result.join("\n");
3654
3527
  }
@@ -3766,11 +3639,11 @@ var fileTools = [
3766
3639
  usage: "path=<file path>",
3767
3640
  execute(workingDir, args) {
3768
3641
  try {
3769
- const filePath = path16.resolve(workingDir, args.path || ".");
3770
- if (!fs17.existsSync(filePath)) {
3642
+ const filePath = path14.resolve(workingDir, args.path || ".");
3643
+ if (!fs15.existsSync(filePath)) {
3771
3644
  return { success: false, output: "", error: `File not found: ${args.path}` };
3772
3645
  }
3773
- const content = fs17.readFileSync(filePath, "utf-8");
3646
+ const content = fs15.readFileSync(filePath, "utf-8");
3774
3647
  const lines = content.split("\n");
3775
3648
  const numbered = lines.map((l, i) => `${String(i + 1).padStart(4, " ")} | ${l}`).join("\n");
3776
3649
  return { success: true, output: numbered };
@@ -3785,9 +3658,9 @@ var fileTools = [
3785
3658
  usage: "path=<file path> content=<file content>",
3786
3659
  execute(workingDir, args) {
3787
3660
  try {
3788
- const filePath = path16.resolve(workingDir, args.path || "");
3789
- fs17.mkdirSync(path16.dirname(filePath), { recursive: true });
3790
- fs17.writeFileSync(filePath, args.content || "", "utf-8");
3661
+ const filePath = path14.resolve(workingDir, args.path || "");
3662
+ fs15.mkdirSync(path14.dirname(filePath), { recursive: true });
3663
+ fs15.writeFileSync(filePath, args.content || "", "utf-8");
3791
3664
  return { success: true, output: `Wrote ${filePath}` };
3792
3665
  } catch (err) {
3793
3666
  return { success: false, output: "", error: String(err) };
@@ -3800,11 +3673,11 @@ var fileTools = [
3800
3673
  usage: "path=<file path> oldString=<text to find> newString=<replacement>",
3801
3674
  execute(workingDir, args) {
3802
3675
  try {
3803
- const filePath = path16.resolve(workingDir, args.path || "");
3804
- if (!fs17.existsSync(filePath)) {
3676
+ const filePath = path14.resolve(workingDir, args.path || "");
3677
+ if (!fs15.existsSync(filePath)) {
3805
3678
  return { success: false, output: "", error: `File not found: ${args.path}` };
3806
3679
  }
3807
- const content = fs17.readFileSync(filePath, "utf-8");
3680
+ const content = fs15.readFileSync(filePath, "utf-8");
3808
3681
  const { oldString, newString } = args;
3809
3682
  if (!oldString) {
3810
3683
  return { success: false, output: "", error: "oldString is required" };
@@ -3814,7 +3687,7 @@ var fileTools = [
3814
3687
  return { success: false, output: "", error: `oldString not found in ${args.path}` };
3815
3688
  }
3816
3689
  const updated = content.replaceAll(oldString, newString || "");
3817
- fs17.writeFileSync(filePath, updated, "utf-8");
3690
+ fs15.writeFileSync(filePath, updated, "utf-8");
3818
3691
  return { success: true, output: `Edited ${filePath} (${count} replacement${count > 1 ? "s" : ""})` };
3819
3692
  } catch (err) {
3820
3693
  return { success: false, output: "", error: String(err) };
@@ -3827,12 +3700,12 @@ var fileTools = [
3827
3700
  usage: "path=<file path>",
3828
3701
  execute(workingDir, args) {
3829
3702
  try {
3830
- const filePath = path16.resolve(workingDir, args.path || "");
3831
- if (fs17.existsSync(filePath)) {
3703
+ const filePath = path14.resolve(workingDir, args.path || "");
3704
+ if (fs15.existsSync(filePath)) {
3832
3705
  return { success: false, output: "", error: `File already exists: ${args.path}` };
3833
3706
  }
3834
- fs17.mkdirSync(path16.dirname(filePath), { recursive: true });
3835
- fs17.writeFileSync(filePath, "", "utf-8");
3707
+ fs15.mkdirSync(path14.dirname(filePath), { recursive: true });
3708
+ fs15.writeFileSync(filePath, "", "utf-8");
3836
3709
  return { success: true, output: `Created ${filePath}` };
3837
3710
  } catch (err) {
3838
3711
  return { success: false, output: "", error: String(err) };
@@ -3845,11 +3718,11 @@ var fileTools = [
3845
3718
  usage: "path=<file path>",
3846
3719
  execute(workingDir, args) {
3847
3720
  try {
3848
- const filePath = path16.resolve(workingDir, args.path || "");
3849
- if (!fs17.existsSync(filePath)) {
3721
+ const filePath = path14.resolve(workingDir, args.path || "");
3722
+ if (!fs15.existsSync(filePath)) {
3850
3723
  return { success: false, output: "", error: `File not found: ${args.path}` };
3851
3724
  }
3852
- fs17.unlinkSync(filePath);
3725
+ fs15.unlinkSync(filePath);
3853
3726
  return { success: true, output: `Deleted ${filePath}` };
3854
3727
  } catch (err) {
3855
3728
  return { success: false, output: "", error: String(err) };
@@ -3862,9 +3735,9 @@ var fileTools = [
3862
3735
  usage: "path=<file path> content=<content to append>",
3863
3736
  execute(workingDir, args) {
3864
3737
  try {
3865
- const filePath = path16.resolve(workingDir, args.path || "");
3866
- fs17.mkdirSync(path16.dirname(filePath), { recursive: true });
3867
- fs17.appendFileSync(filePath, (args.content || "") + "\n", "utf-8");
3738
+ const filePath = path14.resolve(workingDir, args.path || "");
3739
+ fs15.mkdirSync(path14.dirname(filePath), { recursive: true });
3740
+ fs15.appendFileSync(filePath, (args.content || "") + "\n", "utf-8");
3868
3741
  return { success: true, output: `Appended to ${filePath}` };
3869
3742
  } catch (err) {
3870
3743
  return { success: false, output: "", error: String(err) };
@@ -3911,11 +3784,11 @@ var searchTools = [
3911
3784
  usage: "path=<directory path>",
3912
3785
  execute(workingDir, args) {
3913
3786
  try {
3914
- const dirPath = path16.resolve(workingDir, args.path || ".");
3915
- if (!fs17.existsSync(dirPath)) {
3787
+ const dirPath = path14.resolve(workingDir, args.path || ".");
3788
+ if (!fs15.existsSync(dirPath)) {
3916
3789
  return { success: false, output: "", error: `Directory not found: ${args.path}` };
3917
3790
  }
3918
- const entries = fs17.readdirSync(dirPath, { withFileTypes: true });
3791
+ const entries = fs15.readdirSync(dirPath, { withFileTypes: true });
3919
3792
  const output = entries.map((e) => e.isDirectory() ? chalk17.cyan(`${e.name}/`) : e.name).join("\n");
3920
3793
  return { success: true, output };
3921
3794
  } catch (err) {
@@ -3939,7 +3812,7 @@ var fsEngineTools = [
3939
3812
  usage: "[path=<dir>] [maxDepth=<number>] [category=<source|config|doc|script|data>]",
3940
3813
  execute(workingDir, args) {
3941
3814
  try {
3942
- const rootDir = path16.resolve(workingDir, args.path || ".");
3815
+ const rootDir = path14.resolve(workingDir, args.path || ".");
3943
3816
  const maxDepth = parseInt(args.maxDepth || "10", 10);
3944
3817
  const category = args.category;
3945
3818
  const files = scanDirectory({
@@ -4017,8 +3890,8 @@ ${lines.join("\n")}` };
4017
3890
  description: "Rename or move a file",
4018
3891
  usage: "oldPath=<current path> newPath=<new path>",
4019
3892
  execute(workingDir, args) {
4020
- const oldPath = path16.resolve(workingDir, args.oldPath || "");
4021
- const newPath = path16.resolve(workingDir, args.newPath || "");
3893
+ const oldPath = path14.resolve(workingDir, args.oldPath || "");
3894
+ const newPath = path14.resolve(workingDir, args.newPath || "");
4022
3895
  const result = renameFile(oldPath, newPath);
4023
3896
  return { success: result.success, output: result.message, error: result.error };
4024
3897
  }
@@ -4028,8 +3901,8 @@ ${lines.join("\n")}` };
4028
3901
  description: "Copy/duplicate a file",
4029
3902
  usage: "source=<source path> dest=<destination path>",
4030
3903
  execute(workingDir, args) {
4031
- const sourcePath = path16.resolve(workingDir, args.source || "");
4032
- const destPath = path16.resolve(workingDir, args.dest || "");
3904
+ const sourcePath = path14.resolve(workingDir, args.source || "");
3905
+ const destPath = path14.resolve(workingDir, args.dest || "");
4033
3906
  const result = duplicateFile(sourcePath, destPath);
4034
3907
  return { success: result.success, output: result.message, error: result.error };
4035
3908
  }
@@ -4040,7 +3913,7 @@ ${lines.join("\n")}` };
4040
3913
  usage: "[path=<dir>] [maxDepth=<number>]",
4041
3914
  execute(workingDir, args) {
4042
3915
  try {
4043
- const dirPath = path16.resolve(workingDir, args.path || ".");
3916
+ const dirPath = path14.resolve(workingDir, args.path || ".");
4044
3917
  const maxDepth = parseInt(args.maxDepth || "3", 10);
4045
3918
  const tree = getDirectoryTree(dirPath, "", maxDepth);
4046
3919
  return { success: true, output: tree };
@@ -4073,7 +3946,7 @@ var editorTools = [
4073
3946
  description: "Apply a search/replace patch to a file with context matching",
4074
3947
  usage: "path=<file> search=<text to find> replace=<replacement>",
4075
3948
  execute(workingDir, args) {
4076
- const filePath = path16.resolve(workingDir, args.path || "");
3949
+ const filePath = path14.resolve(workingDir, args.path || "");
4077
3950
  const result = applyInlinePatch(filePath, args.search || "", args.replace || "");
4078
3951
  if (result.success) {
4079
3952
  saveUndoPoint(workingDir, filePath, "inline_patch");
@@ -4087,8 +3960,8 @@ var editorTools = [
4087
3960
  usage: "path=<file path>",
4088
3961
  execute(workingDir, args) {
4089
3962
  try {
4090
- const filePath = path16.resolve(workingDir, args.path || "");
4091
- const content = fs17.readFileSync(filePath, "utf-8");
3963
+ const filePath = path14.resolve(workingDir, args.path || "");
3964
+ const content = fs15.readFileSync(filePath, "utf-8");
4092
3965
  const result = checkBraceBalance(content, filePath);
4093
3966
  if (result.valid) {
4094
3967
  return { success: true, output: "Syntax check passed: all braces balanced" };
@@ -4108,7 +3981,7 @@ ${lines.join("\n")}` };
4108
3981
  description: "Undo the last file edit",
4109
3982
  usage: "[path=<file path>]",
4110
3983
  execute(workingDir, args) {
4111
- const filePath = args.path ? path16.resolve(workingDir, args.path) : void 0;
3984
+ const filePath = args.path ? path14.resolve(workingDir, args.path) : void 0;
4112
3985
  const result = filePath ? undoForFile(workingDir, filePath) : undoForFile(workingDir, "");
4113
3986
  if (result) {
4114
3987
  return { success: true, output: `Undone: ${result.label} on ${result.filePath}` };
@@ -4135,7 +4008,7 @@ ${lines.join("\n")}` };
4135
4008
  description: "Create a snapshot of a file",
4136
4009
  usage: "path=<file path> [label=<optional label>]",
4137
4010
  execute(workingDir, args) {
4138
- const filePath = path16.resolve(workingDir, args.path || "");
4011
+ const filePath = path14.resolve(workingDir, args.path || "");
4139
4012
  const label = args.label || "manual";
4140
4013
  const snap = createSnapshot(workingDir, filePath, label);
4141
4014
  if (snap) {
@@ -4526,7 +4399,7 @@ var repoTools = [
4526
4399
  description: "Detect project type, framework, and stack",
4527
4400
  usage: "[dir=<directory>]",
4528
4401
  execute(workingDir, args) {
4529
- const dir = args.dir ? path16.resolve(workingDir, args.dir) : workingDir;
4402
+ const dir = args.dir ? path14.resolve(workingDir, args.dir) : workingDir;
4530
4403
  const info = detectProject(dir);
4531
4404
  return { success: true, output: printProjectInfo(info) };
4532
4405
  }
@@ -4536,7 +4409,7 @@ var repoTools = [
4536
4409
  description: "Analyze dependencies and import graph",
4537
4410
  usage: "[dir=<directory>]",
4538
4411
  execute(workingDir, args) {
4539
- const dir = args.dir ? path16.resolve(workingDir, args.dir) : workingDir;
4412
+ const dir = args.dir ? path14.resolve(workingDir, args.dir) : workingDir;
4540
4413
  const graph = analyzeDependencies(dir);
4541
4414
  return { success: true, output: printDepGraph(graph) };
4542
4415
  }
@@ -4546,7 +4419,7 @@ var repoTools = [
4546
4419
  description: "Generate a full repository architecture summary",
4547
4420
  usage: "[dir=<directory>]",
4548
4421
  execute(workingDir, args) {
4549
- const dir = args.dir ? path16.resolve(workingDir, args.dir) : workingDir;
4422
+ const dir = args.dir ? path14.resolve(workingDir, args.dir) : workingDir;
4550
4423
  const summary = generateSummary(dir);
4551
4424
  return { success: true, output: printSummary(summary) };
4552
4425
  }
@@ -4931,11 +4804,11 @@ var runCommand = new Command2("run").alias("r").description("Run LoveCode AI on
4931
4804
  // src/commands/init.ts
4932
4805
  import { Command as Command3 } from "commander";
4933
4806
  import chalk22 from "chalk";
4934
- import * as fs18 from "fs";
4935
- import * as path18 from "path";
4807
+ import * as fs16 from "fs";
4808
+ import * as path16 from "path";
4936
4809
 
4937
4810
  // src/config/setup.ts
4938
- import * as path17 from "path";
4811
+ import * as path15 from "path";
4939
4812
  import chalk21 from "chalk";
4940
4813
  var MODELS = ["deepseek", "llama3", "codellama", "mistral", "mixtral", "qwen", "phi", "gpt-4o-mini", "claude-3-haiku"];
4941
4814
  var PROVIDERS = ["ollama", "groq", "openrouter", "togetherai", "huggingface"];
@@ -5010,7 +4883,7 @@ async function runSetup(rootDir) {
5010
4883
  };
5011
4884
  saveConfig(config, dir);
5012
4885
  console.log(chalk21.green(`
5013
- \u2713 Config saved to ${path17.join(dir, ".lovecode/config.yaml")}`));
4886
+ \u2713 Config saved to ${path15.join(dir, ".lovecode/config.yaml")}`));
5014
4887
  if (createEnv) {
5015
4888
  const envVars = {};
5016
4889
  if (apiKey && provider !== "ollama") {
@@ -5018,7 +4891,7 @@ async function runSetup(rootDir) {
5018
4891
  if (envKey) envVars[envKey.key] = apiKey;
5019
4892
  }
5020
4893
  saveEnv(envVars, dir);
5021
- console.log(chalk21.green(` \u2713 Environment saved to ${path17.join(dir, ".env")}`));
4894
+ console.log(chalk21.green(` \u2713 Environment saved to ${path15.join(dir, ".env")}`));
5022
4895
  }
5023
4896
  console.log(chalk21.dim("\n Final configuration:"));
5024
4897
  console.log(formatConfig(loadConfig(dir)));
@@ -5028,9 +4901,9 @@ async function runSetup(rootDir) {
5028
4901
  // src/commands/init.ts
5029
4902
  var initCommand = new Command3("init").alias("i").description("Initialize LoveCode AI in the current project").option("-f, --force", "Overwrite existing configuration").option("--dir <path>", "Project directory", process.cwd()).action(async (options) => {
5030
4903
  const dir = options.dir || process.cwd();
5031
- const configPath = path18.join(dir, ".lovecode/config.yaml");
4904
+ const configPath = path16.join(dir, ".lovecode/config.yaml");
5032
4905
  const force = options.force;
5033
- if (fs18.existsSync(configPath) && !force) {
4906
+ if (fs16.existsSync(configPath) && !force) {
5034
4907
  console.log(chalk22.yellow(`
5035
4908
  Config already exists at ${configPath}`));
5036
4909
  console.log(chalk22.dim(' Use --force to overwrite, or run "lovecode setup" for interactive setup.\n'));
@@ -5041,7 +4914,7 @@ var initCommand = new Command3("init").alias("i").description("Initialize LoveCo
5041
4914
  saveEnvExample(dir);
5042
4915
  console.log(chalk22.bold.cyan("\n LoveCode AI \u26A1 Initialized\n"));
5043
4916
  console.log(chalk22.green(` \u2713 ${configPath}`));
5044
- console.log(chalk22.green(` \u2713 ${path18.join(dir, ".env.example")}`));
4917
+ console.log(chalk22.green(` \u2713 ${path16.join(dir, ".env.example")}`));
5045
4918
  console.log(formatConfig(config));
5046
4919
  console.log(chalk22.dim('\n Run "lovecode setup" for interactive configuration,'));
5047
4920
  console.log(chalk22.dim(" or edit .lovecode/config.yaml directly.\n"));
@@ -5188,18 +5061,18 @@ import { Command as Command6 } from "commander";
5188
5061
  import chalk25 from "chalk";
5189
5062
 
5190
5063
  // src/platform/detect.ts
5191
- import * as fs19 from "fs";
5064
+ import * as fs17 from "fs";
5192
5065
  import * as os from "os";
5193
5066
  var _isTermux = null;
5194
5067
  var _isCodespaces = null;
5195
5068
  function isTermux() {
5196
5069
  if (_isTermux !== null) return _isTermux;
5197
- _isTermux = fs19.existsSync("/data/data/com.termux") || process.env.PREFIX === "/data/data/com.termux/files/usr" || !!process.env.TERMUX_VERSION;
5070
+ _isTermux = fs17.existsSync("/data/data/com.termux") || process.env.PREFIX === "/data/data/com.termux/files/usr" || !!process.env.TERMUX_VERSION;
5198
5071
  return _isTermux;
5199
5072
  }
5200
5073
  function isCodespaces() {
5201
5074
  if (_isCodespaces !== null) return _isCodespaces;
5202
- _isCodespaces = process.env.CODESPACES === "true" || !!process.env.CODESPACE_NAME || fs19.existsSync("/.codespaces");
5075
+ _isCodespaces = process.env.CODESPACES === "true" || !!process.env.CODESPACE_NAME || fs17.existsSync("/.codespaces");
5203
5076
  return _isCodespaces;
5204
5077
  }
5205
5078
  function lowRamMode() {
@@ -5251,8 +5124,8 @@ import { Command as Command7 } from "commander";
5251
5124
  import chalk27 from "chalk";
5252
5125
 
5253
5126
  // src/telemetry/telemetry.ts
5254
- import * as fs20 from "fs";
5255
- import * as path19 from "path";
5127
+ import * as fs18 from "fs";
5128
+ import * as path17 from "path";
5256
5129
  import * as os2 from "os";
5257
5130
  import { createRequire as createRequire2 } from "module";
5258
5131
  import chalk26 from "chalk";
@@ -5260,7 +5133,7 @@ var _require2 = createRequire2(import.meta.url);
5260
5133
  var TELEMETRY_DIR = ".lovecode/telemetry";
5261
5134
  var _enabled = null;
5262
5135
  function telemetryDir(rootDir) {
5263
- return path19.resolve(rootDir || process.cwd(), TELEMETRY_DIR);
5136
+ return path17.resolve(rootDir || process.cwd(), TELEMETRY_DIR);
5264
5137
  }
5265
5138
  function isTelemetryEnabled(rootDir) {
5266
5139
  if (_enabled !== null) return _enabled;
@@ -5272,8 +5145,8 @@ function isTelemetryEnabled(rootDir) {
5272
5145
  _enabled = false;
5273
5146
  return false;
5274
5147
  }
5275
- const configPath = path19.resolve(rootDir || process.cwd(), ".lovecode/config.yaml");
5276
- if (fs20.existsSync(configPath)) {
5148
+ const configPath = path17.resolve(rootDir || process.cwd(), ".lovecode/config.yaml");
5149
+ if (fs18.existsSync(configPath)) {
5277
5150
  try {
5278
5151
  const { loadConfig: loadConfig2 } = _require2("../config/config.js");
5279
5152
  const config = loadConfig2(rootDir);
@@ -5314,10 +5187,10 @@ function getTelemetryData(rootDir) {
5314
5187
  const dir = telemetryDir(rootDir);
5315
5188
  const events = [];
5316
5189
  const crashes = [];
5317
- if (!fs20.existsSync(dir)) return { events, crashes };
5318
- for (const file of fs20.readdirSync(dir)) {
5190
+ if (!fs18.existsSync(dir)) return { events, crashes };
5191
+ for (const file of fs18.readdirSync(dir)) {
5319
5192
  try {
5320
- const content = fs20.readFileSync(path19.join(dir, file), "utf-8");
5193
+ const content = fs18.readFileSync(path17.join(dir, file), "utf-8");
5321
5194
  const data = JSON.parse(content);
5322
5195
  if (file.startsWith("crash-")) {
5323
5196
  crashes.push(data);
@@ -5331,8 +5204,8 @@ function getTelemetryData(rootDir) {
5331
5204
  }
5332
5205
  function clearTelemetryData(rootDir) {
5333
5206
  const dir = telemetryDir(rootDir);
5334
- if (fs20.existsSync(dir)) {
5335
- fs20.rmSync(dir, { recursive: true, force: true });
5207
+ if (fs18.existsSync(dir)) {
5208
+ fs18.rmSync(dir, { recursive: true, force: true });
5336
5209
  }
5337
5210
  }
5338
5211
  function formatTelemetryStatus(enabled, data) {
@@ -5390,8 +5263,8 @@ import { Command as Command8 } from "commander";
5390
5263
  import chalk29 from "chalk";
5391
5264
 
5392
5265
  // src/installers/install.ts
5393
- import * as fs21 from "fs";
5394
- import * as path20 from "path";
5266
+ import * as fs19 from "fs";
5267
+ import * as path18 from "path";
5395
5268
  import { execSync as execSync4 } from "child_process";
5396
5269
  import chalk28 from "chalk";
5397
5270
  function detectInstallMethod() {
@@ -5433,7 +5306,7 @@ function printInstallInstructions() {
5433
5306
  }
5434
5307
  function createInstallScript(rootDir) {
5435
5308
  const dir = rootDir || process.cwd();
5436
- const scriptPath = path20.join(dir, "install.sh");
5309
+ const scriptPath = path18.join(dir, "install.sh");
5437
5310
  const script = `#!/usr/bin/env bash
5438
5311
  set -euo pipefail
5439
5312
 
@@ -5488,11 +5361,11 @@ echo " Run: lovecode setup Interactive configuration"
5488
5361
  echo " Run: lovecode Start the AI agent"
5489
5362
  echo ""
5490
5363
  `;
5491
- const scriptDir = path20.dirname(scriptPath);
5492
- if (!fs21.existsSync(scriptDir)) fs21.mkdirSync(scriptDir, { recursive: true });
5493
- fs21.writeFileSync(scriptPath, script, "utf-8");
5364
+ const scriptDir = path18.dirname(scriptPath);
5365
+ if (!fs19.existsSync(scriptDir)) fs19.mkdirSync(scriptDir, { recursive: true });
5366
+ fs19.writeFileSync(scriptPath, script, "utf-8");
5494
5367
  try {
5495
- fs21.chmodSync(scriptPath, "755");
5368
+ fs19.chmodSync(scriptPath, "755");
5496
5369
  } catch {
5497
5370
  }
5498
5371
  }
@@ -5603,8 +5476,8 @@ import { Command as Command10 } from "commander";
5603
5476
  import chalk32 from "chalk";
5604
5477
 
5605
5478
  // src/repo/search.ts
5606
- import * as fs22 from "fs";
5607
- import * as path21 from "path";
5479
+ import * as fs20 from "fs";
5480
+ import * as path19 from "path";
5608
5481
  import chalk31 from "chalk";
5609
5482
  function chunkFile(content, maxLines = 50) {
5610
5483
  const lines = content.split("\n");
@@ -5641,7 +5514,7 @@ async function semanticSearch2(rootDir, query, options = { rootDir: "", query: "
5641
5514
  const queryEmbedding = await getEmbedding(query);
5642
5515
  const files = collectTextFiles(rootDir, 200);
5643
5516
  for (const filePath of files) {
5644
- const relativePath = path21.relative(rootDir, filePath).replace(/\\/g, "/");
5517
+ const relativePath = path19.relative(rootDir, filePath).replace(/\\/g, "/");
5645
5518
  const content = readFileSafe(filePath);
5646
5519
  if (!content) continue;
5647
5520
  const chunks = chunkFile(content, 30);
@@ -5711,14 +5584,14 @@ function collectTextFiles(dir, max) {
5711
5584
  function walk(dir2) {
5712
5585
  if (results.length >= max) return;
5713
5586
  try {
5714
- const entries = fs22.readdirSync(dir2, { withFileTypes: true });
5587
+ const entries = fs20.readdirSync(dir2, { withFileTypes: true });
5715
5588
  for (const entry of entries) {
5716
5589
  if (results.length >= max) return;
5717
5590
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === ".git") continue;
5718
- const fullPath = path21.join(dir2, entry.name);
5591
+ const fullPath = path19.join(dir2, entry.name);
5719
5592
  if (entry.isDirectory()) {
5720
5593
  walk(fullPath);
5721
- } else if (extSet.has(path21.extname(entry.name).toLowerCase())) {
5594
+ } else if (extSet.has(path19.extname(entry.name).toLowerCase())) {
5722
5595
  results.push(fullPath);
5723
5596
  }
5724
5597
  }
@@ -5730,9 +5603,9 @@ function collectTextFiles(dir, max) {
5730
5603
  }
5731
5604
  function readFileSafe(filePath) {
5732
5605
  try {
5733
- const stats = fs22.statSync(filePath);
5606
+ const stats = fs20.statSync(filePath);
5734
5607
  if (stats.size > 5e5) return null;
5735
- return fs22.readFileSync(filePath, "utf-8");
5608
+ return fs20.readFileSync(filePath, "utf-8");
5736
5609
  } catch {
5737
5610
  return null;
5738
5611
  }
@@ -6243,8 +6116,8 @@ import React4 from "react";
6243
6116
  import { render } from "ink";
6244
6117
 
6245
6118
  // src/tui/App.tsx
6246
- import { useState as useState3, useCallback as useCallback2 } from "react";
6247
- import { Box as Box3 } from "ink";
6119
+ import { useState as useState3, useCallback as useCallback2, useEffect as useEffect4 } from "react";
6120
+ import { Box as Box3, Text as Text3 } from "ink";
6248
6121
 
6249
6122
  // src/tui/components.tsx
6250
6123
  import React, { useEffect as useEffect2 } from "react";
@@ -6465,7 +6338,7 @@ function CommandPane({ commands, focused }) {
6465
6338
  ] }, i))
6466
6339
  ] }) });
6467
6340
  }
6468
- function StatusBar({ mode, theme: themeName, focus, vimMode, messages }) {
6341
+ function StatusBar({ mode, theme: themeName, focus, vimMode, messages, sessionName, provider, model }) {
6469
6342
  const theme = getTheme();
6470
6343
  return /* @__PURE__ */ jsxs(
6471
6344
  Box,
@@ -6478,11 +6351,27 @@ function StatusBar({ mode, theme: themeName, focus, vimMode, messages }) {
6478
6351
  /* @__PURE__ */ jsxs(Text, { children: [
6479
6352
  /* @__PURE__ */ jsx(Text, { color: theme.colors.secondary, children: "LoveCode" }),
6480
6353
  /* @__PURE__ */ jsx(Text, { color: theme.colors.textDim, children: " AI " }),
6354
+ sessionName && /* @__PURE__ */ jsxs(Fragment, { children: [
6355
+ /* @__PURE__ */ jsx(Text, { color: theme.colors.muted, children: "|" }),
6356
+ /* @__PURE__ */ jsxs(Text, { color: theme.colors.textDim, children: [
6357
+ " ",
6358
+ sessionName,
6359
+ " "
6360
+ ] })
6361
+ ] }),
6481
6362
  /* @__PURE__ */ jsx(Text, { color: theme.colors.muted, children: "|" }),
6482
6363
  /* @__PURE__ */ jsx(Text, { color: theme.colors.text, children: " Mode: " }),
6483
6364
  /* @__PURE__ */ jsx(Text, { color: theme.colors.primary, children: mode })
6484
6365
  ] }),
6485
6366
  /* @__PURE__ */ jsxs(Text, { children: [
6367
+ provider && /* @__PURE__ */ jsxs(Fragment, { children: [
6368
+ /* @__PURE__ */ jsx(Text, { color: theme.colors.textDim, children: provider }),
6369
+ /* @__PURE__ */ jsx(Text, { color: theme.colors.muted, children: " | " })
6370
+ ] }),
6371
+ model && /* @__PURE__ */ jsxs(Fragment, { children: [
6372
+ /* @__PURE__ */ jsx(Text, { color: theme.colors.textDim, children: model }),
6373
+ /* @__PURE__ */ jsx(Text, { color: theme.colors.muted, children: " | " })
6374
+ ] }),
6486
6375
  /* @__PURE__ */ jsx(Text, { color: theme.colors.textDim, children: "Focus: " }),
6487
6376
  /* @__PURE__ */ jsx(Text, { color: theme.colors.accent, children: focus }),
6488
6377
  /* @__PURE__ */ jsx(Text, { color: theme.colors.muted, children: " | " }),
@@ -6505,29 +6394,60 @@ function StatusBar({ mode, theme: themeName, focus, vimMode, messages }) {
6505
6394
  import { useState as useState2, useEffect as useEffect3, useRef as useRef2 } from "react";
6506
6395
  import { Box as Box2, Text as Text2, useInput as useInput2 } from "ink";
6507
6396
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
6508
- function MessageRow({ msg, isStreaming, streamContent }) {
6397
+ var SLASH_COMMANDS = ["help", "clear", "theme", "connect", "system", "model", "themes", "export", "sessions", "vim", "exit"];
6398
+ function formatTime(ts) {
6399
+ if (!ts) return "";
6400
+ const d = new Date(ts);
6401
+ return `${d.getHours().toString().padStart(2, "0")}:${d.getMinutes().toString().padStart(2, "0")}`;
6402
+ }
6403
+ function MessageRow({ msg, isStreaming, streamContent, timestamp }) {
6509
6404
  const theme = getTheme();
6510
6405
  const displayContent = isStreaming && streamContent !== void 0 ? streamContent : msg.content;
6511
6406
  const label = msg.role === "user" ? "You" : msg.role === "assistant" ? "LoveCode" : "System";
6512
6407
  const labelColor = msg.role === "user" ? theme.colors.success : msg.role === "assistant" ? theme.colors.primary : theme.colors.warning;
6513
6408
  const formatted = msg.role === "assistant" || msg.role === "system" ? renderMarkdown(displayContent) : displayContent;
6409
+ const time = formatTime(timestamp);
6410
+ const lines = formatted.split("\n");
6514
6411
  return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginBottom: 1, children: [
6515
- /* @__PURE__ */ jsx2(Box2, { children: /* @__PURE__ */ jsx2(Text2, { bold: true, color: labelColor, children: label }) }),
6516
6412
  /* @__PURE__ */ jsxs2(Box2, { children: [
6517
- /* @__PURE__ */ jsx2(Text2, { color: theme.colors.text, children: formatted }),
6518
- isStreaming && /* @__PURE__ */ jsx2(Text2, { color: theme.colors.primary, children: "\u2588" })
6519
- ] })
6413
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: labelColor, children: label }),
6414
+ time && /* @__PURE__ */ jsx2(Text2, { color: theme.colors.textDim, children: ` ${time}` })
6415
+ ] }),
6416
+ lines.map((line, i) => /* @__PURE__ */ jsxs2(Box2, { children: [
6417
+ /* @__PURE__ */ jsx2(Text2, { color: theme.colors.text, children: line }),
6418
+ isStreaming && i === lines.length - 1 && /* @__PURE__ */ jsx2(Text2, { color: theme.colors.primary, children: "\u2588" })
6419
+ ] }, i))
6520
6420
  ] });
6521
6421
  }
6522
6422
  function ChatBox({ messages, onSend, streaming, streamedContent, focused, placeholder = "Type a message..." }) {
6523
6423
  const [input, setInput] = useState2("");
6524
6424
  const [vimMode, setVimMode] = useState2("insert");
6425
+ const [history, setHistory] = useState2([]);
6426
+ const [historyIdx, setHistoryIdx] = useState2(-1);
6427
+ const [tabIndex, setTabIndex] = useState2(-1);
6525
6428
  const scroll = useScroll();
6526
6429
  const inputRef = useRef2(input);
6527
6430
  inputRef.current = input;
6528
6431
  useEffect3(() => {
6529
6432
  scroll.scrollToBottom();
6530
6433
  }, [messages.length, streamedContent]);
6434
+ function submitInput(val) {
6435
+ if (!val.trim()) return;
6436
+ onSend(val);
6437
+ setHistory((prev) => [val, ...prev].slice(0, 50));
6438
+ setHistoryIdx(-1);
6439
+ setInput("");
6440
+ }
6441
+ function handleTab() {
6442
+ const trimmed = input.trim().toLowerCase();
6443
+ if (!trimmed.startsWith("/")) return;
6444
+ const partial = trimmed.slice(1);
6445
+ const matches = SLASH_COMMANDS.filter((c) => c.startsWith(partial));
6446
+ if (matches.length === 0) return;
6447
+ const next = (tabIndex + 1) % matches.length;
6448
+ setTabIndex(next);
6449
+ setInput("/" + matches[next] + " ");
6450
+ }
6531
6451
  useInput2((text, key) => {
6532
6452
  if (!focused) return;
6533
6453
  if (vimMode === "normal") {
@@ -6556,27 +6476,42 @@ function ChatBox({ messages, onSend, streaming, streamedContent, focused, placeh
6556
6476
  scroll.scrollToBottom();
6557
6477
  return;
6558
6478
  }
6479
+ if (text === "0") {
6480
+ setInput("");
6481
+ return;
6482
+ }
6559
6483
  return;
6560
6484
  }
6561
6485
  if (key.escape) {
6562
6486
  setVimMode("normal");
6563
6487
  return;
6564
6488
  }
6565
- if (key.return && input.trim()) {
6566
- onSend(input);
6567
- setInput("");
6489
+ if (key.return) {
6490
+ submitInput(input);
6568
6491
  return;
6569
6492
  }
6570
6493
  if (key.backspace || key.delete) {
6571
6494
  setInput((prev) => prev.slice(0, -1));
6495
+ setTabIndex(-1);
6572
6496
  return;
6573
6497
  }
6574
6498
  if (key.upArrow) {
6575
- scroll.scrollUp();
6499
+ if (history.length > 0) {
6500
+ const nextIdx = historyIdx < history.length - 1 ? historyIdx + 1 : historyIdx;
6501
+ setHistoryIdx(nextIdx);
6502
+ setInput(history[nextIdx] || "");
6503
+ }
6576
6504
  return;
6577
6505
  }
6578
6506
  if (key.downArrow) {
6579
- scroll.scrollDown();
6507
+ if (historyIdx > 0) {
6508
+ const nextIdx = historyIdx - 1;
6509
+ setHistoryIdx(nextIdx);
6510
+ setInput(history[nextIdx]);
6511
+ } else {
6512
+ setHistoryIdx(-1);
6513
+ setInput("");
6514
+ }
6580
6515
  return;
6581
6516
  }
6582
6517
  if (key.pageUp) {
@@ -6587,6 +6522,11 @@ function ChatBox({ messages, onSend, streaming, streamedContent, focused, placeh
6587
6522
  for (let i = 0; i < 10; i++) scroll.scrollDown();
6588
6523
  return;
6589
6524
  }
6525
+ if (text === " ") {
6526
+ handleTab();
6527
+ return;
6528
+ }
6529
+ setTabIndex(-1);
6590
6530
  if (text && text.length === 1 && !key.ctrl && !key.meta) {
6591
6531
  setInput((prev) => prev + text);
6592
6532
  }
@@ -6594,7 +6534,8 @@ function ChatBox({ messages, onSend, streaming, streamedContent, focused, placeh
6594
6534
  const theme = getTheme();
6595
6535
  const cursor = vimMode === "normal" ? "\u258C" : "\u2588";
6596
6536
  const modeIndicator = vimMode === "normal" ? " NORMAL " : " INSERT ";
6597
- const maxVisible = 10;
6537
+ const hasMore = messages.length > 10;
6538
+ const totalMessages = messages.length;
6598
6539
  return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", height: "100%", width: "100%", children: [
6599
6540
  /* @__PURE__ */ jsxs2(
6600
6541
  Box2,
@@ -6606,25 +6547,25 @@ function ChatBox({ messages, onSend, streaming, streamedContent, focused, placeh
6606
6547
  paddingX: 1,
6607
6548
  paddingY: 0,
6608
6549
  children: [
6609
- messages.length === 0 && /* @__PURE__ */ jsx2(Text2, { color: theme.colors.textDim, children: "Start typing to chat with LoveCode AI" }),
6550
+ messages.length === 0 && /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", alignItems: "center", marginTop: 2, children: [
6551
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: theme.colors.primary, children: "LoveCode AI" }),
6552
+ /* @__PURE__ */ jsx2(Text2, { color: theme.colors.textDim, children: "Type a message or /help to start" })
6553
+ ] }),
6610
6554
  messages.map((msg, i) => /* @__PURE__ */ jsx2(
6611
6555
  MessageRow,
6612
6556
  {
6613
6557
  msg,
6614
6558
  isStreaming: streaming && i === messages.length - 1,
6615
- streamContent: streaming && i === messages.length - 1 ? streamedContent : void 0
6559
+ streamContent: streaming && i === messages.length - 1 ? streamedContent : void 0,
6560
+ timestamp: msg.timestamp
6616
6561
  },
6617
6562
  i
6618
6563
  )),
6619
- messages.length > maxVisible && /* @__PURE__ */ jsxs2(Text2, { color: theme.colors.textDim, children: [
6620
- "-- Press j/k to scroll (",
6621
- scroll.offset + 1,
6622
- "-",
6623
- Math.min(scroll.offset + maxVisible, messages.length),
6624
- " of ",
6625
- messages.length,
6626
- ") --"
6627
- ] })
6564
+ streaming && !streamedContent && /* @__PURE__ */ jsx2(Box2, { children: /* @__PURE__ */ jsx2(Text2, { color: theme.colors.warning, children: "Thinking..." }) }),
6565
+ hasMore && /* @__PURE__ */ jsx2(Box2, { marginTop: 1, children: /* @__PURE__ */ jsxs2(Text2, { color: theme.colors.textDim, children: [
6566
+ totalMessages,
6567
+ " messages \u2014 j/k to scroll"
6568
+ ] }) })
6628
6569
  ]
6629
6570
  }
6630
6571
  ),
@@ -6637,8 +6578,8 @@ function ChatBox({ messages, onSend, streaming, streamedContent, focused, placeh
6637
6578
  paddingX: 1,
6638
6579
  children: [
6639
6580
  /* @__PURE__ */ jsx2(Text2, { bold: true, color: theme.colors.warning, children: modeIndicator }),
6640
- /* @__PURE__ */ jsx2(Text2, { bold: true, color: theme.colors.success, children: " > " }),
6641
- /* @__PURE__ */ jsx2(Text2, { color: theme.colors.text, children: input || /* @__PURE__ */ jsx2(Text2, { color: theme.colors.textDim, children: placeholder }) }),
6581
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: theme.colors.success, children: "> " }),
6582
+ /* @__PURE__ */ jsx2(Text2, { color: theme.colors.text, children: input || /* @__PURE__ */ jsx2(Text2, { italic: true, color: theme.colors.textDim, children: placeholder }) }),
6642
6583
  focused && vimMode === "insert" && /* @__PURE__ */ jsx2(Text2, { color: theme.colors.primary, children: cursor })
6643
6584
  ]
6644
6585
  }
@@ -6657,15 +6598,27 @@ function App({
6657
6598
  framework: _fw,
6658
6599
  repoStatus: _rs,
6659
6600
  onSendMessage,
6660
- onRunCommand
6601
+ onRunCommand,
6602
+ sessionId: _sid,
6603
+ sessionName: _sname,
6604
+ provider: _provider,
6605
+ model: _model
6661
6606
  }) {
6662
- const [messages, setMessages] = useState3(initialMessages);
6607
+ const [messages, setMessages] = useState3(
6608
+ initialMessages.map((m) => ({ ...m, timestamp: Date.now() }))
6609
+ );
6663
6610
  const [commands, setCommands] = useState3([]);
6664
6611
  const [streaming, setStreaming] = useState3(false);
6665
6612
  const [streamedContent, setStreamedContent] = useState3("");
6666
6613
  const [focus, setFocus] = useFocus();
6667
6614
  const [currentTheme, setCurrentThemeState] = useState3("default");
6615
+ const [systemPrompt, setSystemPrompt] = useState3("You are LoveCode AI, a terminal-native coding assistant.");
6616
+ const [splash, setSplash] = useState3(true);
6668
6617
  useTerminalSize();
6618
+ useEffect4(() => {
6619
+ const timer = setTimeout(() => setSplash(false), 1500);
6620
+ return () => clearTimeout(timer);
6621
+ }, []);
6669
6622
  const setCurrentTheme = useCallback2((name) => {
6670
6623
  setTheme(name);
6671
6624
  setCurrentThemeState(name);
@@ -6675,6 +6628,11 @@ function App({
6675
6628
  setFocus(focus === "chat" ? "command" : focus === "command" ? "repo" : focus === "repo" ? "chat" : "chat");
6676
6629
  }
6677
6630
  });
6631
+ function addMessage(role, content) {
6632
+ const entry = { role, content, timestamp: Date.now() };
6633
+ setMessages((prev) => [...prev, entry]);
6634
+ return entry;
6635
+ }
6678
6636
  async function handleConnect() {
6679
6637
  try {
6680
6638
  const { getAllProviders } = await import("./registry-ADSIKXA4.js");
@@ -6693,19 +6651,83 @@ function App({
6693
6651
  info += "**Available providers:**\n";
6694
6652
  for (const p of providers) {
6695
6653
  const tag = p.local ? "(local)" : "(cloud)";
6696
- const configured = config.provider === p.name ? " \u2190 active" : "";
6697
- info += ` ${p.name} ${tag}${configured}
6654
+ info += ` ${p.name} ${tag}${config.provider === p.name ? " \u2190 active" : ""}
6698
6655
  `;
6699
6656
  }
6700
6657
  info += "\n**To configure:** use `lovecode init` in your terminal, then restart TUI";
6701
- setMessages((prev) => [...prev, { role: "assistant", content: info }]);
6658
+ addMessage("assistant", info);
6659
+ } catch (err) {
6660
+ addMessage("system", `Error loading providers: ${err.message}`);
6661
+ }
6662
+ }
6663
+ async function handleModel() {
6664
+ try {
6665
+ const { loadConfig: loadConfig2 } = await import("./config-FJNTTKR3.js");
6666
+ const config = loadConfig2();
6667
+ const info = `**Current AI Configuration**
6668
+
6669
+ Provider: \`${config.provider || "not set"}\`
6670
+ Model: \`${config.model || "not set"}\`
6671
+ Theme: \`${currentTheme}\`
6672
+ System prompt: ${systemPrompt}`;
6673
+ addMessage("assistant", info);
6674
+ } catch (err) {
6675
+ addMessage("system", `Error: ${err.message}`);
6676
+ }
6677
+ }
6678
+ function handleThemes() {
6679
+ const names = getThemeNames();
6680
+ let info = "**Available Themes**\n\n";
6681
+ for (const name of names) {
6682
+ info += ` ${currentTheme === name ? "\u25CF" : "\u25CB"} **${name}**${currentTheme === name ? " (active)" : ""}
6683
+ `;
6684
+ }
6685
+ info += "\nUse `/theme <name>` to switch.";
6686
+ addMessage("assistant", info);
6687
+ }
6688
+ function handleSystem(prompt) {
6689
+ if (!prompt) {
6690
+ addMessage("system", `Current system prompt: "${systemPrompt}"
6691
+ Use \`/system <new prompt>\` to change it.`);
6692
+ return;
6693
+ }
6694
+ setSystemPrompt(prompt);
6695
+ addMessage("system", `System prompt updated to: "${prompt}"`);
6696
+ }
6697
+ async function handleExport() {
6698
+ try {
6699
+ const { writeChatLog: writeChatLog2 } = await import("./chatlog-WSYM3DWQ.js");
6700
+ const entries = messages.map((m) => ({ role: m.role, content: m.content, timestamp: m.timestamp }));
6701
+ const path21 = writeChatLog2(_sid || "unknown", _sname || "TUI Chat", entries);
6702
+ addMessage("system", `Chat exported to: ${path21}`);
6702
6703
  } catch (err) {
6703
- setMessages((prev) => [...prev, { role: "system", content: `Error loading providers: ${err.message}` }]);
6704
+ addMessage("system", `Export failed: ${err.message}`);
6705
+ }
6706
+ }
6707
+ async function handleSessions() {
6708
+ try {
6709
+ const { listSessions: listSessions2 } = await import("./session-LTPGPQPI.js");
6710
+ const sessions = listSessions2();
6711
+ if (sessions.length === 0) {
6712
+ addMessage("system", "No saved sessions found. Messages are auto-saved during your session.");
6713
+ return;
6714
+ }
6715
+ let info = "**Saved Sessions**\n\n";
6716
+ for (const s of sessions.slice(0, 10)) {
6717
+ const date = new Date(s.updated).toLocaleDateString();
6718
+ info += ` ${_sid === s.id ? "\u25CF" : "\u25CB"} **${s.title}** (${s.entries.length} msgs, ${date})
6719
+ `;
6720
+ }
6721
+ if (sessions.length > 10) info += ` ... and ${sessions.length - 10} more
6722
+ `;
6723
+ info += "\nSessions are auto-saved. Use `lovecode memory list` to manage them.";
6724
+ addMessage("assistant", info);
6725
+ } catch (err) {
6726
+ addMessage("system", `Error: ${err.message}`);
6704
6727
  }
6705
6728
  }
6706
6729
  async function handleSend(text) {
6707
- const userMsg = { role: "user", content: text };
6708
- setMessages((prev) => [...prev, userMsg]);
6730
+ addMessage("user", text);
6709
6731
  if (text.startsWith("/")) {
6710
6732
  handleCommand(text);
6711
6733
  return;
@@ -6716,20 +6738,43 @@ function App({
6716
6738
  try {
6717
6739
  const response = await onSendMessage(text);
6718
6740
  if (response) {
6719
- setMessages((prev) => [...prev, { role: "assistant", content: response }]);
6741
+ addMessage("assistant", response);
6720
6742
  }
6721
6743
  } catch (err) {
6722
- setMessages((prev) => [...prev, { role: "assistant", content: `Error: ${err.message}` }]);
6744
+ addMessage("assistant", `Error: ${err.message}`);
6723
6745
  }
6724
6746
  setStreaming(false);
6725
6747
  }
6726
6748
  }
6727
6749
  function handleCommand(text) {
6728
- const cmd = text.slice(1).toLowerCase();
6750
+ const cmd = text.slice(1).toLowerCase().trim();
6729
6751
  if (cmd === "help") {
6730
- setMessages((prev) => [...prev, { role: "system", content: "Commands: /help, /clear, /theme <name>, /connect, /vim, /exit" }]);
6752
+ addMessage("system", [
6753
+ "**Commands:**",
6754
+ " `/help` \u2014 Show this help",
6755
+ " `/clear` \u2014 Clear chat",
6756
+ " `/theme <name>` \u2014 Change theme",
6757
+ " `/themes` \u2014 List themes",
6758
+ " `/connect` \u2014 Show AI providers",
6759
+ " `/model` \u2014 Show AI config",
6760
+ " `/system <prompt>` \u2014 Set system prompt",
6761
+ " `/export` \u2014 Save chat to file",
6762
+ " `/sessions` \u2014 List sessions",
6763
+ " `/!<cmd>` \u2014 Run shell command",
6764
+ " `/exit` \u2014 Quit TUI",
6765
+ "",
6766
+ "**Keys:** Tab=focus, Esc=normal mode, i=insert, j/k=scroll, \u2191\u2193=history"
6767
+ ].join("\n"));
6731
6768
  } else if (cmd === "connect") {
6732
6769
  handleConnect();
6770
+ } else if (cmd === "model") {
6771
+ handleModel();
6772
+ } else if (cmd === "themes") {
6773
+ handleThemes();
6774
+ } else if (cmd === "export") {
6775
+ handleExport();
6776
+ } else if (cmd === "sessions") {
6777
+ handleSessions();
6733
6778
  } else if (cmd === "clear") {
6734
6779
  setMessages([]);
6735
6780
  } else if (cmd.startsWith("theme ")) {
@@ -6737,12 +6782,16 @@ function App({
6737
6782
  const names = getThemeNames();
6738
6783
  if (names.includes(name)) {
6739
6784
  setCurrentTheme(name);
6740
- setMessages((prev) => [...prev, { role: "system", content: `Theme changed to: ${name}` }]);
6785
+ addMessage("system", `Theme changed to: ${name}`);
6741
6786
  } else {
6742
- setMessages((prev) => [...prev, { role: "system", content: `Unknown theme: ${name}. Available: ${names.join(", ")}` }]);
6787
+ addMessage("system", `Unknown theme: ${name}. Available: ${names.join(", ")}`);
6743
6788
  }
6789
+ } else if (cmd.startsWith("system ")) {
6790
+ handleSystem(cmd.slice(7));
6791
+ } else if (cmd === "system") {
6792
+ handleSystem("");
6744
6793
  } else if (cmd === "vim") {
6745
- setMessages((prev) => [...prev, { role: "system", content: "Vim mode is built into the chat box (Esc = normal, i = insert)" }]);
6794
+ addMessage("system", "Vim mode: Esc=normal, i=insert, j/k=scroll");
6746
6795
  } else if (cmd === "exit" || cmd === "quit") {
6747
6796
  process.exit(0);
6748
6797
  } else if (cmd.startsWith("!")) {
@@ -6771,8 +6820,18 @@ function App({
6771
6820
  });
6772
6821
  });
6773
6822
  }
6823
+ } else {
6824
+ addMessage("system", `Unknown command: ${cmd}. Try /help`);
6774
6825
  }
6775
6826
  }
6827
+ if (splash) {
6828
+ const theme = getTheme();
6829
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", alignItems: "center", justifyContent: "center", width: "100%", height: "100%", children: [
6830
+ /* @__PURE__ */ jsx3(Text3, { bold: true, color: theme.colors.primary, children: "LoveCode AI" }),
6831
+ /* @__PURE__ */ jsx3(Text3, { color: theme.colors.textDim, children: "Terminal-native autonomous coding agent" }),
6832
+ /* @__PURE__ */ jsx3(Text3, { color: theme.colors.muted, children: "v0.1.5" })
6833
+ ] });
6834
+ }
6776
6835
  return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", width: "100%", height: "100%", children: [
6777
6836
  /* @__PURE__ */ jsx3(Box3, { flexDirection: "column", flexGrow: 1, paddingX: 0, children: /* @__PURE__ */ jsxs3(SplitPane, { direction: "vertical", sizes: [15, 60, 25], children: [
6778
6837
  /* @__PURE__ */ jsx3(
@@ -6813,7 +6872,10 @@ function App({
6813
6872
  theme: currentTheme,
6814
6873
  focus,
6815
6874
  vimMode: "INSERT",
6816
- messages: messages.length
6875
+ messages: messages.length,
6876
+ sessionName: _sname,
6877
+ provider: _provider,
6878
+ model: _model
6817
6879
  }
6818
6880
  )
6819
6881
  ] });
@@ -6980,8 +7042,8 @@ async function cmdActions(actions, options) {
6980
7042
  const { runActions } = await import("./playwright-N7OAVW2N.js");
6981
7043
  let parsedActions;
6982
7044
  if (options.file) {
6983
- const fs25 = await import("fs");
6984
- const content = fs25.readFileSync(options.file, "utf-8");
7045
+ const fs23 = await import("fs");
7046
+ const content = fs23.readFileSync(options.file, "utf-8");
6985
7047
  parsedActions = JSON.parse(content);
6986
7048
  } else {
6987
7049
  parsedActions = actions.map((a) => JSON.parse(a));
@@ -7146,7 +7208,7 @@ function formatRisk(risk) {
7146
7208
  }
7147
7209
 
7148
7210
  // src/security/secrets.ts
7149
- import * as fs23 from "fs";
7211
+ import * as fs21 from "fs";
7150
7212
  import chalk39 from "chalk";
7151
7213
  var SECRET_RULES = [
7152
7214
  { type: "aws_key", pattern: /(?:AKIA|ASIA)[0-9A-Z]{16}/g, severity: "critical", description: "AWS Access Key ID" },
@@ -7195,7 +7257,7 @@ function scanText(text, fileName) {
7195
7257
  }
7196
7258
  function scanFile(filePath) {
7197
7259
  try {
7198
- const content = fs23.readFileSync(filePath, "utf-8");
7260
+ const content = fs21.readFileSync(filePath, "utf-8");
7199
7261
  return scanText(content, filePath);
7200
7262
  } catch {
7201
7263
  return [];
@@ -7207,7 +7269,7 @@ function scanDirectory2(dirPath, maxFiles = 100) {
7207
7269
  function walk(dir) {
7208
7270
  if (count >= maxFiles) return;
7209
7271
  try {
7210
- const entries = fs23.readdirSync(dir, { withFileTypes: true });
7272
+ const entries = fs21.readdirSync(dir, { withFileTypes: true });
7211
7273
  for (const entry of entries) {
7212
7274
  if (count >= maxFiles) return;
7213
7275
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist") continue;
@@ -7409,8 +7471,8 @@ function formatProfile(profile) {
7409
7471
  }
7410
7472
 
7411
7473
  // src/security/permissions.ts
7412
- import * as fs24 from "fs";
7413
- import * as path22 from "path";
7474
+ import * as fs22 from "fs";
7475
+ import * as path20 from "path";
7414
7476
  import chalk41 from "chalk";
7415
7477
  var PERMISSION_FILE = ".lovecode/permissions.json";
7416
7478
  var DEFAULT_PERMISSIONS = {
@@ -7427,18 +7489,18 @@ var DEFAULT_PERMISSIONS = {
7427
7489
  };
7428
7490
  var cachedPermissions = null;
7429
7491
  function getPermPath(rootDir) {
7430
- return path22.join(rootDir || process.cwd(), PERMISSION_FILE);
7492
+ return path20.join(rootDir || process.cwd(), PERMISSION_FILE);
7431
7493
  }
7432
7494
  function loadPermissions(rootDir) {
7433
7495
  if (cachedPermissions) return cachedPermissions;
7434
7496
  const filePath = getPermPath(rootDir);
7435
- if (!fs24.existsSync(filePath)) {
7497
+ if (!fs22.existsSync(filePath)) {
7436
7498
  savePermissions(DEFAULT_PERMISSIONS, rootDir);
7437
7499
  cachedPermissions = { ...DEFAULT_PERMISSIONS };
7438
7500
  return cachedPermissions;
7439
7501
  }
7440
7502
  try {
7441
- const raw = fs24.readFileSync(filePath, "utf-8");
7503
+ const raw = fs22.readFileSync(filePath, "utf-8");
7442
7504
  cachedPermissions = JSON.parse(raw);
7443
7505
  return cachedPermissions;
7444
7506
  } catch {
@@ -7448,11 +7510,11 @@ function loadPermissions(rootDir) {
7448
7510
  }
7449
7511
  function savePermissions(perms, rootDir) {
7450
7512
  const filePath = getPermPath(rootDir);
7451
- const dir = path22.dirname(filePath);
7452
- if (!fs24.existsSync(dir)) {
7453
- fs24.mkdirSync(dir, { recursive: true });
7513
+ const dir = path20.dirname(filePath);
7514
+ if (!fs22.existsSync(dir)) {
7515
+ fs22.mkdirSync(dir, { recursive: true });
7454
7516
  }
7455
- fs24.writeFileSync(filePath, JSON.stringify(perms, null, 2), "utf-8");
7517
+ fs22.writeFileSync(filePath, JSON.stringify(perms, null, 2), "utf-8");
7456
7518
  cachedPermissions = perms;
7457
7519
  }
7458
7520
  function setDefault(key, value, rootDir) {
@@ -7518,8 +7580,8 @@ function removeTrustedSource(source, rootDir) {
7518
7580
  }
7519
7581
  function resetPermissions(rootDir) {
7520
7582
  const filePath = getPermPath(rootDir);
7521
- if (fs24.existsSync(filePath)) {
7522
- fs24.unlinkSync(filePath);
7583
+ if (fs22.existsSync(filePath)) {
7584
+ fs22.unlinkSync(filePath);
7523
7585
  }
7524
7586
  cachedPermissions = null;
7525
7587
  }