@riconext/hermes-repo 1.1.0 → 1.1.1

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/cli.js CHANGED
@@ -102,8 +102,13 @@ function parseLlmConfig(raw) {
102
102
  const llm = raw.llm;
103
103
  return {
104
104
  enabled: typeof llm?.enabled === "boolean" ? llm.enabled : false,
105
+ provider: typeof llm?.provider === "string" ? llm.provider : "openai",
105
106
  baseUrl: typeof llm?.baseUrl === "string" ? llm.baseUrl : "https://api.openai.com/v1",
106
- model: typeof llm?.model === "string" ? llm.model : "gpt-4o"
107
+ model: typeof llm?.model === "string" ? llm.model : "gpt-4o",
108
+ apiKey: typeof llm?.apiKey === "string" ? llm.apiKey : "",
109
+ timeoutMs: typeof llm?.timeoutMs === "number" && llm.timeoutMs > 0 ? llm.timeoutMs : 6e4,
110
+ maxInputChars: typeof llm?.maxInputChars === "number" && llm.maxInputChars > 0 ? llm.maxInputChars : 24e3,
111
+ mode: llm?.mode === "sync" ? "sync" : "async"
107
112
  };
108
113
  }
109
114
  function parseConsolidateConfig(raw) {
@@ -136,7 +141,16 @@ function readConfigAtRepo(repoRoot) {
136
141
  storage: { backend: "file" },
137
142
  assistants,
138
143
  debug: raw.debug === true,
139
- llm: { enabled: false, baseUrl: "https://api.openai.com/v1", model: "gpt-4o" },
144
+ llm: {
145
+ enabled: false,
146
+ provider: "openai",
147
+ baseUrl: "https://api.openai.com/v1",
148
+ model: "gpt-4o",
149
+ apiKey: "",
150
+ timeoutMs: 6e4,
151
+ maxInputChars: 24e3,
152
+ mode: "async"
153
+ },
140
154
  consolidate: { autoArchiveDays: 30 }
141
155
  };
142
156
  }
@@ -158,12 +172,10 @@ function loadRepoContext(cwd) {
158
172
  }
159
173
 
160
174
  // src/capture/runLlmJob.ts
161
- import { existsSync as existsSync5, readFileSync as readFileSync6, renameSync, writeFileSync as writeFileSync3 } from "fs";
175
+ import { existsSync as existsSync4, readFileSync as readFileSync5, renameSync, writeFileSync as writeFileSync3 } from "fs";
162
176
  import { join as join6 } from "path";
163
177
 
164
178
  // src/config/llmConfig.ts
