@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.
Files changed (2) hide show
  1. package/dist/index.mjs +22 -31
  2. 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 MEMORY_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.", "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."].join("\n");
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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
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${MEMORY_GUIDANCE}\n</memory-guidance>`);
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
- event: "SessionStart",
1144
- command: "npx -y @membank/cli inject --harness claude-code",
1145
- existingCommand: extractInjectCommand(sessionStartInner) || null
1146
- },
1147
- {
1148
- event: "UserPromptSubmit",
1149
- command: "npx -y @membank/cli inject --harness claude-code --event user-prompt-submit",
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.14.2",
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/mcp": "0.14.3",
25
- "@membank/core": "0.12.1"
24
+ "@membank/core": "0.13.0",
25
+ "@membank/mcp": "0.15.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^25.6.0",