claude_memory 0.7.1 → 0.9.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 (107) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/memory.sqlite3 +0 -0
  3. data/.claude/rules/claude_memory.generated.md +32 -2
  4. data/.claude/settings.json +65 -15
  5. data/.claude/settings.local.json +5 -2
  6. data/.claude/skills/improve/SKILL.md +113 -25
  7. data/.claude/skills/upgrade-dependencies/SKILL.md +154 -0
  8. data/.claude-plugin/commands/distill-transcripts.md +98 -0
  9. data/.claude-plugin/commands/memory-recall.md +67 -0
  10. data/.claude-plugin/marketplace.json +2 -2
  11. data/.claude-plugin/plugin.json +3 -3
  12. data/.claude-plugin/scripts/hook-runner.sh +14 -0
  13. data/.claude-plugin/scripts/serve-mcp.sh +14 -0
  14. data/.ruby-version +1 -1
  15. data/CHANGELOG.md +90 -1
  16. data/CLAUDE.md +56 -18
  17. data/README.md +35 -0
  18. data/db/migrations/013_add_mcp_tool_calls.rb +26 -0
  19. data/db/migrations/014_canonicalize_predicates.rb +30 -0
  20. data/docs/improvements.md +74 -74
  21. data/docs/influence/claude-mem.md +1 -0
  22. data/docs/influence/claude-supermemory.md +1 -0
  23. data/docs/influence/episodic-memory.md +1 -0
  24. data/docs/influence/grepai.md +1 -0
  25. data/docs/influence/kbs.md +1 -0
  26. data/docs/influence/lossless-claw.md +1 -0
  27. data/docs/influence/qmd.md +1 -0
  28. data/docs/quality_review.md +119 -224
  29. data/hooks/hooks.json +39 -7
  30. data/lib/claude_memory/commands/checks/distill_check.rb +61 -0
  31. data/lib/claude_memory/commands/checks/hooks_check.rb +2 -2
  32. data/lib/claude_memory/commands/checks/vec_check.rb +2 -1
  33. data/lib/claude_memory/commands/completion_command.rb +149 -0
  34. data/lib/claude_memory/commands/doctor_command.rb +2 -0
  35. data/lib/claude_memory/commands/embeddings_command.rb +198 -0
  36. data/lib/claude_memory/commands/help_command.rb +12 -1
  37. data/lib/claude_memory/commands/hook_command.rb +2 -1
  38. data/lib/claude_memory/commands/index_command.rb +85 -78
  39. data/lib/claude_memory/commands/initializers/database_ensurer.rb +16 -0
  40. data/lib/claude_memory/commands/initializers/global_initializer.rb +2 -1
  41. data/lib/claude_memory/commands/initializers/hooks_configurator.rb +55 -11
  42. data/lib/claude_memory/commands/initializers/project_initializer.rb +2 -1
  43. data/lib/claude_memory/commands/install_skill_command.rb +78 -0
  44. data/lib/claude_memory/commands/registry.rb +47 -32
  45. data/lib/claude_memory/commands/reject_command.rb +62 -0
  46. data/lib/claude_memory/commands/restore_command.rb +77 -0
  47. data/lib/claude_memory/commands/skills/distill-transcripts.md +102 -0
  48. data/lib/claude_memory/commands/skills/memory-recall.md +67 -0
  49. data/lib/claude_memory/commands/stats_command.rb +98 -2
  50. data/lib/claude_memory/configuration.rb +14 -1
  51. data/lib/claude_memory/core/fact_ranker.rb +2 -2
  52. data/lib/claude_memory/core/rr_fusion.rb +23 -6
  53. data/lib/claude_memory/core/snippet_extractor.rb +7 -3
  54. data/lib/claude_memory/core/text_builder.rb +11 -0
  55. data/lib/claude_memory/distill/json_schema.md +8 -4
  56. data/lib/claude_memory/distill/null_distiller.rb +2 -0
  57. data/lib/claude_memory/domain/entity.rb +13 -1
  58. data/lib/claude_memory/domain/fact.rb +26 -2
  59. data/lib/claude_memory/domain/provenance.rb +0 -1
  60. data/lib/claude_memory/embeddings/api_adapter.rb +97 -0
  61. data/lib/claude_memory/embeddings/dimension_check.rb +23 -0
  62. data/lib/claude_memory/embeddings/fastembed_adapter.rb +46 -12
  63. data/lib/claude_memory/embeddings/generator.rb +4 -0
  64. data/lib/claude_memory/embeddings/inspector.rb +91 -0
  65. data/lib/claude_memory/embeddings/model_registry.rb +210 -0
  66. data/lib/claude_memory/embeddings/resolver.rb +44 -0
  67. data/lib/claude_memory/hook/context_injector.rb +58 -2
  68. data/lib/claude_memory/hook/distillation_runner.rb +46 -0
  69. data/lib/claude_memory/hook/handler.rb +11 -2
  70. data/lib/claude_memory/index/vector_index.rb +15 -2
  71. data/lib/claude_memory/infrastructure/schema_validator.rb +3 -3
  72. data/lib/claude_memory/ingest/ingester.rb +17 -0
  73. data/lib/claude_memory/mcp/handlers/context_handlers.rb +38 -0
  74. data/lib/claude_memory/mcp/handlers/management_handlers.rb +169 -0
  75. data/lib/claude_memory/mcp/handlers/query_handlers.rb +115 -0
  76. data/lib/claude_memory/mcp/handlers/setup_handlers.rb +211 -0
  77. data/lib/claude_memory/mcp/handlers/shortcut_handlers.rb +37 -0
  78. data/lib/claude_memory/mcp/handlers/stats_handlers.rb +205 -0
  79. data/lib/claude_memory/mcp/instructions_builder.rb +19 -1
  80. data/lib/claude_memory/mcp/query_guide.rb +10 -0
  81. data/lib/claude_memory/mcp/response_formatter.rb +1 -0
  82. data/lib/claude_memory/mcp/server.rb +22 -1
  83. data/lib/claude_memory/mcp/telemetry.rb +86 -0
  84. data/lib/claude_memory/mcp/text_summary.rb +26 -0
  85. data/lib/claude_memory/mcp/tool_definitions.rb +116 -4
  86. data/lib/claude_memory/mcp/tool_helpers.rb +43 -0
  87. data/lib/claude_memory/mcp/tools.rb +50 -679
  88. data/lib/claude_memory/publish.rb +40 -5
  89. data/lib/claude_memory/recall/dual_engine.rb +105 -0
  90. data/lib/claude_memory/recall/legacy_engine.rb +138 -0
  91. data/lib/claude_memory/recall/query_core.rb +371 -0
  92. data/lib/claude_memory/recall.rb +121 -673
  93. data/lib/claude_memory/resolve/predicate_policy.rb +63 -3
  94. data/lib/claude_memory/resolve/resolver.rb +43 -0
  95. data/lib/claude_memory/shortcuts.rb +4 -4
  96. data/lib/claude_memory/store/retry_handler.rb +61 -0
  97. data/lib/claude_memory/store/schema_manager.rb +68 -0
  98. data/lib/claude_memory/store/sqlite_store.rb +334 -201
  99. data/lib/claude_memory/store/store_manager.rb +50 -1
  100. data/lib/claude_memory/sweep/maintenance.rb +115 -1
  101. data/lib/claude_memory/sweep/sweeper.rb +3 -0
  102. data/lib/claude_memory/templates/hooks.example.json +26 -7
  103. data/lib/claude_memory/version.rb +1 -1
  104. data/lib/claude_memory.rb +16 -0
  105. metadata +48 -8
  106. data/.claude/memory.sqlite3-shm +0 -0
  107. data/.claude/memory.sqlite3-wal +0 -0
