@lotargo/memory_plugin 1.6.4 → 1.6.5

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.
@@ -16,14 +16,16 @@ export function registerIdentityTools(server) {
16
16
  factText: optStr().describe("Memory fact text or keyword"),
17
17
  docId: optStr().describe("Document ID, title, or file path"),
18
18
  scope: defStr("project").describe("'project' (default) or 'global'"),
19
+ directory: optStr().describe("Optional workspace/project directory path"),
20
+ project: optStr().describe("Alias for directory"),
19
21
  startLine: optNum().describe("Starting line number in target document"),
20
22
  endLine: optNum().describe("Ending line number in target document"),
21
23
  relationType: defStr("LINKS_TO").describe("Relation type (e.g. 'RULES_FOR', 'IMPLEMENTS', 'EXPLAINS')"),
22
24
  }),
23
25
  },
24
- async ({ action, factText, docId, scope, startLine, endLine, relationType }) => {
26
+ async ({ action, factText, docId, scope, directory, project, startLine, endLine, relationType }) => {
25
27
  const { linkFactToDocument, getLinksForDoc, listAllLinks } = await import("../graph/knowledge_linker.js");
26
- const key = await scopeKey(scope, null, null);
28
+ const key = await scopeKey(scope, null, directory || project || null);
27
29
 
28
30
  if (action === "link" || action === "list_links") {
29
31
  requireProjectKey(key);
@@ -1,125 +1,138 @@
1
- import * as z from "zod/v4";
2
- import { optStr, optNum, defStr, defBool } from "./helpers.js";
3
- import {
4
- rememberFact,
5
- recallFacts,
6
- getFactById,
7
- forgetFacts,
8
- updateFactText,
9
- memoryInfo,
10
- } from "./core/memory_core.js";
11
-
12
- export function registerMemoryTools(server) {
13
- server.registerTool(
14
- "remember",
15
- {
16
- description:
17
- "Save an important, durable fact to memory. Only use for high-signal information " +
18
- "(name, goals, constraints, tech preferences, project conventions). " +
19
- "docId/startLine/endLine/relationType are OPTIONAL and only used to link the fact to a " +
20
- "Knowledge Base document or line range; omit them when no linking is needed. " +
21
- "ttl is OPTIONAL (e.g. '90d', '2w', '24h') expired facts are shown with [EXPIRED] but not auto-deleted. " +
22
- "keep=true protects the fact from forget deletion unless force=true. " +
23
- "tags is OPTIONAL comma-separated text for filtering. " +
24
- "supersedes is OPTIONAL: a number (from recall), id, or text of a fact this one replaces; " +
25
- "the target is then marked [SUPERSEDED]. " +
26
- "Translate the fact into English and keep it concise. " +
27
- "scope: 'project' (default) or 'global'",
28
- inputSchema: z.object({
29
- fact: z.string().describe("The fact to remember, written in English"),
30
- title: optStr().describe("Optional title for the fact. If not specified, one is auto-generated."),
31
- scope: defStr("project").describe("'project' (default) or 'global'"),
32
- docId: optStr().describe("Optional document ID, title, or path to link this fact to"),
33
- startLine: optNum().describe("Optional starting line number in target document"),
34
- endLine: optNum().describe("Optional ending line number in target document"),
35
- relationType: defStr("LINKS_TO").describe("Relation type (e.g. 'RULES_FOR', 'IMPLEMENTS', 'REFERENCES')"),
36
- ttl: optStr().describe("Optional time-to-live, e.g. '90d', '2w', '24h', '12m'"),
37
- keep: defBool(false).describe("Protect the fact from forget deletion unless force=true"),
38
- tags: optStr().describe("Optional comma-separated tags, e.g. 'pref,arch'"),
39
- supersedes: optStr().describe("Optional number, id, or text of the fact this one replaces"),
40
- }),
41
- },
42
- async (args) => ({ content: [{ type: "text", text: await rememberFact(args) }] })
43
- );
44
-
45
- server.registerTool(
46
- "recall",
47
- {
48
- description:
49
- "Show saved facts with any Agent-linked Knowledge Base documents/lines. " +
50
- "scope: 'project', 'global', 'all' (default), or 'list_projects'. " +
51
- "Use project: '<directory path>' with scope 'project'/'all' to read facts of a specific project from any working directory. " +
52
- "query filters by keyword (all space-separated terms must match). " +
53
- "tags filters by comma-separated tags. since/until filter by date (YYYY-MM-DD, inclusive). " +
1
+ import * as z from "zod/v4";
2
+ import { optStr, optNum, defStr, defBool } from "./helpers.js";
3
+ import {
4
+ rememberFact,
5
+ recallFacts,
6
+ getFactById,
7
+ forgetFacts,
8
+ updateFactText,
9
+ memoryInfo,
10
+ } from "./core/memory_core.js";
11
+
12
+ export function registerMemoryTools(server) {
13
+ server.registerTool(
14
+ "remember",
15
+ {
16
+ description:
17
+ "Save an important, durable fact to memory. Only use for high-signal information " +
18
+ "(name, goals, constraints, tech preferences, project conventions). " +
19
+ "directory: optional workspace/project directory path to target (ensures saving into the project store even from external cwd). " +
20
+ "docId/startLine/endLine/relationType are OPTIONAL and only used to link the fact to a " +
21
+ "Knowledge Base document or line range; omit them when no linking is needed. " +
22
+ "ttl is OPTIONAL (e.g. '90d', '2w', '24h') expired facts are shown with [EXPIRED] but not auto-deleted. " +
23
+ "keep=true protects the fact from forget deletion unless force=true. " +
24
+ "tags is OPTIONAL comma-separated text for filtering. " +
25
+ "supersedes is OPTIONAL: a number (from recall), id, or text of a fact this one replaces; " +
26
+ "the target is then marked [SUPERSEDED]. " +
27
+ "Translate the fact into English and keep it concise. " +
28
+ "scope: 'project' (default) or 'global'",
29
+ inputSchema: z.object({
30
+ fact: z.string().describe("The fact to remember, written in English"),
31
+ title: optStr().describe("Optional title for the fact. If not specified, one is auto-generated."),
32
+ scope: defStr("project").describe("'project' (default) or 'global'"),
33
+ directory: optStr().describe("Optional workspace/project directory path to target when scope='project' (e.g. 'F:/projects/my-app')"),
34
+ project: optStr().describe("Alias for directory"),
35
+ docId: optStr().describe("Optional document ID, title, or path to link this fact to"),
36
+ startLine: optNum().describe("Optional starting line number in target document"),
37
+ endLine: optNum().describe("Optional ending line number in target document"),
38
+ relationType: defStr("LINKS_TO").describe("Relation type (e.g. 'RULES_FOR', 'IMPLEMENTS', 'REFERENCES')"),
39
+ ttl: optStr().describe("Optional time-to-live, e.g. '90d', '2w', '24h', '12m'"),
40
+ keep: defBool(false).describe("Protect the fact from forget deletion unless force=true"),
41
+ tags: optStr().describe("Optional comma-separated tags, e.g. 'pref,arch'"),
42
+ supersedes: optStr().describe("Optional number, id, or text of the fact this one replaces"),
43
+ }),
44
+ },
45
+ async (args) => ({ content: [{ type: "text", text: await rememberFact(args) }] })
46
+ );
47
+
48
+ server.registerTool(
49
+ "recall",
50
+ {
51
+ description:
52
+ "Show saved facts with any Agent-linked Knowledge Base documents/lines. " +
53
+ "scope: 'project', 'global', 'all' (default), or 'list_projects'. " +
54
+ "Use directory: '<directory path>' with scope 'project'/'all' to read facts of a specific project from any working directory. " +
55
+ "query filters by keyword (all space-separated terms must match). " +
56
+ "tags filters by comma-separated tags. since/until filter by date (YYYY-MM-DD, inclusive). " +
54
57
  "Superseded facts are excluded by default; pass includeSuperseded=true to inspect history. " +
55
58
  "Expired facts are shown with [EXPIRED], protected ones with [KEEP]. The response includes the store file paths.",
56
- inputSchema: z.object({
57
- scope: defStr("all").describe("'project', 'global', 'all', or 'list_projects'"),
58
- project: optStr().describe("Directory path of the project to read facts from (e.g. 'F:/projects/plugins/memory')"),
59
- query: optStr().describe("Optional keyword filter; all space-separated terms must match"),
60
- tags: optStr().describe("Optional comma-separated tag filter (any match)"),
61
- since: optStr().describe("Optional start date filter, YYYY-MM-DD (inclusive)"),
62
- until: optStr().describe("Optional end date filter, YYYY-MM-DD (inclusive)"),
63
- mode: z.enum(["headers", "full"]).nullish().transform((v) => v || "full").describe("Result mode: 'full' (with body, default) or 'headers' (title and badges only)"),
64
- offset: optNum().describe("Pagination offset (optional)"),
59
+ inputSchema: z.object({
60
+ scope: defStr("all").describe("'project', 'global', 'all', or 'list_projects'"),
61
+ directory: optStr().describe("Directory path of the project to read facts from (e.g. 'F:/projects/plugins/memory')"),
62
+ project: optStr().describe("Alias for directory"),
63
+ query: optStr().describe("Optional keyword filter; all space-separated terms must match"),
64
+ tags: optStr().describe("Optional comma-separated tag filter (any match)"),
65
+ since: optStr().describe("Optional start date filter, YYYY-MM-DD (inclusive)"),
66
+ until: optStr().describe("Optional end date filter, YYYY-MM-DD (inclusive)"),
67
+ mode: z.enum(["headers", "full"]).nullish().transform((v) => v || "full").describe("Result mode: 'full' (with body, default) or 'headers' (title and badges only)"),
68
+ offset: optNum().describe("Pagination offset (optional)"),
65
69
  limit: optNum().describe("Pagination limit (optional)"),
66
70
  includeSuperseded: defBool(false).describe("Include superseded historical facts (excluded by default)"),
67
- }),
68
- },
69
- async (args) => ({ content: [{ type: "text", text: await recallFacts(args) }] })
70
- );
71
-
72
- server.registerTool(
73
- "get_fact",
74
- {
75
- description: "Get the full text and metadata of a single fact by its metadata id.",
76
- inputSchema: z.object({
77
- id: z.string().describe("The unique metadata id of the fact (e.g. '8f3a2c')"),
78
- scope: defStr("all").describe("'project', 'global', or 'all' (default)"),
79
- }),
80
- },
81
- async (args) => ({ content: [{ type: "text", text: await getFactById(args) }] })
82
- );
83
-
84
- server.registerTool(
85
- "forget",
86
- {
87
- description:
88
- "Delete a fact by number (from recall), by range (e.g. '3-30', inclusive), or by text search. " +
89
- "Protected facts (remember with keep=true) are skipped unless force=true.",
90
- inputSchema: z.object({
91
- query: z.string().describe("Number, range like '3-30', or text to search for"),
92
- scope: defStr("project").describe("'project' (default) or 'global'"),
93
- force: defBool(false).describe("Also delete protected (keep) facts"),
94
- }),
95
- },
96
- async (args) => ({ content: [{ type: "text", text: await forgetFacts(args) }] })
97
- );
98
-
99
- server.registerTool(
100
- "update_fact",
101
- {
102
- description:
103
- "Update the text of an existing fact by number (from recall), id, or text match, " +
104
- "preserving its original date and metadata. Linked Knowledge Base documents are re-pointed to the new text.",
105
- inputSchema: z.object({
106
- id: z.string().describe("Number (from recall), metadata id, or text of the fact to update"),
107
- newText: z.string().describe("New fact text"),
108
- title: optStr().describe("Optional new title for the fact"),
109
- scope: defStr("project").describe("'project' (default) or 'global'"),
110
- }),
111
- },
112
- async (args) => ({ content: [{ type: "text", text: await updateFactText(args) }] })
113
- );
114
-
115
- server.registerTool(
116
- "memory_info",
117
- {
118
- description:
119
- "Show memory storage paths (store file locations, MEMORY_DIR, SQLite DB), fact counts, " +
120
- "Knowledge Base stats, and the installed package version.",
121
- inputSchema: z.object({}),
122
- },
123
- async () => ({ content: [{ type: "text", text: await memoryInfo() }] })
124
- );
125
- }
71
+ }),
72
+ },
73
+ async (args) => ({ content: [{ type: "text", text: await recallFacts(args) }] })
74
+ );
75
+
76
+ server.registerTool(
77
+ "get_fact",
78
+ {
79
+ description: "Get the full text and metadata of a single fact by its metadata id.",
80
+ inputSchema: z.object({
81
+ id: z.string().describe("The unique metadata id of the fact (e.g. '8f3a2c')"),
82
+ scope: defStr("all").describe("'project', 'global', or 'all' (default)"),
83
+ directory: optStr().describe("Optional workspace/project directory path"),
84
+ project: optStr().describe("Alias for directory"),
85
+ }),
86
+ },
87
+ async (args) => ({ content: [{ type: "text", text: await getFactById(args) }] })
88
+ );
89
+
90
+ server.registerTool(
91
+ "forget",
92
+ {
93
+ description:
94
+ "Delete a fact by number (from recall), by range (e.g. '3-30', inclusive), or by text search. " +
95
+ "Protected facts (remember with keep=true) are skipped unless force=true.",
96
+ inputSchema: z.object({
97
+ query: z.string().describe("Number, range like '3-30', or text to search for"),
98
+ scope: defStr("project").describe("'project' (default) or 'global'"),
99
+ directory: optStr().describe("Optional workspace/project directory path"),
100
+ project: optStr().describe("Alias for directory"),
101
+ force: defBool(false).describe("Also delete protected (keep) facts"),
102
+ }),
103
+ },
104
+ async (args) => ({ content: [{ type: "text", text: await forgetFacts(args) }] })
105
+ );
106
+
107
+ server.registerTool(
108
+ "update_fact",
109
+ {
110
+ description:
111
+ "Update the text of an existing fact by number (from recall), id, or text match, " +
112
+ "preserving its original date and metadata. Linked Knowledge Base documents are re-pointed to the new text.",
113
+ inputSchema: z.object({
114
+ id: z.string().describe("Number (from recall), metadata id, or text of the fact to update"),
115
+ newText: z.string().describe("New fact text"),
116
+ title: optStr().describe("Optional new title for the fact"),
117
+ scope: defStr("project").describe("'project' (default) or 'global'"),
118
+ directory: optStr().describe("Optional workspace/project directory path"),
119
+ project: optStr().describe("Alias for directory"),
120
+ }),
121
+ },
122
+ async (args) => ({ content: [{ type: "text", text: await updateFactText(args) }] })
123
+ );
124
+
125
+ server.registerTool(
126
+ "memory_info",
127
+ {
128
+ description:
129
+ "Show memory storage paths (store file locations, MEMORY_DIR, SQLite DB), fact counts, " +
130
+ "Knowledge Base stats, and the installed package version.",
131
+ inputSchema: z.object({
132
+ directory: optStr().describe("Optional workspace/project directory path to inspect (default: current directory)"),
133
+ project: optStr().describe("Alias for directory"),
134
+ }),
135
+ },
136
+ async (args) => ({ content: [{ type: "text", text: await memoryInfo(args) }] })
137
+ );
138
+ }