@riconext/hermes-repo 1.2.4 → 1.2.5
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/CHANGELOG.md +6 -0
- package/README.md +2 -2
- package/dist/cli.js +122 -103
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Command } from "commander";
|
|
|
5
5
|
|
|
6
6
|
// src/config/debugLog.ts
|
|
7
7
|
import { appendFileSync, mkdirSync } from "fs";
|
|
8
|
-
import {
|
|
8
|
+
import { join as join2 } from "path";
|
|
9
9
|
|
|
10
10
|
// src/init/paths.ts
|
|
11
11
|
import { join } from "path";
|
|
@@ -34,33 +34,52 @@ function memoryPath(root, ...segments) {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
// src/config/debugLog.ts
|
|
37
|
-
var
|
|
38
|
-
var
|
|
37
|
+
var DEBUG_LOG_DIR = "logs";
|
|
38
|
+
var DEBUG_LOG_FILES = {
|
|
39
|
+
capture: "capture.log",
|
|
40
|
+
flush: "flush.log",
|
|
41
|
+
consolidate: "consolidate.log"
|
|
42
|
+
};
|
|
43
|
+
var logDirPath = null;
|
|
39
44
|
function configureDebugLogging(repoRoot, enabled) {
|
|
40
45
|
if (!enabled || !repoRoot) {
|
|
41
|
-
|
|
46
|
+
logDirPath = null;
|
|
42
47
|
return;
|
|
43
48
|
}
|
|
44
|
-
|
|
49
|
+
logDirPath = memoryPath(repoRoot, DEBUG_LOG_DIR);
|
|
45
50
|
}
|
|
46
51
|
function formatLine(phase, message) {
|
|
47
52
|
return `${(/* @__PURE__ */ new Date()).toISOString()} hermes-repo [${phase}] ${message}`;
|
|
48
53
|
}
|
|
49
|
-
function writeToLogFile(line) {
|
|
50
|
-
if (!
|
|
54
|
+
function writeToLogFile(phase, line) {
|
|
55
|
+
if (!logDirPath) {
|
|
51
56
|
return;
|
|
52
57
|
}
|
|
53
|
-
mkdirSync(
|
|
54
|
-
appendFileSync(
|
|
58
|
+
mkdirSync(logDirPath, { recursive: true });
|
|
59
|
+
appendFileSync(join2(logDirPath, logFileNameForPhase(phase)), `${line}
|
|
55
60
|
`, "utf8");
|
|
56
61
|
}
|
|
62
|
+
function logFileNameForPhase(phase) {
|
|
63
|
+
switch (phase) {
|
|
64
|
+
case "capture":
|
|
65
|
+
case "capture-llm":
|
|
66
|
+
return DEBUG_LOG_FILES.capture;
|
|
67
|
+
case "flush":
|
|
68
|
+
return DEBUG_LOG_FILES.flush;
|
|
69
|
+
case "consolidate":
|
|
70
|
+
case "llm":
|
|
71
|
+
return DEBUG_LOG_FILES.consolidate;
|
|
72
|
+
default:
|
|
73
|
+
return `${phase.replace(/[^a-z0-9_-]/gi, "-") || "debug"}.log`;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
57
76
|
function debugLog(enabled, phase, message) {
|
|
58
77
|
if (!enabled) {
|
|
59
78
|
return;
|
|
60
79
|
}
|
|
61
80
|
const line = formatLine(phase, message);
|
|
62
81
|
console.error(line);
|
|
63
|
-
writeToLogFile(line);
|
|
82
|
+
writeToLogFile(phase, line);
|
|
64
83
|
}
|
|
65
84
|
function debugLogBlock(enabled, phase, label, content) {
|
|
66
85
|
if (!enabled) {
|
|
@@ -78,19 +97,19 @@ function debugFromContext(ctx, phase, message) {
|
|
|
78
97
|
|
|
79
98
|
// src/config/readConfig.ts
|
|
80
99
|
import { readFileSync } from "fs";
|
|
81
|
-
import { join as
|
|
100
|
+
import { join as join4 } from "path";
|
|
82
101
|
|
|
83
102
|
// src/config/findRepoRoot.ts
|
|
84
103
|
import { existsSync } from "fs";
|
|
85
|
-
import { dirname
|
|
86
|
-
var CONFIG_REL =
|
|
104
|
+
import { dirname, join as join3, resolve } from "path";
|
|
105
|
+
var CONFIG_REL = join3(".memory", "config.json");
|
|
87
106
|
function findRepoRoot(startDir) {
|
|
88
107
|
let dir = resolve(startDir ?? process.cwd());
|
|
89
108
|
while (true) {
|
|
90
|
-
if (existsSync(
|
|
109
|
+
if (existsSync(join3(dir, CONFIG_REL))) {
|
|
91
110
|
return dir;
|
|
92
111
|
}
|
|
93
|
-
const parent =
|
|
112
|
+
const parent = dirname(dir);
|
|
94
113
|
if (parent === dir) {
|
|
95
114
|
return null;
|
|
96
115
|
}
|
|
@@ -129,7 +148,7 @@ function parseConsolidateConfig(raw) {
|
|
|
129
148
|
};
|
|
130
149
|
}
|
|
131
150
|
function readConfigAtRepo(repoRoot) {
|
|
132
|
-
const configPath =
|
|
151
|
+
const configPath = join4(repoRoot, ".memory", "config.json");
|
|
133
152
|
try {
|
|
134
153
|
const raw = JSON.parse(readFileSync(configPath, "utf8"));
|
|
135
154
|
const version = raw.version;
|
|
@@ -192,7 +211,7 @@ function loadRepoContext(cwd) {
|
|
|
192
211
|
|
|
193
212
|
// src/capture/runLlmJob.ts
|
|
194
213
|
import { existsSync as existsSync4, readFileSync as readFileSync5, renameSync, writeFileSync as writeFileSync3 } from "fs";
|
|
195
|
-
import { join as
|
|
214
|
+
import { join as join7 } from "path";
|
|
196
215
|
|
|
197
216
|
// src/config/llmConfig.ts
|
|
198
217
|
function isLlmAvailable(cfg) {
|
|
@@ -359,13 +378,13 @@ import {
|
|
|
359
378
|
rmSync,
|
|
360
379
|
writeFileSync
|
|
361
380
|
} from "fs";
|
|
362
|
-
import { dirname as
|
|
381
|
+
import { dirname as dirname2, join as join5 } from "path";
|
|
363
382
|
import { fileURLToPath } from "url";
|
|
364
383
|
function pendingDir(repoRoot) {
|
|
365
384
|
return memoryPath(repoRoot, "captures", "pending");
|
|
366
385
|
}
|
|
367
386
|
function cliPath() {
|
|
368
|
-
return
|
|
387
|
+
return join5(dirname2(fileURLToPath(import.meta.url)), "..", "cli.js");
|
|
369
388
|
}
|
|
370
389
|
function makeJobId(sessionId) {
|
|
371
390
|
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "").slice(0, 32);
|
|
@@ -382,10 +401,10 @@ function removeStaleJobsForSession(repoRoot, sessionId) {
|
|
|
382
401
|
}
|
|
383
402
|
try {
|
|
384
403
|
const raw = JSON.parse(
|
|
385
|
-
readFileSync3(
|
|
404
|
+
readFileSync3(join5(dir, name), "utf8")
|
|
386
405
|
);
|
|
387
406
|
if (raw.sessionId === sessionId) {
|
|
388
|
-
rmSync(
|
|
407
|
+
rmSync(join5(dir, name), { force: true });
|
|
389
408
|
}
|
|
390
409
|
} catch {
|
|
391
410
|
}
|
|
@@ -406,7 +425,7 @@ function enqueueLlmJob(opts) {
|
|
|
406
425
|
enqueuedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
407
426
|
};
|
|
408
427
|
writeFileSync(
|
|
409
|
-
|
|
428
|
+
join5(dir, `${jobId}.json`),
|
|
410
429
|
`${JSON.stringify(payload, null, 2)}
|
|
411
430
|
`,
|
|
412
431
|
"utf8"
|
|
@@ -425,7 +444,7 @@ function enqueueLlmJob(opts) {
|
|
|
425
444
|
return true;
|
|
426
445
|
}
|
|
427
446
|
function readLlmJob(repoRoot, jobId) {
|
|
428
|
-
const path =
|
|
447
|
+
const path = join5(pendingDir(repoRoot), `${jobId}.json`);
|
|
429
448
|
if (!existsSync2(path)) {
|
|
430
449
|
return null;
|
|
431
450
|
}
|
|
@@ -436,7 +455,7 @@ function readLlmJob(repoRoot, jobId) {
|
|
|
436
455
|
}
|
|
437
456
|
}
|
|
438
457
|
function deleteLlmJob(repoRoot, jobId) {
|
|
439
|
-
const path =
|
|
458
|
+
const path = join5(pendingDir(repoRoot), `${jobId}.json`);
|
|
440
459
|
if (existsSync2(path)) {
|
|
441
460
|
rmSync(path, { force: true });
|
|
442
461
|
}
|
|
@@ -453,7 +472,7 @@ function listPendingJobs(repoRoot) {
|
|
|
453
472
|
}
|
|
454
473
|
try {
|
|
455
474
|
jobs.push(
|
|
456
|
-
JSON.parse(readFileSync3(
|
|
475
|
+
JSON.parse(readFileSync3(join5(dir, name), "utf8"))
|
|
457
476
|
);
|
|
458
477
|
} catch {
|
|
459
478
|
}
|
|
@@ -684,7 +703,7 @@ async function llmFormat(session, assistant, llm) {
|
|
|
684
703
|
|
|
685
704
|
// src/capture/writeCapture.ts
|
|
686
705
|
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
687
|
-
import { join as
|
|
706
|
+
import { join as join6 } from "path";
|
|
688
707
|
function isoNow() {
|
|
689
708
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
690
709
|
}
|
|
@@ -735,7 +754,7 @@ function renderCaptureSection(formatted, index) {
|
|
|
735
754
|
function resolveSessionFile(repoRoot, sessionId) {
|
|
736
755
|
const filename = `session-${sessionId}.md`;
|
|
737
756
|
const absolutePath = memoryPath(repoRoot, "captures", "raw", filename);
|
|
738
|
-
const relativePath =
|
|
757
|
+
const relativePath = join6(".memory", "captures", "raw", filename);
|
|
739
758
|
return { absolutePath, relativePath, exists: existsSync3(absolutePath) };
|
|
740
759
|
}
|
|
741
760
|
function renderCaptureMarkdown(formatted, date) {
|
|
@@ -759,7 +778,7 @@ function renderCaptureMarkdown(formatted, date) {
|
|
|
759
778
|
function appendCaptureToSession(repoRoot, formatted) {
|
|
760
779
|
const { absolutePath, relativePath, exists } = resolveSessionFile(repoRoot, formatted.sessionId);
|
|
761
780
|
const filename = `session-${formatted.sessionId}.md`;
|
|
762
|
-
mkdirSync3(
|
|
781
|
+
mkdirSync3(join6(absolutePath, ".."), { recursive: true });
|
|
763
782
|
const now = isoNow();
|
|
764
783
|
if (!exists) {
|
|
765
784
|
const fm = {
|
|
@@ -856,7 +875,7 @@ function markSessionConsolidated(repoRoot, sessionId) {
|
|
|
856
875
|
|
|
857
876
|
// src/capture/runLlmJob.ts
|
|
858
877
|
function captureAlreadyUpgraded(repoRoot, captureFile) {
|
|
859
|
-
const path =
|
|
878
|
+
const path = join7(repoRoot, captureFile);
|
|
860
879
|
if (!existsSync4(path)) {
|
|
861
880
|
return false;
|
|
862
881
|
}
|
|
@@ -881,7 +900,7 @@ async function runLlmJob(repoRoot, job, debug) {
|
|
|
881
900
|
debugLog(debug === true, "capture-llm", `llm job failed: ${job.jobId}`);
|
|
882
901
|
return { ok: false, reason: "llm format failed" };
|
|
883
902
|
}
|
|
884
|
-
const target =
|
|
903
|
+
const target = join7(repoRoot, job.captureFile);
|
|
885
904
|
const temp = `${target}.hermes-tmp`;
|
|
886
905
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
887
906
|
writeFileSync3(temp, renderCaptureMarkdown(upgraded, date), "utf8");
|
|
@@ -1127,7 +1146,7 @@ function needsLlm(session) {
|
|
|
1127
1146
|
|
|
1128
1147
|
// src/consolidate/scheduleConsolidate.ts
|
|
1129
1148
|
import { spawn as spawn2 } from "child_process";
|
|
1130
|
-
import { dirname as
|
|
1149
|
+
import { dirname as dirname4, join as join12 } from "path";
|
|
1131
1150
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1132
1151
|
|
|
1133
1152
|
// src/consolidate/state.ts
|
|
@@ -1222,7 +1241,7 @@ function isLockStale(lock, ttlMs) {
|
|
|
1222
1241
|
|
|
1223
1242
|
// src/consolidate/sessionScanner.ts
|
|
1224
1243
|
import { readdirSync as readdirSync2, readFileSync as readFileSync8 } from "fs";
|
|
1225
|
-
import { join as
|
|
1244
|
+
import { join as join8 } from "path";
|
|
1226
1245
|
function parseSessionFrontmatter(content) {
|
|
1227
1246
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
1228
1247
|
if (!match) return null;
|
|
@@ -1250,7 +1269,7 @@ function scanAllSessions(repoRoot) {
|
|
|
1250
1269
|
}
|
|
1251
1270
|
const sessions = [];
|
|
1252
1271
|
for (const file of files) {
|
|
1253
|
-
const absolutePath =
|
|
1272
|
+
const absolutePath = join8(rawDir, file);
|
|
1254
1273
|
try {
|
|
1255
1274
|
const content = readFileSync8(absolutePath, "utf8");
|
|
1256
1275
|
const fm = parseSessionFrontmatter(content);
|
|
@@ -1262,7 +1281,7 @@ function scanAllSessions(repoRoot) {
|
|
|
1262
1281
|
sessionId: fm.sessionId,
|
|
1263
1282
|
filename: file,
|
|
1264
1283
|
absolutePath,
|
|
1265
|
-
relativePath:
|
|
1284
|
+
relativePath: join8(".memory", "captures", "raw", file),
|
|
1266
1285
|
frontmatter: fm,
|
|
1267
1286
|
bodyContent: bodyContent.trim()
|
|
1268
1287
|
});
|
|
@@ -1282,7 +1301,7 @@ function filterPendingSessions(sessions) {
|
|
|
1282
1301
|
|
|
1283
1302
|
// src/consolidate/llmConsolidateV2.ts
|
|
1284
1303
|
import { readFileSync as readFileSync9, readdirSync as readdirSync3 } from "fs";
|
|
1285
|
-
import { join as
|
|
1304
|
+
import { join as join9 } from "path";
|
|
1286
1305
|
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
|
|
1287
1306
|
|
|
1288
1307
|
## \u5DE5\u4F5C\u6D41\u7A0B
|
|
@@ -1372,7 +1391,7 @@ function scanExistingKnowledge(repoRoot) {
|
|
|
1372
1391
|
try {
|
|
1373
1392
|
const subdirs = readdirSync3(domainsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
1374
1393
|
for (const domain of subdirs) {
|
|
1375
|
-
const domainAbsDir =
|
|
1394
|
+
const domainAbsDir = join9(domainsDir, domain);
|
|
1376
1395
|
scanMarkdownDirectory(
|
|
1377
1396
|
domainAbsDir,
|
|
1378
1397
|
`domains/${domain}`,
|
|
@@ -1394,7 +1413,7 @@ function scanMarkdownDirectory(absoluteDir, relativePrefix, type, domain, result
|
|
|
1394
1413
|
}
|
|
1395
1414
|
for (const file of files) {
|
|
1396
1415
|
try {
|
|
1397
|
-
const content = readFileSync9(
|
|
1416
|
+
const content = readFileSync9(join9(absoluteDir, file), "utf8");
|
|
1398
1417
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
1399
1418
|
let title = file.replace(/\.md$/, "");
|
|
1400
1419
|
if (fmMatch) {
|
|
@@ -1625,7 +1644,7 @@ function isSkippedEntry(raw) {
|
|
|
1625
1644
|
|
|
1626
1645
|
// src/consolidate/writeKnowledge.ts
|
|
1627
1646
|
import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "fs";
|
|
1628
|
-
import { dirname as
|
|
1647
|
+
import { dirname as dirname3 } from "path";
|
|
1629
1648
|
var KNOWLEDGE_LINK_PREFIXES = [
|
|
1630
1649
|
"rules/",
|
|
1631
1650
|
"domains/",
|
|
@@ -1642,7 +1661,7 @@ function writeKnowledgeFiles(repoRoot, files) {
|
|
|
1642
1661
|
for (const kf of files) {
|
|
1643
1662
|
try {
|
|
1644
1663
|
const absolutePath = memoryPath(repoRoot, kf.targetPath);
|
|
1645
|
-
const dir =
|
|
1664
|
+
const dir = dirname3(absolutePath);
|
|
1646
1665
|
mkdirSync5(dir, { recursive: true });
|
|
1647
1666
|
const content = serializeKnowledgeFile(kf.frontmatter, kf.body);
|
|
1648
1667
|
const alreadyExists = existsSync7(absolutePath);
|
|
@@ -1770,7 +1789,7 @@ ${endMarker}` + result.slice(endIdx + endMarker.length);
|
|
|
1770
1789
|
|
|
1771
1790
|
// src/consolidate/archive.ts
|
|
1772
1791
|
import { mkdirSync as mkdirSync6, renameSync as renameSync2 } from "fs";
|
|
1773
|
-
import { join as
|
|
1792
|
+
import { join as join11 } from "path";
|
|
1774
1793
|
function archiveDoneSessions(repoRoot, sessions, autoArchiveDays = 30) {
|
|
1775
1794
|
const archivedDir = memoryPath(repoRoot, "captures", "archived");
|
|
1776
1795
|
const cutoffMs = Date.now() - autoArchiveDays * 24 * 60 * 60 * 1e3;
|
|
@@ -1783,7 +1802,7 @@ function archiveDoneSessions(repoRoot, sessions, autoArchiveDays = 30) {
|
|
|
1783
1802
|
if (consolidatedTime > cutoffMs) continue;
|
|
1784
1803
|
try {
|
|
1785
1804
|
mkdirSync6(archivedDir, { recursive: true });
|
|
1786
|
-
renameSync2(s.absolutePath,
|
|
1805
|
+
renameSync2(s.absolutePath, join11(archivedDir, s.filename));
|
|
1787
1806
|
archivedCount++;
|
|
1788
1807
|
} catch {
|
|
1789
1808
|
}
|
|
@@ -1965,7 +1984,7 @@ var CONSOLIDATE_LOCK_TTL_MS = 30 * 60 * 1e3;
|
|
|
1965
1984
|
|
|
1966
1985
|
// src/consolidate/scheduleConsolidate.ts
|
|
1967
1986
|
function cliPath2() {
|
|
1968
|
-
return
|
|
1987
|
+
return join12(dirname4(fileURLToPath2(import.meta.url)), "..", "cli.js");
|
|
1969
1988
|
}
|
|
1970
1989
|
async function runFlushCommand(opts) {
|
|
1971
1990
|
const ctx = loadRepoContext(opts.cwd);
|
|
@@ -2150,7 +2169,7 @@ async function commitCapture(opts) {
|
|
|
2150
2169
|
// src/capture/claude-code/resolveSession.ts
|
|
2151
2170
|
import { existsSync as existsSync9, readdirSync as readdirSync4, readFileSync as readFileSync12, statSync } from "fs";
|
|
2152
2171
|
import { homedir } from "os";
|
|
2153
|
-
import { basename as basename2, join as
|
|
2172
|
+
import { basename as basename2, join as join13, resolve as resolve3 } from "path";
|
|
2154
2173
|
function encodeClaudeProjectDir(absPath) {
|
|
2155
2174
|
return resolve3(absPath).replace(/\//g, "-");
|
|
2156
2175
|
}
|
|
@@ -2164,20 +2183,20 @@ function resolveSessionJsonlPath(repoRoot, options = {}) {
|
|
|
2164
2183
|
return resolve3(fromHook);
|
|
2165
2184
|
}
|
|
2166
2185
|
const sessionId = process.env.CLAUDE_SESSION_ID ?? process.env.CLAUDE_CODE_SESSION_ID ?? process.env.SESSION_ID;
|
|
2167
|
-
const claudeHome = process.env.CLAUDE_CONFIG_DIR ? resolve3(process.env.CLAUDE_CONFIG_DIR) :
|
|
2168
|
-
const projectsRoot =
|
|
2186
|
+
const claudeHome = process.env.CLAUDE_CONFIG_DIR ? resolve3(process.env.CLAUDE_CONFIG_DIR) : join13(homedir(), ".claude");
|
|
2187
|
+
const projectsRoot = join13(claudeHome, "projects");
|
|
2169
2188
|
if (!existsSync9(projectsRoot)) {
|
|
2170
2189
|
return null;
|
|
2171
2190
|
}
|
|
2172
2191
|
const cwd = resolve3(options.cwd ?? repoRoot);
|
|
2173
2192
|
const preferredProjectDir = encodeClaudeProjectDir(cwd);
|
|
2174
|
-
const preferredPath =
|
|
2193
|
+
const preferredPath = join13(projectsRoot, preferredProjectDir);
|
|
2175
2194
|
if (existsSync9(preferredPath)) {
|
|
2176
2195
|
const hit = pickNewestJsonl(preferredPath, sessionId);
|
|
2177
2196
|
if (hit) {
|
|
2178
2197
|
return hit;
|
|
2179
2198
|
}
|
|
2180
|
-
const legacySessions =
|
|
2199
|
+
const legacySessions = join13(preferredPath, "sessions");
|
|
2181
2200
|
if (existsSync9(legacySessions)) {
|
|
2182
2201
|
const legacyHit = pickNewestJsonl(legacySessions, sessionId);
|
|
2183
2202
|
if (legacyHit) {
|
|
@@ -2188,9 +2207,9 @@ function resolveSessionJsonlPath(repoRoot, options = {}) {
|
|
|
2188
2207
|
const candidates = [];
|
|
2189
2208
|
for (const projectDir of readdirSync4(projectsRoot, { withFileTypes: true })) {
|
|
2190
2209
|
if (!projectDir.isDirectory()) continue;
|
|
2191
|
-
const projectPath =
|
|
2210
|
+
const projectPath = join13(projectsRoot, projectDir.name);
|
|
2192
2211
|
collectJsonlCandidates(projectPath, sessionId, candidates);
|
|
2193
|
-
const legacySessions =
|
|
2212
|
+
const legacySessions = join13(projectPath, "sessions");
|
|
2194
2213
|
if (existsSync9(legacySessions)) {
|
|
2195
2214
|
collectJsonlCandidates(legacySessions, sessionId, candidates);
|
|
2196
2215
|
}
|
|
@@ -2218,7 +2237,7 @@ function collectJsonlCandidates(dir, sessionId, out) {
|
|
|
2218
2237
|
if (!entry.isFile() || !entry.name.endsWith(".jsonl")) {
|
|
2219
2238
|
continue;
|
|
2220
2239
|
}
|
|
2221
|
-
const fullPath =
|
|
2240
|
+
const fullPath = join13(dir, entry.name);
|
|
2222
2241
|
if (sessionId && !entry.name.includes(sessionId) && basename2(entry.name, ".jsonl") !== sessionId) {
|
|
2223
2242
|
continue;
|
|
2224
2243
|
}
|
|
@@ -2253,7 +2272,7 @@ async function runClaudeCodeCapture(repoRoot, cwd, dryRun, options) {
|
|
|
2253
2272
|
// src/capture/codebuddy/resolveSession.ts
|
|
2254
2273
|
import { existsSync as existsSync10, readdirSync as readdirSync5, statSync as statSync2 } from "fs";
|
|
2255
2274
|
import { homedir as homedir2 } from "os";
|
|
2256
|
-
import { basename as basename3, join as
|
|
2275
|
+
import { basename as basename3, join as join14, resolve as resolve4 } from "path";
|
|
2257
2276
|
function encodeCodebuddyProjectDir(absPath) {
|
|
2258
2277
|
return resolve4(absPath).replace(/^\//, "").replace(/\//g, "-");
|
|
2259
2278
|
}
|
|
@@ -2267,14 +2286,14 @@ function resolveCodebuddySessionJsonl(options) {
|
|
|
2267
2286
|
return resolve4(fromHook);
|
|
2268
2287
|
}
|
|
2269
2288
|
const sessionId = process.env.CODEBUDDY_SESSION_ID ?? process.env.SESSION_ID;
|
|
2270
|
-
const codebuddyHome = process.env.CODEBUDDY_CONFIG_DIR ? resolve4(process.env.CODEBUDDY_CONFIG_DIR) :
|
|
2271
|
-
const projectsRoot =
|
|
2289
|
+
const codebuddyHome = process.env.CODEBUDDY_CONFIG_DIR ? resolve4(process.env.CODEBUDDY_CONFIG_DIR) : join14(homedir2(), ".codebuddy");
|
|
2290
|
+
const projectsRoot = join14(codebuddyHome, "projects");
|
|
2272
2291
|
if (!existsSync10(projectsRoot)) {
|
|
2273
2292
|
return null;
|
|
2274
2293
|
}
|
|
2275
2294
|
const cwd = resolve4(options.cwd ?? options.repoRoot);
|
|
2276
2295
|
const preferredProjectDir = encodeCodebuddyProjectDir(cwd);
|
|
2277
|
-
const preferredPath =
|
|
2296
|
+
const preferredPath = join14(projectsRoot, preferredProjectDir);
|
|
2278
2297
|
if (existsSync10(preferredPath)) {
|
|
2279
2298
|
const hit = pickNewestJsonlRecursive(preferredPath, sessionId);
|
|
2280
2299
|
if (hit) {
|
|
@@ -2286,7 +2305,7 @@ function resolveCodebuddySessionJsonl(options) {
|
|
|
2286
2305
|
if (!projectDir.isDirectory()) {
|
|
2287
2306
|
continue;
|
|
2288
2307
|
}
|
|
2289
|
-
collectJsonlRecursive(
|
|
2308
|
+
collectJsonlRecursive(join14(projectsRoot, projectDir.name), sessionId, candidates);
|
|
2290
2309
|
}
|
|
2291
2310
|
if (candidates.length === 0) {
|
|
2292
2311
|
return null;
|
|
@@ -2308,7 +2327,7 @@ function collectJsonlRecursive(dir, sessionId, out) {
|
|
|
2308
2327
|
return;
|
|
2309
2328
|
}
|
|
2310
2329
|
for (const entry of readdirSync5(dir, { withFileTypes: true })) {
|
|
2311
|
-
const full =
|
|
2330
|
+
const full = join14(dir, entry.name);
|
|
2312
2331
|
if (entry.isDirectory()) {
|
|
2313
2332
|
collectJsonlRecursive(full, sessionId, out);
|
|
2314
2333
|
continue;
|
|
@@ -2358,7 +2377,7 @@ async function runCodebuddyCapture(repoRoot, cwd, dryRun, options) {
|
|
|
2358
2377
|
// src/capture/cursor/resolveSession.ts
|
|
2359
2378
|
import { existsSync as existsSync11, readdirSync as readdirSync6, statSync as statSync3 } from "fs";
|
|
2360
2379
|
import { homedir as homedir3 } from "os";
|
|
2361
|
-
import { join as
|
|
2380
|
+
import { join as join15, resolve as resolve5 } from "path";
|
|
2362
2381
|
function encodeCursorProjectDir(absPath) {
|
|
2363
2382
|
return resolve5(absPath).replace(/^\//, "").replace(/\//g, "-");
|
|
2364
2383
|
}
|
|
@@ -2367,25 +2386,25 @@ function resolveCursorSessionJsonl(options) {
|
|
|
2367
2386
|
if (override && existsSync11(override)) {
|
|
2368
2387
|
return resolve5(override);
|
|
2369
2388
|
}
|
|
2370
|
-
const cursorHome = process.env.CURSOR_CONFIG_DIR ? resolve5(process.env.CURSOR_CONFIG_DIR) :
|
|
2371
|
-
const projectsRoot =
|
|
2389
|
+
const cursorHome = process.env.CURSOR_CONFIG_DIR ? resolve5(process.env.CURSOR_CONFIG_DIR) : join15(homedir3(), ".cursor");
|
|
2390
|
+
const projectsRoot = join15(cursorHome, "projects");
|
|
2372
2391
|
if (!existsSync11(projectsRoot)) {
|
|
2373
2392
|
return null;
|
|
2374
2393
|
}
|
|
2375
2394
|
const sessionId = options.hookInput?.sessionId ?? options.hookInput?.conversationId ?? process.env.CURSOR_SESSION_ID ?? process.env.CURSOR_AGENT_SESSION_ID;
|
|
2376
2395
|
const workspace = options.hookInput?.workspaceRoots?.[0] ?? (options.cwd ? resolve5(options.cwd) : resolve5(options.repoRoot));
|
|
2377
2396
|
const encoded = encodeCursorProjectDir(workspace);
|
|
2378
|
-
const projectDir =
|
|
2379
|
-
const transcriptsRoot =
|
|
2397
|
+
const projectDir = join15(projectsRoot, encoded);
|
|
2398
|
+
const transcriptsRoot = join15(projectDir, "agent-transcripts");
|
|
2380
2399
|
if (!existsSync11(transcriptsRoot)) {
|
|
2381
2400
|
return pickNewestCursorJsonl(projectsRoot);
|
|
2382
2401
|
}
|
|
2383
2402
|
if (sessionId) {
|
|
2384
|
-
const direct =
|
|
2403
|
+
const direct = join15(transcriptsRoot, sessionId, `${sessionId}.jsonl`);
|
|
2385
2404
|
if (existsSync11(direct)) {
|
|
2386
2405
|
return direct;
|
|
2387
2406
|
}
|
|
2388
|
-
const nested = findJsonlUnderDir(
|
|
2407
|
+
const nested = findJsonlUnderDir(join15(transcriptsRoot, sessionId), sessionId);
|
|
2389
2408
|
if (nested) {
|
|
2390
2409
|
return nested;
|
|
2391
2410
|
}
|
|
@@ -2396,16 +2415,16 @@ function findJsonlUnderDir(dir, sessionId) {
|
|
|
2396
2415
|
if (!existsSync11(dir)) {
|
|
2397
2416
|
return null;
|
|
2398
2417
|
}
|
|
2399
|
-
const direct =
|
|
2418
|
+
const direct = join15(dir, `${sessionId}.jsonl`);
|
|
2400
2419
|
if (existsSync11(direct)) {
|
|
2401
2420
|
return direct;
|
|
2402
2421
|
}
|
|
2403
2422
|
for (const entry of readdirSync6(dir, { withFileTypes: true })) {
|
|
2404
2423
|
if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
2405
|
-
return
|
|
2424
|
+
return join15(dir, entry.name);
|
|
2406
2425
|
}
|
|
2407
2426
|
if (entry.isDirectory()) {
|
|
2408
|
-
const found = findJsonlUnderDir(
|
|
2427
|
+
const found = findJsonlUnderDir(join15(dir, entry.name), sessionId);
|
|
2409
2428
|
if (found) {
|
|
2410
2429
|
return found;
|
|
2411
2430
|
}
|
|
@@ -2427,7 +2446,7 @@ function collectJsonlRecursive2(dir, out) {
|
|
|
2427
2446
|
return;
|
|
2428
2447
|
}
|
|
2429
2448
|
for (const entry of readdirSync6(dir, { withFileTypes: true })) {
|
|
2430
|
-
const full =
|
|
2449
|
+
const full = join15(dir, entry.name);
|
|
2431
2450
|
if (entry.isDirectory()) {
|
|
2432
2451
|
collectJsonlRecursive2(full, out);
|
|
2433
2452
|
continue;
|
|
@@ -2671,7 +2690,7 @@ async function runFlushCommandCli(opts) {
|
|
|
2671
2690
|
|
|
2672
2691
|
// src/inject/runInject.ts
|
|
2673
2692
|
import { existsSync as existsSync12, readdirSync as readdirSync7, readFileSync as readFileSync13 } from "fs";
|
|
2674
|
-
import { join as
|
|
2693
|
+
import { join as join16 } from "path";
|
|
2675
2694
|
|
|
2676
2695
|
// src/inject/constants.ts
|
|
2677
2696
|
var INJECT_MAX_CHARS = 8e3;
|
|
@@ -2751,7 +2770,7 @@ function readAllRules(repoRoot) {
|
|
|
2751
2770
|
const parts = [];
|
|
2752
2771
|
for (const file of files) {
|
|
2753
2772
|
try {
|
|
2754
|
-
const filePath =
|
|
2773
|
+
const filePath = join16(rulesDir, file);
|
|
2755
2774
|
const content = readFileSync13(filePath, "utf8").trim();
|
|
2756
2775
|
if (!content) continue;
|
|
2757
2776
|
parts.push(`### ${file}`, "", content, "");
|
|
@@ -2779,46 +2798,46 @@ import { resolve as resolve7 } from "path";
|
|
|
2779
2798
|
|
|
2780
2799
|
// src/init/assistants/claude-code.ts
|
|
2781
2800
|
import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
2782
|
-
import { join as
|
|
2801
|
+
import { join as join20 } from "path";
|
|
2783
2802
|
|
|
2784
2803
|
// src/init/mergeClaudeSettings.ts
|
|
2785
2804
|
import { existsSync as existsSync14, readFileSync as readFileSync16 } from "fs";
|
|
2786
|
-
import { join as
|
|
2805
|
+
import { join as join19 } from "path";
|
|
2787
2806
|
|
|
2788
2807
|
// src/init/templateDir.ts
|
|
2789
2808
|
import { existsSync as existsSync13, readFileSync as readFileSync15 } from "fs";
|
|
2790
|
-
import { dirname as
|
|
2809
|
+
import { dirname as dirname6, join as join18 } from "path";
|
|
2791
2810
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
2792
2811
|
|
|
2793
2812
|
// src/index.ts
|
|
2794
2813
|
import { readFileSync as readFileSync14 } from "fs";
|
|
2795
|
-
import { dirname as
|
|
2814
|
+
import { dirname as dirname5, join as join17 } from "path";
|
|
2796
2815
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2797
2816
|
var PACKAGE_NAME = "@riconext/hermes-repo";
|
|
2798
|
-
var __dirname =
|
|
2817
|
+
var __dirname = dirname5(fileURLToPath3(import.meta.url));
|
|
2799
2818
|
function readPkgVersion() {
|
|
2800
|
-
const pkgPath =
|
|
2819
|
+
const pkgPath = join17(__dirname, "..", "package.json");
|
|
2801
2820
|
const pkg = JSON.parse(readFileSync14(pkgPath, "utf8"));
|
|
2802
2821
|
return pkg.version;
|
|
2803
2822
|
}
|
|
2804
2823
|
|
|
2805
2824
|
// src/init/templateDir.ts
|
|
2806
2825
|
function resolveTemplateDir() {
|
|
2807
|
-
const here =
|
|
2826
|
+
const here = dirname6(fileURLToPath4(import.meta.url));
|
|
2808
2827
|
const candidates = [
|
|
2809
|
-
|
|
2810
|
-
|
|
2828
|
+
join18(here, "templates"),
|
|
2829
|
+
join18(here, "..", "..", "templates")
|
|
2811
2830
|
];
|
|
2812
2831
|
for (const dir of candidates) {
|
|
2813
2832
|
if (existsSync13(dir)) {
|
|
2814
2833
|
return dir;
|
|
2815
2834
|
}
|
|
2816
2835
|
}
|
|
2817
|
-
return
|
|
2836
|
+
return join18(here, "templates");
|
|
2818
2837
|
}
|
|
2819
2838
|
var templateDir = resolveTemplateDir();
|
|
2820
2839
|
function resolveTemplatePath(name) {
|
|
2821
|
-
return
|
|
2840
|
+
return join18(templateDir, name);
|
|
2822
2841
|
}
|
|
2823
2842
|
function readTemplate(name) {
|
|
2824
2843
|
return readFileSync15(resolveTemplatePath(name), "utf8");
|
|
@@ -2831,7 +2850,7 @@ function renderTemplate(name) {
|
|
|
2831
2850
|
// src/init/mergeClaudeSettings.ts
|
|
2832
2851
|
var CLAUDE_SETTINGS_LOCAL_REL = ".claude/settings.local.json";
|
|
2833
2852
|
function claudeSettingsLocalPath(repoRoot) {
|
|
2834
|
-
return
|
|
2853
|
+
return join19(repoRoot, ".claude", "settings.local.json");
|
|
2835
2854
|
}
|
|
2836
2855
|
function mergeClaudeLocalSettings(repoRoot) {
|
|
2837
2856
|
const settingsPath = claudeSettingsLocalPath(repoRoot);
|
|
@@ -2868,7 +2887,7 @@ var claudeCodeAdapter = {
|
|
|
2868
2887
|
available: true,
|
|
2869
2888
|
scaffoldPaths: [CLAUDE_SETTINGS_LOCAL_REL],
|
|
2870
2889
|
write(ctx) {
|
|
2871
|
-
mkdirSync7(
|
|
2890
|
+
mkdirSync7(join20(ctx.repoRoot, ".claude"), { recursive: true });
|
|
2872
2891
|
const { content, action } = mergeClaudeLocalSettings(ctx.repoRoot);
|
|
2873
2892
|
writeFileSync6(claudeSettingsLocalPath(ctx.repoRoot), content, "utf8");
|
|
2874
2893
|
ctx.report.files.push({ path: CLAUDE_SETTINGS_LOCAL_REL, action });
|
|
@@ -2877,11 +2896,11 @@ var claudeCodeAdapter = {
|
|
|
2877
2896
|
|
|
2878
2897
|
// src/init/assistants/codex.ts
|
|
2879
2898
|
import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
2880
|
-
import { join as
|
|
2899
|
+
import { join as join22 } from "path";
|
|
2881
2900
|
|
|
2882
2901
|
// src/init/mergeCodexConfig.ts
|
|
2883
2902
|
import { existsSync as existsSync15, readFileSync as readFileSync17 } from "fs";
|
|
2884
|
-
import { join as
|
|
2903
|
+
import { join as join21 } from "path";
|
|
2885
2904
|
var CODEX_CONFIG_REL = ".codex/config.toml";
|
|
2886
2905
|
var CODEX_HERMES_START_MARKER = "# >>> hermes-repo codex (do not edit this block manually)";
|
|
2887
2906
|
var CODEX_HERMES_END_MARKER = "# <<< hermes-repo codex";
|
|
@@ -2895,7 +2914,7 @@ function buildCodexHermesBlock() {
|
|
|
2895
2914
|
].join("\n");
|
|
2896
2915
|
}
|
|
2897
2916
|
function codexConfigPath(repoRoot) {
|
|
2898
|
-
return
|
|
2917
|
+
return join21(repoRoot, ".codex", "config.toml");
|
|
2899
2918
|
}
|
|
2900
2919
|
function spliceHermesBlock(existing, block) {
|
|
2901
2920
|
const startIdx = existing.indexOf(CODEX_HERMES_START_MARKER);
|
|
@@ -2942,7 +2961,7 @@ var codexAdapter = {
|
|
|
2942
2961
|
available: true,
|
|
2943
2962
|
scaffoldPaths: [CODEX_CONFIG_REL],
|
|
2944
2963
|
write(ctx) {
|
|
2945
|
-
mkdirSync8(
|
|
2964
|
+
mkdirSync8(join22(ctx.repoRoot, ".codex"), { recursive: true });
|
|
2946
2965
|
const { content, action } = mergeCodexConfig(ctx.repoRoot);
|
|
2947
2966
|
writeFileSync7(codexConfigPath(ctx.repoRoot), content, "utf8");
|
|
2948
2967
|
ctx.report.files.push({ path: CODEX_CONFIG_REL, action });
|
|
@@ -2951,14 +2970,14 @@ var codexAdapter = {
|
|
|
2951
2970
|
|
|
2952
2971
|
// src/init/assistants/codebuddy.ts
|
|
2953
2972
|
import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync8 } from "fs";
|
|
2954
|
-
import { join as
|
|
2973
|
+
import { join as join24 } from "path";
|
|
2955
2974
|
|
|
2956
2975
|
// src/init/mergeCodebuddySettings.ts
|
|
2957
2976
|
import { existsSync as existsSync16, readFileSync as readFileSync18 } from "fs";
|
|
2958
|
-
import { join as
|
|
2977
|
+
import { join as join23 } from "path";
|
|
2959
2978
|
var CODEBUDDY_SETTINGS_LOCAL_REL = ".codebuddy/settings.local.json";
|
|
2960
2979
|
function codebuddySettingsLocalPath(repoRoot) {
|
|
2961
|
-
return
|
|
2980
|
+
return join23(repoRoot, ".codebuddy", "settings.local.json");
|
|
2962
2981
|
}
|
|
2963
2982
|
function mergeCodebuddyLocalSettings(repoRoot) {
|
|
2964
2983
|
const settingsPath = codebuddySettingsLocalPath(repoRoot);
|
|
@@ -2997,7 +3016,7 @@ var codebuddyAdapter = {
|
|
|
2997
3016
|
available: true,
|
|
2998
3017
|
scaffoldPaths: [CODEBUDDY_SETTINGS_LOCAL_REL],
|
|
2999
3018
|
write(ctx) {
|
|
3000
|
-
mkdirSync9(
|
|
3019
|
+
mkdirSync9(join24(ctx.repoRoot, ".codebuddy"), { recursive: true });
|
|
3001
3020
|
const { content, action } = mergeCodebuddyLocalSettings(ctx.repoRoot);
|
|
3002
3021
|
writeFileSync8(codebuddySettingsLocalPath(ctx.repoRoot), content, "utf8");
|
|
3003
3022
|
ctx.report.files.push({ path: CODEBUDDY_SETTINGS_LOCAL_REL, action });
|
|
@@ -3006,14 +3025,14 @@ var codebuddyAdapter = {
|
|
|
3006
3025
|
|
|
3007
3026
|
// src/init/assistants/cursor.ts
|
|
3008
3027
|
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync9 } from "fs";
|
|
3009
|
-
import { join as
|
|
3028
|
+
import { join as join26 } from "path";
|
|
3010
3029
|
|
|
3011
3030
|
// src/init/mergeCursorHooks.ts
|
|
3012
3031
|
import { existsSync as existsSync17, readFileSync as readFileSync19 } from "fs";
|
|
3013
|
-
import { join as
|
|
3032
|
+
import { join as join25 } from "path";
|
|
3014
3033
|
var CURSOR_HOOKS_REL = ".cursor/hooks.json";
|
|
3015
3034
|
function cursorHooksPath(repoRoot) {
|
|
3016
|
-
return
|
|
3035
|
+
return join25(repoRoot, ".cursor", "hooks.json");
|
|
3017
3036
|
}
|
|
3018
3037
|
function mergeCursorHooks(repoRoot) {
|
|
3019
3038
|
const hooksPath = cursorHooksPath(repoRoot);
|
|
@@ -3051,7 +3070,7 @@ var cursorAdapter = {
|
|
|
3051
3070
|
available: true,
|
|
3052
3071
|
scaffoldPaths: [CURSOR_HOOKS_REL],
|
|
3053
3072
|
write(ctx) {
|
|
3054
|
-
mkdirSync10(
|
|
3073
|
+
mkdirSync10(join26(ctx.repoRoot, ".cursor"), { recursive: true });
|
|
3055
3074
|
const { content, action } = mergeCursorHooks(ctx.repoRoot);
|
|
3056
3075
|
writeFileSync9(cursorHooksPath(ctx.repoRoot), content, "utf8");
|
|
3057
3076
|
ctx.report.files.push({ path: CURSOR_HOOKS_REL, action });
|
|
@@ -3114,16 +3133,16 @@ function validateAssistantSelection(ids) {
|
|
|
3114
3133
|
|
|
3115
3134
|
// src/init/ensureDirs.ts
|
|
3116
3135
|
import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync10 } from "fs";
|
|
3117
|
-
import { join as
|
|
3136
|
+
import { join as join27 } from "path";
|
|
3118
3137
|
function ensureMemoryTree(repoRoot) {
|
|
3119
|
-
const memoryRoot =
|
|
3138
|
+
const memoryRoot = join27(repoRoot, MEMORY_DIR);
|
|
3120
3139
|
mkdirSync11(memoryRoot, { recursive: true });
|
|
3121
3140
|
for (const sub of MEMORY_SUBDIRS) {
|
|
3122
|
-
mkdirSync11(
|
|
3141
|
+
mkdirSync11(join27(memoryRoot, sub), { recursive: true });
|
|
3123
3142
|
}
|
|
3124
|
-
mkdirSync11(
|
|
3143
|
+
mkdirSync11(join27(repoRoot, ".claude"), { recursive: true });
|
|
3125
3144
|
for (const sub of GITKEEP_DIRS) {
|
|
3126
|
-
const keepPath =
|
|
3145
|
+
const keepPath = join27(memoryRoot, sub, ".gitkeep");
|
|
3127
3146
|
writeFileSync10(keepPath, "", { flag: "a" });
|
|
3128
3147
|
}
|
|
3129
3148
|
}
|
|
@@ -3152,12 +3171,12 @@ function mergeAssistants(repoRoot, selected) {
|
|
|
3152
3171
|
|
|
3153
3172
|
// src/init/mergeGitignore.ts
|
|
3154
3173
|
import { existsSync as existsSync19, readFileSync as readFileSync21, writeFileSync as writeFileSync11 } from "fs";
|
|
3155
|
-
import { join as
|
|
3174
|
+
import { join as join28 } from "path";
|
|
3156
3175
|
var START_MARKER = "# >>> hermes-repo memory (do not edit this block manually)";
|
|
3157
3176
|
var END_MARKER = "# <<< hermes-repo memory";
|
|
3158
3177
|
function mergeHermesGitignore(repoRoot) {
|
|
3159
3178
|
const block = readTemplate("gitignore-block.txt").trimEnd() + "\n";
|
|
3160
|
-
const gitignorePath =
|
|
3179
|
+
const gitignorePath = join28(repoRoot, ".gitignore");
|
|
3161
3180
|
const contentBefore = existsSync19(gitignorePath) ? readFileSync21(gitignorePath, "utf8") : "";
|
|
3162
3181
|
const warnBroadMemoryIgnore = contentBefore.length > 0 && !contentBefore.includes(START_MARKER) && /(^|\n)\.memory\/\s*$/m.test(contentBefore);
|
|
3163
3182
|
if (!existsSync19(gitignorePath)) {
|
|
@@ -3255,7 +3274,7 @@ function mergeConfigForInit(repoRoot, assistants) {
|
|
|
3255
3274
|
|
|
3256
3275
|
// src/init/mergeAgentsMd.ts
|
|
3257
3276
|
import { existsSync as existsSync21, readFileSync as readFileSync23, writeFileSync as writeFileSync12 } from "fs";
|
|
3258
|
-
import { join as
|
|
3277
|
+
import { join as join29 } from "path";
|
|
3259
3278
|
var HERMES_AGENTS_START_MARKER = "<!-- >>> hermes-repo agents (do not edit this block manually) -->";
|
|
3260
3279
|
var HERMES_AGENTS_END_MARKER = "<!-- <<< hermes-repo agents -->";
|
|
3261
3280
|
function buildHermesAgentsBlockBody() {
|
|
@@ -3311,7 +3330,7 @@ function spliceHermesBlock2(existing, block) {
|
|
|
3311
3330
|
`;
|
|
3312
3331
|
}
|
|
3313
3332
|
function mergeAgentsMd(repoRoot, force) {
|
|
3314
|
-
const agentsPath =
|
|
3333
|
+
const agentsPath = join29(repoRoot, "AGENTS.md");
|
|
3315
3334
|
const block = buildHermesAgentsMarkedBlock();
|
|
3316
3335
|
if (!existsSync21(agentsPath)) {
|
|
3317
3336
|
writeFileSync12(agentsPath, buildNewAgentsMd(), "utf8");
|