@@ -4,9 +4,25 @@ require "fileutils"
4
4
 
5
5
  module ClaudeMemory
6
6
  module Store
7
+ # Dual-database connection manager for global and project stores.
8
+ # Lazily opens SQLiteStore connections to the global database
9
+ # (~/.claude/memory.sqlite3) and the project database
10
+ # (.claude/memory.sqlite3 under the project root). Commands query
11
+ # both databases by default, with project facts taking precedence.
7
12
  class StoreManager
8
- attr_reader :global_store, :project_store, :project_path
13
+ # @return [SQLiteStore, nil] global store (nil until {#ensure_global!} is called)
14
+ attr_reader :global_store
9
15
 
16
+ # @return [SQLiteStore, nil] project store (nil until {#ensure_project!} is called)
17
+ attr_reader :project_store
18
+
19
+ # @return [String] project directory path
20
+ attr_reader :project_path
21
+
22
+ # @param global_db_path [String, nil] override path to the global database
23
+ # @param project_db_path [String, nil] override path to the project database
24
+ # @param project_path [String, nil] project directory (defaults to Configuration)
25
+ # @param env [Hash] environment variable hash (default: ENV)
10
26
  def initialize(global_db_path: nil, project_db_path: nil, project_path: nil, env: ENV)
11
27
  config = Configuration.new(env)
