Class: ClaudeMemory::Commands::CensusCommand

Inherits:
BaseCommand
  • Object
show all
Defined in:
lib/claude_memory/commands/census_command.rb

Overview

Aggregates predicate/entity/schema usage across many ClaudeMemory databases into a privacy-safe JSON report. Used for informed vocabulary curation across machines without exposing content, names, or paths.

What’s emitted: schema versions, fact counts by predicate × status, entity type counts, novel predicates (outside the curated vocabulary), and synonym candidates (novel predicates overlapping known ones).

What’s never emitted: object_literal, entity names, project paths, provenance quotes, raw session IDs.

Constant Summary collapse

DB_FILENAME =
"memory.sqlite3"
TOP_PREDICATES_PER_DB =
5
SYNONYM_OVERLAP_THRESHOLD =
0.4
DEFAULT_ROOT =
"~/src"

Instance Attribute Summary

Attributes inherited from BaseCommand

#stderr, #stdin, #stdout

Instance Method Summary collapse

Methods inherited from BaseCommand

#initialize

Constructor Details

This class inherits a constructor from ClaudeMemory::Commands::BaseCommand

Instance Method Details

#call(args) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/claude_memory/commands/census_command.rb', line 24

def call(args)
  opts = parse_options(args, {root: DEFAULT_ROOT, output: nil, pretty: false, include_global: true}) do |o|
    OptionParser.new do |parser|
      parser.banner = "Usage: claude-memory census [options]"
      parser.on("--root DIR", "Directory to scan (default: #{DEFAULT_ROOT})") { |v| o[:root] = v }
      parser.on("--output FILE", "Write JSON to file instead of stdout") { |v| o[:output] = v }
      parser.on("--pretty", "Pretty-print JSON output") { o[:pretty] = true }
      parser.on("--no-global", "Skip the global database (~/.claude/memory.sqlite3)") { o[:include_global] = false }
    end
  end
  return 1 if opts.nil?

  root = File.expand_path(opts[:root])
  paths = discover_databases(root)
  paths << global_db_path if opts[:include_global] && File.exist?(global_db_path) && !paths.include?(global_db_path)

  if paths.empty?
    stderr.puts "No ClaudeMemory databases found under #{root}"
    return 0
  end

  report = build_report(paths)
  json = opts[:pretty] ? JSON.pretty_generate(report) : JSON.generate(report)

  if opts[:output]
    File.write(opts[:output], json)
    stderr.puts "Census: scanned #{paths.size} database(s); wrote #{opts[:output]}"
  else
    stdout.puts json
  end

  0
end