@riconext/hermes-repo 0.13.2 → 0.14.0
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 +13 -0
- package/README.md +23 -4
- package/dist/cli.js +212 -137
- package/dist/cli.js.map +1 -1
- package/package.json +8 -2
package/dist/cli.js
CHANGED
|
@@ -3735,27 +3735,101 @@ var claudeCodeAdapter = {
|
|
|
3735
3735
|
}
|
|
3736
3736
|
};
|
|
3737
3737
|
|
|
3738
|
-
// src/init/assistants/
|
|
3738
|
+
// src/init/assistants/codex.ts
|
|
3739
3739
|
import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync14 } from "fs";
|
|
3740
3740
|
import { join as join27 } from "path";
|
|
3741
3741
|
|
|
3742
|
-
// src/init/
|
|
3742
|
+
// src/init/mergeCodexConfig.ts
|
|
3743
3743
|
import { existsSync as existsSync24, readFileSync as readFileSync24 } from "fs";
|
|
3744
3744
|
import { join as join26 } from "path";
|
|
3745
|
+
var CODEX_CONFIG_REL = ".codex/config.toml";
|
|
3746
|
+
var CODEX_HERMES_START_MARKER = "# >>> hermes-repo codex (do not edit this block manually)";
|
|
3747
|
+
var CODEX_HERMES_END_MARKER = "# <<< hermes-repo codex";
|
|
3748
|
+
function buildCodexHermesBlock() {
|
|
3749
|
+
return [
|
|
3750
|
+
CODEX_HERMES_START_MARKER,
|
|
3751
|
+
"# Hermes uses AGENTS.md as the shared Codex project guidance entry.",
|
|
3752
|
+
"# Run `npx @riconext/hermes-repo search <keyword>` to inspect project memory.",
|
|
3753
|
+
'# Run `npx @riconext/hermes-repo ref --capture <path> --reason "..."` after using memory.',
|
|
3754
|
+
CODEX_HERMES_END_MARKER
|
|
3755
|
+
].join("\n");
|
|
3756
|
+
}
|
|
3757
|
+
function codexConfigPath(repoRoot) {
|
|
3758
|
+
return join26(repoRoot, ".codex", "config.toml");
|
|
3759
|
+
}
|
|
3760
|
+
function spliceHermesBlock(existing, block) {
|
|
3761
|
+
const startIdx = existing.indexOf(CODEX_HERMES_START_MARKER);
|
|
3762
|
+
const endIdx = existing.indexOf(CODEX_HERMES_END_MARKER);
|
|
3763
|
+
if (startIdx >= 0 && endIdx >= startIdx) {
|
|
3764
|
+
const before = existing.slice(0, startIdx).trimEnd();
|
|
3765
|
+
const after = existing.slice(endIdx + CODEX_HERMES_END_MARKER.length).trimStart();
|
|
3766
|
+
return `${before ? `${before}
|
|
3767
|
+
|
|
3768
|
+
` : ""}${block}${after ? `
|
|
3769
|
+
|
|
3770
|
+
${after}` : ""}
|
|
3771
|
+
`;
|
|
3772
|
+
}
|
|
3773
|
+
const trimmed = existing.trimEnd();
|
|
3774
|
+
return `${trimmed ? `${trimmed}
|
|
3775
|
+
|
|
3776
|
+
` : ""}${block}
|
|
3777
|
+
`;
|
|
3778
|
+
}
|
|
3779
|
+
function mergeCodexConfig(repoRoot) {
|
|
3780
|
+
const configPath = codexConfigPath(repoRoot);
|
|
3781
|
+
const existed = existsSync24(configPath);
|
|
3782
|
+
const block = buildCodexHermesBlock();
|
|
3783
|
+
if (!existed) {
|
|
3784
|
+
return {
|
|
3785
|
+
content: `${block}
|
|
3786
|
+
`,
|
|
3787
|
+
action: "created"
|
|
3788
|
+
};
|
|
3789
|
+
}
|
|
3790
|
+
const existing = readFileSync24(configPath, "utf8");
|
|
3791
|
+
const hasBlock = existing.includes(CODEX_HERMES_START_MARKER) && existing.includes(CODEX_HERMES_END_MARKER);
|
|
3792
|
+
return {
|
|
3793
|
+
content: spliceHermesBlock(existing, block),
|
|
3794
|
+
action: hasBlock ? "replaced" : "appended"
|
|
3795
|
+
};
|
|
3796
|
+
}
|
|
3797
|
+
|
|
3798
|
+
// src/init/assistants/codex.ts
|
|
3799
|
+
var codexAdapter = {
|
|
3800
|
+
id: "codex",
|
|
3801
|
+
label: "OpenAI Codex\uFF08AGENTS.md + .codex/config.toml\uFF09",
|
|
3802
|
+
available: true,
|
|
3803
|
+
scaffoldPaths: [CODEX_CONFIG_REL],
|
|
3804
|
+
write(ctx) {
|
|
3805
|
+
mkdirSync9(join27(ctx.repoRoot, ".codex"), { recursive: true });
|
|
3806
|
+
const { content, action } = mergeCodexConfig(ctx.repoRoot);
|
|
3807
|
+
writeFileSync14(codexConfigPath(ctx.repoRoot), content, "utf8");
|
|
3808
|
+
ctx.report.files.push({ path: CODEX_CONFIG_REL, action });
|
|
3809
|
+
}
|
|
3810
|
+
};
|
|
3811
|
+
|
|
3812
|
+
// src/init/assistants/codebuddy.ts
|
|
3813
|
+
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync15 } from "fs";
|
|
3814
|
+
import { join as join29 } from "path";
|
|
3815
|
+
|
|
3816
|
+
// src/init/mergeCodebuddySettings.ts
|
|
3817
|
+
import { existsSync as existsSync25, readFileSync as readFileSync25 } from "fs";
|
|
3818
|
+
import { join as join28 } from "path";
|
|
3745
3819
|
var CODEBUDDY_SETTINGS_LOCAL_REL = ".codebuddy/settings.local.json";
|
|
3746
3820
|
function codebuddySettingsLocalPath(repoRoot) {
|
|
3747
|
-
return
|
|
3821
|
+
return join28(repoRoot, ".codebuddy", "settings.local.json");
|
|
3748
3822
|
}
|
|
3749
3823
|
function mergeCodebuddyLocalSettings(repoRoot) {
|
|
3750
3824
|
const settingsPath = codebuddySettingsLocalPath(repoRoot);
|
|
3751
|
-
const existed =
|
|
3825
|
+
const existed = existsSync25(settingsPath);
|
|
3752
3826
|
const templateParsed = JSON.parse(
|
|
3753
3827
|
renderTemplate("hooks.codebuddy.json.tpl")
|
|
3754
3828
|
);
|
|
3755
3829
|
let existing = {};
|
|
3756
3830
|
if (existed) {
|
|
3757
3831
|
try {
|
|
3758
|
-
existing = JSON.parse(
|
|
3832
|
+
existing = JSON.parse(readFileSync25(settingsPath, "utf8"));
|
|
3759
3833
|
} catch {
|
|
3760
3834
|
existing = {};
|
|
3761
3835
|
}
|
|
@@ -3783,32 +3857,32 @@ var codebuddyAdapter = {
|
|
|
3783
3857
|
available: true,
|
|
3784
3858
|
scaffoldPaths: [CODEBUDDY_SETTINGS_LOCAL_REL],
|
|
3785
3859
|
write(ctx) {
|
|
3786
|
-
|
|
3860
|
+
mkdirSync10(join29(ctx.repoRoot, ".codebuddy"), { recursive: true });
|
|
3787
3861
|
const { content, action } = mergeCodebuddyLocalSettings(ctx.repoRoot);
|
|
3788
|
-
|
|
3862
|
+
writeFileSync15(codebuddySettingsLocalPath(ctx.repoRoot), content, "utf8");
|
|
3789
3863
|
ctx.report.files.push({ path: CODEBUDDY_SETTINGS_LOCAL_REL, action });
|
|
3790
3864
|
}
|
|
3791
3865
|
};
|
|
3792
3866
|
|
|
3793
3867
|
// src/init/assistants/cursor.ts
|
|
3794
|
-
import { mkdirSync as
|
|
3795
|
-
import { join as
|
|
3868
|
+
import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync16 } from "fs";
|
|
3869
|
+
import { join as join31 } from "path";
|
|
3796
3870
|
|
|
3797
3871
|
// src/init/mergeCursorHooks.ts
|
|
3798
|
-
import { existsSync as
|
|
3799
|
-
import { join as
|
|
3872
|
+
import { existsSync as existsSync26, readFileSync as readFileSync26 } from "fs";
|
|
3873
|
+
import { join as join30 } from "path";
|
|
3800
3874
|
var CURSOR_HOOKS_REL = ".cursor/hooks.json";
|
|
3801
3875
|
function cursorHooksPath(repoRoot) {
|
|
3802
|
-
return
|
|
3876
|
+
return join30(repoRoot, ".cursor", "hooks.json");
|
|
3803
3877
|
}
|
|
3804
3878
|
function mergeCursorHooks(repoRoot) {
|
|
3805
3879
|
const hooksPath = cursorHooksPath(repoRoot);
|
|
3806
|
-
const existed =
|
|
3880
|
+
const existed = existsSync26(hooksPath);
|
|
3807
3881
|
const templateParsed = JSON.parse(renderTemplate("hooks.cursor.json.tpl"));
|
|
3808
3882
|
let existing = {};
|
|
3809
3883
|
if (existed) {
|
|
3810
3884
|
try {
|
|
3811
|
-
existing = JSON.parse(
|
|
3885
|
+
existing = JSON.parse(readFileSync26(hooksPath, "utf8"));
|
|
3812
3886
|
} catch {
|
|
3813
3887
|
existing = {};
|
|
3814
3888
|
}
|
|
@@ -3837,9 +3911,9 @@ var cursorAdapter = {
|
|
|
3837
3911
|
available: true,
|
|
3838
3912
|
scaffoldPaths: [CURSOR_HOOKS_REL],
|
|
3839
3913
|
write(ctx) {
|
|
3840
|
-
|
|
3914
|
+
mkdirSync11(join31(ctx.repoRoot, ".cursor"), { recursive: true });
|
|
3841
3915
|
const { content, action } = mergeCursorHooks(ctx.repoRoot);
|
|
3842
|
-
|
|
3916
|
+
writeFileSync16(cursorHooksPath(ctx.repoRoot), content, "utf8");
|
|
3843
3917
|
ctx.report.files.push({ path: CURSOR_HOOKS_REL, action });
|
|
3844
3918
|
}
|
|
3845
3919
|
};
|
|
@@ -3849,7 +3923,8 @@ var DEFAULT_ASSISTANT_IDS = ["claude-code"];
|
|
|
3849
3923
|
var ALL_ADAPTERS = [
|
|
3850
3924
|
claudeCodeAdapter,
|
|
3851
3925
|
cursorAdapter,
|
|
3852
|
-
codebuddyAdapter
|
|
3926
|
+
codebuddyAdapter,
|
|
3927
|
+
codexAdapter
|
|
3853
3928
|
];
|
|
3854
3929
|
var ADAPTER_BY_ID = new Map(
|
|
3855
3930
|
ALL_ADAPTERS.map((a) => [a.id, a])
|
|
@@ -3898,30 +3973,30 @@ function validateAssistantSelection(ids) {
|
|
|
3898
3973
|
}
|
|
3899
3974
|
|
|
3900
3975
|
// src/init/ensureDirs.ts
|
|
3901
|
-
import { mkdirSync as
|
|
3902
|
-
import { join as
|
|
3976
|
+
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync17 } from "fs";
|
|
3977
|
+
import { join as join32 } from "path";
|
|
3903
3978
|
function ensureMemoryTree(repoRoot) {
|
|
3904
|
-
const memoryRoot =
|
|
3905
|
-
|
|
3979
|
+
const memoryRoot = join32(repoRoot, MEMORY_DIR);
|
|
3980
|
+
mkdirSync12(memoryRoot, { recursive: true });
|
|
3906
3981
|
for (const sub of MEMORY_SUBDIRS) {
|
|
3907
|
-
|
|
3982
|
+
mkdirSync12(join32(memoryRoot, sub), { recursive: true });
|
|
3908
3983
|
}
|
|
3909
|
-
|
|
3984
|
+
mkdirSync12(join32(repoRoot, ".claude"), { recursive: true });
|
|
3910
3985
|
for (const sub of GITKEEP_DIRS) {
|
|
3911
|
-
const keepPath =
|
|
3912
|
-
|
|
3986
|
+
const keepPath = join32(memoryRoot, sub, ".gitkeep");
|
|
3987
|
+
writeFileSync17(keepPath, "", { flag: "a" });
|
|
3913
3988
|
}
|
|
3914
3989
|
}
|
|
3915
3990
|
|
|
3916
3991
|
// src/init/mergeAssistants.ts
|
|
3917
|
-
import { existsSync as
|
|
3992
|
+
import { existsSync as existsSync27, readFileSync as readFileSync27 } from "fs";
|
|
3918
3993
|
function readExistingAssistants(repoRoot) {
|
|
3919
3994
|
const configPath = memoryPath(repoRoot, "config.json");
|
|
3920
|
-
if (!
|
|
3995
|
+
if (!existsSync27(configPath)) {
|
|
3921
3996
|
return [];
|
|
3922
3997
|
}
|
|
3923
3998
|
try {
|
|
3924
|
-
const config = JSON.parse(
|
|
3999
|
+
const config = JSON.parse(readFileSync27(configPath, "utf8"));
|
|
3925
4000
|
if (!Array.isArray(config.assistants)) {
|
|
3926
4001
|
return [];
|
|
3927
4002
|
}
|
|
@@ -3936,17 +4011,17 @@ function mergeAssistants(repoRoot, selected) {
|
|
|
3936
4011
|
}
|
|
3937
4012
|
|
|
3938
4013
|
// src/init/mergeGitignore.ts
|
|
3939
|
-
import { existsSync as
|
|
3940
|
-
import { join as
|
|
4014
|
+
import { existsSync as existsSync28, readFileSync as readFileSync28, writeFileSync as writeFileSync18 } from "fs";
|
|
4015
|
+
import { join as join33 } from "path";
|
|
3941
4016
|
var START_MARKER = "# >>> hermes-repo memory (do not edit this block manually)";
|
|
3942
4017
|
var END_MARKER = "# <<< hermes-repo memory";
|
|
3943
4018
|
function mergeHermesGitignore(repoRoot) {
|
|
3944
4019
|
const block = readTemplate("gitignore-block.txt").trimEnd() + "\n";
|
|
3945
|
-
const gitignorePath =
|
|
3946
|
-
const contentBefore =
|
|
4020
|
+
const gitignorePath = join33(repoRoot, ".gitignore");
|
|
4021
|
+
const contentBefore = existsSync28(gitignorePath) ? readFileSync28(gitignorePath, "utf8") : "";
|
|
3947
4022
|
const warnBroadMemoryIgnore = contentBefore.length > 0 && !contentBefore.includes(START_MARKER) && /(^|\n)\.memory\/\s*$/m.test(contentBefore);
|
|
3948
|
-
if (!
|
|
3949
|
-
|
|
4023
|
+
if (!existsSync28(gitignorePath)) {
|
|
4024
|
+
writeFileSync18(gitignorePath, `${block}
|
|
3950
4025
|
`, "utf8");
|
|
3951
4026
|
return { action: "created", warnBroadMemoryIgnore: false };
|
|
3952
4027
|
}
|
|
@@ -3956,7 +4031,7 @@ function mergeHermesGitignore(repoRoot) {
|
|
|
3956
4031
|
const before = contentBefore.slice(0, startIdx);
|
|
3957
4032
|
const after = contentBefore.slice(endIdx + END_MARKER.length);
|
|
3958
4033
|
const next = `${before}${block}${after}`.replace(/\n{3,}/g, "\n\n");
|
|
3959
|
-
|
|
4034
|
+
writeFileSync18(gitignorePath, next.endsWith("\n") ? next : `${next}
|
|
3960
4035
|
`, "utf8");
|
|
3961
4036
|
return { action: "replaced", warnBroadMemoryIgnore };
|
|
3962
4037
|
}
|
|
@@ -3964,11 +4039,11 @@ function mergeHermesGitignore(repoRoot) {
|
|
|
3964
4039
|
const before = contentBefore.slice(0, startIdx);
|
|
3965
4040
|
const next = `${before}${block}
|
|
3966
4041
|
`;
|
|
3967
|
-
|
|
4042
|
+
writeFileSync18(gitignorePath, next, "utf8");
|
|
3968
4043
|
return { action: "updated", warnBroadMemoryIgnore };
|
|
3969
4044
|
}
|
|
3970
4045
|
const separator = contentBefore.endsWith("\n") || contentBefore.length === 0 ? "\n" : "\n\n";
|
|
3971
|
-
|
|
4046
|
+
writeFileSync18(gitignorePath, `${contentBefore}${separator}${block}
|
|
3972
4047
|
`, "utf8");
|
|
3973
4048
|
return { action: "appended", warnBroadMemoryIgnore };
|
|
3974
4049
|
}
|
|
@@ -4039,8 +4114,8 @@ async function withSpinnerProgress(label, fn, formatDone, stream = process.stder
|
|
|
4039
4114
|
}
|
|
4040
4115
|
|
|
4041
4116
|
// src/coldstart/collectors/existingRules.ts
|
|
4042
|
-
import { existsSync as
|
|
4043
|
-
import { join as
|
|
4117
|
+
import { existsSync as existsSync29, readFileSync as readFileSync29, readdirSync as readdirSync9 } from "fs";
|
|
4118
|
+
import { join as join34 } from "path";
|
|
4044
4119
|
var MAX_EXCERPT = 3500;
|
|
4045
4120
|
var RULE_CANDIDATES = [
|
|
4046
4121
|
"AGENTS.md",
|
|
@@ -4048,12 +4123,12 @@ var RULE_CANDIDATES = [
|
|
|
4048
4123
|
".cursorrules"
|
|
4049
4124
|
];
|
|
4050
4125
|
function readExcerpt(repoRoot, rel) {
|
|
4051
|
-
const full =
|
|
4052
|
-
if (!
|
|
4126
|
+
const full = join34(repoRoot, rel);
|
|
4127
|
+
if (!existsSync29(full)) {
|
|
4053
4128
|
return null;
|
|
4054
4129
|
}
|
|
4055
4130
|
try {
|
|
4056
|
-
const raw =
|
|
4131
|
+
const raw = readFileSync29(full, "utf8");
|
|
4057
4132
|
return raw.length > MAX_EXCERPT ? `${raw.slice(0, MAX_EXCERPT)}
|
|
4058
4133
|
...(truncated)` : raw;
|
|
4059
4134
|
} catch {
|
|
@@ -4061,8 +4136,8 @@ function readExcerpt(repoRoot, rel) {
|
|
|
4061
4136
|
}
|
|
4062
4137
|
}
|
|
4063
4138
|
function collectCursorRules(repoRoot) {
|
|
4064
|
-
const dir =
|
|
4065
|
-
if (!
|
|
4139
|
+
const dir = join34(repoRoot, ".cursor", "rules");
|
|
4140
|
+
if (!existsSync29(dir)) {
|
|
4066
4141
|
return [];
|
|
4067
4142
|
}
|
|
4068
4143
|
const out = [];
|
|
@@ -4113,8 +4188,8 @@ function collectGitLog(repoRoot, limit = 50) {
|
|
|
4113
4188
|
}
|
|
4114
4189
|
|
|
4115
4190
|
// src/coldstart/collectors/packageJson.ts
|
|
4116
|
-
import { existsSync as
|
|
4117
|
-
import { join as
|
|
4191
|
+
import { existsSync as existsSync30, readFileSync as readFileSync30 } from "fs";
|
|
4192
|
+
import { join as join35 } from "path";
|
|
4118
4193
|
var STACK_HINTS = {
|
|
4119
4194
|
react: "react",
|
|
4120
4195
|
vue: "vue",
|
|
@@ -4147,12 +4222,12 @@ function inferStackTags(deps) {
|
|
|
4147
4222
|
return [...tags];
|
|
4148
4223
|
}
|
|
4149
4224
|
function collectPackageJson(repoRoot) {
|
|
4150
|
-
const path =
|
|
4151
|
-
if (!
|
|
4225
|
+
const path = join35(repoRoot, "package.json");
|
|
4226
|
+
if (!existsSync30(path)) {
|
|
4152
4227
|
return null;
|
|
4153
4228
|
}
|
|
4154
4229
|
try {
|
|
4155
|
-
const raw = JSON.parse(
|
|
4230
|
+
const raw = JSON.parse(readFileSync30(path, "utf8"));
|
|
4156
4231
|
return {
|
|
4157
4232
|
name: raw.name,
|
|
4158
4233
|
dependencies: depKeys(raw.dependencies),
|
|
@@ -4164,8 +4239,8 @@ function collectPackageJson(repoRoot) {
|
|
|
4164
4239
|
}
|
|
4165
4240
|
|
|
4166
4241
|
// src/coldstart/collectors/repoSignals.ts
|
|
4167
|
-
import { existsSync as
|
|
4168
|
-
import { join as
|
|
4242
|
+
import { existsSync as existsSync31, readdirSync as readdirSync10 } from "fs";
|
|
4243
|
+
import { join as join36 } from "path";
|
|
4169
4244
|
var SIGNAL_FILES = [
|
|
4170
4245
|
"Dockerfile",
|
|
4171
4246
|
"Makefile",
|
|
@@ -4177,12 +4252,12 @@ var SIGNAL_FILES = [
|
|
|
4177
4252
|
function collectRepoSignals(repoRoot) {
|
|
4178
4253
|
const signals = [];
|
|
4179
4254
|
for (const rel of SIGNAL_FILES) {
|
|
4180
|
-
const full =
|
|
4181
|
-
if (
|
|
4255
|
+
const full = join36(repoRoot, rel);
|
|
4256
|
+
if (existsSync31(full)) {
|
|
4182
4257
|
signals.push(rel);
|
|
4183
4258
|
}
|
|
4184
4259
|
}
|
|
4185
|
-
if (
|
|
4260
|
+
if (existsSync31(join36(repoRoot, ".gitignore"))) {
|
|
4186
4261
|
signals.push(".gitignore");
|
|
4187
4262
|
}
|
|
4188
4263
|
try {
|
|
@@ -4327,7 +4402,7 @@ function runProjectScan(repoRoot) {
|
|
|
4327
4402
|
|
|
4328
4403
|
// src/init/prompts.ts
|
|
4329
4404
|
import { checkbox, confirm, input, password } from "@inquirer/prompts";
|
|
4330
|
-
import { existsSync as
|
|
4405
|
+
import { existsSync as existsSync32, readFileSync as readFileSync31 } from "fs";
|
|
4331
4406
|
import { resolve as resolve6 } from "path";
|
|
4332
4407
|
|
|
4333
4408
|
// src/coldstart/countCaptures.ts
|
|
@@ -4338,11 +4413,11 @@ function countExistingCaptures(repoRoot) {
|
|
|
4338
4413
|
// src/init/prompts.ts
|
|
4339
4414
|
function isInitialized(targetDir) {
|
|
4340
4415
|
const configPath = memoryPath(targetDir, "config.json");
|
|
4341
|
-
if (!
|
|
4416
|
+
if (!existsSync32(configPath)) {
|
|
4342
4417
|
return false;
|
|
4343
4418
|
}
|
|
4344
4419
|
try {
|
|
4345
|
-
const config = JSON.parse(
|
|
4420
|
+
const config = JSON.parse(readFileSync31(configPath, "utf8"));
|
|
4346
4421
|
return config.version === 1;
|
|
4347
4422
|
} catch {
|
|
4348
4423
|
return false;
|
|
@@ -4441,7 +4516,7 @@ async function promptLlmFields(defaults = {}, options = {}) {
|
|
|
4441
4516
|
}
|
|
4442
4517
|
async function gatherLlmInitInput(targetDir) {
|
|
4443
4518
|
const llmPath = memoryPath(targetDir, "llm.json");
|
|
4444
|
-
if (
|
|
4519
|
+
if (existsSync32(llmPath)) {
|
|
4445
4520
|
const overwrite = await confirm({
|
|
4446
4521
|
message: "\u68C0\u6D4B\u5230\u5DF2\u6709 .memory/llm.json\uFF0C\u662F\u5426\u8986\u76D6\u5E76\u91CD\u65B0\u914D\u7F6E\uFF1F",
|
|
4447
4522
|
default: false
|
|
@@ -4472,17 +4547,17 @@ async function gatherLlmInitInput(targetDir) {
|
|
|
4472
4547
|
}
|
|
4473
4548
|
|
|
4474
4549
|
// src/init/writeScaffoldFile.ts
|
|
4475
|
-
import { copyFileSync, writeFileSync as
|
|
4550
|
+
import { copyFileSync, writeFileSync as writeFileSync22 } from "fs";
|
|
4476
4551
|
|
|
4477
4552
|
// src/init/mergeConfig.ts
|
|
4478
|
-
import { existsSync as
|
|
4553
|
+
import { existsSync as existsSync33, readFileSync as readFileSync32 } from "fs";
|
|
4479
4554
|
function mergeConfigForInit(repoRoot, assistants) {
|
|
4480
4555
|
const configPath = memoryPath(repoRoot, "config.json");
|
|
4481
|
-
const existed =
|
|
4556
|
+
const existed = existsSync33(configPath);
|
|
4482
4557
|
let existing = {};
|
|
4483
4558
|
if (existed) {
|
|
4484
4559
|
try {
|
|
4485
|
-
existing = JSON.parse(
|
|
4560
|
+
existing = JSON.parse(readFileSync32(configPath, "utf8"));
|
|
4486
4561
|
} catch {
|
|
4487
4562
|
existing = {};
|
|
4488
4563
|
}
|
|
@@ -4506,8 +4581,8 @@ function mergeConfigForInit(repoRoot, assistants) {
|
|
|
4506
4581
|
}
|
|
4507
4582
|
|
|
4508
4583
|
// src/init/mergeAgentsMd.ts
|
|
4509
|
-
import { existsSync as
|
|
4510
|
-
import { join as
|
|
4584
|
+
import { existsSync as existsSync34, readFileSync as readFileSync33, writeFileSync as writeFileSync19 } from "fs";
|
|
4585
|
+
import { join as join37 } from "path";
|
|
4511
4586
|
var HERMES_AGENTS_START_MARKER = "<!-- >>> hermes-repo agents (do not edit this block manually) -->";
|
|
4512
4587
|
var HERMES_AGENTS_END_MARKER = "<!-- <<< hermes-repo agents -->";
|
|
4513
4588
|
function buildHermesAgentsBlockBody() {
|
|
@@ -4544,7 +4619,7 @@ function withGapBeforeHermesBlock(prefix) {
|
|
|
4544
4619
|
}
|
|
4545
4620
|
return `${trimmed}${GAP_BEFORE_HERMES_BLOCK}`;
|
|
4546
4621
|
}
|
|
4547
|
-
function
|
|
4622
|
+
function spliceHermesBlock2(existing, block) {
|
|
4548
4623
|
const startIdx = existing.indexOf(HERMES_AGENTS_START_MARKER);
|
|
4549
4624
|
const endIdx = existing.indexOf(HERMES_AGENTS_END_MARKER);
|
|
4550
4625
|
if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
|
|
@@ -4563,32 +4638,32 @@ function spliceHermesBlock(existing, block) {
|
|
|
4563
4638
|
`;
|
|
4564
4639
|
}
|
|
4565
4640
|
function mergeAgentsMd(repoRoot, force) {
|
|
4566
|
-
const agentsPath =
|
|
4641
|
+
const agentsPath = join37(repoRoot, "AGENTS.md");
|
|
4567
4642
|
const block = buildHermesAgentsMarkedBlock();
|
|
4568
|
-
if (!
|
|
4569
|
-
|
|
4643
|
+
if (!existsSync34(agentsPath)) {
|
|
4644
|
+
writeFileSync19(agentsPath, buildNewAgentsMd(), "utf8");
|
|
4570
4645
|
return "created";
|
|
4571
4646
|
}
|
|
4572
|
-
const content =
|
|
4647
|
+
const content = readFileSync33(agentsPath, "utf8");
|
|
4573
4648
|
if (agentsMdHasHermesBlock(content)) {
|
|
4574
4649
|
if (!force) {
|
|
4575
4650
|
return "skipped";
|
|
4576
4651
|
}
|
|
4577
|
-
|
|
4652
|
+
writeFileSync19(agentsPath, spliceHermesBlock2(content, block), "utf8");
|
|
4578
4653
|
return "replaced";
|
|
4579
4654
|
}
|
|
4580
4655
|
if (agentsMdHasLegacyHermesContent(content)) {
|
|
4581
4656
|
return "skipped";
|
|
4582
4657
|
}
|
|
4583
|
-
|
|
4658
|
+
writeFileSync19(agentsPath, spliceHermesBlock2(content, block), "utf8");
|
|
4584
4659
|
return "appended";
|
|
4585
4660
|
}
|
|
4586
4661
|
|
|
4587
4662
|
// src/init/mergeLlmConfig.ts
|
|
4588
|
-
import { existsSync as
|
|
4663
|
+
import { existsSync as existsSync35, writeFileSync as writeFileSync20 } from "fs";
|
|
4589
4664
|
function mergeLlmConfigForInit(repoRoot, input2) {
|
|
4590
4665
|
const llmPath = memoryPath(repoRoot, "llm.json");
|
|
4591
|
-
const existed =
|
|
4666
|
+
const existed = existsSync35(llmPath);
|
|
4592
4667
|
let existing = {};
|
|
4593
4668
|
if (existed) {
|
|
4594
4669
|
try {
|
|
@@ -4617,14 +4692,14 @@ function mergeLlmConfigForInit(repoRoot, input2) {
|
|
|
4617
4692
|
}
|
|
4618
4693
|
function writeLlmJson(repoRoot, input2) {
|
|
4619
4694
|
const { content, action } = mergeLlmConfigForInit(repoRoot, input2);
|
|
4620
|
-
|
|
4695
|
+
writeFileSync20(memoryPath(repoRoot, "llm.json"), content, "utf8");
|
|
4621
4696
|
return action;
|
|
4622
4697
|
}
|
|
4623
4698
|
|
|
4624
4699
|
// src/init/scaffoldWrite.ts
|
|
4625
|
-
import { existsSync as
|
|
4700
|
+
import { existsSync as existsSync36, writeFileSync as writeFileSync21 } from "fs";
|
|
4626
4701
|
function shouldWriteFile(absolutePath, force) {
|
|
4627
|
-
if (!
|
|
4702
|
+
if (!existsSync36(absolutePath)) {
|
|
4628
4703
|
return { write: true, action: "created" };
|
|
4629
4704
|
}
|
|
4630
4705
|
if (force) {
|
|
@@ -4638,7 +4713,7 @@ function writeIfAllowed(report, absolutePath, relativePath, content, force) {
|
|
|
4638
4713
|
report.files.push({ path: relativePath, action });
|
|
4639
4714
|
return;
|
|
4640
4715
|
}
|
|
4641
|
-
|
|
4716
|
+
writeFileSync21(absolutePath, content, "utf8");
|
|
4642
4717
|
report.files.push({ path: relativePath, action });
|
|
4643
4718
|
}
|
|
4644
4719
|
|
|
@@ -4646,7 +4721,7 @@ function writeIfAllowed(report, absolutePath, relativePath, content, force) {
|
|
|
4646
4721
|
function writeConfigJson(report, repoRoot, assistants) {
|
|
4647
4722
|
const { content, action } = mergeConfigForInit(repoRoot, assistants);
|
|
4648
4723
|
const absolutePath = memoryPath(repoRoot, "config.json");
|
|
4649
|
-
|
|
4724
|
+
writeFileSync22(absolutePath, content, "utf8");
|
|
4650
4725
|
report.files.push({ path: ".memory/config.json", action });
|
|
4651
4726
|
}
|
|
4652
4727
|
function copyTemplateIfAllowed(report, templateName, destAbsolute, relativePath, force) {
|
|
@@ -4933,10 +5008,10 @@ async function runInitCommand(opts) {
|
|
|
4933
5008
|
}
|
|
4934
5009
|
|
|
4935
5010
|
// src/feedback/writeRef.ts
|
|
4936
|
-
import { existsSync as
|
|
4937
|
-
import { join as
|
|
5011
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync13, writeFileSync as writeFileSync23 } from "fs";
|
|
5012
|
+
import { join as join38 } from "path";
|
|
4938
5013
|
function targetExists(repoRoot, target) {
|
|
4939
|
-
return
|
|
5014
|
+
return existsSync37(join38(repoRoot, ".memory", target));
|
|
4940
5015
|
}
|
|
4941
5016
|
function writeRef(opts) {
|
|
4942
5017
|
const { repoRoot, reason, session } = opts;
|
|
@@ -4958,16 +5033,16 @@ function writeRef(opts) {
|
|
|
4958
5033
|
date,
|
|
4959
5034
|
...session ? { session } : {}
|
|
4960
5035
|
};
|
|
4961
|
-
|
|
5036
|
+
mkdirSync13(refsDir(repoRoot), { recursive: true });
|
|
4962
5037
|
const filePath = refFilePath(repoRoot, target, date);
|
|
4963
5038
|
const base = filePath.replace(/\.json$/, "");
|
|
4964
5039
|
let finalPath = `${filePath}`;
|
|
4965
5040
|
let n = 0;
|
|
4966
|
-
while (
|
|
5041
|
+
while (existsSync37(finalPath)) {
|
|
4967
5042
|
n++;
|
|
4968
5043
|
finalPath = `${base}-${n}.json`;
|
|
4969
5044
|
}
|
|
4970
|
-
|
|
5045
|
+
writeFileSync23(finalPath, `${JSON.stringify(record, null, 2)}
|
|
4971
5046
|
`, "utf8");
|
|
4972
5047
|
const file = finalPath.split("/refs/").pop() ?? finalPath;
|
|
4973
5048
|
return { target, file: `refs/${file}` };
|
|
@@ -5007,15 +5082,15 @@ function runRefCommand(opts) {
|
|
|
5007
5082
|
}
|
|
5008
5083
|
|
|
5009
5084
|
// src/search/runSearch.ts
|
|
5010
|
-
import { existsSync as
|
|
5011
|
-
import { join as
|
|
5085
|
+
import { existsSync as existsSync38, readdirSync as readdirSync11, readFileSync as readFileSync35 } from "fs";
|
|
5086
|
+
import { join as join39 } from "path";
|
|
5012
5087
|
function walkMdFiles(dir) {
|
|
5013
|
-
if (!
|
|
5088
|
+
if (!existsSync38(dir)) {
|
|
5014
5089
|
return [];
|
|
5015
5090
|
}
|
|
5016
5091
|
const out = [];
|
|
5017
5092
|
for (const name of readdirSync11(dir)) {
|
|
5018
|
-
const full =
|
|
5093
|
+
const full = join39(dir, name);
|
|
5019
5094
|
if (name.endsWith(".md")) {
|
|
5020
5095
|
out.push(full);
|
|
5021
5096
|
} else if (!name.startsWith(".")) {
|
|
@@ -5024,7 +5099,7 @@ function walkMdFiles(dir) {
|
|
|
5024
5099
|
if (Array.isArray(st)) {
|
|
5025
5100
|
for (const child of readdirSync11(full)) {
|
|
5026
5101
|
if (child.endsWith(".md")) {
|
|
5027
|
-
out.push(
|
|
5102
|
+
out.push(join39(full, child));
|
|
5028
5103
|
}
|
|
5029
5104
|
}
|
|
5030
5105
|
}
|
|
@@ -5036,13 +5111,13 @@ function walkMdFiles(dir) {
|
|
|
5036
5111
|
}
|
|
5037
5112
|
function listSkillMd(repoRoot) {
|
|
5038
5113
|
const skillsDir = memoryPath(repoRoot, "skills");
|
|
5039
|
-
if (!
|
|
5114
|
+
if (!existsSync38(skillsDir)) {
|
|
5040
5115
|
return [];
|
|
5041
5116
|
}
|
|
5042
5117
|
const out = [];
|
|
5043
5118
|
for (const slug of readdirSync11(skillsDir)) {
|
|
5044
|
-
const f =
|
|
5045
|
-
if (
|
|
5119
|
+
const f = join39(skillsDir, slug, "SKILL.md");
|
|
5120
|
+
if (existsSync38(f)) {
|
|
5046
5121
|
out.push(f);
|
|
5047
5122
|
}
|
|
5048
5123
|
}
|
|
@@ -5050,7 +5125,7 @@ function listSkillMd(repoRoot) {
|
|
|
5050
5125
|
}
|
|
5051
5126
|
function summaryFromFile(absPath, relFromMemory) {
|
|
5052
5127
|
try {
|
|
5053
|
-
const content =
|
|
5128
|
+
const content = readFileSync35(absPath, "utf8");
|
|
5054
5129
|
if (relFromMemory.startsWith("captures/")) {
|
|
5055
5130
|
const parsed = parseCaptureMarkdown(content, relFromMemory, absPath);
|
|
5056
5131
|
if (parsed) {
|
|
@@ -5073,10 +5148,10 @@ function runSearch(opts) {
|
|
|
5073
5148
|
const memRoot = memoryPath(opts.repoRoot);
|
|
5074
5149
|
const captureTypes = opts.type ? [opts.type] : ["semantic", "episodic", "procedural"];
|
|
5075
5150
|
for (const t of captureTypes) {
|
|
5076
|
-
const dir =
|
|
5151
|
+
const dir = join39(memRoot, "captures", t);
|
|
5077
5152
|
for (const abs of walkMdFiles(dir)) {
|
|
5078
5153
|
const rel = abs.replace(memRoot + "/", "").replace(/\\/g, "/");
|
|
5079
|
-
const content =
|
|
5154
|
+
const content = readFileSync35(abs, "utf8").toLowerCase();
|
|
5080
5155
|
if (content.includes(kw)) {
|
|
5081
5156
|
hits.push({
|
|
5082
5157
|
path: rel,
|
|
@@ -5088,10 +5163,10 @@ function runSearch(opts) {
|
|
|
5088
5163
|
}
|
|
5089
5164
|
}
|
|
5090
5165
|
}
|
|
5091
|
-
const topicsDir =
|
|
5166
|
+
const topicsDir = join39(memRoot, "topics");
|
|
5092
5167
|
for (const abs of walkMdFiles(topicsDir)) {
|
|
5093
5168
|
const rel = abs.replace(memRoot + "/", "").replace(/\\/g, "/");
|
|
5094
|
-
if (
|
|
5169
|
+
if (readFileSync35(abs, "utf8").toLowerCase().includes(kw)) {
|
|
5095
5170
|
hits.push({ path: rel, summary: summaryFromFile(abs, rel) });
|
|
5096
5171
|
}
|
|
5097
5172
|
if (hits.length >= limit) {
|
|
@@ -5100,7 +5175,7 @@ function runSearch(opts) {
|
|
|
5100
5175
|
}
|
|
5101
5176
|
for (const abs of listSkillMd(opts.repoRoot)) {
|
|
5102
5177
|
const rel = abs.replace(memRoot + "/", "").replace(/\\/g, "/");
|
|
5103
|
-
if (
|
|
5178
|
+
if (readFileSync35(abs, "utf8").toLowerCase().includes(kw)) {
|
|
5104
5179
|
hits.push({ path: rel, summary: summaryFromFile(abs, rel) });
|
|
5105
5180
|
}
|
|
5106
5181
|
if (hits.length >= limit) {
|
|
@@ -5153,7 +5228,7 @@ function runSearchCommand(opts) {
|
|
|
5153
5228
|
}
|
|
5154
5229
|
|
|
5155
5230
|
// src/stats/runStats.ts
|
|
5156
|
-
import { existsSync as
|
|
5231
|
+
import { existsSync as existsSync39, statSync as statSync6 } from "fs";
|
|
5157
5232
|
function collectStats(repoRoot, nowMs = Date.now()) {
|
|
5158
5233
|
const all = listAllCaptures(repoRoot);
|
|
5159
5234
|
const active = filterActiveCaptures(all);
|
|
@@ -5183,7 +5258,7 @@ function collectStats(repoRoot, nowMs = Date.now()) {
|
|
|
5183
5258
|
}
|
|
5184
5259
|
}
|
|
5185
5260
|
const memoryFile = memoryPath(repoRoot, "MEMORY.md");
|
|
5186
|
-
const memoryBytes =
|
|
5261
|
+
const memoryBytes = existsSync39(memoryFile) ? statSync6(memoryFile).size : 0;
|
|
5187
5262
|
const allSkills = listSkillIndex(repoRoot);
|
|
5188
5263
|
const skillUsage = readSkillUsage(repoRoot);
|
|
5189
5264
|
const inMemory = filterSkillIndexForMemory(allSkills, skillUsage, repoRoot, nowMs);
|
|
@@ -5250,11 +5325,11 @@ function runStatsCommand(opts) {
|
|
|
5250
5325
|
}
|
|
5251
5326
|
|
|
5252
5327
|
// src/promote/runPromote.ts
|
|
5253
|
-
import { existsSync as
|
|
5328
|
+
import { existsSync as existsSync45, mkdirSync as mkdirSync15, writeFileSync as writeFileSync25 } from "fs";
|
|
5254
5329
|
import { resolve as resolve8 } from "path";
|
|
5255
5330
|
|
|
5256
5331
|
// src/promote/buildTopicDraft.ts
|
|
5257
|
-
import { existsSync as
|
|
5332
|
+
import { existsSync as existsSync40, readFileSync as readFileSync36 } from "fs";
|
|
5258
5333
|
function ruleTopicDraftBody(tag, captures, existing) {
|
|
5259
5334
|
const lines = captures.map(
|
|
5260
5335
|
(c) => `- [${c.date}] [${c.type}] ${c.summary.slice(0, 120)} (${c.path}) [\u664B\u5347\u5019\u9009]`
|
|
@@ -5281,9 +5356,9 @@ async function buildTopicDraftBody(repoRoot, captures, llm) {
|
|
|
5281
5356
|
const slug = tagToSlug(tag);
|
|
5282
5357
|
const abs = memoryPath(repoRoot, "topics", `${slug}.md`);
|
|
5283
5358
|
let existing = "";
|
|
5284
|
-
if (
|
|
5359
|
+
if (existsSync40(abs)) {
|
|
5285
5360
|
try {
|
|
5286
|
-
existing =
|
|
5361
|
+
existing = readFileSync36(abs, "utf8");
|
|
5287
5362
|
} catch {
|
|
5288
5363
|
existing = "";
|
|
5289
5364
|
}
|
|
@@ -5308,7 +5383,7 @@ ${c.findings.slice(0, 300)}`
|
|
|
5308
5383
|
}
|
|
5309
5384
|
|
|
5310
5385
|
// src/promote/detectTopicConflict.ts
|
|
5311
|
-
import { existsSync as
|
|
5386
|
+
import { existsSync as existsSync41, readFileSync as readFileSync37 } from "fs";
|
|
5312
5387
|
var MUTEX_PAIRS2 = [
|
|
5313
5388
|
["localstorage", "httponly"],
|
|
5314
5389
|
["local storage", "httponly"],
|
|
@@ -5338,12 +5413,12 @@ function detectTopicConflict(repoRoot, capture) {
|
|
|
5338
5413
|
const slug = tagToSlug(tag);
|
|
5339
5414
|
const topicPath = memoryPath(repoRoot, "topics", `${slug}.md`);
|
|
5340
5415
|
const relTopic = `topics/${slug}.md`;
|
|
5341
|
-
if (!
|
|
5416
|
+
if (!existsSync41(topicPath)) {
|
|
5342
5417
|
return { hasConflict: false, reason: "none" };
|
|
5343
5418
|
}
|
|
5344
5419
|
let existing = "";
|
|
5345
5420
|
try {
|
|
5346
|
-
existing =
|
|
5421
|
+
existing = readFileSync37(topicPath, "utf8");
|
|
5347
5422
|
} catch {
|
|
5348
5423
|
return { hasConflict: false, reason: "none" };
|
|
5349
5424
|
}
|
|
@@ -5509,17 +5584,17 @@ async function buildMergedStagingDrafts(repoRoot, analyses, llm) {
|
|
|
5509
5584
|
|
|
5510
5585
|
// src/promote/applyDecisions.ts
|
|
5511
5586
|
import {
|
|
5512
|
-
existsSync as
|
|
5513
|
-
mkdirSync as
|
|
5587
|
+
existsSync as existsSync42,
|
|
5588
|
+
mkdirSync as mkdirSync14,
|
|
5514
5589
|
readdirSync as readdirSync12,
|
|
5515
|
-
readFileSync as
|
|
5590
|
+
readFileSync as readFileSync38,
|
|
5516
5591
|
unlinkSync as unlinkSync3,
|
|
5517
|
-
writeFileSync as
|
|
5592
|
+
writeFileSync as writeFileSync24
|
|
5518
5593
|
} from "fs";
|
|
5519
|
-
import { join as
|
|
5594
|
+
import { join as join41 } from "path";
|
|
5520
5595
|
|
|
5521
5596
|
// src/promote/paths.ts
|
|
5522
|
-
import { join as
|
|
5597
|
+
import { join as join40 } from "path";
|
|
5523
5598
|
function promoteDir(repoRoot) {
|
|
5524
5599
|
return memoryPath(repoRoot, "promote");
|
|
5525
5600
|
}
|
|
@@ -5537,7 +5612,7 @@ function resolvePromoteTemplatePath(repoRoot) {
|
|
|
5537
5612
|
return inMemory;
|
|
5538
5613
|
}
|
|
5539
5614
|
function stagingTopicPath(repoRoot, slug) {
|
|
5540
|
-
return
|
|
5615
|
+
return join40(promoteStagingTopicsDir(repoRoot), `${slug}.md`);
|
|
5541
5616
|
}
|
|
5542
5617
|
|
|
5543
5618
|
// src/promote/applyDecisions.ts
|
|
@@ -5573,17 +5648,17 @@ function buildManifestTemplate(capturePaths, dateIso) {
|
|
|
5573
5648
|
}
|
|
5574
5649
|
function removePromoteMarker(repoRoot, capturePath) {
|
|
5575
5650
|
const marker = promoteMarkerPath(repoRoot, capturePath);
|
|
5576
|
-
if (
|
|
5651
|
+
if (existsSync42(marker)) {
|
|
5577
5652
|
unlinkSync3(marker);
|
|
5578
5653
|
}
|
|
5579
5654
|
}
|
|
5580
5655
|
function annotateReject(repoRoot, capturePath, note) {
|
|
5581
|
-
const abs =
|
|
5582
|
-
if (!
|
|
5656
|
+
const abs = join41(repoRoot, ".memory", capturePath);
|
|
5657
|
+
if (!existsSync42(abs)) {
|
|
5583
5658
|
return;
|
|
5584
5659
|
}
|
|
5585
5660
|
try {
|
|
5586
|
-
let content =
|
|
5661
|
+
let content = readFileSync38(abs, "utf8");
|
|
5587
5662
|
const fields = {
|
|
5588
5663
|
promote_rejected_at: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)
|
|
5589
5664
|
};
|
|
@@ -5591,22 +5666,22 @@ function annotateReject(repoRoot, capturePath, note) {
|
|
|
5591
5666
|
fields.promote_note = note.trim().slice(0, 200);
|
|
5592
5667
|
}
|
|
5593
5668
|
content = setFrontmatterScalars(content, fields);
|
|
5594
|
-
|
|
5669
|
+
writeFileSync24(abs, content, "utf8");
|
|
5595
5670
|
} catch {
|
|
5596
5671
|
}
|
|
5597
5672
|
}
|
|
5598
5673
|
function mergeTopicFromStaging(repoRoot, slug, dryRun) {
|
|
5599
5674
|
const staging = stagingTopicPath(repoRoot, slug);
|
|
5600
|
-
if (!
|
|
5675
|
+
if (!existsSync42(staging)) {
|
|
5601
5676
|
return null;
|
|
5602
5677
|
}
|
|
5603
|
-
const draft =
|
|
5678
|
+
const draft = readFileSync38(staging, "utf8");
|
|
5604
5679
|
const dest = memoryPath(repoRoot, "topics", `${slug}.md`);
|
|
5605
5680
|
if (dryRun) {
|
|
5606
5681
|
return `topics/${slug}.md`;
|
|
5607
5682
|
}
|
|
5608
|
-
|
|
5609
|
-
|
|
5683
|
+
mkdirSync14(memoryPath(repoRoot, "topics"), { recursive: true });
|
|
5684
|
+
writeFileSync24(dest, draft.endsWith("\n") ? draft : `${draft}
|
|
5610
5685
|
`, "utf8");
|
|
5611
5686
|
return `topics/${slug}.md`;
|
|
5612
5687
|
}
|
|
@@ -5642,7 +5717,7 @@ function applyDecisions(repoRoot, manifest, opts) {
|
|
|
5642
5717
|
}
|
|
5643
5718
|
if (slugsToMerge.size === 0 && result.approved.length > 0) {
|
|
5644
5719
|
const stagingDir = promoteStagingTopicsDir(repoRoot);
|
|
5645
|
-
if (
|
|
5720
|
+
if (existsSync42(stagingDir)) {
|
|
5646
5721
|
for (const name of readdirSync12(stagingDir)) {
|
|
5647
5722
|
if (name.endsWith(".md")) {
|
|
5648
5723
|
slugsToMerge.add(name.replace(/\.md$/, ""));
|
|
@@ -5659,21 +5734,21 @@ function applyDecisions(repoRoot, manifest, opts) {
|
|
|
5659
5734
|
return result;
|
|
5660
5735
|
}
|
|
5661
5736
|
function readManifestFile(manifestPath) {
|
|
5662
|
-
const raw =
|
|
5737
|
+
const raw = readFileSync38(manifestPath, "utf8");
|
|
5663
5738
|
return parseManifestJson(raw);
|
|
5664
5739
|
}
|
|
5665
5740
|
function writeManifestTemplate(repoRoot, capturePaths) {
|
|
5666
5741
|
const dateIso = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
5667
5742
|
const manifest = buildManifestTemplate(capturePaths, dateIso);
|
|
5668
5743
|
const path = decisionsTemplatePath(repoRoot);
|
|
5669
|
-
|
|
5670
|
-
|
|
5744
|
+
mkdirSync14(memoryPath(repoRoot, "promote"), { recursive: true });
|
|
5745
|
+
writeFileSync24(path, `${JSON.stringify(manifest, null, 2)}
|
|
5671
5746
|
`, "utf8");
|
|
5672
5747
|
return path;
|
|
5673
5748
|
}
|
|
5674
5749
|
|
|
5675
5750
|
// src/promote/buildPrBody.ts
|
|
5676
|
-
import { existsSync as
|
|
5751
|
+
import { existsSync as existsSync43, readFileSync as readFileSync39 } from "fs";
|
|
5677
5752
|
function actionLabel(action) {
|
|
5678
5753
|
if (action === "approve") {
|
|
5679
5754
|
return "\u6279\u51C6\u664B\u5347";
|
|
@@ -5713,9 +5788,9 @@ ${conflictLine}
|
|
|
5713
5788
|
}
|
|
5714
5789
|
function loadTemplate(repoRoot) {
|
|
5715
5790
|
const path = resolvePromoteTemplatePath(repoRoot);
|
|
5716
|
-
if (
|
|
5791
|
+
if (existsSync43(path)) {
|
|
5717
5792
|
try {
|
|
5718
|
-
return
|
|
5793
|
+
return readFileSync39(path, "utf8");
|
|
5719
5794
|
} catch {
|
|
5720
5795
|
}
|
|
5721
5796
|
}
|
|
@@ -5763,7 +5838,7 @@ ${items}
|
|
|
5763
5838
|
}
|
|
5764
5839
|
|
|
5765
5840
|
// src/promote/listPromoteCandidates.ts
|
|
5766
|
-
import { existsSync as
|
|
5841
|
+
import { existsSync as existsSync44, readdirSync as readdirSync13 } from "fs";
|
|
5767
5842
|
var TYPES2 = ["semantic", "episodic", "procedural"];
|
|
5768
5843
|
function normalizeCapturePath(input2) {
|
|
5769
5844
|
let p = input2.replace(/\\/g, "/").trim();
|
|
@@ -5780,7 +5855,7 @@ function listPromoteCandidates(repoRoot, filterPaths) {
|
|
|
5780
5855
|
const results = [];
|
|
5781
5856
|
for (const type of TYPES2) {
|
|
5782
5857
|
const dir = memoryPath(repoRoot, "captures", type);
|
|
5783
|
-
if (!
|
|
5858
|
+
if (!existsSync44(dir)) {
|
|
5784
5859
|
continue;
|
|
5785
5860
|
}
|
|
5786
5861
|
for (const name of readdirSync13(dir)) {
|
|
@@ -5807,8 +5882,8 @@ function listPromoteCandidates(repoRoot, filterPaths) {
|
|
|
5807
5882
|
|
|
5808
5883
|
// src/promote/runPromote.ts
|
|
5809
5884
|
function ensurePromoteDirs(repoRoot) {
|
|
5810
|
-
|
|
5811
|
-
|
|
5885
|
+
mkdirSync15(promoteDir(repoRoot), { recursive: true });
|
|
5886
|
+
mkdirSync15(promoteStagingTopicsDir(repoRoot), { recursive: true });
|
|
5812
5887
|
}
|
|
5813
5888
|
function formatPreviewTable(analyses) {
|
|
5814
5889
|
const lines = [
|
|
@@ -5852,15 +5927,15 @@ async function runPromote(opts) {
|
|
|
5852
5927
|
const stagingTopicPaths = [];
|
|
5853
5928
|
for (const [slug, body] of mergedDrafts) {
|
|
5854
5929
|
const path = stagingTopicPath(repoRoot, slug);
|
|
5855
|
-
|
|
5930
|
+
writeFileSync25(path, body, "utf8");
|
|
5856
5931
|
stagingTopicPaths.push(
|
|
5857
5932
|
`.memory/promote/staging/topics/${slug}.md`
|
|
5858
5933
|
);
|
|
5859
5934
|
}
|
|
5860
5935
|
const prBody = buildPrBody(repoRoot, analyses);
|
|
5861
5936
|
const prBodyPath = opts.outPath ? resolve8(opts.outPath) : defaultPrBodyPath(repoRoot, dateIso);
|
|
5862
|
-
|
|
5863
|
-
|
|
5937
|
+
mkdirSync15(memoryPath(repoRoot, "promote"), { recursive: true });
|
|
5938
|
+
writeFileSync25(prBodyPath, prBody, "utf8");
|
|
5864
5939
|
const manifestTemplatePath = writeManifestTemplate(
|
|
5865
5940
|
repoRoot,
|
|
5866
5941
|
candidates.map((c) => c.path)
|