12
28
  @project_path = project_path || config.project_dir
@@ -17,14 +33,23 @@ module ClaudeMemory
17
33
  @project_store = nil
18
34
  end
19
35
 
36
+ # Default global database path from Configuration.
37
+ # @param env [Hash] environment variable hash
38
+ # @return [String]
20
39
  def self.default_global_db_path(env = ENV)
21
40
  Configuration.new(env).global_db_path
22
41
  end
23
42
 
43
+ # Default project database path for a given project directory.
44
+ # @param project_path [String] project directory (default: current working directory)
45
+ # @return [String]
24
46
  def self.default_project_db_path(project_path = Dir.pwd)
25
47
  Configuration.new.project_db_path(project_path)
26
48
  end
27
49
 
50
+ # Open the global store, creating the directory and database if needed.
51
+ # No-op if already open.
52
+ # @return [SQLiteStore] the global store
28
53
  def ensure_global!
29
54
  return @global_store if @global_store
30
55
 
@@ -32,6 +57,9 @@ module ClaudeMemory
32
57
  @global_store = SQLiteStore.new(@global_db_path)
33
58
  end
34
59
 
60
+ # Open the project store, creating the directory and database if needed.
61
+ # No-op if already open.
62
+ # @return [SQLiteStore] the project store
35
63
  def ensure_project!
36
64
  return @project_store if @project_store
37
65
 
@@ -39,23 +67,33 @@ module ClaudeMemory
39
67
  @project_store = SQLiteStore.new(@project_db_path)
40
68
  end
41
69
 
70
+ # Open both global and project stores.
71
+ # @return [void]
42
72
  def ensure_both!
43
73
  ensure_global!
44
74
  ensure_project!
45
75
  end
46
76
 
77
+ # @return [String] filesystem path to the global database
47
78
  attr_reader :global_db_path
48
79
 
80
+ # @return [String] filesystem path to the project database
49
81
  attr_reader :project_db_path
50
82
 
83
+ # Check whether the global database file exists on disk.
84
+ # @return [Boolean]
51
85
  def global_exists?
52
86
  File.exist?(@global_db_path)
53
87
  end
54
88
 
89
+ # Check whether the project database file exists on disk.
90
+ # @return [Boolean]
55
91
  def project_exists?
56
92
  File.exist?(@project_db_path)
57
93
  end
58
94
 
95
+ # Close both database connections and reset store references.
96
+ # @return [void]
59
97
  def close
60
98
  @global_store&.close
61
99
  @project_store&.close
@@ -63,6 +101,10 @@ module ClaudeMemory
63
101
  @project_store = nil
64
102
  end
65
103
 
104
+ # Return the appropriate store for a given scope string.
105
+ # @param scope [String] "global" or "project"
106
+ # @return [SQLiteStore]
107
+ # @raise [ArgumentError] if scope is not "global" or "project"
66
108
  def store_for_scope(scope)
67
109
  case scope
68
110
  when "global"
@@ -76,6 +118,13 @@ module ClaudeMemory
76
118
  end
77
119
  end
78
120
 
121
+ # Copy a project-scoped fact (with its entities and provenance) into the
122
+ # global store, making it available across all projects. Runs the global
123
+ # writes in a single transaction for atomicity.
124
+ #
125
+ # @param fact_id [Integer] project fact row id to promote
126
+ # @return [Integer, nil] the new global fact id, or nil if the fact/subject
127
+ # was not found in the project store
79
128
  def promote_fact(fact_id)
80
129
  ensure_both!
81
130
 
@@ -8,10 +8,16 @@ module ClaudeMemory
8
8
  #
9
9
  # Source: QMD v2.0.1 Maintenance class pattern
10
10
  class Maintenance
11
+ # Short / noise tokens dropped before Jaccard comparison.
12
+ # Intentionally minimal — we want conservative token extraction that
13
+ # still treats "Rails 8.0" and "Rails 8.1" as overlapping.
14
+ RESTORE_STOPWORDS = %w[for the and with via of in on to by is are].to_set.freeze
15
+ RESTORE_JACCARD_THRESHOLD = 0.5
11
16
  DEFAULT_CONFIG = {
12
17
  proposed_fact_ttl_days: 14,
13
18
  disputed_fact_ttl_days: 30,
14
- content_retention_days: 30
19
+ content_retention_days: 30,
20
+ mcp_tool_call_retention_days: 90
15
21
  }.freeze
