@riconext/hermes-repo 1.2.3 → 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 +12 -0
- package/README.md +2 -2
- package/dist/cli.js +165 -107
- 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
|
|
@@ -1349,7 +1368,11 @@ var CONSOLIDATE_SYSTEM_PROMPT = `\u4F60\u662F\u4E00\u4E2A\u9879\u76EE\u77E5\u8BC
|
|
|
1349
1368
|
## \u8F93\u51FA\u8981\u6C42
|
|
1350
1369
|
- \u8F93\u51FA\u4E25\u683C JSON \u683C\u5F0F
|
|
1351
1370
|
- knowledgeFiles \u6570\u7EC4\u5305\u542B\u6240\u6709\u9700\u8981\u521B\u5EFA/\u66F4\u65B0\u7684\u6587\u4EF6
|
|
1352
|
-
- \u6BCF\u9879\u5FC5\u987B\u5305\u542B\
|
|
1371
|
+
- \u6BCF\u9879\u5FC5\u987B\u5305\u542B targetPath\u3001action\u3001frontmatter\u3001body
|
|
1372
|
+
- targetPath \u662F\u76F8\u5BF9 .memory/ \u7684\u8DEF\u5F84\uFF0C\u4F8B\u5982 "domains/canvas/canvas-interaction.md"
|
|
1373
|
+
- \u4E0D\u8981\u4F7F\u7528 path\u3001filePath\u3001filename \u7B49\u5B57\u6BB5\u4EE3\u66FF targetPath
|
|
1374
|
+
- frontmatter \u5FC5\u987B\u662F JSON \u5BF9\u8C61\uFF0C\u4E0D\u8981\u8F93\u51FA YAML \u5B57\u7B26\u4E32
|
|
1375
|
+
- body \u662F\u4E0D\u5305\u542B frontmatter \u7684 markdown \u6B63\u6587
|
|
1353
1376
|
- memoryMd \u662F\u5B8C\u6574 MEMORY.md \u5185\u5BB9
|
|
1354
1377
|
- \u65E0\u4EF7\u503C\u7684 session \u5728 skippedSessions \u4E2D\u8BF4\u660E\u539F\u56E0\uFF08\u800C\u975E\u751F\u6210\u7A7A\u5185\u5BB9\uFF09`;
|
|
1355
1378
|
function scanExistingKnowledge(repoRoot) {
|
|
@@ -1368,7 +1391,7 @@ function scanExistingKnowledge(repoRoot) {
|
|
|
1368
1391
|
try {
|
|
1369
1392
|
const subdirs = readdirSync3(domainsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
1370
1393
|
for (const domain of subdirs) {
|
|
1371
|
-
const domainAbsDir =
|
|
1394
|
+
const domainAbsDir = join9(domainsDir, domain);
|
|
1372
1395
|
scanMarkdownDirectory(
|
|
1373
1396
|
domainAbsDir,
|
|
1374
1397
|
`domains/${domain}`,
|
|
@@ -1390,7 +1413,7 @@ function scanMarkdownDirectory(absoluteDir, relativePrefix, type, domain, result
|
|
|
1390
1413
|
}
|
|
1391
1414
|
for (const file of files) {
|
|
1392
1415
|
try {
|
|
1393
|
-
const content = readFileSync9(
|
|
1416
|
+
const content = readFileSync9(join9(absoluteDir, file), "utf8");
|
|
1394
1417
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
1395
1418
|
let title = file.replace(/\.md$/, "");
|
|
1396
1419
|
if (fmMatch) {
|
|
@@ -1568,16 +1591,51 @@ function validateAndNormalizeLlmResult(raw) {
|
|
|
1568
1591
|
function normalizeKnowledgeFile(raw) {
|
|
1569
1592
|
if (!raw || typeof raw !== "object") return null;
|
|
1570
1593
|
const obj = raw;
|
|
1571
|
-
|
|
1594
|
+
const targetPath = typeof obj.targetPath === "string" ? obj.targetPath : typeof obj.path === "string" ? obj.path : null;
|
|
1595
|
+
if (!targetPath || !["create", "update"].includes(obj.action) || typeof obj.body !== "string") {
|
|
1572
1596
|
return null;
|
|
1573
1597
|
}
|
|
1574
1598
|
return {
|
|
1575
|
-
targetPath
|
|
1599
|
+
targetPath,
|
|
1576
1600
|
action: obj.action,
|
|
1577
|
-
frontmatter:
|
|
1601
|
+
frontmatter: normalizeFrontmatter(obj.frontmatter),
|
|
1578
1602
|
body: obj.body
|
|
1579
1603
|
};
|
|
1580
1604
|
}
|
|
1605
|
+
function normalizeFrontmatter(raw) {
|
|
1606
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
1607
|
+
return raw;
|
|
1608
|
+
}
|
|
1609
|
+
if (typeof raw !== "string") {
|
|
1610
|
+
return {};
|
|
1611
|
+
}
|
|
1612
|
+
const text = raw.trim();
|
|
1613
|
+
const yaml = text.startsWith("---") ? text.replace(/^---\r?\n?/, "").replace(/\r?\n?---$/, "") : text;
|
|
1614
|
+
const frontmatter = {};
|
|
1615
|
+
for (const line of yaml.split(/\r?\n/)) {
|
|
1616
|
+
const trimmed = line.trim();
|
|
1617
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
1618
|
+
continue;
|
|
1619
|
+
}
|
|
1620
|
+
const separator = trimmed.indexOf(":");
|
|
1621
|
+
if (separator <= 0) {
|
|
1622
|
+
continue;
|
|
1623
|
+
}
|
|
1624
|
+
const key = trimmed.slice(0, separator).trim();
|
|
1625
|
+
const value = trimmed.slice(separator + 1).trim();
|
|
1626
|
+
frontmatter[key] = parseFrontmatterValue(value);
|
|
1627
|
+
}
|
|
1628
|
+
return frontmatter;
|
|
1629
|
+
}
|
|
1630
|
+
function parseFrontmatterValue(value) {
|
|
1631
|
+
const unquoted = value.replace(/^["']|["']$/g, "");
|
|
1632
|
+
if (unquoted.startsWith("[") && unquoted.endsWith("]")) {
|
|
1633
|
+
return unquoted.slice(1, -1).split(",").map((item) => item.trim().replace(/^["']|["']$/g, "")).filter(Boolean);
|
|
1634
|
+
}
|
|
1635
|
+
if (unquoted === "true") return true;
|
|
1636
|
+
if (unquoted === "false") return false;
|
|
1637
|
+
return unquoted;
|
|
1638
|
+
}
|
|
1581
1639
|
function isSkippedEntry(raw) {
|
|
1582
1640
|
if (!raw || typeof raw !== "object") return false;
|
|
1583
1641
|
const obj = raw;
|
|
@@ -1586,7 +1644,7 @@ function isSkippedEntry(raw) {
|
|
|
1586
1644
|
|
|
1587
1645
|
// src/consolidate/writeKnowledge.ts
|
|
1588
1646
|
import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "fs";
|
|
1589
|
-
import { dirname as
|
|
1647
|
+
import { dirname as dirname3 } from "path";
|
|
1590
1648
|
var KNOWLEDGE_LINK_PREFIXES = [
|
|
1591
1649
|
"rules/",
|
|
1592
1650
|
"domains/",
|
|
@@ -1603,7 +1661,7 @@ function writeKnowledgeFiles(repoRoot, files) {
|
|
|
1603
1661
|
for (const kf of files) {
|
|
1604
1662
|
try {
|
|
1605
1663
|
const absolutePath = memoryPath(repoRoot, kf.targetPath);
|
|
1606
|
-
const dir =
|
|
1664
|
+
const dir = dirname3(absolutePath);
|
|
1607
1665
|
mkdirSync5(dir, { recursive: true });
|
|
1608
1666
|
const content = serializeKnowledgeFile(kf.frontmatter, kf.body);
|
|
1609
1667
|
const alreadyExists = existsSync7(absolutePath);
|
|
@@ -1731,7 +1789,7 @@ ${endMarker}` + result.slice(endIdx + endMarker.length);
|
|
|
1731
1789
|
|
|
1732
1790
|
// src/consolidate/archive.ts
|
|
1733
1791
|
import { mkdirSync as mkdirSync6, renameSync as renameSync2 } from "fs";
|
|
1734
|
-
import { join as
|
|
1792
|
+
import { join as join11 } from "path";
|
|
1735
1793
|
function archiveDoneSessions(repoRoot, sessions, autoArchiveDays = 30) {
|
|
1736
1794
|
const archivedDir = memoryPath(repoRoot, "captures", "archived");
|
|
1737
1795
|
const cutoffMs = Date.now() - autoArchiveDays * 24 * 60 * 60 * 1e3;
|
|
@@ -1744,7 +1802,7 @@ function archiveDoneSessions(repoRoot, sessions, autoArchiveDays = 30) {
|
|
|
1744
1802
|
if (consolidatedTime > cutoffMs) continue;
|
|
1745
1803
|
try {
|
|
1746
1804
|
mkdirSync6(archivedDir, { recursive: true });
|
|
1747
|
-
renameSync2(s.absolutePath,
|
|
1805
|
+
renameSync2(s.absolutePath, join11(archivedDir, s.filename));
|
|
1748
1806
|
archivedCount++;
|
|
1749
1807
|
} catch {
|
|
1750
1808
|
}
|
|
@@ -1926,7 +1984,7 @@ var CONSOLIDATE_LOCK_TTL_MS = 30 * 60 * 1e3;
|
|
|
1926
1984
|
|
|
1927
1985
|
// src/consolidate/scheduleConsolidate.ts
|
|
1928
1986
|
function cliPath2() {
|
|
1929
|
-
return
|
|
1987
|
+
return join12(dirname4(fileURLToPath2(import.meta.url)), "..", "cli.js");
|
|
1930
1988
|
}
|
|
1931
1989
|
async function runFlushCommand(opts) {
|
|
1932
1990
|
const ctx = loadRepoContext(opts.cwd);
|
|
@@ -2111,7 +2169,7 @@ async function commitCapture(opts) {
|
|
|
2111
2169
|
// src/capture/claude-code/resolveSession.ts
|
|
2112
2170
|
import { existsSync as existsSync9, readdirSync as readdirSync4, readFileSync as readFileSync12, statSync } from "fs";
|
|
2113
2171
|
import { homedir } from "os";
|
|
2114
|
-
import { basename as basename2, join as
|
|
2172
|
+
import { basename as basename2, join as join13, resolve as resolve3 } from "path";
|
|
2115
2173
|
function encodeClaudeProjectDir(absPath) {
|
|
2116
2174
|
return resolve3(absPath).replace(/\//g, "-");
|
|
2117
2175
|
}
|
|
@@ -2125,20 +2183,20 @@ function resolveSessionJsonlPath(repoRoot, options = {}) {
|
|
|
2125
2183
|
return resolve3(fromHook);
|
|
2126
2184
|
}
|
|
2127
2185
|
const sessionId = process.env.CLAUDE_SESSION_ID ?? process.env.CLAUDE_CODE_SESSION_ID ?? process.env.SESSION_ID;
|
|
2128
|
-
const claudeHome = process.env.CLAUDE_CONFIG_DIR ? resolve3(process.env.CLAUDE_CONFIG_DIR) :
|
|
2129
|
-
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");
|
|
2130
2188
|
if (!existsSync9(projectsRoot)) {
|
|
2131
2189
|
return null;
|
|
2132
2190
|
}
|
|
2133
2191
|
const cwd = resolve3(options.cwd ?? repoRoot);
|
|
2134
2192
|
const preferredProjectDir = encodeClaudeProjectDir(cwd);
|
|
2135
|
-
const preferredPath =
|
|
2193
|
+
const preferredPath = join13(projectsRoot, preferredProjectDir);
|
|
2136
2194
|
if (existsSync9(preferredPath)) {
|
|
2137
2195
|
const hit = pickNewestJsonl(preferredPath, sessionId);
|
|
2138
2196
|
if (hit) {
|
|
2139
2197
|
return hit;
|
|
2140
2198
|
}
|
|
2141
|
-
const legacySessions =
|
|
2199
|
+
const legacySessions = join13(preferredPath, "sessions");
|
|
2142
2200
|
if (existsSync9(legacySessions)) {
|
|
2143
2201
|
const legacyHit = pickNewestJsonl(legacySessions, sessionId);
|
|
2144
2202
|
if (legacyHit) {
|
|
@@ -2149,9 +2207,9 @@ function resolveSessionJsonlPath(repoRoot, options = {}) {
|
|
|
2149
2207
|
const candidates = [];
|
|
2150
2208
|
for (const projectDir of readdirSync4(projectsRoot, { withFileTypes: true })) {
|
|
2151
2209
|
if (!projectDir.isDirectory()) continue;
|
|
2152
|
-
const projectPath =
|
|
2210
|
+
const projectPath = join13(projectsRoot, projectDir.name);
|
|
2153
2211
|
collectJsonlCandidates(projectPath, sessionId, candidates);
|
|
2154
|
-
const legacySessions =
|
|
2212
|
+
const legacySessions = join13(projectPath, "sessions");
|
|
2155
2213
|
if (existsSync9(legacySessions)) {
|
|
2156
2214
|
collectJsonlCandidates(legacySessions, sessionId, candidates);
|
|
2157
2215
|
}
|
|
@@ -2179,7 +2237,7 @@ function collectJsonlCandidates(dir, sessionId, out) {
|
|
|
2179
2237
|
if (!entry.isFile() || !entry.name.endsWith(".jsonl")) {
|
|
2180
2238
|
continue;
|
|
2181
2239
|
}
|
|
2182
|
-
const fullPath =
|
|
2240
|
+
const fullPath = join13(dir, entry.name);
|
|
2183
2241
|
if (sessionId && !entry.name.includes(sessionId) && basename2(entry.name, ".jsonl") !== sessionId) {
|
|
2184
2242
|
continue;
|
|
2185
2243
|
}
|
|
@@ -2214,7 +2272,7 @@ async function runClaudeCodeCapture(repoRoot, cwd, dryRun, options) {
|
|
|
2214
2272
|
// src/capture/codebuddy/resolveSession.ts
|
|
2215
2273
|
import { existsSync as existsSync10, readdirSync as readdirSync5, statSync as statSync2 } from "fs";
|
|
2216
2274
|
import { homedir as homedir2 } from "os";
|
|
2217
|
-
import { basename as basename3, join as
|
|
2275
|
+
import { basename as basename3, join as join14, resolve as resolve4 } from "path";
|
|
2218
2276
|
function encodeCodebuddyProjectDir(absPath) {
|
|
2219
2277
|
return resolve4(absPath).replace(/^\//, "").replace(/\//g, "-");
|
|
2220
2278
|
}
|
|
@@ -2228,14 +2286,14 @@ function resolveCodebuddySessionJsonl(options) {
|
|
|
2228
2286
|
return resolve4(fromHook);
|
|
2229
2287
|
}
|
|
2230
2288
|
const sessionId = process.env.CODEBUDDY_SESSION_ID ?? process.env.SESSION_ID;
|
|
2231
|
-
const codebuddyHome = process.env.CODEBUDDY_CONFIG_DIR ? resolve4(process.env.CODEBUDDY_CONFIG_DIR) :
|
|
2232
|
-
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");
|
|
2233
2291
|
if (!existsSync10(projectsRoot)) {
|
|
2234
2292
|
return null;
|
|
2235
2293
|
}
|
|
2236
2294
|
const cwd = resolve4(options.cwd ?? options.repoRoot);
|
|
2237
2295
|
const preferredProjectDir = encodeCodebuddyProjectDir(cwd);
|
|
2238
|
-
const preferredPath =
|
|
2296
|
+
const preferredPath = join14(projectsRoot, preferredProjectDir);
|
|
2239
2297
|
if (existsSync10(preferredPath)) {
|
|
2240
2298
|
const hit = pickNewestJsonlRecursive(preferredPath, sessionId);
|
|
2241
2299
|
if (hit) {
|
|
@@ -2247,7 +2305,7 @@ function resolveCodebuddySessionJsonl(options) {
|
|
|
2247
2305
|
if (!projectDir.isDirectory()) {
|
|
2248
2306
|
continue;
|
|
2249
2307
|
}
|
|
2250
|
-
collectJsonlRecursive(
|
|
2308
|
+
collectJsonlRecursive(join14(projectsRoot, projectDir.name), sessionId, candidates);
|
|
2251
2309
|
}
|
|
2252
2310
|
if (candidates.length === 0) {
|
|
2253
2311
|
return null;
|
|
@@ -2269,7 +2327,7 @@ function collectJsonlRecursive(dir, sessionId, out) {
|
|
|
2269
2327
|
return;
|
|
2270
2328
|
}
|
|
2271
2329
|
for (const entry of readdirSync5(dir, { withFileTypes: true })) {
|
|
2272
|
-
const full =
|
|
2330
|
+
const full = join14(dir, entry.name);
|
|
2273
2331
|
if (entry.isDirectory()) {
|
|
2274
2332
|
collectJsonlRecursive(full, sessionId, out);
|
|
2275
2333
|
continue;
|
|
@@ -2319,7 +2377,7 @@ async function runCodebuddyCapture(repoRoot, cwd, dryRun, options) {
|
|
|
2319
2377
|
// src/capture/cursor/resolveSession.ts
|
|
2320
2378
|
import { existsSync as existsSync11, readdirSync as readdirSync6, statSync as statSync3 } from "fs";
|
|
2321
2379
|
import { homedir as homedir3 } from "os";
|
|
2322
|
-
import { join as
|
|
2380
|
+
import { join as join15, resolve as resolve5 } from "path";
|
|
2323
2381
|
function encodeCursorProjectDir(absPath) {
|
|
2324
2382
|
return resolve5(absPath).replace(/^\//, "").replace(/\//g, "-");
|
|
2325
2383
|
}
|
|
@@ -2328,25 +2386,25 @@ function resolveCursorSessionJsonl(options) {
|
|
|
2328
2386
|
if (override && existsSync11(override)) {
|
|
2329
2387
|
return resolve5(override);
|
|
2330
2388
|
}
|
|
2331
|
-
const cursorHome = process.env.CURSOR_CONFIG_DIR ? resolve5(process.env.CURSOR_CONFIG_DIR) :
|
|
2332
|
-
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");
|
|
2333
2391
|
if (!existsSync11(projectsRoot)) {
|
|
2334
2392
|
return null;
|
|
2335
2393
|
}
|
|
2336
2394
|
const sessionId = options.hookInput?.sessionId ?? options.hookInput?.conversationId ?? process.env.CURSOR_SESSION_ID ?? process.env.CURSOR_AGENT_SESSION_ID;
|
|
2337
2395
|
const workspace = options.hookInput?.workspaceRoots?.[0] ?? (options.cwd ? resolve5(options.cwd) : resolve5(options.repoRoot));
|
|
2338
2396
|
const encoded = encodeCursorProjectDir(workspace);
|
|
2339
|
-
const projectDir =
|
|
2340
|
-
const transcriptsRoot =
|
|
2397
|
+
const projectDir = join15(projectsRoot, encoded);
|
|
2398
|
+
const transcriptsRoot = join15(projectDir, "agent-transcripts");
|
|
2341
2399
|
if (!existsSync11(transcriptsRoot)) {
|
|
2342
2400
|
return pickNewestCursorJsonl(projectsRoot);
|
|
2343
2401
|
}
|
|
2344
2402
|
if (sessionId) {
|
|
2345
|
-
const direct =
|
|
2403
|
+
const direct = join15(transcriptsRoot, sessionId, `${sessionId}.jsonl`);
|
|
2346
2404
|
if (existsSync11(direct)) {
|
|
2347
2405
|
return direct;
|
|
2348
2406
|
}
|
|
2349
|
-
const nested = findJsonlUnderDir(
|
|
2407
|
+
const nested = findJsonlUnderDir(join15(transcriptsRoot, sessionId), sessionId);
|
|
2350
2408
|
if (nested) {
|
|
2351
2409
|
return nested;
|
|
2352
2410
|
}
|
|
@@ -2357,16 +2415,16 @@ function findJsonlUnderDir(dir, sessionId) {
|
|
|
2357
2415
|
if (!existsSync11(dir)) {
|
|
2358
2416
|
return null;
|
|
2359
2417
|
}
|
|
2360
|
-
const direct =
|
|
2418
|
+
const direct = join15(dir, `${sessionId}.jsonl`);
|
|
2361
2419
|
if (existsSync11(direct)) {
|
|
2362
2420
|
return direct;
|
|
2363
2421
|
}
|
|
2364
2422
|
for (const entry of readdirSync6(dir, { withFileTypes: true })) {
|
|
2365
2423
|
if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
2366
|
-
return
|
|
2424
|
+
return join15(dir, entry.name);
|
|
2367
2425
|
}
|
|
2368
2426
|
if (entry.isDirectory()) {
|
|
2369
|
-
const found = findJsonlUnderDir(
|
|
2427
|
+
const found = findJsonlUnderDir(join15(dir, entry.name), sessionId);
|
|
2370
2428
|
if (found) {
|
|
2371
2429
|
return found;
|
|
2372
2430
|
}
|
|
@@ -2388,7 +2446,7 @@ function collectJsonlRecursive2(dir, out) {
|
|
|
2388
2446
|
return;
|
|
2389
2447
|
}
|
|
2390
2448
|
for (const entry of readdirSync6(dir, { withFileTypes: true })) {
|
|
2391
|
-
const full =
|
|
2449
|
+
const full = join15(dir, entry.name);
|
|
2392
2450
|
if (entry.isDirectory()) {
|
|
2393
2451
|
collectJsonlRecursive2(full, out);
|
|
2394
2452
|
continue;
|
|
@@ -2632,7 +2690,7 @@ async function runFlushCommandCli(opts) {
|
|
|
2632
2690
|
|
|
2633
2691
|
// src/inject/runInject.ts
|
|
2634
2692
|
import { existsSync as existsSync12, readdirSync as readdirSync7, readFileSync as readFileSync13 } from "fs";
|
|
2635
|
-
import { join as
|
|
2693
|
+
import { join as join16 } from "path";
|
|
2636
2694
|
|
|
2637
2695
|
// src/inject/constants.ts
|
|
2638
2696
|
var INJECT_MAX_CHARS = 8e3;
|
|
@@ -2712,7 +2770,7 @@ function readAllRules(repoRoot) {
|
|
|
2712
2770
|
const parts = [];
|
|
2713
2771
|
for (const file of files) {
|
|
2714
2772
|
try {
|
|
2715
|
-
const filePath =
|
|
2773
|
+
const filePath = join16(rulesDir, file);
|
|
2716
2774
|
const content = readFileSync13(filePath, "utf8").trim();
|
|
2717
2775
|
if (!content) continue;
|
|
2718
2776
|
parts.push(`### ${file}`, "", content, "");
|
|
@@ -2740,46 +2798,46 @@ import { resolve as resolve7 } from "path";
|
|
|
2740
2798
|
|
|
2741
2799
|
// src/init/assistants/claude-code.ts
|
|
2742
2800
|
import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
2743
|
-
import { join as
|
|
2801
|
+
import { join as join20 } from "path";
|
|
2744
2802
|
|
|
2745
2803
|
// src/init/mergeClaudeSettings.ts
|
|
2746
2804
|
import { existsSync as existsSync14, readFileSync as readFileSync16 } from "fs";
|
|
2747
|
-
import { join as
|
|
2805
|
+
import { join as join19 } from "path";
|
|
2748
2806
|
|
|
2749
2807
|
// src/init/templateDir.ts
|
|
2750
2808
|
import { existsSync as existsSync13, readFileSync as readFileSync15 } from "fs";
|
|
2751
|
-
import { dirname as
|
|
2809
|
+
import { dirname as dirname6, join as join18 } from "path";
|
|
2752
2810
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
2753
2811
|
|
|
2754
2812
|
// src/index.ts
|
|
2755
2813
|
import { readFileSync as readFileSync14 } from "fs";
|
|
2756
|
-
import { dirname as
|
|
2814
|
+
import { dirname as dirname5, join as join17 } from "path";
|
|
2757
2815
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2758
2816
|
var PACKAGE_NAME = "@riconext/hermes-repo";
|
|
2759
|
-
var __dirname =
|
|
2817
|
+
var __dirname = dirname5(fileURLToPath3(import.meta.url));
|
|
2760
2818
|
function readPkgVersion() {
|
|
2761
|
-
const pkgPath =
|
|
2819
|
+
const pkgPath = join17(__dirname, "..", "package.json");
|
|
2762
2820
|
const pkg = JSON.parse(readFileSync14(pkgPath, "utf8"));
|
|
2763
2821
|
return pkg.version;
|
|
2764
2822
|
}
|
|
2765
2823
|
|
|
2766
2824
|
// src/init/templateDir.ts
|
|
2767
2825
|
function resolveTemplateDir() {
|
|
2768
|
-
const here =
|
|
2826
|
+
const here = dirname6(fileURLToPath4(import.meta.url));
|
|
2769
2827
|
const candidates = [
|
|
2770
|
-
|
|
2771
|
-
|
|
2828
|
+
join18(here, "templates"),
|
|
2829
|
+
join18(here, "..", "..", "templates")
|
|
2772
2830
|
];
|
|
2773
2831
|
for (const dir of candidates) {
|
|
2774
2832
|
if (existsSync13(dir)) {
|
|
2775
2833
|
return dir;
|
|
2776
2834
|
}
|
|
2777
2835
|
}
|
|
2778
|
-
return
|
|
2836
|
+
return join18(here, "templates");
|
|
2779
2837
|
}
|
|
2780
2838
|
var templateDir = resolveTemplateDir();
|
|
2781
2839
|
function resolveTemplatePath(name) {
|
|
2782
|
-
return
|
|
2840
|
+
return join18(templateDir, name);
|
|
2783
2841
|
}
|
|
2784
2842
|
function readTemplate(name) {
|
|
2785
2843
|
return readFileSync15(resolveTemplatePath(name), "utf8");
|
|
@@ -2792,7 +2850,7 @@ function renderTemplate(name) {
|
|
|
2792
2850
|
// src/init/mergeClaudeSettings.ts
|
|
2793
2851
|
var CLAUDE_SETTINGS_LOCAL_REL = ".claude/settings.local.json";
|
|
2794
2852
|
function claudeSettingsLocalPath(repoRoot) {
|
|
2795
|
-
return
|
|
2853
|
+
return join19(repoRoot, ".claude", "settings.local.json");
|
|
2796
2854
|
}
|
|
2797
2855
|
function mergeClaudeLocalSettings(repoRoot) {
|
|
2798
2856
|
const settingsPath = claudeSettingsLocalPath(repoRoot);
|
|
@@ -2829,7 +2887,7 @@ var claudeCodeAdapter = {
|
|
|
2829
2887
|
available: true,
|
|
2830
2888
|
scaffoldPaths: [CLAUDE_SETTINGS_LOCAL_REL],
|
|
2831
2889
|
write(ctx) {
|
|
2832
|
-
mkdirSync7(
|
|
2890
|
+
mkdirSync7(join20(ctx.repoRoot, ".claude"), { recursive: true });
|
|
2833
2891
|
const { content, action } = mergeClaudeLocalSettings(ctx.repoRoot);
|
|
2834
2892
|
writeFileSync6(claudeSettingsLocalPath(ctx.repoRoot), content, "utf8");
|
|
2835
2893
|
ctx.report.files.push({ path: CLAUDE_SETTINGS_LOCAL_REL, action });
|
|
@@ -2838,11 +2896,11 @@ var claudeCodeAdapter = {
|
|
|
2838
2896
|
|
|
2839
2897
|
// src/init/assistants/codex.ts
|
|
2840
2898
|
import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
2841
|
-
import { join as
|
|
2899
|
+
import { join as join22 } from "path";
|
|
2842
2900
|
|
|
2843
2901
|
// src/init/mergeCodexConfig.ts
|
|
2844
2902
|
import { existsSync as existsSync15, readFileSync as readFileSync17 } from "fs";
|
|
2845
|
-
import { join as
|
|
2903
|
+
import { join as join21 } from "path";
|
|
2846
2904
|
var CODEX_CONFIG_REL = ".codex/config.toml";
|
|
2847
2905
|
var CODEX_HERMES_START_MARKER = "# >>> hermes-repo codex (do not edit this block manually)";
|
|
2848
2906
|
var CODEX_HERMES_END_MARKER = "# <<< hermes-repo codex";
|
|
@@ -2856,7 +2914,7 @@ function buildCodexHermesBlock() {
|
|
|
2856
2914
|
].join("\n");
|
|
2857
2915
|
}
|
|
2858
2916
|
function codexConfigPath(repoRoot) {
|
|
2859
|
-
return
|
|
2917
|
+
return join21(repoRoot, ".codex", "config.toml");
|
|
2860
2918
|
}
|
|
2861
2919
|
function spliceHermesBlock(existing, block) {
|
|
2862
2920
|
const startIdx = existing.indexOf(CODEX_HERMES_START_MARKER);
|
|
@@ -2903,7 +2961,7 @@ var codexAdapter = {
|
|
|
2903
2961
|
available: true,
|
|
2904
2962
|
scaffoldPaths: [CODEX_CONFIG_REL],
|
|
2905
2963
|
write(ctx) {
|
|
2906
|
-
mkdirSync8(
|
|
2964
|
+
mkdirSync8(join22(ctx.repoRoot, ".codex"), { recursive: true });
|
|
2907
2965
|
const { content, action } = mergeCodexConfig(ctx.repoRoot);
|
|
2908
2966
|
writeFileSync7(codexConfigPath(ctx.repoRoot), content, "utf8");
|
|
2909
2967
|
ctx.report.files.push({ path: CODEX_CONFIG_REL, action });
|
|
@@ -2912,14 +2970,14 @@ var codexAdapter = {
|
|
|
2912
2970
|
|
|
2913
2971
|
// src/init/assistants/codebuddy.ts
|
|
2914
2972
|
import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync8 } from "fs";
|
|
2915
|
-
import { join as
|
|
2973
|
+
import { join as join24 } from "path";
|
|
2916
2974
|
|
|
2917
2975
|
// src/init/mergeCodebuddySettings.ts
|
|
2918
2976
|
import { existsSync as existsSync16, readFileSync as readFileSync18 } from "fs";
|
|
2919
|
-
import { join as
|
|
2977
|
+
import { join as join23 } from "path";
|
|
2920
2978
|
var CODEBUDDY_SETTINGS_LOCAL_REL = ".codebuddy/settings.local.json";
|
|
2921
2979
|
function codebuddySettingsLocalPath(repoRoot) {
|
|
2922
|
-
return
|
|
2980
|
+
return join23(repoRoot, ".codebuddy", "settings.local.json");
|
|
2923
2981
|
}
|
|
2924
2982
|
function mergeCodebuddyLocalSettings(repoRoot) {
|
|
2925
2983
|
const settingsPath = codebuddySettingsLocalPath(repoRoot);
|
|
@@ -2958,7 +3016,7 @@ var codebuddyAdapter = {
|
|
|
2958
3016
|
available: true,
|
|
2959
3017
|
scaffoldPaths: [CODEBUDDY_SETTINGS_LOCAL_REL],
|
|
2960
3018
|
write(ctx) {
|
|
2961
|
-
mkdirSync9(
|
|
3019
|
+
mkdirSync9(join24(ctx.repoRoot, ".codebuddy"), { recursive: true });
|
|
2962
3020
|
const { content, action } = mergeCodebuddyLocalSettings(ctx.repoRoot);
|
|
2963
3021
|
writeFileSync8(codebuddySettingsLocalPath(ctx.repoRoot), content, "utf8");
|
|
2964
3022
|
ctx.report.files.push({ path: CODEBUDDY_SETTINGS_LOCAL_REL, action });
|
|
@@ -2967,14 +3025,14 @@ var codebuddyAdapter = {
|
|
|
2967
3025
|
|
|
2968
3026
|
// src/init/assistants/cursor.ts
|
|
2969
3027
|
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync9 } from "fs";
|
|
2970
|
-
import { join as
|
|
3028
|
+
import { join as join26 } from "path";
|
|
2971
3029
|
|
|
2972
3030
|
// src/init/mergeCursorHooks.ts
|
|
2973
3031
|
import { existsSync as existsSync17, readFileSync as readFileSync19 } from "fs";
|
|
2974
|
-
import { join as
|
|
3032
|
+
import { join as join25 } from "path";
|
|
2975
3033
|
var CURSOR_HOOKS_REL = ".cursor/hooks.json";
|
|
2976
3034
|
function cursorHooksPath(repoRoot) {
|
|
2977
|
-
return
|
|
3035
|
+
return join25(repoRoot, ".cursor", "hooks.json");
|
|
2978
3036
|
}
|
|
2979
3037
|
function mergeCursorHooks(repoRoot) {
|
|
2980
3038
|
const hooksPath = cursorHooksPath(repoRoot);
|
|
@@ -3012,7 +3070,7 @@ var cursorAdapter = {
|
|
|
3012
3070
|
available: true,
|
|
3013
3071
|
scaffoldPaths: [CURSOR_HOOKS_REL],
|
|
3014
3072
|
write(ctx) {
|
|
3015
|
-
mkdirSync10(
|
|
3073
|
+
mkdirSync10(join26(ctx.repoRoot, ".cursor"), { recursive: true });
|
|
3016
3074
|
const { content, action } = mergeCursorHooks(ctx.repoRoot);
|
|
3017
3075
|
writeFileSync9(cursorHooksPath(ctx.repoRoot), content, "utf8");
|
|
3018
3076
|
ctx.report.files.push({ path: CURSOR_HOOKS_REL, action });
|
|
@@ -3075,16 +3133,16 @@ function validateAssistantSelection(ids) {
|
|
|
3075
3133
|
|
|
3076
3134
|
// src/init/ensureDirs.ts
|
|
3077
3135
|
import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync10 } from "fs";
|
|
3078
|
-
import { join as
|
|
3136
|
+
import { join as join27 } from "path";
|
|
3079
3137
|
function ensureMemoryTree(repoRoot) {
|
|
3080
|
-
const memoryRoot =
|
|
3138
|
+
const memoryRoot = join27(repoRoot, MEMORY_DIR);
|
|
3081
3139
|
mkdirSync11(memoryRoot, { recursive: true });
|
|
3082
3140
|
for (const sub of MEMORY_SUBDIRS) {
|
|
3083
|
-
mkdirSync11(
|
|
3141
|
+
mkdirSync11(join27(memoryRoot, sub), { recursive: true });
|
|
3084
3142
|
}
|
|
3085
|
-
mkdirSync11(
|
|
3143
|
+
mkdirSync11(join27(repoRoot, ".claude"), { recursive: true });
|
|
3086
3144
|
for (const sub of GITKEEP_DIRS) {
|
|
3087
|
-
const keepPath =
|
|
3145
|
+
const keepPath = join27(memoryRoot, sub, ".gitkeep");
|
|
3088
3146
|
writeFileSync10(keepPath, "", { flag: "a" });
|
|
3089
3147
|
}
|
|
3090
3148
|
}
|
|
@@ -3113,12 +3171,12 @@ function mergeAssistants(repoRoot, selected) {
|
|
|
3113
3171
|
|
|
3114
3172
|
// src/init/mergeGitignore.ts
|
|
3115
3173
|
import { existsSync as existsSync19, readFileSync as readFileSync21, writeFileSync as writeFileSync11 } from "fs";
|
|
3116
|
-
import { join as
|
|
3174
|
+
import { join as join28 } from "path";
|
|
3117
3175
|
var START_MARKER = "# >>> hermes-repo memory (do not edit this block manually)";
|
|
3118
3176
|
var END_MARKER = "# <<< hermes-repo memory";
|
|
3119
3177
|
function mergeHermesGitignore(repoRoot) {
|
|
3120
3178
|
const block = readTemplate("gitignore-block.txt").trimEnd() + "\n";
|
|
3121
|
-
const gitignorePath =
|
|
3179
|
+
const gitignorePath = join28(repoRoot, ".gitignore");
|
|
3122
3180
|
const contentBefore = existsSync19(gitignorePath) ? readFileSync21(gitignorePath, "utf8") : "";
|
|
3123
3181
|
const warnBroadMemoryIgnore = contentBefore.length > 0 && !contentBefore.includes(START_MARKER) && /(^|\n)\.memory\/\s*$/m.test(contentBefore);
|
|
3124
3182
|
if (!existsSync19(gitignorePath)) {
|
|
@@ -3216,7 +3274,7 @@ function mergeConfigForInit(repoRoot, assistants) {
|
|
|
3216
3274
|
|
|
3217
3275
|
// src/init/mergeAgentsMd.ts
|
|
3218
3276
|
import { existsSync as existsSync21, readFileSync as readFileSync23, writeFileSync as writeFileSync12 } from "fs";
|
|
3219
|
-
import { join as
|
|
3277
|
+
import { join as join29 } from "path";
|
|
3220
3278
|
var HERMES_AGENTS_START_MARKER = "<!-- >>> hermes-repo agents (do not edit this block manually) -->";
|
|
3221
3279
|
var HERMES_AGENTS_END_MARKER = "<!-- <<< hermes-repo agents -->";
|
|
3222
3280
|
function buildHermesAgentsBlockBody() {
|
|
@@ -3272,7 +3330,7 @@ function spliceHermesBlock2(existing, block) {
|
|
|
3272
3330
|
`;
|
|
3273
3331
|
}
|
|
3274
3332
|
function mergeAgentsMd(repoRoot, force) {
|
|
3275
|
-
const agentsPath =
|
|
3333
|
+
const agentsPath = join29(repoRoot, "AGENTS.md");
|
|
3276
3334
|
const block = buildHermesAgentsMarkedBlock();
|
|
3277
3335
|
if (!existsSync21(agentsPath)) {
|
|
3278
3336
|
writeFileSync12(agentsPath, buildNewAgentsMd(), "utf8");
|