165
- var DEFAULT_LLM_TIMEOUT_MS = 6e4;
166
- var DEFAULT_LLM_MAX_INPUT_CHARS = 24e3;
167
179
  function isLlmAvailable(cfg) {
168
180
  if (!cfg?.enabled) {
169
181
  return false;
@@ -171,52 +183,11 @@ function isLlmAvailable(cfg) {
171
183
  return Boolean(cfg.apiKey?.trim()) && Boolean(cfg.baseUrl?.trim()) && Boolean(cfg.model?.trim());
172
184
  }
173
185
  function effectiveLlmMode(cfg) {
174
- const forceSync = process.env.HERMES_LLM_SYNC;
175
- if (forceSync === "1" || forceSync === "true") {
176
- return "sync";
177
- }
178
186
  return cfg.mode === "sync" ? "sync" : "async";
179
187
  }
180
- function parseLlmConfigRaw(raw) {
181
- if (raw.enabled !== true && raw.enabled !== false) {
182
- return null;
183
- }
184
- const baseUrl = typeof raw.baseUrl === "string" ? raw.baseUrl : "";
185
- const model = typeof raw.model === "string" ? raw.model : "";
186
- const apiKey = typeof raw.apiKey === "string" ? raw.apiKey : "";
187
- const timeoutMs = typeof raw.timeoutMs === "number" && raw.timeoutMs > 0 ? raw.timeoutMs : DEFAULT_LLM_TIMEOUT_MS;
188
- const maxInputChars = typeof raw.maxInputChars === "number" && raw.maxInputChars > 0 ? raw.maxInputChars : DEFAULT_LLM_MAX_INPUT_CHARS;
189
- const mode = raw.mode === "sync" ? "sync" : "async";
190
- const provider = typeof raw.provider === "string" ? raw.provider : "openai";
191
- return {
192
- enabled: raw.enabled,
193
- provider,
194
- baseUrl,
195
- model,
196
- apiKey,
197
- timeoutMs,
198
- maxInputChars,
199
- mode
200
- };
201
- }
202
-
203
- // src/config/readLlmConfig.ts
204
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
205
- function readLlmConfigAtRepo(repoRoot) {
206
- const llmPath = memoryPath(repoRoot, "llm.json");
207
- if (!existsSync2(llmPath)) {
208
- return null;
209
- }
210
- try {
211
- const raw = JSON.parse(readFileSync2(llmPath, "utf8"));
212
- return parseLlmConfigRaw(raw);
213
- } catch {
214
- return null;
215
- }
216
- }
217
188
 
218
189
  // src/capture/claude-code/parseJsonl.ts
219
- import { readFileSync as readFileSync3 } from "fs";
190
+ import { readFileSync as readFileSync2 } from "fs";
220
191
  import { basename } from "path";
221
192
  var FILE_CHANGE_TOOLS = /^(Write|Edit|MultiEdit|NotebookEdit|write|edit)$/i;
222
193
  var SKIP_LINE_TYPES = /* @__PURE__ */ new Set([
@@ -318,7 +289,7 @@ function countNestedTools(record) {
318
289
  }
319
290
  function parseJsonlFile(jsonlPath) {
320
291
  const sessionId = basename(jsonlPath, ".jsonl");
321
- const raw = readFileSync3(jsonlPath, "utf8");
292
+ const raw = readFileSync2(jsonlPath, "utf8");
322
293
  const messages = [];
323
294
  let fileChanges = 0;
324
295
  let toolCalls = 0;
@@ -362,10 +333,10 @@ function parseJsonlFile(jsonlPath) {
362
333
  // src/capture/enqueueLlmJob.ts
363
334
  import { spawn } from "child_process";
364
335
  import {
365
- existsSync as existsSync3,
336
+ existsSync as existsSync2,
366
337
  mkdirSync as mkdirSync2,
367
338
  readdirSync,
368
- readFileSync as readFileSync4,
339
+ readFileSync as readFileSync3,
369
340
  rmSync,
370
341
  writeFileSync
371
342
  } from "fs";
@@ -383,7 +354,7 @@ function makeJobId(sessionId) {
383
354
  }
384
355
  function removeStaleJobsForSession(repoRoot, sessionId) {
385
356
  const dir = pendingDir(repoRoot);
386
- if (!existsSync3(dir)) {
357
+ if (!existsSync2(dir)) {
387
358
  return;
388
359
  }
389
360
  for (const name of readdirSync(dir)) {
@@ -392,7 +363,7 @@ function removeStaleJobsForSession(repoRoot, sessionId) {
392
363
  }
393
364
  try {
394
365
  const raw = JSON.parse(
395
- readFileSync4(join4(dir, name), "utf8")
366
+ readFileSync3(join4(dir, name), "utf8")
396
367
  );
397
368
  if (raw.sessionId === sessionId) {
398
369
  rmSync(join4(dir, name), { force: true });
@@ -436,24 +407,24 @@ function enqueueLlmJob(opts) {
436
407
  }
437
408
  function readLlmJob(repoRoot, jobId) {
438
409
  const path = join4(pendingDir(repoRoot), `${jobId}.json`);
439
- if (!existsSync3(path)) {
410
+ if (!existsSync2(path)) {
440
411
  return null;
441
412
  }
442
413
  try {
443
- return JSON.parse(readFileSync4(path, "utf8"));
414
+ return JSON.parse(readFileSync3(path, "utf8"));
444
415
  } catch {
445
416
  return null;
446
417
  }
447
418
  }
448
419
  function deleteLlmJob(repoRoot, jobId) {
449
420
  const path = join4(pendingDir(repoRoot), `${jobId}.json`);
450
- if (existsSync3(path)) {
421
+ if (existsSync2(path)) {
451
422
  rmSync(path, { force: true });
452
423
  }
453
424
  }
454
425
  function listPendingJobs(repoRoot) {
455
426
  const dir = pendingDir(repoRoot);
456
- if (!existsSync3(dir)) {
427
+ if (!existsSync2(dir)) {
457
428
  return [];
458
429
  }
459
430
  const jobs = [];
@@ -463,7 +434,7 @@ function listPendingJobs(repoRoot) {
463
434
  }
464
435
  try {
465
436
  jobs.push(
466
- JSON.parse(readFileSync4(join4(dir, name), "utf8"))
437
+ JSON.parse(readFileSync3(join4(dir, name), "utf8"))
467
438
  );
468
439
  } catch {
469
440
  }
@@ -693,7 +664,7 @@ async function llmFormat(session, assistant, llm) {
693
664
  }
694
665
 
695
666
  // src/capture/writeCapture.ts
696
- import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
667
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
697
668
  import { join as join5 } from "path";
698
669
  function isoNow() {
699
670
  return (/* @__PURE__ */ new Date()).toISOString();
@@ -746,7 +717,7 @@ function resolveSessionFile(repoRoot, sessionId) {
746
717
  const filename = `session-${sessionId}.md`;
747
718
  const absolutePath = memoryPath(repoRoot, "captures", "raw", filename);
748
719
  const relativePath = join5(".memory", "captures", "raw", filename);
749
- return { absolutePath, relativePath, exists: existsSync4(absolutePath) };
720
+ return { absolutePath, relativePath, exists: existsSync3(absolutePath) };
750
721
  }
751
722
  function renderCaptureMarkdown(formatted, date) {
752
723
  const tagsStr = formatted.tags.map((t) => JSON.stringify(t)).join(", ");
@@ -793,7 +764,7 @@ function appendCaptureToSession(repoRoot, formatted) {
793
764
  previousStatus: null
794
765
  };
795
766
  }
796
- const existingContent = readFileSync5(absolutePath, "utf8");
767
+ const existingContent = readFileSync4(absolutePath, "utf8");
797
768
  const existingFm = parseSessionFileFrontmatter(existingContent);
798
769
  if (!existingFm) {
799
770
  const fm = {
@@ -847,7 +818,7 @@ function appendCaptureToSession(repoRoot, formatted) {
847
818
  function markSessionConsolidated(repoRoot, sessionId) {
848
819
  const { absolutePath, exists } = resolveSessionFile(repoRoot, sessionId);
849
820
  if (!exists) return;
850
- const content = readFileSync5(absolutePath, "utf8");
821
+ const content = readFileSync4(absolutePath, "utf8");
851
822
  const fm = parseSessionFileFrontmatter(content);
852
823
  if (!fm) return;
853
824
  const updatedFm = {
@@ -867,10 +838,10 @@ function markSessionConsolidated(repoRoot, sessionId) {
867
838
  // src/capture/runLlmJob.ts
868
839
  function captureAlreadyUpgraded(repoRoot, captureFile) {
869
840
  const path = join6(repoRoot, captureFile);
870
- if (!existsSync5(path)) {
841
+ if (!existsSync4(path)) {
871
842
  return false;
872
843
  }
873
- const text = readFileSync6(path, "utf8");
844
+ const text = readFileSync5(path, "utf8");
874
845
  return /llmUpgradedAt:/.test(text);
875
846
  }
876
847
  async function runLlmJob(repoRoot, job, debug) {
@@ -878,11 +849,11 @@ async function runLlmJob(repoRoot, job, debug) {
878
849
  deleteLlmJob(repoRoot, job.jobId);
879
850
  return { ok: true, reason: "already-upgraded" };
880
851
  }
881
- const llm = readLlmConfigAtRepo(repoRoot);
852
+ const llm = readConfigAtRepo(repoRoot)?.llm ?? null;
882
853
  if (!isLlmAvailable(llm)) {
883
854
  return { ok: false, reason: "llm not available" };
884
855
  }
885
- if (!existsSync5(job.jsonlPath)) {
856
+ if (!existsSync4(job.jsonlPath)) {
886
857
  return { ok: false, reason: "jsonl missing" };
887
858
  }
888
859
  const session = parseJsonlFile(job.jsonlPath);
@@ -965,7 +936,7 @@ function runCaptureLlmCommand(opts) {
965
936
  }
966
937
 
967
938
  // src/capture/hookInput.ts
968
- import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
939
+ import { existsSync as existsSync5, readFileSync as readFileSync6 } from "fs";
969
940
  import { resolve as resolve2 } from "path";
970
941
  function pickString(obj, ...keys) {
971
942
  for (const key of keys) {
@@ -1003,7 +974,7 @@ function parseHookInputJson(raw) {
1003
974
  try {
1004
975
  const parsed = JSON.parse(trimmed);
1005
976
  const transcriptRaw = pickString(parsed, "transcript_path", "transcriptPath");
1006
- const transcriptPath = transcriptRaw && existsSync6(transcriptRaw) ? resolve2(transcriptRaw) : void 0;
977
+ const transcriptPath = transcriptRaw && existsSync5(transcriptRaw) ? resolve2(transcriptRaw) : void 0;
1007
978
  return {
1008
979
  transcriptPath,
1009
980
  transcriptPathRaw: transcriptRaw,
@@ -1022,7 +993,7 @@ function readHookInputSync() {
1022
993
  return null;
1023
994
  }
1024
995
  try {
1025
- const raw = readFileSync7(0, "utf8");
996
+ const raw = readFileSync6(0, "utf8");
1026
997
  return parseHookInputJson(raw);
1027
998
  } catch {
1028
999
  return null;
@@ -1137,9 +1108,9 @@ function needsLlm(session) {
1137
1108
 
1138
1109
  // src/consolidate/state.ts
1139
1110
  import {
1140
- existsSync as existsSync7,
1111
+ existsSync as existsSync6,
1141
1112
  mkdirSync as mkdirSync4,
1142
- readFileSync as readFileSync8,
1113
+ readFileSync as readFileSync7,
1143
1114
  rmSync as rmSync2,
1144
1115
  writeFileSync as writeFileSync4
1145
1116
  } from "fs";
@@ -1161,11 +1132,11 @@ function consolidateLockPath(repoRoot) {
1161
1132
  }
1162
1133
  function readConsolidateState(repoRoot) {
1163
1134
  const path = consolidateStatePath(repoRoot);
1164
- if (!existsSync7(path)) {
1135
+ if (!existsSync6(path)) {
1165
1136
  return { ...EMPTY_STATE, processedSessions: {} };
1166
1137
  }
1167
1138
  try {
1168
- const raw = JSON.parse(readFileSync8(path, "utf8"));
1139
+ const raw = JSON.parse(readFileSync7(path, "utf8"));
1169
1140
  if (typeof raw === "object" && raw !== null) {
1170
1141
  const obj = raw;
1171
1142
  if (obj.version === 2 && typeof obj.processedSessions === "object") {
@@ -1189,11 +1160,11 @@ function writeConsolidateState(repoRoot, state) {
1189
1160
  }
1190
1161
  function readConsolidateLock(repoRoot) {
1191
1162
  const path = consolidateLockPath(repoRoot);
1192
- if (!existsSync7(path)) {
1163
+ if (!existsSync6(path)) {
1193
1164
  return null;
1194
1165
  }
1195
1166
  try {
1196
- return JSON.parse(readFileSync8(path, "utf8"));
1167
+ return JSON.parse(readFileSync7(path, "utf8"));
1197
1168
  } catch {
1198
1169
  return null;
1199
1170
  }
@@ -1213,7 +1184,7 @@ function writeConsolidateLock(repoRoot) {
1213
1184
  }
1214
1185
  function releaseConsolidateLock(repoRoot) {
1215
1186
  const path = consolidateLockPath(repoRoot);
1216
- if (existsSync7(path)) {
1187
+ if (existsSync6(path)) {
1217
1188
  rmSync2(path, { force: true });
1218
1189
  }
1219
1190
  }
@@ -1226,7 +1197,7 @@ function isLockStale(lock, ttlMs) {
1226
1197
  }
1227
1198
 
1228
1199
  // src/consolidate/sessionScanner.ts
1229
- import { readdirSync as readdirSync2, readFileSync as readFileSync9 } from "fs";
1200
+ import { readdirSync as readdirSync2, readFileSync as readFileSync8 } from "fs";
1230
1201
  import { join as join7 } from "path";
1231
1202
  function parseSessionFrontmatter(content) {
1232
1203
  const match = content.match(/^---\n([\s\S]*?)\n---/);
@@ -1257,7 +1228,7 @@ function scanAllSessions(repoRoot) {
1257
1228
  for (const file of files) {
1258
1229
  const absolutePath = join7(rawDir, file);
1259
1230
  try {
1260
- const content = readFileSync9(absolutePath, "utf8");
1231
+ const content = readFileSync8(absolutePath, "utf8");
1261
1232
  const fm = parseSessionFrontmatter(content);
1262
1233
  if (!fm || !fm.sessionId) continue;
1263
1234
  const fmEndIndex = content.indexOf("---", 4);
@@ -1286,7 +1257,7 @@ function filterPendingSessions(sessions) {
1286
1257
  }
1287
1258
 
1288
1259
  // src/consolidate/llmConsolidateV2.ts
1289
- import { readFileSync as readFileSync10, readdirSync as readdirSync3 } from "fs";
1260
+ import { readFileSync as readFileSync9, readdirSync as readdirSync3 } from "fs";
1290
1261
  import { join as join8 } from "path";
1291
1262
  var CONSOLIDATE_SYSTEM_PROMPT = `\u4F60\u662F\u4E00\u4E2A\u9879\u76EE\u77E5\u8BC6\u6574\u7406\u4E13\u5BB6\u3002\u4F60\u7684\u4EFB\u52A1\u662F\u4ECE AI \u7F16\u7A0B\u52A9\u624B\u7684\u5BF9\u8BDD\u8BB0\u5F55\u4E2D\u63D0\u70BC\u51FA\u7ED3\u6784\u5316\u7684\u77E5\u8BC6\u5E93\u3002
1292
1263
 
@@ -1395,7 +1366,7 @@ function scanMarkdownDirectory(absoluteDir, relativePrefix, type, domain, result
1395
1366
  }
1396
1367
  for (const file of files) {
1397
1368
  try {
1398
- const content = readFileSync10(join8(absoluteDir, file), "utf8");
1369
+ const content = readFileSync9(join8(absoluteDir, file), "utf8");
1399
1370
  const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
1400
1371
  let title = file.replace(/\.md$/, "");
1401
1372
  if (fmMatch) {
@@ -1421,7 +1392,7 @@ function buildLlmConsolidateInput(repoRoot, sessions) {
1421
1392
  const pendingSessions = sessions.map((s) => ({
1422
1393
  sessionId: s.sessionId,
1423
1394
  status: s.frontmatter.status,
1424
- content: readFileSync10(s.absolutePath, "utf8"),
1395
+ content: readFileSync9(s.absolutePath, "utf8"),
1425
1396
  captureCount: s.frontmatter.captureCount,
1426
1397
  createdAt: s.frontmatter.createdAt
1427
1398
  }));
@@ -1429,7 +1400,7 @@ function buildLlmConsolidateInput(repoRoot, sessions) {
1429
1400
  const memoryPathAbs = memoryPath(repoRoot, "MEMORY.md");
1430
1401
  let currentMemoryMd = null;
1431
1402
  try {
1432
- currentMemoryMd = readFileSync10(memoryPathAbs, "utf8");
1403
+ currentMemoryMd = readFileSync9(memoryPathAbs, "utf8");
1433
1404
  } catch {
1434
1405
  }
1435
1406
  return {
@@ -1439,15 +1410,14 @@ function buildLlmConsolidateInput(repoRoot, sessions) {
1439
1410
  };
1440
1411
  }
1441
1412
  async function callLlmConsolidate(input2, llmConfig) {
1442
- const apiKey = process.env.HERMES_LLM_API_KEY;
1443
- if (!apiKey) {
1413
+ if (!llmConfig.enabled) {
1444
1414
  throw new Error(
1445
- "LLM \u672A\u914D\u7F6E\uFF1A\u8BF7\u8BBE\u7F6E HERMES_LLM_API_KEY \u73AF\u5883\u53D8\u91CF"
1415
+ "LLM \u672A\u542F\u7528\uFF1A\u8BF7\u5728 config.json \u4E2D\u8BBE\u7F6E llm.enabled = true"
1446
1416
  );
1447
1417
  }
1448
- if (!llmConfig.enabled) {
1418
+ if (!llmConfig.apiKey.trim() || !llmConfig.baseUrl.trim() || !llmConfig.model.trim()) {
1449
1419
  throw new Error(
1450
- "LLM \u672A\u542F\u7528\uFF1A\u8BF7\u5728 config.json \u4E2D\u8BBE\u7F6E llm.enabled = true"
1420
+ "LLM \u672A\u914D\u7F6E\uFF1A\u8BF7\u5728 config.json \u4E2D\u8BBE\u7F6E llm.apiKey\u3001llm.baseUrl \u548C llm.model"
1451
1421
  );
1452
1422
  }
1453
1423
  const url = `${llmConfig.baseUrl.replace(/\/$/, "")}/chat/completions`;
@@ -1459,7 +1429,7 @@ async function callLlmConsolidate(input2, llmConfig) {
1459
1429
  method: "POST",
1460
1430
  headers: {
1461
1431
  "Content-Type": "application/json",
1462
- Authorization: `Bearer ${apiKey}`
1432
+ Authorization: `Bearer ${llmConfig.apiKey}`
1463
1433
  },
1464
1434
  body: JSON.stringify({
1465
1435
  model: llmConfig.model,
@@ -1551,7 +1521,7 @@ function isSkippedEntry(raw) {
1551
1521
  }
1552
1522
 
1553
1523
  // src/consolidate/writeKnowledge.ts
1554
- import { existsSync as existsSync8, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "fs";
1524
+ import { existsSync as existsSync7, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "fs";
1555
1525
  import { dirname as dirname4 } from "path";
1556
1526
  function writeKnowledgeFiles(repoRoot, files) {
1557
1527
  const result = {
@@ -1565,7 +1535,7 @@ function writeKnowledgeFiles(repoRoot, files) {
1565
1535
  const dir = dirname4(absolutePath);
1566
1536
  mkdirSync5(dir, { recursive: true });
1567
1537
  const content = serializeKnowledgeFile(kf.frontmatter, kf.body);
1568
- const alreadyExists = existsSync8(absolutePath);
1538
+ const alreadyExists = existsSync7(absolutePath);
1569
1539
  if (kf.action === "create" && alreadyExists) {
1570
1540
  result.updated.push(kf.targetPath);
1571
1541
  } else if (kf.action === "create") {
@@ -1585,7 +1555,7 @@ function writeKnowledgeFiles(repoRoot, files) {
1585
1555
  }
1586
1556
  function writeMemoryMd(repoRoot, memoryMd) {
1587
1557
  const memoryPathAbs = memoryPath(repoRoot, "MEMORY.md");
1588
- if (existsSync8(memoryPathAbs)) {
1558
+ if (existsSync7(memoryPathAbs)) {
1589
1559
  const existing = __require("fs").readFileSync(memoryPathAbs, "utf8");
1590
1560
  const preserved = extractUserEditedSections(existing);
1591
1561
  if (preserved.length > 0) {
@@ -1863,7 +1833,7 @@ async function commitCapture(opts) {
1863
1833
  }
1864
1834
  const result = appendCaptureToSession(repoRoot, formatted);
1865
1835
  const captureFile = result.relativePath;
1866
- const llm = readLlmConfigAtRepo(repoRoot);
1836
+ const llm = readConfigAtRepo(repoRoot)?.llm ?? null;
1867
1837
  if (!isLlmAvailable(llm) || !needsLlm(session)) {
1868
1838
  debugLog(debug === true, "capture", `ok: ${captureFile} (format=simple)`);
1869
1839
  return finishCapture(repoRoot, debug, {
@@ -1911,7 +1881,7 @@ async function commitCapture(opts) {
1911
1881
  }
1912
1882
 
1913
1883
  // src/capture/claude-code/resolveSession.ts
1914
- import { existsSync as existsSync10, readdirSync as readdirSync4, readFileSync as readFileSync12, statSync } from "fs";
1884
+ import { existsSync as existsSync9, readdirSync as readdirSync4, readFileSync as readFileSync11, statSync } from "fs";
1915
1885
  import { homedir } from "os";
1916
1886
  import { basename as basename2, join as join11, resolve as resolve3 } from "path";
1917
1887
  function encodeClaudeProjectDir(absPath) {
@@ -1919,29 +1889,29 @@ function encodeClaudeProjectDir(absPath) {
1919
1889
  }
1920
1890
  function resolveSessionJsonlPath(repoRoot, options = {}) {
1921
1891
  const override = process.env.HERMES_SESSION_JSONL;
1922
- if (override && existsSync10(override)) {
1892
+ if (override && existsSync9(override)) {
1923
1893
  return resolve3(override);
1924
1894
  }
1925
1895
  const fromHook = options.transcriptPath;
1926
- if (fromHook && existsSync10(fromHook)) {
1896
+ if (fromHook && existsSync9(fromHook)) {
1927
1897
  return resolve3(fromHook);
1928
1898
  }
1929
1899
  const sessionId = process.env.CLAUDE_SESSION_ID ?? process.env.CLAUDE_CODE_SESSION_ID ?? process.env.SESSION_ID;
1930
1900
  const claudeHome = process.env.CLAUDE_CONFIG_DIR ? resolve3(process.env.CLAUDE_CONFIG_DIR) : join11(homedir(), ".claude");
1931
1901
  const projectsRoot = join11(claudeHome, "projects");
1932
- if (!existsSync10(projectsRoot)) {
1902
+ if (!existsSync9(projectsRoot)) {
1933
1903
  return null;
1934
1904
  }
1935
1905
  const cwd = resolve3(options.cwd ?? repoRoot);
1936
1906
  const preferredProjectDir = encodeClaudeProjectDir(cwd);
1937
1907
  const preferredPath = join11(projectsRoot, preferredProjectDir);
1938
- if (existsSync10(preferredPath)) {
1908
+ if (existsSync9(preferredPath)) {
1939
1909
  const hit = pickNewestJsonl(preferredPath, sessionId);
1940
1910
  if (hit) {
1941
1911
  return hit;
1942
1912
  }
1943
1913
  const legacySessions = join11(preferredPath, "sessions");
1944
- if (existsSync10(legacySessions)) {
1914
+ if (existsSync9(legacySessions)) {
1945
1915
  const legacyHit = pickNewestJsonl(legacySessions, sessionId);
1946
1916
  if (legacyHit) {
1947
1917
  return legacyHit;
@@ -1954,7 +1924,7 @@ function resolveSessionJsonlPath(repoRoot, options = {}) {
1954
1924
  const projectPath = join11(projectsRoot, projectDir.name);
1955
1925
  collectJsonlCandidates(projectPath, sessionId, candidates);
1956
1926
  const legacySessions = join11(projectPath, "sessions");
1957
- if (existsSync10(legacySessions)) {
1927
+ if (existsSync9(legacySessions)) {
1958
1928
  collectJsonlCandidates(legacySessions, sessionId, candidates);
1959
1929
  }
1960
1930
  }
@@ -1974,7 +1944,7 @@ function pickNewestJsonl(dir, sessionId) {
1974
1944
  return candidates[0]?.path ?? null;
1975
1945
  }
1976
1946
  function collectJsonlCandidates(dir, sessionId, out) {
1977
- if (!existsSync10(dir)) {
1947
+ if (!existsSync9(dir)) {
1978
1948
  return;
1979
1949
  }
1980
1950
  for (const entry of readdirSync4(dir, { withFileTypes: true })) {
@@ -2014,7 +1984,7 @@ async function runClaudeCodeCapture(repoRoot, cwd, dryRun, options) {
2014
1984
  }
2015
1985
 
2016
1986
  // src/capture/codebuddy/resolveSession.ts
2017
- import { existsSync as existsSync11, readdirSync as readdirSync5, statSync as statSync2 } from "fs";
1987
+ import { existsSync as existsSync10, readdirSync as readdirSync5, statSync as statSync2 } from "fs";
2018
1988
  import { homedir as homedir2 } from "os";
2019
1989
  import { basename as basename3, join as join12, resolve as resolve4 } from "path";
2020
1990
  function encodeCodebuddyProjectDir(absPath) {
@@ -2022,23 +1992,23 @@ function encodeCodebuddyProjectDir(absPath) {
2022
1992
  }
2023
1993
  function resolveCodebuddySessionJsonl(options) {
2024
1994
  const override = process.env.HERMES_CODEBUDDY_SESSION;
2025
- if (override && existsSync11(override)) {
1995
+ if (override && existsSync10(override)) {
2026
1996
  return resolve4(override);
2027
1997
  }
2028
1998
  const fromHook = options.transcriptPath;
2029
- if (fromHook && existsSync11(fromHook)) {
1999
+ if (fromHook && existsSync10(fromHook)) {
2030
2000
  return resolve4(fromHook);
2031
2001
  }
2032
2002
  const sessionId = process.env.CODEBUDDY_SESSION_ID ?? process.env.SESSION_ID;
2033
2003
  const codebuddyHome = process.env.CODEBUDDY_CONFIG_DIR ? resolve4(process.env.CODEBUDDY_CONFIG_DIR) : join12(homedir2(), ".codebuddy");
2034
2004
  const projectsRoot = join12(codebuddyHome, "projects");
2035
- if (!existsSync11(projectsRoot)) {
2005
+ if (!existsSync10(projectsRoot)) {
2036
2006
  return null;
2037
2007
  }
2038
2008
  const cwd = resolve4(options.cwd ?? options.repoRoot);
2039
2009
  const preferredProjectDir = encodeCodebuddyProjectDir(cwd);
2040
2010
  const preferredPath = join12(projectsRoot, preferredProjectDir);
2041
- if (existsSync11(preferredPath)) {
2011
+ if (existsSync10(preferredPath)) {
2042
2012
  const hit = pickNewestJsonlRecursive(preferredPath, sessionId);
2043
2013
  if (hit) {
2044
2014
  return hit;
@@ -2067,7 +2037,7 @@ function pickNewestJsonlRecursive(dir, sessionId) {
2067
2037
  return candidates[0]?.path ?? null;
2068
2038
  }
2069
2039
  function collectJsonlRecursive(dir, sessionId, out) {
2070
- if (!existsSync11(dir)) {
2040
+ if (!existsSync10(dir)) {
2071
2041
  return;
2072
2042
  }
2073
2043
  for (const entry of readdirSync5(dir, { withFileTypes: true })) {
@@ -2119,7 +2089,7 @@ async function runCodebuddyCapture(repoRoot, cwd, dryRun, options) {
2119
2089
  }
2120
2090
 
2121
2091
  // src/capture/cursor/resolveSession.ts
2122
- import { existsSync as existsSync12, readdirSync as readdirSync6, statSync as statSync3 } from "fs";
2092
+ import { existsSync as existsSync11, readdirSync as readdirSync6, statSync as statSync3 } from "fs";
2123
2093
  import { homedir as homedir3 } from "os";
2124
2094
  import { join as join13, resolve as resolve5 } from "path";
2125
2095
  function encodeCursorProjectDir(absPath) {
@@ -2127,12 +2097,12 @@ function encodeCursorProjectDir(absPath) {
2127
2097
  }
2128
2098
  function resolveCursorSessionJsonl(options) {
2129
2099
  const override = process.env.HERMES_CURSOR_SESSION;
2130
- if (override && existsSync12(override)) {
2100
+ if (override && existsSync11(override)) {
2131
2101
  return resolve5(override);
2132
2102
  }
2133
2103
  const cursorHome = process.env.CURSOR_CONFIG_DIR ? resolve5(process.env.CURSOR_CONFIG_DIR) : join13(homedir3(), ".cursor");
2134
2104
  const projectsRoot = join13(cursorHome, "projects");
2135
- if (!existsSync12(projectsRoot)) {
2105
+ if (!existsSync11(projectsRoot)) {
2136
2106
  return null;
2137
2107
  }
2138
2108
  const sessionId = options.hookInput?.sessionId ?? options.hookInput?.conversationId ?? process.env.CURSOR_SESSION_ID ?? process.env.CURSOR_AGENT_SESSION_ID;
@@ -2140,12 +2110,12 @@ function resolveCursorSessionJsonl(options) {
2140
2110
  const encoded = encodeCursorProjectDir(workspace);
2141
2111
  const projectDir = join13(projectsRoot, encoded);
2142
2112
  const transcriptsRoot = join13(projectDir, "agent-transcripts");
2143
- if (!existsSync12(transcriptsRoot)) {
2113
+ if (!existsSync11(transcriptsRoot)) {
2144
2114
  return pickNewestCursorJsonl(projectsRoot);
2145
2115
  }
2146
2116
  if (sessionId) {
2147
2117
  const direct = join13(transcriptsRoot, sessionId, `${sessionId}.jsonl`);
2148
- if (existsSync12(direct)) {
2118
+ if (existsSync11(direct)) {
2149
2119
  return direct;
2150
2120
  }
2151
2121
  const nested = findJsonlUnderDir(join13(transcriptsRoot, sessionId), sessionId);
@@ -2156,11 +2126,11 @@ function resolveCursorSessionJsonl(options) {
2156
2126
  return pickNewestCursorJsonl(transcriptsRoot);
2157
2127
  }
2158
2128
  function findJsonlUnderDir(dir, sessionId) {
2159
- if (!existsSync12(dir)) {
2129
+ if (!existsSync11(dir)) {
2160
2130
  return null;
2161
2131
  }
2162
2132
  const direct = join13(dir, `${sessionId}.jsonl`);
2163
- if (existsSync12(direct)) {
2133
+ if (existsSync11(direct)) {
2164
2134
  return direct;
2165
2135
  }
2166
2136
  for (const entry of readdirSync6(dir, { withFileTypes: true })) {
@@ -2186,7 +2156,7 @@ function pickNewestCursorJsonl(root) {
2186
2156
  return candidates[0]?.path ?? null;
2187
2157
  }
2188
2158
  function collectJsonlRecursive2(dir, out) {
2189
- if (!existsSync12(dir)) {
2159
+ if (!existsSync11(dir)) {
2190
2160
  return;
2191
2161
  }
2192
2162
  for (const entry of readdirSync6(dir, { withFileTypes: true })) {
@@ -2415,7 +2385,7 @@ async function runFlushCommandCli(opts) {
2415
2385
  }
2416
2386
 
2417
2387
  // src/inject/runInject.ts
2418
- import { existsSync as existsSync13, readdirSync as readdirSync7, readFileSync as readFileSync13 } from "fs";
2388
+ import { existsSync as existsSync12, readdirSync as readdirSync7, readFileSync as readFileSync12 } from "fs";
2419
2389
  import { join as join14 } from "path";
2420
2390
 
2421
2391
  // src/inject/constants.ts
@@ -2476,9 +2446,9 @@ function rulesPathOnDisk(repoRoot) {
2476
2446
  }
2477
2447
  function readMemoryMd(repoRoot) {
2478
2448
  const path = memoryPathOnDisk(repoRoot);
2479
- if (!existsSync13(path)) return null;
2449
+ if (!existsSync12(path)) return null;
2480
2450
  try {
2481
- const content = readFileSync13(path, "utf8");
2451
+ const content = readFileSync12(path, "utf8");
2482
2452
  return content.trim() || null;
2483
2453
  } catch {
2484
2454
  return null;
@@ -2497,7 +2467,7 @@ function readAllRules(repoRoot) {
2497
2467
  for (const file of files) {
2498
2468
  try {
2499
2469
  const filePath = join14(rulesDir, file);
2500
- const content = readFileSync13(filePath, "utf8").trim();
2470
+ const content = readFileSync12(filePath, "utf8").trim();
2501
2471
  if (!content) continue;
2502
2472
  parts.push(`### ${file}`, "", content, "");
2503
2473
  } catch {
@@ -2527,23 +2497,23 @@ import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync6 } from "fs";
2527
2497
  import { join as join18 } from "path";
2528
2498
 
2529
2499
  // src/init/mergeClaudeSettings.ts
2530
- import { existsSync as existsSync15, readFileSync as readFileSync16 } from "fs";
2500
+ import { existsSync as existsSync14, readFileSync as readFileSync15 } from "fs";
2531
2501
  import { join as join17 } from "path";
2532
2502
 
2533
2503
  // src/init/templateDir.ts
2534
- import { existsSync as existsSync14, readFileSync as readFileSync15 } from "fs";
2504
+ import { existsSync as existsSync13, readFileSync as readFileSync14 } from "fs";
2535
2505
  import { dirname as dirname6, join as join16 } from "path";
2536
2506
  import { fileURLToPath as fileURLToPath3 } from "url";
2537
2507
 
2538
2508
  // src/index.ts
2539
- import { readFileSync as readFileSync14 } from "fs";
2509
+ import { readFileSync as readFileSync13 } from "fs";
2540
2510
  import { dirname as dirname5, join as join15 } from "path";
2541
2511
  import { fileURLToPath as fileURLToPath2 } from "url";
2542
2512
  var PACKAGE_NAME = "@riconext/hermes-repo";
2543
2513
  var __dirname = dirname5(fileURLToPath2(import.meta.url));
2544
2514
  function readPkgVersion() {
2545
2515
  const pkgPath = join15(__dirname, "..", "package.json");
2546
- const pkg = JSON.parse(readFileSync14(pkgPath, "utf8"));
2516
+ const pkg = JSON.parse(readFileSync13(pkgPath, "utf8"));
2547
2517
  return pkg.version;
2548
2518
  }
2549
2519
 
@@ -2555,7 +2525,7 @@ function resolveTemplateDir() {
2555
2525
  join16(here, "..", "..", "templates")
2556
2526
  ];
2557
2527
  for (const dir of candidates) {
2558
- if (existsSync14(dir)) {
2528
+ if (existsSync13(dir)) {
2559
2529
  return dir;
2560
2530
  }
2561
2531
  }
@@ -2566,7 +2536,7 @@ function resolveTemplatePath(name) {
2566
2536
  return join16(templateDir, name);
2567
2537
  }
2568
2538
  function readTemplate(name) {
2569
- return readFileSync15(resolveTemplatePath(name), "utf8");
2539
+ return readFileSync14(resolveTemplatePath(name), "utf8");
2570
2540
  }
2571
2541
  function renderTemplate(name) {
2572
2542
  const raw = readTemplate(name);
@@ -2580,12 +2550,12 @@ function claudeSettingsLocalPath(repoRoot) {
2580
2550
  }
2581
2551
  function mergeClaudeLocalSettings(repoRoot) {
2582
2552
  const settingsPath = claudeSettingsLocalPath(repoRoot);
2583
- const existed = existsSync15(settingsPath);
2553
+ const existed = existsSync14(settingsPath);
2584
2554
  const templateParsed = JSON.parse(renderTemplate("hooks.json.tpl"));
2585
2555
  let existing = {};
2586
2556
  if (existed) {
2587
2557
  try {
2588
- existing = JSON.parse(readFileSync16(settingsPath, "utf8"));
2558
+ existing = JSON.parse(readFileSync15(settingsPath, "utf8"));
2589
2559
  } catch {
2590
2560
  existing = {};
2591
2561
  }
@@ -2625,7 +2595,7 @@ import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync7 } from "fs";
2625
2595
  import { join as join20 } from "path";
2626
2596
 
2627
2597
  // src/init/mergeCodexConfig.ts
2628
- import { existsSync as existsSync16, readFileSync as readFileSync17 } from "fs";
2598
+ import { existsSync as existsSync15, readFileSync as readFileSync16 } from "fs";
2629
2599
  import { join as join19 } from "path";
2630
2600
  var CODEX_CONFIG_REL = ".codex/config.toml";
2631
2601
  var CODEX_HERMES_START_MARKER = "# >>> hermes-repo codex (do not edit this block manually)";
@@ -2663,7 +2633,7 @@ ${after}` : ""}
2663
2633
  }
2664
2634
  function mergeCodexConfig(repoRoot) {
2665
2635
  const configPath = codexConfigPath(repoRoot);
2666
- const existed = existsSync16(configPath);
2636
+ const existed = existsSync15(configPath);
2667
2637
  const block = buildCodexHermesBlock();
2668
2638
  if (!existed) {
2669
2639
  return {
@@ -2672,7 +2642,7 @@ function mergeCodexConfig(repoRoot) {
2672
2642
  action: "created"
2673
2643
  };
2674
2644
  }
2675
- const existing = readFileSync17(configPath, "utf8");
2645
+ const existing = readFileSync16(configPath, "utf8");
2676
2646
  const hasBlock = existing.includes(CODEX_HERMES_START_MARKER) && existing.includes(CODEX_HERMES_END_MARKER);
2677
2647
  return {
2678
2648
  content: spliceHermesBlock(existing, block),
@@ -2699,7 +2669,7 @@ import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync8 } from "fs";
2699
2669
  import { join as join22 } from "path";
2700
2670
 
2701
2671
  // src/init/mergeCodebuddySettings.ts
2702
- import { existsSync as existsSync17, readFileSync as readFileSync18 } from "fs";
2672
+ import { existsSync as existsSync16, readFileSync as readFileSync17 } from "fs";
2703
2673
  import { join as join21 } from "path";
2704
2674
  var CODEBUDDY_SETTINGS_LOCAL_REL = ".codebuddy/settings.local.json";
2705
2675
  function codebuddySettingsLocalPath(repoRoot) {
@@ -2707,14 +2677,14 @@ function codebuddySettingsLocalPath(repoRoot) {
2707
2677
  }
2708
2678
  function mergeCodebuddyLocalSettings(repoRoot) {
2709
2679
  const settingsPath = codebuddySettingsLocalPath(repoRoot);
2710
- const existed = existsSync17(settingsPath);
2680
+ const existed = existsSync16(settingsPath);
2711
2681
  const templateParsed = JSON.parse(
2712
2682
  renderTemplate("hooks.codebuddy.json.tpl")
2713
2683
  );
2714
2684
  let existing = {};
2715
2685
  if (existed) {
2716
2686
  try {
2717
- existing = JSON.parse(readFileSync18(settingsPath, "utf8"));
2687
+ existing = JSON.parse(readFileSync17(settingsPath, "utf8"));
2718
2688
  } catch {
2719
2689
  existing = {};
2720
2690
  }
@@ -2754,7 +2724,7 @@ import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync9 } from "fs";
2754
2724
  import { join as join24 } from "path";
2755
2725
 
2756
2726
  // src/init/mergeCursorHooks.ts
2757
- import { existsSync as existsSync18, readFileSync as readFileSync19 } from "fs";
2727
+ import { existsSync as existsSync17, readFileSync as readFileSync18 } from "fs";
2758
2728
  import { join as join23 } from "path";
2759
2729
  var CURSOR_HOOKS_REL = ".cursor/hooks.json";
2760
2730
  function cursorHooksPath(repoRoot) {
@@ -2762,12 +2732,12 @@ function cursorHooksPath(repoRoot) {
2762
2732
  }
2763
2733
  function mergeCursorHooks(repoRoot) {
2764
2734
  const hooksPath = cursorHooksPath(repoRoot);
2765
- const existed = existsSync18(hooksPath);
2735
+ const existed = existsSync17(hooksPath);
2766
2736
  const templateParsed = JSON.parse(renderTemplate("hooks.cursor.json.tpl"));
2767
2737
  let existing = {};
2768
2738
  if (existed) {
2769
2739
  try {
2770
- existing = JSON.parse(readFileSync19(hooksPath, "utf8"));
2740
+ existing = JSON.parse(readFileSync18(hooksPath, "utf8"));
2771
2741
  } catch {
2772
2742
  existing = {};
2773
2743
  }
@@ -2874,14 +2844,14 @@ function ensureMemoryTree(repoRoot) {
2874
2844
  }
2875
2845
 
2876
2846
  // src/init/mergeAssistants.ts
2877
- import { existsSync as existsSync19, readFileSync as readFileSync20 } from "fs";
2847
+ import { existsSync as existsSync18, readFileSync as readFileSync19 } from "fs";
2878
2848
  function readExistingAssistants(repoRoot) {
2879
2849
  const configPath = memoryPath(repoRoot, "config.json");
2880
- if (!existsSync19(configPath)) {
2850
+ if (!existsSync18(configPath)) {
2881
2851
  return [];
2882
2852
  }
2883
2853
  try {
2884
- const config = JSON.parse(readFileSync20(configPath, "utf8"));
2854
+ const config = JSON.parse(readFileSync19(configPath, "utf8"));
2885
2855
  if (!Array.isArray(config.assistants)) {
2886
2856
  return [];
2887
2857
  }
@@ -2896,16 +2866,16 @@ function mergeAssistants(repoRoot, selected) {
2896
2866
  }
2897
2867
 
2898
2868
  // src/init/mergeGitignore.ts
2899
- import { existsSync as existsSync20, readFileSync as readFileSync21, writeFileSync as writeFileSync11 } from "fs";
2869
+ import { existsSync as existsSync19, readFileSync as readFileSync20, writeFileSync as writeFileSync11 } from "fs";
2900
2870
  import { join as join26 } from "path";
2901
2871
  var START_MARKER = "# >>> hermes-repo memory (do not edit this block manually)";
2902
2872
  var END_MARKER = "# <<< hermes-repo memory";
2903
2873
  function mergeHermesGitignore(repoRoot) {
2904
2874
  const block = readTemplate("gitignore-block.txt").trimEnd() + "\n";
2905
2875
  const gitignorePath = join26(repoRoot, ".gitignore");
2906
- const contentBefore = existsSync20(gitignorePath) ? readFileSync21(gitignorePath, "utf8") : "";
2876
+ const contentBefore = existsSync19(gitignorePath) ? readFileSync20(gitignorePath, "utf8") : "";
2907
2877
  const warnBroadMemoryIgnore = contentBefore.length > 0 && !contentBefore.includes(START_MARKER) && /(^|\n)\.memory\/\s*$/m.test(contentBefore);
2908
- if (!existsSync20(gitignorePath)) {
2878
+ if (!existsSync19(gitignorePath)) {
2909
2879
  writeFileSync11(gitignorePath, `${block}
2910
2880
  `, "utf8");
2911
2881
  return { action: "created", warnBroadMemoryIgnore: false };
@@ -2937,22 +2907,27 @@ function mergeHermesGitignore(repoRoot) {
2937
2907
  import { copyFileSync, mkdirSync as mkdirSync12, writeFileSync as writeFileSync14 } from "fs";
2938
2908
 
2939
2909
  // src/init/mergeConfig.ts
2940
- import { existsSync as existsSync21, readFileSync as readFileSync22 } from "fs";
2910
+ import { existsSync as existsSync20, readFileSync as readFileSync21 } from "fs";
2941
2911
  var DEFAULT_LLM = {
2942
2912
  enabled: false,
2913
+ provider: "openai",
2943
2914
  baseUrl: "https://api.openai.com/v1",
2944
- model: "gpt-4o"
2915
+ model: "gpt-4o",
2916
+ apiKey: "",
2917
+ timeoutMs: 6e4,
2918
+ maxInputChars: 24e3,
2919
+ mode: "async"
2945
2920
  };
2946
2921
  var DEFAULT_CONSOLIDATE = {
2947
2922
  autoArchiveDays: 30
2948
2923
  };
2949
2924
  function mergeConfigForInit(repoRoot, assistants) {
2950
2925
  const configPath = memoryPath(repoRoot, "config.json");
2951
- const existed = existsSync21(configPath);
2926
+ const existed = existsSync20(configPath);
2952
2927
  let existing = {};
2953
2928
  if (existed) {
2954
2929
  try {
2955
- existing = JSON.parse(readFileSync22(configPath, "utf8"));
2930
+ existing = JSON.parse(readFileSync21(configPath, "utf8"));
2956
2931
  } catch {
2957
2932
  existing = {};
2958
2933
  }
@@ -2980,7 +2955,7 @@ function mergeConfigForInit(repoRoot, assistants) {
2980
2955
  }
2981
2956
 
2982
2957
  // src/init/mergeAgentsMd.ts
2983
- import { existsSync as existsSync22, readFileSync as readFileSync23, writeFileSync as writeFileSync12 } from "fs";
2958
+ import { existsSync as existsSync21, readFileSync as readFileSync22, writeFileSync as writeFileSync12 } from "fs";
2984
2959
  import { join as join27 } from "path";
2985
2960
  var HERMES_AGENTS_START_MARKER = "<!-- >>> hermes-repo agents (do not edit this block manually) -->";
2986
2961
  var HERMES_AGENTS_END_MARKER = "<!-- <<< hermes-repo agents -->";
@@ -3039,11 +3014,11 @@ function spliceHermesBlock2(existing, block) {
3039
3014
  function mergeAgentsMd(repoRoot, force) {
3040
3015
  const agentsPath = join27(repoRoot, "AGENTS.md");
3041
3016
  const block = buildHermesAgentsMarkedBlock();
3042
- if (!existsSync22(agentsPath)) {
3017
+ if (!existsSync21(agentsPath)) {
3043
3018
  writeFileSync12(agentsPath, buildNewAgentsMd(), "utf8");
3044
3019
  return "created";
3045
3020
  }
3046
- const content = readFileSync23(agentsPath, "utf8");
3021
+ const content = readFileSync22(agentsPath, "utf8");
3047
3022
  if (agentsMdHasHermesBlock(content)) {
3048
3023
  if (!force) {
3049
3024
  return "skipped";
@@ -3059,9 +3034,9 @@ function mergeAgentsMd(repoRoot, force) {
3059
3034
  }
3060
3035
 
3061
3036
  // src/init/scaffoldWrite.ts
3062
- import { existsSync as existsSync23, writeFileSync as writeFileSync13 } from "fs";
3037
+ import { existsSync as existsSync22, writeFileSync as writeFileSync13 } from "fs";
3063
3038
  function shouldWriteFile(absolutePath, force) {
3064
- if (!existsSync23(absolutePath)) {
3039
+ if (!existsSync22(absolutePath)) {
3065
3040
  return { write: true, action: "created" };
3066
3041
  }
3067
3042
  if (force) {
@@ -3151,15 +3126,15 @@ function writeScaffoldFiles(repoRoot, opts, report) {
3151
3126
 
3152
3127
  // src/init/prompts.ts
3153
3128
  import { checkbox, confirm, input } from "@inquirer/prompts";
3154
- import { existsSync as existsSync24, readFileSync as readFileSync24 } from "fs";
3129
+ import { existsSync as existsSync23, readFileSync as readFileSync23 } from "fs";
3155
3130
  import { resolve as resolve6 } from "path";
3156
3131
  function isInitialized(targetDir) {
3157
3132
  const configPath = memoryPath(targetDir, "config.json");
3158
- if (!existsSync24(configPath)) {
3133
+ if (!existsSync23(configPath)) {
3159
3134
  return false;
3160
3135
  }
3161
3136
  try {
3162
- const config = JSON.parse(readFileSync24(configPath, "utf8"));
3137
+ const config = JSON.parse(readFileSync23(configPath, "utf8"));
3163
3138
  return typeof config.version === "number" && config.version >= 1;
3164
3139
  } catch {
3165
3140
  return false;