16
22
 
17
23
  attr_reader :store
@@ -96,6 +102,85 @@ module ClaudeMemory
96
102
  0
97
103
  end
98
104
 
105
+ # Restore superseded facts in a (subject, predicate) slot that were
106
+ # only superseded because of an obsolete single-value classification.
107
+ # Uses Jaccard-based token overlap to distinguish bug-superseded facts
108
+ # (token-disjoint siblings) from legitimate corrections (overlapping
109
+ # siblings).
110
+ #
111
+ # Refuses to run on predicates still classified as single-value — they
112
+ # should stay superseded by design.
113
+ #
114
+ # Never touches status: "rejected" facts (explicit user decisions).
115
+ #
116
+ # @return [Hash] {inspected, restored, skipped_ambiguous, skipped_rejected, decisions}
117
+ def restore_multi_value_supersessions(predicate:, dry_run: false)
118
+ if ClaudeMemory::Resolve::PredicatePolicy.single?(predicate)
119
+ raise ArgumentError, "Predicate '#{predicate}' is still classified single-value; refusing to restore"
120
+ end
121
+
122
+ result = {inspected: 0, restored: 0, skipped_ambiguous: 0, skipped_rejected: 0, decisions: []}
123
+
124
+ rows_by_subject = @store.facts
125
+ .where(predicate: predicate)
126
+ .exclude(status: "rejected")
127
+ .select(:id, :subject_entity_id, :object_literal, :status)
128
+ .all
129
+ .group_by { |r| r[:subject_entity_id] }
130
+
131
+ rejected_by_subject = @store.facts
132
+ .where(predicate: predicate, status: "rejected")
133
+ .select(:id, :subject_entity_id, :object_literal)
134
+ .all
135
+ .group_by { |r| r[:subject_entity_id] }
136
+
137
+ @store.db.transaction do
138
+ rows_by_subject.each do |subject_id, rows|
139
+ rejected_rows = rejected_by_subject[subject_id] || []
140
+ siblings = rows + rejected_rows
141
+
142
+ rows.each do |candidate|
143
+ next unless candidate[:status] == "superseded"
144
+ result[:inspected] += 1
145
+
146
+ candidate_tokens = restore_tokenize(candidate[:object_literal])
147
+ ambiguous_against = find_overlapping_siblings(candidate, siblings, candidate_tokens)
148
+
149
+ if ambiguous_against.empty?
150
+ result[:restored] += 1
151
+ result[:decisions] << {
152
+ subject_entity_id: subject_id,
153
+ fact_id: candidate[:id],
154
+ object: candidate[:object_literal],
155
+ action: :restore
156
+ }
157
+ restore_fact!(candidate[:id]) unless dry_run
158
+ else
159
+ result[:skipped_ambiguous] += 1
160
+ result[:decisions] << {
161
+ subject_entity_id: subject_id,
162
+ fact_id: candidate[:id],
163
+ object: candidate[:object_literal],
164
+ action: :skip_ambiguous,
165
+ overlaps_with: ambiguous_against.map { |s| s[:object_literal] }
166
+ }
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ result
173
+ end
174
+
175
+ # Delete MCP tool-call telemetry rows older than retention window.
176
+ # Returns: Integer count of deleted rows (0 if table missing).
177
+ def prune_old_mcp_tool_calls
178
+ return 0 unless @store.db.table_exists?(:mcp_tool_calls)
179
+
180
+ cutoff = cutoff_time(@config[:mcp_tool_call_retention_days])
181
+ @store.mcp_tool_calls.where { called_at < cutoff }.delete
182
+ end
183
+
99
184
  # Checkpoint the SQLite WAL file for compaction.
100
185
  # Returns: true
101
186
  def checkpoint_wal
@@ -112,6 +197,35 @@ module ClaudeMemory
112
197
 
113
198
  private
114
199
 
