@hir4ta/mneme 0.23.0 → 0.23.2

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.
@@ -29951,15 +29951,15 @@ var StdioServerTransport = class {
29951
29951
  }
29952
29952
  };
29953
29953
 
29954
- // lib/search-core.ts
29954
+ // lib/search/core.ts
29955
29955
  import * as fs4 from "node:fs";
29956
29956
  import * as path4 from "node:path";
29957
29957
 
29958
- // lib/search-helpers.ts
29958
+ // lib/search/helpers.ts
29959
29959
  import * as fs3 from "node:fs";
29960
29960
  import * as path3 from "node:path";
29961
29961
 
29962
- // lib/fuzzy-search.ts
29962
+ // lib/search/fuzzy.ts
29963
29963
  import * as fs2 from "node:fs";
29964
29964
  import * as path2 from "node:path";
29965
29965
 
@@ -29989,7 +29989,7 @@ function findJsonFiles(dir) {
29989
29989
  return results;
29990
29990
  }
29991
29991
 
29992
- // lib/fuzzy-search.ts
29992
+ // lib/search/fuzzy.ts
29993
29993
  function levenshtein(a, b) {
29994
29994
  const matrix = [];
29995
29995
  for (let i = 0; i <= a.length; i++) {
@@ -30151,7 +30151,7 @@ function scoreDocument(doc, queries, fields) {
30151
30151
  }
30152
30152
  return totalScore;
30153
30153
  }
30154
- var isMain = process.argv[1]?.endsWith("fuzzy-search.js") || process.argv[1]?.endsWith("fuzzy-search.ts");
30154
+ var isMain = process.argv[1]?.endsWith("fuzzy.js") || process.argv[1]?.endsWith("fuzzy.ts");
30155
30155
  if (isMain && process.argv.length > 2) {
30156
30156
  const args = process.argv.slice(2);
30157
30157
  const queryIndex = args.indexOf("--query");
@@ -30168,7 +30168,7 @@ if (isMain && process.argv.length > 2) {
30168
30168
  });
30169
30169
  }
30170
30170
 
30171
- // lib/search-helpers.ts
30171
+ // lib/search/helpers.ts
30172
30172
  function escapeRegex2(value) {
30173
30173
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
30174
30174
  }
@@ -30229,7 +30229,7 @@ function walkJsonFiles(dir, callback) {
30229
30229
  }
30230
30230
  }
30231
30231
 
