claude-memory-layer 1.0.45 → 1.0.46

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/README.md CHANGED
@@ -21,6 +21,7 @@ Claude Memory Layer는 AI 에이전트의 대화와 작업 이벤트를 프로
21
21
  - **Vector Outbox V2**: SQLite source write와 vector enqueue를 같은 트랜잭션으로 묶고, versioned LanceDB upsert와 stuck-job recovery를 지원합니다.
22
22
  - **Dashboard 운영성 강화**: local-only 기본 bind, 선택적 password gate, Vector Health 카드, Perspective Memory aggregate 카드, retrieval trace/score breakdown을 제공합니다.
23
23
  - **Codex/Hermes history ingest**: 원본 세션은 read-only validate/replay로 먼저 확인하고, 명시적 import로만 프로젝트 메모리에 반영합니다.
24
+ - **Hermes/CML/Headroom 운영 모델**: Hermes built-in memory, `session_search`, CML context-pack, read-only Hermes provider, Headroom reference stance는 [`docs/HERMES_CML_HEADROOM_OPERATING_MODEL.md`](docs/HERMES_CML_HEADROOM_OPERATING_MODEL.md)에 정리되어 있습니다.
24
25
  - **npm 설치 안정화**: `@huggingface/transformers`는 optional dependency + postinstall repair로 설치하며, CUDA 11 환경에서는 CPU-only ONNX Runtime으로 자동 복구합니다.
25
26
 
26
27
  ## 빠른 시작 (신규 프로젝트 기준)
package/dist/cli/index.js CHANGED
@@ -9926,6 +9926,18 @@ var COMMAND_ARTIFACT_PATTERNS = [
9926
9926
  /<local-command-stdout>[\s\S]*?<\/local-command-stdout>/i,
9927
9927
  /<local-command-stderr>[\s\S]*?<\/local-command-stderr>/i
9928
9928
  ];