200
+ def restore_tokenize(text)
201
+ return Set.new if text.nil?
202
+ text.downcase
203
+ .scan(/[a-z0-9]+/)
204
+ .reject { |t| t.length <= 2 || RESTORE_STOPWORDS.include?(t) }
205
+ .to_set
206
+ end
207
+
208
+ def restore_jaccard(a, b)
209
+ return 0.0 if a.empty? && b.empty?
210
+ intersection = (a & b).size
211
+ union = (a | b).size
212
+ return 0.0 if union.zero?
213
+ intersection.to_f / union
214
+ end
215
+
216
+ def find_overlapping_siblings(candidate, siblings, candidate_tokens)
217
+ siblings.select do |other|
218
+ next false if other[:id] == candidate[:id]
219
+ other_tokens = restore_tokenize(other[:object_literal])
220
+ restore_jaccard(candidate_tokens, other_tokens) >= RESTORE_JACCARD_THRESHOLD
221
+ end
222
+ end
223
+
224
+ def restore_fact!(fact_id)
225
+ @store.facts.where(id: fact_id).update(status: "active", valid_to: nil)
226
+ @store.fact_links.where(to_fact_id: fact_id, link_type: "supersedes").delete
227
+ end
228
+
115
229
  def cutoff_time(days)
116
230
  (Time.now - days * 86400).utc.iso8601
117
231
  end
@@ -7,6 +7,7 @@ module ClaudeMemory
7
7
  proposed_fact_ttl_days: 14,
8
8
  disputed_fact_ttl_days: 30,
9
9
  content_retention_days: 30,
10
+ mcp_tool_call_retention_days: 90,
10
11
  default_budget_seconds: 5
11
12
  }.freeze
12
13
 
@@ -29,6 +30,7 @@ module ClaudeMemory
29
30
  disputed_facts_expired: 0,
30
31
  orphaned_provenance_deleted: 0,
31
32
  old_content_pruned: 0,
33
+ mcp_tool_calls_pruned: 0,
32
34
  escalation_level: :normal
33
35
  }
34
36
 
@@ -38,6 +40,7 @@ module ClaudeMemory
38
40
  run_if_within_budget { @stats[:disputed_facts_expired] = maintenance.expire_disputed_facts }
39
41
  run_if_within_budget { @stats[:orphaned_provenance_deleted] = maintenance.prune_orphaned_provenance }
40
42
  run_if_within_budget { @stats[:old_content_pruned] = maintenance.prune_old_content }
43
+ run_if_within_budget { @stats[:mcp_tool_calls_pruned] = maintenance.prune_old_mcp_tool_calls }
41
44
  run_if_within_budget { @stats[:vec_backfilled] = maintenance.backfill_vec_index }
42
45
  run_if_within_budget { @stats[:vec_cleaned] = maintenance.cleanup_vec_expired }
43
46
  run_if_within_budget { @stats[:wal_checkpointed] = maintenance.checkpoint_wal }
@@ -6,7 +6,20 @@
6
6
  {
7
7
  "type": "command",
8
8
  "command": "claude-memory hook ingest",
9
- "timeout": 10
9
+ "timeout": 10,
10
+ "statusMessage": "Saving memory..."
11
+ }
12
+ ]
13
+ }
14
+ ],
15
+ "StopFailure": [
16
+ {
17
+ "hooks": [
18
+ {
19
+ "type": "command",
20
+ "command": "claude-memory hook ingest",
21
+ "timeout": 10,
22
+ "statusMessage": "Saving memory..."
10
23
  }
11
24
  ]
12
25
  }
@@ -17,7 +30,8 @@
17
30
  {
18
31
  "type": "command",
19
32
  "command": "claude-memory hook ingest",
20
- "timeout": 10
33
+ "timeout": 10,
34
+ "statusMessage": "Saving memory..."
21
35
  }
22
36
  ]
23
37
  }
@@ -28,12 +42,14 @@
28
42
  {
29
43
  "type": "command",
30
44
  "command": "claude-memory hook ingest",
31
- "timeout": 30
45
+ "timeout": 30,
46
+ "statusMessage": "Saving memory..."
32
47
  },
33
48
  {
34
49
  "type": "command",
35
50
  "command": "claude-memory hook sweep",
36
- "timeout": 30
51
+ "timeout": 30,
52
+ "statusMessage": "Sweeping memory..."
37
53
  }
38
54
  ]
39
55
  }
@@ -44,12 +60,14 @@
44
60
  {
45
61
  "type": "command",
46
62
  "command": "claude-memory hook ingest",
47
- "timeout": 30
63
+ "timeout": 30,
64
+ "statusMessage": "Saving memory..."
48
65
  },