30232
- // lib/search-core.ts
30232
+ // lib/search/core.ts
30233
30233
  function searchInteractions(keywords, projectPath, database, limit = 5) {
30234
30234
  if (!database) return [];
30235
30235
  try {
@@ -30480,7 +30480,7 @@ var server = new McpServer({
30480
30480
  server.registerTool(
30481
30481
  "mneme_search",
30482
30482
  {
30483
- description: "Search mneme's knowledge base for sessions and interactions. Returns scored results with matched fields.",
30483
+ description: "Search mneme's knowledge base for sessions and interactions.",
30484
30484
  inputSchema: {
30485
30485
  query: external_exports3.string().max(QUERY_MAX_LENGTH).describe("Search query (keywords)"),
30486
30486
  types: external_exports3.array(external_exports3.enum(["session", "interaction"])).optional().describe("Types to search (default: session/interaction)."),
@@ -28,16 +28,26 @@ validate_mneme() {
28
28
  # Find a script: first try dist/ (production), then lib/ (development).
29
29
  # Usage: find_script <plugin_root> <name>
30
30
  # Example: find_script "$PLUGIN_ROOT" "incremental-save"
31
- # → /path/to/dist/lib/incremental-save.js or
32
- # → /path/to/lib/incremental-save.ts or
31
+ # → /path/to/dist/lib/save/index.js or
32
+ # → /path/to/lib/save/index.ts or
33
33
  # → "" (not found)
34
34
  find_script() {
35
35
  local plugin_root="$1"
36
36
  local name="$2"
37
- if [ -f "${plugin_root}/dist/lib/${name}.js" ]; then
38
- echo "${plugin_root}/dist/lib/${name}.js"
39
- elif [ -f "${plugin_root}/lib/${name}.ts" ]; then
40
- echo "${plugin_root}/lib/${name}.ts"
37
+
38
+ # Map names to subdirectory paths
39
+ local mapped_name="$name"
40
+ case "$name" in
41
+ incremental-save) mapped_name="save/index" ;;
42
+ prompt-search) mapped_name="search/prompt" ;;
43
+ session-init) mapped_name="session/init" ;;
44
+ session-finalize) mapped_name="session/finalize" ;;
45
+ esac
46
+
47
+ if [ -f "${plugin_root}/dist/lib/${mapped_name}.js" ]; then
48
+ echo "${plugin_root}/dist/lib/${mapped_name}.js"
49
+ elif [ -f "${plugin_root}/lib/${mapped_name}.ts" ]; then
50
+ echo "${plugin_root}/lib/${mapped_name}.ts"
41
51
  fi
42
52
  }
43
53
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hir4ta/mneme",
3
- "version": "0.23.0",
3
+ "version": "0.23.2",
4
4
  "description": "Long-term memory plugin for Claude Code - automated session saving, recording technical decisions, and web dashboard",
5
5
  "keywords": [
6
6
  "claude",
@@ -27,7 +27,7 @@
27
27
  "dev:server": "tsx watch dashboard/server/index.ts",
28
28
  "build": "vite build && npm run build:server && npm run build:lib && npm run build:mcp",
29
29
  "build:server": "esbuild dashboard/server/index.ts --bundle --platform=node --outfile=dist/server.js --format=esm --external:fsevents",
30
- "build:lib": "esbuild lib/*.ts --bundle --platform=node --outdir=dist/lib --format=esm --external:fsevents",
30
+ "build:lib": "esbuild lib/save/index.ts lib/search/prompt.ts lib/session/init.ts lib/session/finalize.ts --bundle --platform=node --outdir=dist/lib --format=esm --external:fsevents",
31
31
  "build:mcp": "esbuild servers/db-server.ts servers/search-server.ts --bundle --platform=node --outdir=dist/servers --format=esm --external:fsevents",
32
32
  "preview": "npm run build && node dist/server.js",
33
33
  "lint": "biome check .",
@@ -1,6 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { type QueryableDb, searchKnowledge } from "../lib/search-core.js";
3
+ import { type QueryableDb, searchKnowledge } from "../lib/search/core.js";
4
4
 
5
5
  // Suppress Node.js SQLite experimental warning.
6
6
  const originalEmit = process.emit;
@@ -4,15 +4,15 @@
4
4
 
5
5
  import * as path from "node:path";
6
6
 
7
- import { searchKnowledge } from "../lib/search-core.js";
8
- import type { BenchmarkQuery } from "./db-types.js";
7
+ import { searchKnowledge } from "../../lib/search/core.js";
8
+ import type { BenchmarkQuery } from "./types.js";
9
9
  import {
10
10
  getDb,
11
11
  getMnemeDir,
12
12
  getProjectPath,
13
13
  readJsonFile,
14
14
  readRuleItems,
15
- } from "./db-utils.js";
15
+ } from "./utils.js";
16
16
 
17
17
  export function runSearchBenchmark(limit: number): {
18
18
  queryCount: number;
@@ -1,10 +1,5 @@
1
- import type {
2
- Interaction,
3
- ProjectInfo,
4
- SessionInfo,
5
- Stats,
6
- } from "./db-types.js";
7
- import { getDb } from "./db-utils.js";
1
+ import type { Interaction, ProjectInfo, SessionInfo, Stats } from "./types.js";
2
+ import { getDb } from "./utils.js";
8
3
 
9
4
  type SearchRow = {
10
5
  session_id: string;
@@ -3,9 +3,9 @@
3
3
  */
4
4
 
5
5
  import * as os from "node:os";
6
- import { getTranscriptPath, parseTranscript } from "./db-transcript.js";
7
- import type { ParsedInteraction } from "./db-types.js";
8
- import { getDb, getProjectPath } from "./db-utils.js";
6
+ import { getTranscriptPath, parseTranscript } from "./transcript.js";
7
+ import type { ParsedInteraction } from "./types.js";
8
+ import { getDb, getProjectPath } from "./utils.js";
9
9
 
10
10
  interface SaveInteractionsResult {
11
11
  success: boolean;
@@ -7,10 +7,10 @@ import * as path from "node:path";
7
7
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8
8
  import { z } from "zod";
9
9
 
10
- import { markSessionCommitted } from "./db-save.js";
11
- import { getTranscriptPath, parseTranscript } from "./db-transcript.js";
12
- import { fail, ok } from "./db-types.js";
13
- import { getProjectPath, readJsonFile } from "./db-utils.js";
10
+ import { markSessionCommitted } from "./save.js";
11
+ import { getTranscriptPath, parseTranscript } from "./transcript.js";
12
+ import { fail, ok } from "./types.js";
13
+ import { getProjectPath, readJsonFile } from "./utils.js";
14
14
 
15
15
  interface SessionSummaryParams {
16
16
  claudeSessionId: string;
@@ -182,9 +182,7 @@ export function registerSessionSummaryTool(server: McpServer) {
182
182
  "mneme_update_session_summary",
183
183
  {
184
184
  description:
185
- "Update session JSON file with summary data. " +
186
- "MUST be called during /mneme:save Phase 3 to persist session metadata. " +
187
- "Creates the session file if it does not exist (e.g. when SessionStart hook was skipped).",
185
+ "Update session JSON with summary data for /mneme:save Phase 3.",
188
186
  inputSchema: {
189
187
  claudeSessionId: z
190
188
  .string()
@@ -6,25 +6,23 @@
6
6
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
7
7
  import { z } from "zod";
8
8
 
9
- import { lintRules, runSearchBenchmark } from "./db-benchmark.js";
10
- import { getInteractions } from "./db-queries.js";
11
- import { markSessionCommitted } from "./db-save.js";
9
+ import { lintRules, runSearchBenchmark } from "./benchmark.js";
10
+ import { getInteractions } from "./queries.js";
11
+ import { markSessionCommitted } from "./save.js";
12
12
  import {
13
13
  fail,
14
14
  LIST_LIMIT_MIN,
15
15
  ok,
16
16
  SEARCH_EVAL_DEFAULT_LIMIT,
17
- } from "./db-types.js";
18
- import { getDb, readSessionsById } from "./db-utils.js";
17
+ } from "./types.js";
18
+ import { getDb, readSessionsById } from "./utils.js";
19
19
 
20
20
  export function registerExtendedTools(server: McpServer) {
21
21
  server.registerTool(
22
22
  "mneme_mark_session_committed",
23
23
  {
24
24
  description:
25
- "Mark a session as committed (saved with /mneme:save). " +
26
- "This prevents the session's interactions from being deleted on SessionEnd. " +
27
- "Call this after successfully saving session data.",
25
+ "Mark session as committed to prevent cleanup on SessionEnd.",
28
26
  inputSchema: {
29
27
  claudeSessionId: z
30
28
  .string()
@@ -46,8 +44,7 @@ export function registerExtendedTools(server: McpServer) {
46
44
  server.registerTool(
47
45
  "mneme_session_timeline",
48
46
  {
49
- description:
50
- "Build timeline for one session or a resume-chain using sessions metadata and interactions.",
47
+ description: "Build timeline for a session or its resume-chain.",
51
48
  inputSchema: {
52
49
  sessionId: z.string().min(1).describe("Session ID (short or full)"),
53
50
  includeChain: z
@@ -122,8 +119,7 @@ export function registerExtendedTools(server: McpServer) {
122
119
  server.registerTool(
123
120
  "mneme_rule_linter",
124
121
  {
125
- description:
126
- "Lint rules for schema and quality (required fields, priority, clarity, duplicates).",
122
+ description: "Lint rules for schema and quality.",
127
123
  inputSchema: {
128
124
  ruleType: z
129
125
  .enum(["dev-rules", "review-guidelines", "all"])
@@ -139,8 +135,7 @@ export function registerExtendedTools(server: McpServer) {
139
135
  server.registerTool(
140
136
  "mneme_search_eval",
141
137
  {
142
- description:
143
- "Run/compare search benchmark and emit regression summary. Intended for CI and save-time quality checks.",
138
+ description: "Run/compare search benchmark for quality checks.",
144
139
  inputSchema: {
145
140
  mode: z
146
141
  .enum(["run", "compare", "regression"])
@@ -7,8 +7,8 @@ import * as os from "node:os";
7
7
  import * as path from "node:path";
8
8
  import * as readline from "node:readline";
9
9
 
10
- import type { ParsedInteraction, ParsedTranscript } from "./db-types.js";
11
- import { getProjectPath } from "./db-utils.js";
10
+ import type { ParsedInteraction, ParsedTranscript } from "./types.js";
11
+ import { getProjectPath } from "./utils.js";
12
12
 
13
13
  export function getTranscriptPath(claudeSessionId: string): string | null {
14
14
  const projectPath = getProjectPath();
@@ -5,11 +5,7 @@
5
5
  import * as fs from "node:fs";
6
6
  import * as path from "node:path";
7
7
 
8
- import {
9
- DatabaseSync,
10
- type DatabaseSyncType,
11
- type RuleDoc,
12
- } from "./db-types.js";
8
+ import { DatabaseSync, type DatabaseSyncType, type RuleDoc } from "./types.js";
13
9
 
14
10
  export function getProjectPath(): string {
15
11
  return process.env.MNEME_PROJECT_PATH || process.cwd();
@@ -20,10 +20,10 @@ import {
20
20
  getStats,
21
21
  listProjects,
22
22
  listSessions,
23
- } from "./db-queries.js";
24
- import { saveInteractions } from "./db-save.js";
25
- import { registerExtendedTools } from "./db-server-tools.js";
26
- import { registerSessionSummaryTool } from "./db-session-summary.js";
23
+ } from "./db/queries.js";
24
+ import { saveInteractions } from "./db/save.js";
25
+ import { registerSessionSummaryTool } from "./db/session-summary.js";
26
+ import { registerExtendedTools } from "./db/tools.js";
27
27
  import {
28
28
  fail,
29
29
  INTERACTION_OFFSET_MIN,
@@ -31,8 +31,8 @@ import {
31
31
  LIST_LIMIT_MIN,
32
32
  ok,
33
33
  QUERY_MAX_LENGTH,
34
- } from "./db-types.js";
35
- import { getDb } from "./db-utils.js";
34
+ } from "./db/types.js";
35
+ import { getDb } from "./db/utils.js";
36
36
 
37
37
  const server = new McpServer({
38
38
  name: "mneme-db",
@@ -42,8 +42,7 @@ const server = new McpServer({
42
42
  server.registerTool(
43
43
  "mneme_list_projects",
44
44
  {
45
- description:
46
- "List all projects tracked in mneme's local database with session counts and last activity",
45
+ description: "List all projects with session counts and last activity",
47
46
  inputSchema: {},
48
47
  },
49
48
  async () => {
@@ -118,7 +117,7 @@ server.registerTool(
118
117
  "mneme_stats",
119
118
  {
120
119
  description:
121
- "Get statistics across all projects: total counts, per-project breakdown, recent activity",
120
+ "Get statistics: total counts, per-project breakdown, recent activity",
122
121
  inputSchema: {},
123
122
  },
124
123
  async () => {
@@ -131,8 +130,7 @@ server.registerTool(
131
130
  server.registerTool(
132
131
  "mneme_cross_project_search",
133
132
  {
134
- description:
135
- "Search interactions across ALL projects (not just current). Uses FTS5 for fast full-text search.",
133
+ description: "Search interactions across all projects via FTS5.",
136
134
  inputSchema: {
137
135
  query: z.string().max(QUERY_MAX_LENGTH).describe("Search query"),
138
136
  limit: z
@@ -159,10 +157,7 @@ server.registerTool(
159
157
  server.registerTool(
160
158
  "mneme_save_interactions",
161
159
  {
162
- description:
163
- "Save conversation interactions from Claude Code transcript to SQLite. " +
164
- "Use this during /mneme:save to persist the conversation history. " +
165
- "Reads the transcript file directly and extracts user/assistant messages.",
160
+ description: "Save transcript interactions to SQLite for /mneme:save.",
166
161
  inputSchema: {
167
162
  claudeSessionId: z
168
163
  .string()
@@ -11,7 +11,7 @@ import {
11
11
  type QueryableDb,
12
12
  type SearchType,
13
13
  searchKnowledge,
14
- } from "../lib/search-core.js";
14
+ } from "../lib/search/core.js";
15
15
 
16
16
  const { DatabaseSync } = await import("node:sqlite");
17
17
  type DatabaseSyncType = InstanceType<typeof DatabaseSync>;
@@ -131,8 +131,7 @@ const server = new McpServer({
131
131
  server.registerTool(
132
132
  "mneme_search",
133
133
  {
134
- description:
135
- "Search mneme's knowledge base for sessions and interactions. Returns scored results with matched fields.",
134
+ description: "Search mneme's knowledge base for sessions and interactions.",
136
135
  inputSchema: {
137
136
  query: z
138
137
  .string()
@@ -6,6 +6,7 @@ description: |
6
6
  (3) merged PRs contain operational lessons.
7
7
  argument-hint: "<PR-URL>"
8
8
  disable-model-invocation: true
9
+ allowed-tools: Read, Write, Edit, Glob, Grep, Bash
9
10
  ---
10
11
 
11
12
  # /mneme:harvest
@@ -4,7 +4,9 @@ description: |
4
4
  Generate an AI-powered knowledge report from mneme session data.
5
5
  Use when: (1) sharing team progress, (2) reviewing accumulated knowledge,
6
6
  (3) generating weekly/monthly summaries for stakeholders.
7
- disable-model-invocation: false
7
+ disable-model-invocation: true
8
+ context: fork
9
+ allowed-tools: Read, Write, Glob, Grep, AskUserQuestion
8
10
  ---
9
11
 
10
12
  # /mneme:report
@@ -6,6 +6,7 @@ description: |
6
6
  (3) picking up where you left off after a break.
7
7
  argument-hint: "[session-id]"
8
8
  disable-model-invocation: true
9
+ allowed-tools: Read, Write, Edit, Glob, mcp__mneme-db__mneme_get_interactions
9
10
  ---
10
11
 
11
12
  # /mneme:resume
@@ -5,6 +5,7 @@ description: |
5
5
  Use when: (1) finishing meaningful implementation work, (2) capturing reusable guidance,
6
6
  (3) before ending a long session.
7
7
  disable-model-invocation: false
8
+ allowed-tools: Read, Write, Edit, Glob, Grep, Bash, mcp__mneme-db__mneme_save_interactions, mcp__mneme-db__mneme_update_session_summary, mcp__mneme-db__mneme_mark_session_committed, mcp__mneme-db__mneme_rule_linter, mcp__mneme-db__mneme_search_eval
8
9
  ---
9
10
 
10
11
  # /mneme:save
@@ -5,6 +5,7 @@ description: |
5
5
  Use when: (1) looking for past solutions, (2) recalling approved guidance,
6
6
  (3) finding related implementation context.
7
7
  argument-hint: "<query>"
8
+ allowed-tools: mcp__mneme-search__mneme_search, mcp__mneme-search__mneme_get_session
8
9
  ---
9
10
 
10
11
  # /mneme:search
File without changes