9929
+ var LOW_SIGNAL_CONTEXT_PATTERNS = [
9930
+ /<environment_context\b[\s\S]*<\/environment_context>/i,
9931
+ /<turn_aborted>/i,
9932
+ /^#\s*AGENTS\.md\s+instructions\b[\s\S]*<INSTRUCTIONS>/i,
9933
+ /^\s*(?:understood[,\s.]*)?(?:stopping|stopped|pausing|paused)\s+here\b[\s\S]{0,180}\blet\s+me\s+know\s+when\s+you(?:'d|\s+would)?\s+like\s+to\s+continue\b/i,
9934
+ /^\s*\[?CONTEXT\s+COMPACTION\s*[—-]\s*REFERENCE\s+ONLY\]?\b[\s\S]{0,600}\b(?:earlier\s+turns\s+were\s+compacted|handoff\s+from\s+a\s+previous\s+context\s+window|active\s+task)\b/i,
9935
+ /^\s*Summary\s+generation\s+was\s+unavailable\.\s*\d+\s+message\(s\)\s+were\s+removed\s+to\s+free\s+context\s+space\b/i,
9936
+ /^\s*---\s*END\s+OF\s+CONTEXT\s+SUMMARY\b/i,
9937
+ /^\s*\[Your\s+active\s+task\s+list\s+was\s+preserved\s+across\s+context\s+compression\]/i,
9938
+ /^➜\s+\S+\s+git:\([^)]*\)\s+/i,
9939
+ /^\$\s+\S+/i
9940
+ ];
9929
9941
  var CONTINUATION_QUERY_PATTERNS = [
9930
9942
  /^\s*(?:continue|resume|next|what(?:'s| is)? next|next\s+(?:step|task|action)|recommended\s+(?:next\s+)?(?:step|task|action)|what should (?:we|i) do next)\??\s*$/i,
9931
9943
  /^\s*(?:응\s*)?(?:이어서(?:\s*진행(?:해줘)?)?|계속(?:\s*해줘)?|다음\s*(?:단계|작업|추천\s*작업|추천|할\s*일)?(?:은|는)?(?:\s*(?:뭐야|진행(?:해줘)?))?\??|남은\s*(?:추가(?:로)?\s*)?(?:(?:할\s*만한\s*)?(?:작업|일)|할\s*일)?(?:은|는)?\s*(?:있어|있나|있나요|뭐야)\??|추천\s*작업(?:은|는)?(?:\s*뭐야)?\??|진행해줘)\s*$/i
@@ -9937,7 +9949,7 @@ var SHORT_REPAIR_FOLLOW_UP_PATTERNS = [
9937
9949
  var CURRENT_STATE_QUERY_PATTERNS = [
9938
9950
  /\bcurrent\b.*\b(?:state|status|deployment|blocker|pr|pull request)\b/i,
9939
9951
  /\b(?:still|as current|current)\b.*\b(?:unresolved|open|pending|not completed)\b/i,
9940
- /\b(?:old|obsolete|stale|resolved|already resolved)\b.*\b(?:current|still|unresolved|open|state|status)\b/i,
9952
+ /\b(?:old|obsolete|stale|resolved|already resolved)\b.*\b(?:current|still|unresolved|open|status)\b/i,
9941
9953
  /(?:현재|아직|이전|오래된|해결된).*(?:상태|미해결|열린|블로커|PR|풀리퀘스트)/i
9942
9954
  ];
9943
9955
  var STALE_CONTENT_PATTERNS = [
@@ -10083,6 +10095,21 @@ function isCommandArtifactQuery(query) {
10083
10095
  if (normalized.includes("command-name") || normalized.includes("command-message")) return true;
10084
10096
  return COMMAND_ARTIFACT_PATTERNS.some((pattern) => pattern.test(trimmed));
10085
10097
  }
10098
+ function isCommandArtifactContent(content) {
10099
+ const trimmed = content.trim();
10100
+ if (!trimmed) return false;
10101
+ const normalized = trimmed.toLowerCase();
10102
+ if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr")) return true;
10103
+ if (normalized.includes("command-name") || normalized.includes("command-message")) return true;
10104
+ return COMMAND_ARTIFACT_PATTERNS.some((pattern) => pattern.test(trimmed));
10105
+ }
10106
+ function isLowSignalContextContent(content) {
10107
+ const trimmed = content.trim();
10108
+ if (!trimmed) return true;
10109
+ if (isCommandArtifactContent(trimmed)) return true;
10110
+ if (LOW_SIGNAL_CONTEXT_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;
10111
+ return false;
10112
+ }
10086
10113
  function isGenericContinuationQuery(query) {
10087
10114
  const trimmed = query.trim();
10088
10115
  if (!trimmed) return false;
@@ -10100,6 +10127,16 @@ function isShortRepairFollowUpQuery(query) {
10100
10127
  if (tokens.length > 8) return false;
10101
10128
  return SHORT_REPAIR_FOLLOW_UP_PATTERNS.some((pattern) => pattern.test(trimmed));
10102
10129
  }
10130
+ function isLowConfidenceContextFallbackQuery(query) {
10131
+ const trimmed = query.trim();
10132
+ if (!trimmed) return false;
10133
+ if (isGenericContinuationQuery(trimmed) || isShortRepairFollowUpQuery(trimmed)) return true;
10134
+ const terms = new Set(tokenizeQualityText(trimmed));
10135
+ if ((terms.has("compacted") || terms.has("compaction")) && terms.has("handoff")) return false;
10136
+ const hasContinuationRecall = /^(?:continue|resume)\b/i.test(trimmed) && (terms.has("work") || terms.has("step") || terms.has("task") || terms.has("last") || terms.has("completed"));
10137
+ const hasValidationGateRecall = terms.has("validation") && (terms.has("gate") || terms.has("check")) && (terms.has("run") || terms.has("before") || terms.has("commit") || terms.has("committing") || terms.has("change"));
10138
+ return hasContinuationRecall || hasValidationGateRecall;
10139
+ }
10103
10140
  function isCurrentStateQuery(query) {
10104
10141
  const trimmed = query.trim();
10105
10142
  if (!trimmed) return false;
@@ -10367,7 +10404,14 @@ var Retriever = class {
10367
10404
  };
10368
10405
  fallbackTrace.push("fallback:summary");
10369
10406
  }
10370
- const memories = await this.enrichResults(current.results.slice(0, opts.topK), opts);
10407
+ const selectedResults = current.results.slice(0, opts.topK).filter((result) => {
10408
+ if (current.matchResult.confidence !== "none") return true;
10409
+ if (isLowConfidenceContextFallbackQuery(query)) {
10410
+ return (result.semanticScore ?? result.score) >= 0.5 || result.score >= 0.5;
10411
+ }
10412
+ return (result.semanticScore ?? result.score) >= 0.62 || result.score >= 0.62;
10413
+ });
10414
+ const memories = await this.enrichResults(selectedResults, opts, query);
10371
10415
  const context = this.buildContext(memories, opts.maxTokens);
10372
10416
  return {
10373
10417
  memories,
@@ -10375,7 +10419,7 @@ var Retriever = class {
10375
10419
  totalTokens: this.estimateTokens(context),
10376
10420
  context,
10377
10421
  fallbackTrace,
10378
- selectedDebug: current.results.slice(0, opts.topK).map((r) => this.debugDetailForResult(r)),
10422
+ selectedDebug: selectedResults.map((r) => this.debugDetailForResult(r)),
10379
10423
  candidateDebug: (current.candidateResults || []).slice(0, Math.max(opts.topK * 3, 20)).map((r) => this.debugDetailForResult(r)),
10380
10424
  rawQueryText: current.queryRewriteKind ? query : void 0,
10381
10425
  effectiveQueryText: current.effectiveQueryText,
@@ -10470,6 +10514,7 @@ var Retriever = class {
10470
10514
  if (isCurrentStateQuery(options.query)) {
10471
10515
  filtered = filtered.filter((result) => !isStaleOrSupersededContent(result.content));
10472
10516
  }
10517
+ filtered = filtered.filter((result) => !isLowSignalContextContent(result.content));
10473
10518
  filtered = filtered.filter(
10474
10519
  (result) => this.isGraphPathResult(result) || hasDiscriminativeTermOverlap(options.query, result.content)
10475
10520
  );
@@ -10810,7 +10855,7 @@ var Retriever = class {
10810
10855
  async retrieveRecent(limit = 100) {
10811
10856
  return this.eventStore.getRecentEvents(limit);
10812
10857
  }
10813
- async enrichResults(results, options) {
10858
+ async enrichResults(results, options, query) {
10814
10859
  const memories = [];
10815
10860
  for (const result of results) {
10816
10861
  const event = await this.eventStore.getEvent(result.eventId);
@@ -10820,13 +10865,13 @@ var Retriever = class {
10820
10865
  }
10821
10866
  let sessionContext;
10822
10867
  if (options.includeSessionContext) {
10823
- sessionContext = await this.getSessionContext(event.sessionId, event.id);
10868
+ sessionContext = await this.getSessionContext(event.sessionId, event.id, query);
10824
10869
  }
10825
10870
  memories.push({ event, score: result.score, sessionContext });
10826
10871
  }
10827
10872
  return memories;
10828
10873
  }
10829
- async getSessionContext(sessionId, eventId) {
10874
+ async getSessionContext(sessionId, eventId, query) {
10830
10875
  const sessionEvents = await this.eventStore.getSessionEvents(sessionId);
10831
10876
  const eventIndex = sessionEvents.findIndex((e) => e.id === eventId);
10832
10877
  if (eventIndex === -1) return void 0;
@@ -10834,7 +10879,9 @@ var Retriever = class {
10834
10879
  const end = Math.min(sessionEvents.length, eventIndex + 2);
10835
10880
  const contextEvents = sessionEvents.slice(start, end);
10836
10881
  if (contextEvents.length <= 1) return void 0;
10837
- return contextEvents.filter((e) => e.id !== eventId).map((e) => `[${e.eventType}]: ${e.content.slice(0, 200)}...`).join("\n");
10882
+ const suppressStaleState = isCurrentStateQuery(query);
10883
+ const contextLines = contextEvents.filter((e) => e.id !== eventId).filter((e) => !isLowSignalContextContent(e.content)).filter((e) => !(suppressStaleState && isStaleOrSupersededContent(e.content))).map((e) => `[${e.eventType}]: ${e.content.slice(0, 200)}...`);
10884
+ return contextLines.length > 0 ? contextLines.join("\n") : void 0;
10838
10885
  }
10839
10886
  buildUnifiedContext(projectResult, sharedMemories) {
10840
10887
  let context = projectResult.context;
@@ -20990,7 +21037,7 @@ async function runOperationCli(action, label) {
20990
21037
  }
20991
21038
  }
20992
21039
  var program = new Command();
20993
- program.name("claude-memory-layer").description("Claude Code Memory Plugin CLI").version("1.0.45");
21040
+ program.name("claude-memory-layer").description("Claude Code Memory Plugin CLI").version("1.0.46");
20994
21041
  program.command("market-context").description("Fetch read-only DART/FRED/Finnhub context with structured MarketContextSnapshot bull/bear/risk/catalyst analysis").option("--company <name>", "Company name for DART fallback search and report subject").option("--dart-corp-code <code>", "Exact DART corp_code for issuer-specific filings").option("--symbol <ticker>", "Listed ticker for Finnhub company profile").option("--providers <list>", "Comma-separated providers: dart,fred,finnhub").option("--fred-series <list>", "Comma-separated FRED series IDs").option("--json", "Print structured JSON including analysis.marketSnapshot").option("--no-snapshot", "Disable MarketContextSnapshot and DART company snapshot analysis").action(async (options) => {
20995
21042
  try {
20996
21043
  await runMarketContextCommand(options);