49
66
  {
50
67
  "type": "command",
51
68
  "command": "claude-memory hook sweep",
52
- "timeout": 30
69
+ "timeout": 30,
70
+ "statusMessage": "Sweeping memory..."
53
71
  }
54
72
  ]
55
73
  }
@@ -61,7 +79,8 @@
61
79
  {
62
80
  "type": "command",
63
81
  "command": "claude-memory hook sweep",
64
- "timeout": 10
82
+ "timeout": 10,
83
+ "statusMessage": "Sweeping memory..."
65
84
  }
66
85
  ]
67
86
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ClaudeMemory
4
- VERSION = "0.7.1"
4
+ VERSION = "0.9.0"
5
5
  end
data/lib/claude_memory.rb CHANGED
@@ -38,6 +38,7 @@ require_relative "claude_memory/commands/checks/claude_md_check"
38
38
  require_relative "claude_memory/commands/checks/hooks_check"
39
39
  require_relative "claude_memory/commands/checks/reporter"
40
40
  require_relative "claude_memory/commands/checks/vec_check"
41
+ require_relative "claude_memory/commands/checks/distill_check"
41
42
  require_relative "claude_memory/commands/help_command"
42
43
  require_relative "claude_memory/commands/version_command"
43
44
  require_relative "claude_memory/commands/doctor_command"
@@ -67,6 +68,11 @@ require_relative "claude_memory/commands/recover_command"
67
68
  require_relative "claude_memory/commands/compact_command"
68
69
  require_relative "claude_memory/commands/export_command"
69
70
  require_relative "claude_memory/commands/git_lfs_command"
71
+ require_relative "claude_memory/commands/install_skill_command"
72
+ require_relative "claude_memory/commands/completion_command"
73
+ require_relative "claude_memory/commands/embeddings_command"
74
+ require_relative "claude_memory/commands/reject_command"
75
+ require_relative "claude_memory/commands/restore_command"
70
76
  require_relative "claude_memory/commands/registry"
71
77
  require_relative "claude_memory/cli"
72
78
  require_relative "claude_memory/configuration"
@@ -77,9 +83,16 @@ require_relative "claude_memory/domain/fact"
77
83
  require_relative "claude_memory/domain/entity"
78
84
  require_relative "claude_memory/domain/provenance"
79
85
  require_relative "claude_memory/domain/conflict"
86
+ require_relative "claude_memory/embeddings/model_registry"
87
+ require_relative "claude_memory/embeddings/inspector"
80
88
  require_relative "claude_memory/embeddings/generator"
89
+ require_relative "claude_memory/embeddings/fastembed_adapter"
90
+ require_relative "claude_memory/embeddings/api_adapter"
91
+ require_relative "claude_memory/embeddings/dimension_check"
92
+ require_relative "claude_memory/embeddings/resolver"
81
93
  require_relative "claude_memory/embeddings/similarity"
82
94
  require_relative "claude_memory/hook/context_injector"
95
+ require_relative "claude_memory/hook/distillation_runner"
83
96
  require_relative "claude_memory/hook/exit_codes"
84
97
  require_relative "claude_memory/hook/handler"
85
98
  require_relative "claude_memory/hook/error_classifier"
@@ -110,6 +123,9 @@ require_relative "claude_memory/mcp/tools"
110
123
  require_relative "claude_memory/publish"
111
124
  require_relative "claude_memory/recall/dual_query_template"
112
125
  require_relative "claude_memory/recall/expansion_detector"
126
+ require_relative "claude_memory/recall/query_core"
127
+ require_relative "claude_memory/recall/legacy_engine"
128
+ require_relative "claude_memory/recall/dual_engine"
113
129
  require_relative "claude_memory/recall"
114
130
  require_relative "claude_memory/shortcuts"
115
131
  require_relative "claude_memory/resolve/predicate_policy"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: claude_memory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Valentino Stoll
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '5.0'
18
+ version: '5.102'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '5.0'
25
+ version: '5.102'
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: extralite
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -44,6 +44,9 @@ dependencies:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0.1'
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 0.1.9
47
50
  type: :runtime
48
51
  prerelease: false
49
52
  version_requirements: !ruby/object:Gem::Requirement
@@ -51,8 +54,13 @@ dependencies:
51
54
  - - "~>"
52
55
  - !ruby/object:Gem::Version
53
56
  version: '0.1'
