@membank/cli 0.14.2 → 0.15.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/dist/index.mjs +22 -31
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -380,11 +380,16 @@ async function importCommand(filePath, db, formatter, prompt) {
|
|
|
380
380
|
}
|
|
381
381
|
//#endregion
|
|
382
382
|
//#region src/commands/inject.ts
|
|
383
|
-
const
|
|
383
|
+
const SAVE_GUIDANCE = "Save (call save_memory) when: (1) user states a preference or makes a decision; (2) user corrects you; (3) you discover a working fix after a tool error; (4) you learn a non-obvious project fact. Type ∈ correction|preference|decision|learning|fact. When unsure, save.";
|
|
384
|
+
const QUERY_GUIDANCE = "Query (call query_memory) before: answering anything that touches prior decisions, and before exploration tasks (file reads, searches, web lookups) where past corrections or preferences may apply. Skip when clearly irrelevant (e.g. trivial arithmetic). Soft guideline, not a hard rule.";
|
|
385
|
+
const MEMORY_GUIDANCE = [SAVE_GUIDANCE, QUERY_GUIDANCE].join("\n");
|
|
386
|
+
function buildGuidance(harness) {
|
|
387
|
+
return harness === "claude-code" ? QUERY_GUIDANCE : MEMORY_GUIDANCE;
|
|
388
|
+
}
|
|
384
389
|
function xmlEscape(s) {
|
|
385
390
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
386
391
|
}
|
|
387
|
-
function formatContext(ctx) {
|
|
392
|
+
function formatContext(ctx, guidance) {
|
|
388
393
|
const parts = [];
|
|
389
394
|
const statParts = Object.entries(ctx.stats).filter(([, count]) => count > 0).map(([type, count]) => `${count} ${type}${count !== 1 ? "s" : ""}`);
|
|
390
395
|
if (statParts.length > 0) parts.push(`<memory-stats>\n${statParts.join(", ")}\n</memory-stats>`);
|
|
@@ -396,7 +401,7 @@ function formatContext(ctx) {
|
|
|
396
401
|
parts.push(`<pinned-memories>\n${memLines.join("\n")}\n</pinned-memories>`);
|
|
397
402
|
}
|
|
398
403
|
}
|
|
399
|
-
parts.push(`<memory-guidance>\n${
|
|
404
|
+
parts.push(`<memory-guidance>\n${guidance}\n</memory-guidance>`);
|
|
400
405
|
return parts.join("\n");
|
|
401
406
|
}
|
|
402
407
|
function outputAdditionalContext(text, harness, eventName) {
|
|
@@ -416,7 +421,7 @@ function outputAdditionalContext(text, harness, eventName) {
|
|
|
416
421
|
function pickBestSynthesis(globalSynthesis, projectSynthesis) {
|
|
417
422
|
return projectSynthesis ?? globalSynthesis;
|
|
418
423
|
}
|
|
419
|
-
async function buildText() {
|
|
424
|
+
async function buildText(harness) {
|
|
420
425
|
const resolved = await resolveProject();
|
|
421
426
|
const db = DatabaseManager.open();
|
|
422
427
|
try {
|
|
@@ -425,13 +430,13 @@ async function buildText() {
|
|
|
425
430
|
const globalRow = synthRepo.getSynthesis(GLOBAL_SCOPE_HASH);
|
|
426
431
|
const projectRow = synthRepo.getSynthesis(resolved.hash);
|
|
427
432
|
const synthesis = pickBestSynthesis(globalRow?.inFlightSince === null ? globalRow.content : void 0, projectRow?.inFlightSince === null ? projectRow.content : void 0);
|
|
428
|
-
return formatContext(builder.getSessionContext(resolved.hash, synthesis));
|
|
433
|
+
return formatContext(builder.getSessionContext(resolved.hash, synthesis), buildGuidance(harness));
|
|
429
434
|
} finally {
|
|
430
435
|
db.close();
|
|
431
436
|
}
|
|
432
437
|
}
|
|
433
438
|
async function handleEvent(harness, eventName) {
|
|
434
|
-
const text = await buildText().catch((err) => {
|
|
439
|
+
const text = await buildText(harness).catch((err) => {
|
|
435
440
|
const msg = err instanceof Error ? err.message : String(err);
|
|
436
441
|
process.stderr.write(`membank inject: ${msg}\n`);
|
|
437
442
|
return null;
|
|
@@ -447,6 +452,7 @@ async function injectCommand(opts) {
|
|
|
447
452
|
return;
|
|
448
453
|
}
|
|
449
454
|
if (opts.event === "user-prompt-submit") {
|
|
455
|
+
if (harness === "claude-code") process.exit(0);
|
|
450
456
|
await handleEvent(harness, "UserPromptSubmit");
|
|
451
457
|
return;
|
|
452
458
|
}
|
|
@@ -1133,28 +1139,19 @@ const writers = {
|
|
|
1133
1139
|
const cfg = readJson(cfgPath);
|
|
1134
1140
|
const hooks = MaybeJsonObjectSchema.parse(cfg.hooks) ?? {};
|
|
1135
1141
|
const sessionStartInner = (Array.isArray(hooks.SessionStart) ? hooks.SessionStart : []).flatMap(getHooksArray);
|
|
1136
|
-
const userPromptSubmitInner = (Array.isArray(hooks.UserPromptSubmit) ? hooks.UserPromptSubmit : []).flatMap(getHooksArray);
|
|
1137
1142
|
const sessionEndInner = (Array.isArray(hooks.SessionEnd) ? hooks.SessionEnd : []).flatMap(getHooksArray);
|
|
1138
1143
|
return {
|
|
1139
1144
|
status: "ready",
|
|
1140
1145
|
configPath: cfgPath,
|
|
1141
|
-
hooks: [
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
existingCommand: extractInjectCommand(userPromptSubmitInner) || null
|
|
1151
|
-
},
|
|
1152
|
-
{
|
|
1153
|
-
event: "SessionEnd",
|
|
1154
|
-
command: "npx -y @membank/cli extract --harness claude-code",
|
|
1155
|
-
existingCommand: extractInjectCommand(sessionEndInner) || null
|
|
1156
|
-
}
|
|
1157
|
-
]
|
|
1146
|
+
hooks: [{
|
|
1147
|
+
event: "SessionStart",
|
|
1148
|
+
command: "npx -y @membank/cli inject --harness claude-code",
|
|
1149
|
+
existingCommand: extractInjectCommand(sessionStartInner) || null
|
|
1150
|
+
}, {
|
|
1151
|
+
event: "SessionEnd",
|
|
1152
|
+
command: "npx -y @membank/cli extract --harness claude-code",
|
|
1153
|
+
existingCommand: extractInjectCommand(sessionEndInner) || null
|
|
1154
|
+
}]
|
|
1158
1155
|
};
|
|
1159
1156
|
},
|
|
1160
1157
|
write(resolver, events) {
|
|
@@ -1164,6 +1161,7 @@ const writers = {
|
|
|
1164
1161
|
const newHooks = { ...hooks };
|
|
1165
1162
|
pruneNestedEvent(newHooks, "PostToolUseFailure");
|
|
1166
1163
|
pruneNestedEvent(newHooks, "Stop");
|
|
1164
|
+
pruneNestedEvent(newHooks, "UserPromptSubmit");
|
|
1167
1165
|
if (events.includes("SessionStart")) newHooks.SessionStart = [...filterOutMembank(Array.isArray(hooks.SessionStart) ? hooks.SessionStart : []), {
|
|
1168
1166
|
matcher: "",
|
|
1169
1167
|
hooks: [{
|
|
@@ -1171,13 +1169,6 @@ const writers = {
|
|
|
1171
1169
|
command: "npx -y @membank/cli inject --harness claude-code"
|
|
1172
1170
|
}]
|
|
1173
1171
|
}];
|
|
1174
|
-
if (events.includes("UserPromptSubmit")) newHooks.UserPromptSubmit = [...filterOutMembank(Array.isArray(hooks.UserPromptSubmit) ? hooks.UserPromptSubmit : []), {
|
|
1175
|
-
matcher: "",
|
|
1176
|
-
hooks: [{
|
|
1177
|
-
type: "command",
|
|
1178
|
-
command: "npx -y @membank/cli inject --harness claude-code --event user-prompt-submit"
|
|
1179
|
-
}]
|
|
1180
|
-
}];
|
|
1181
1172
|
if (events.includes("SessionEnd")) newHooks.SessionEnd = [...filterOutMembank(Array.isArray(hooks.SessionEnd) ? hooks.SessionEnd : []), {
|
|
1182
1173
|
matcher: "clear|resume|logout|prompt_input_exit|other",
|
|
1183
1174
|
hooks: [{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@membank/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"commander": "^14.0.3",
|
|
22
22
|
"ora": "^9.4.0",
|
|
23
23
|
"zod": "^4.4.3",
|
|
24
|
-
"@membank/
|
|
25
|
-
"@membank/
|
|
24
|
+
"@membank/core": "0.13.0",
|
|
25
|
+
"@membank/mcp": "0.15.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^25.6.0",
|