54
- description: Turn-key Ruby gem providing Claude Code with instant, high-quality, long-term,
55
- self-managed memory using Claude Code Hooks + MCP + Output Style.
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 0.1.9
60
+ description: Gives Claude Code persistent memory across sessions. Claude recalls your
61
+ codebase architecture without file traversal, enforces project conventions during
62
+ code generation, tracks decisions with rationale, and remembers your preferences
63
+ across all projects. Zero-config via Hooks + MCP.
56
64
  email:
57
65
  - v@codenamev.com
58
66
  executables:
@@ -60,13 +68,15 @@ executables:
60
68
  extensions: []
61
69
  extra_rdoc_files: []
62
70
  files:
71
+ - ".claude-plugin/commands/distill-transcripts.md"
72
+ - ".claude-plugin/commands/memory-recall.md"
63
73
  - ".claude-plugin/marketplace.json"
64
74
  - ".claude-plugin/plugin.json"
75
+ - ".claude-plugin/scripts/hook-runner.sh"
76
+ - ".claude-plugin/scripts/serve-mcp.sh"
65
77
  - ".claude.json"
66
78
  - ".claude/CLAUDE.md"
67
79
  - ".claude/memory.sqlite3"
68
- - ".claude/memory.sqlite3-shm"
69
- - ".claude/memory.sqlite3-wal"
70
80
  - ".claude/output-styles/memory-aware.md"
71
81
  - ".claude/rules/claude_memory.generated.md"
72
82
  - ".claude/settings.json"
@@ -86,6 +96,7 @@ files:
86
96
  - ".claude/skills/study-repo/SKILL.md"
87
97
  - ".claude/skills/study-repo/analysis-template.md"
88
98
  - ".claude/skills/study-repo/focus-examples.md"
99
+ - ".claude/skills/upgrade-dependencies/SKILL.md"
89
100
  - ".gitattributes"
90
101
  - ".lefthook/map_specs.rb"
91
102
  - ".mcp.json"
@@ -112,6 +123,8 @@ files:
112
123
  - db/migrations/010_add_llm_cache.rb
113
124
  - db/migrations/011_add_tool_call_summaries.rb
114
125
  - db/migrations/012_add_vec_indexing_support.rb
126
+ - db/migrations/013_add_mcp_tool_calls.rb
127
+ - db/migrations/014_canonicalize_predicates.rb
115
128
  - docs/EXAMPLES.md
116
129
  - docs/GETTING_STARTED.md
117
130
  - docs/RELEASE_NOTES_v0.2.0.md
@@ -151,14 +164,17 @@ files:
151
164
  - lib/claude_memory/commands/changes_command.rb
152
165
  - lib/claude_memory/commands/checks/claude_md_check.rb
153
166
  - lib/claude_memory/commands/checks/database_check.rb
167
+ - lib/claude_memory/commands/checks/distill_check.rb
154
168
  - lib/claude_memory/commands/checks/hooks_check.rb
155
169
  - lib/claude_memory/commands/checks/reporter.rb
156
170
  - lib/claude_memory/commands/checks/snapshot_check.rb
157
171
  - lib/claude_memory/commands/checks/vec_check.rb
158
172
  - lib/claude_memory/commands/compact_command.rb
173
+ - lib/claude_memory/commands/completion_command.rb
159
174
  - lib/claude_memory/commands/conflicts_command.rb
160
175
  - lib/claude_memory/commands/db_init_command.rb
161
176
  - lib/claude_memory/commands/doctor_command.rb
177
+ - lib/claude_memory/commands/embeddings_command.rb
162
178
  - lib/claude_memory/commands/explain_command.rb
163
179
  - lib/claude_memory/commands/export_command.rb
164
180
  - lib/claude_memory/commands/git_lfs_command.rb
@@ -173,13 +189,18 @@ files:
173
189
  - lib/claude_memory/commands/initializers/mcp_configurator.rb
174
190
  - lib/claude_memory/commands/initializers/memory_instructions_writer.rb
175
191
  - lib/claude_memory/commands/initializers/project_initializer.rb
192
+ - lib/claude_memory/commands/install_skill_command.rb
176
193
  - lib/claude_memory/commands/promote_command.rb
177
194
  - lib/claude_memory/commands/publish_command.rb
178
195
  - lib/claude_memory/commands/recall_command.rb
179
196
  - lib/claude_memory/commands/recover_command.rb
180
197
  - lib/claude_memory/commands/registry.rb
198
+ - lib/claude_memory/commands/reject_command.rb
199
+ - lib/claude_memory/commands/restore_command.rb
181
200
  - lib/claude_memory/commands/search_command.rb
182
201
  - lib/claude_memory/commands/serve_mcp_command.rb
202
+ - lib/claude_memory/commands/skills/distill-transcripts.md
203
+ - lib/claude_memory/commands/skills/memory-recall.md
183
204
  - lib/claude_memory/commands/stats_command.rb
184
205
  - lib/claude_memory/commands/sweep_command.rb
185
206
  - lib/claude_memory/commands/uninstall_command.rb
@@ -214,10 +235,16 @@ files:
214
235
  - lib/claude_memory/domain/entity.rb
215
236
  - lib/claude_memory/domain/fact.rb
216
237
  - lib/claude_memory/domain/provenance.rb
238
+ - lib/claude_memory/embeddings/api_adapter.rb
239
+ - lib/claude_memory/embeddings/dimension_check.rb
217
240
  - lib/claude_memory/embeddings/fastembed_adapter.rb
218
241
  - lib/claude_memory/embeddings/generator.rb
242
+ - lib/claude_memory/embeddings/inspector.rb
243
+ - lib/claude_memory/embeddings/model_registry.rb
244
+ - lib/claude_memory/embeddings/resolver.rb
219
245
  - lib/claude_memory/embeddings/similarity.rb
220
246
  - lib/claude_memory/hook/context_injector.rb
247
+ - lib/claude_memory/hook/distillation_runner.rb
221
248
  - lib/claude_memory/hook/error_classifier.rb
222
249
  - lib/claude_memory/hook/exit_codes.rb
223
250
  - lib/claude_memory/hook/handler.rb
@@ -240,22 +267,34 @@ files:
240
267
  - lib/claude_memory/ingest/transcript_reader.rb
241
268
  - lib/claude_memory/logging/logger.rb
242
269
  - lib/claude_memory/mcp/error_classifier.rb
270
+ - lib/claude_memory/mcp/handlers/context_handlers.rb
271
+ - lib/claude_memory/mcp/handlers/management_handlers.rb
272
+ - lib/claude_memory/mcp/handlers/query_handlers.rb
273
+ - lib/claude_memory/mcp/handlers/setup_handlers.rb
274
+ - lib/claude_memory/mcp/handlers/shortcut_handlers.rb
275
+ - lib/claude_memory/mcp/handlers/stats_handlers.rb
243
276
  - lib/claude_memory/mcp/instructions_builder.rb
244
277
  - lib/claude_memory/mcp/query_guide.rb
245
278
  - lib/claude_memory/mcp/response_formatter.rb
246
279
  - lib/claude_memory/mcp/server.rb
247
280
  - lib/claude_memory/mcp/setup_status_analyzer.rb
281
+ - lib/claude_memory/mcp/telemetry.rb
248
282
  - lib/claude_memory/mcp/text_summary.rb
249
283
  - lib/claude_memory/mcp/tool_definitions.rb
250
284
  - lib/claude_memory/mcp/tool_helpers.rb
251
285
  - lib/claude_memory/mcp/tools.rb
252
286
  - lib/claude_memory/publish.rb
253
287
  - lib/claude_memory/recall.rb
288
+ - lib/claude_memory/recall/dual_engine.rb
254
289
  - lib/claude_memory/recall/dual_query_template.rb
255
290
  - lib/claude_memory/recall/expansion_detector.rb
291
+ - lib/claude_memory/recall/legacy_engine.rb
292
+ - lib/claude_memory/recall/query_core.rb
256
293
  - lib/claude_memory/resolve/predicate_policy.rb
257
294
  - lib/claude_memory/resolve/resolver.rb
258
295
  - lib/claude_memory/shortcuts.rb
296
+ - lib/claude_memory/store/retry_handler.rb
297
+ - lib/claude_memory/store/schema_manager.rb
259
298
  - lib/claude_memory/store/sqlite_store.rb
260
299
  - lib/claude_memory/store/store_manager.rb
261
300
  - lib/claude_memory/sweep/maintenance.rb
@@ -296,5 +335,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
296
335
  requirements: []
297
336
  rubygems_version: 4.0.6
298
337
  specification_version: 4
299
- summary: Long-term, self-managed memory for Claude Code
338
+ summary: Long-term memory for Claude Code — architecture recall, convention enforcement,
339
+ decision tracking
300
340
  test_files: []
Binary file
Binary file