@yandy0725/pi-memory 1.3.1 → 1.3.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.
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.3.1",
6
+ "version": "1.3.2",
7
7
  "description": "File-system driven persistent memory layer for pi coding agent",
8
8
  "license": "MIT",
9
9
  "repository": {
package/src/dream.ts CHANGED
@@ -3,7 +3,7 @@ import type { ModelRegistry } from "@earendil-works/pi-coding-agent";
3
3
  import { runHeadlessAgent } from "./agent-runner";
4
4
  import type { SessionPersistenceConfig, ThinkLevel } from "./config";
5
5
 
6
- /** Build dream consolidation task. (unchanged) */
6
+ /** Build dream consolidation task. */
7
7
  export function buildDreamTask(memoryDir: string, maxLines: number): string {
8
8
  return `You are a memory consolidation agent. Your job is to read all memory files
9
9
  and consolidate them into a clean, deduplicated memory store.
@@ -33,6 +33,8 @@ Phase 4 — Prune & Index:
33
33
  description: specific summary that helps LLM match queries (be specific!)
34
34
  type: one of user, feedback, project, reference
35
35
  updated: today's date
36
+ - Ensure entry titles are self-contained and descriptive
37
+ (only titles appear in future sessions' index, not the entry body)
36
38
  - Generate a compact hook (~150 chars) for each topic summarizing its entries
37
39
  - Rebuild MEMORY.md with one line per topic file (max ${maxLines} lines):
38
40
  - [Name](file.md) — hook
@@ -47,7 +49,13 @@ CRITICAL for hooks and descriptions:
47
49
  - Good: "SSH port 2222 on staging; MySQL 30s timeout; Redis auth fix"
48
50
  - Each topic file's \`## Entry Title\` blocks contain the actual memory entries.
49
51
  The MEMORY.md line is just a pointer — only ONE line per topic file.
50
- - When done, output a concise summary of changes (merged N, removed N, moved N, updated N).`;
52
+
53
+ IMPORTANT — Do not prune process rules:
54
+ - "Always do X" / "Never do Y" rules and workflow discipline entries are
55
+ as valuable as technical facts. Do not delete them as "obsolete"
56
+ just because they look like meta-instructions.
57
+
58
+ When done, output a concise summary of changes (merged N, removed N, moved N, updated N).`;
51
59
  }
52
60
 
53
61
  export interface RunDreamOpts {
package/src/extract.ts CHANGED
@@ -35,33 +35,38 @@ export function buildExtractTask(
35
35
  "",
36
36
  "Analyze the conversation snippet below. If you find valuable learnings, persist them using the memory tools.",
37
37
  "",
38
- "You have these tools available:",
39
- "- 'ls' and 'read': list files and read topic files in the memory directory to check for existing topics",
40
- "- memory_search: search across all memory files for relevant existing entries",
41
- "- memory_add: persist a new memory entry to a topic file (creates the topic if new)",
38
+ "## Tools",
39
+ "- ls — list files in the memory directory",
40
+ "- read — read MEMORY.md and topic files to check for existing topics",
41
+ "- memory_search — full-text search across all memory files for related entries",
42
+ "- memory_add — persist a new memory entry to a topic file (creates the topic if new)",
42
43
  "",
43
- "Use 'ls' to list files and 'read' to inspect MEMORY.md and topic files. Use memory_search to find related entries. Use memory_add to write new memories. Do NOT use 'bash', 'write', 'edit', or any other tools.",
44
+ "Do NOT use 'bash', 'write', 'edit', or any other tools.",
44
45
  "",
45
- "Worth remembering:",
46
- "- User preferences, coding style choices, tooling preferences",
47
- "- Project conventions, architecture decisions, naming patterns",
48
- "- Debugging insights, workarounds, gotchas discovered",
49
- '- "Always do X" / "Never do Y" rules',
50
- "- References to external systems or documentation",
46
+ "## Workflow",
47
+ "1. Use ls + read to survey existing topic files and MEMORY.md index.",
48
+ "2. Use memory_search to check for overlapping or related entries.",
49
+ "3. Use memory_add to write new memories — only if the information is novel and valuable.",
51
50
  "",
52
- "NOT worth remembering:",
51
+ "## What to Remember",
52
+ "- Process rules: \"Always do X\" / \"Never do Y\" directives, workflow discipline, reporting standards, self-check habits — treat these as seriously as technical facts",
53
+ "- User preferences: coding style, tool choices, naming conventions, workflow habits",
54
+ "- Project conventions: architecture decisions, file organization, tech stack choices",
55
+ "- Discoveries: debugging workarounds, gotchas, configuration quirks, undocumented behavior",
56
+ "- References: external docs, APIs, or systems the user treats as important",
57
+ "",
58
+ "## What to Skip",
53
59
  "- One-time task instructions or ephemeral details",
54
60
  "- Code snippets or file paths derivable from the project",
55
- "- Information already captured in CLAUDE.md or AGENTS.md",
61
+ "- Information already captured in AGENTS.md",
56
62
  "- Git history or recent changes",
63
+ "- Obvious or trivial observations",
57
64
  "",
58
- "When writing memories:",
59
- "- Use 'ls' and 'read' first to check for existing topic files and MEMORY.md index",
60
- "- Use memory_search to find overlapping or related memories before adding",
61
- "- Use descriptive, self-contained entry titles (only index lines are injected into future sessions)",
62
- '- Choose the appropriate type: user, feedback, project, reference (default "feedback")',
63
- "- Be concise but complete",
64
- "- If unsure, do NOT write anything",
65
+ "## Memory Entry Guidelines",
66
+ "- Entry titles must be self-contained and descriptive (only titles appear in future sessions' index)",
67
+ '- Choose the appropriate type: user, feedback, project, or reference (default "feedback")',
68
+ "- Be concise but complete — one clear point per entry",
69
+ "- When in doubt, skip it",
65
70
  "",
66
71
  "=== Conversation ===",
67
72
  `User: ${truncatedUser}`,
package/src/inject.ts CHANGED
@@ -60,25 +60,7 @@ export async function scanTopics(memoryDir: string): Promise<TopicManifest[]> {
60
60
  return manifests.sort((a, b) => b.mtimeMs - a.mtimeMs);
61
61
  }
62
62
 
63
- function buildSurfacingPrompt(manifest: TopicManifest[], userPrompt: string): string {
64
- const lines = manifest.map((t) => {
65
- return `[${t.type}] ${t.filename} — ${t.description.slice(0, 80)}`;
66
- });
67
63
 
68
- return [
69
- "You are a memory relevance selector. Below is a list of memory topic files and a user message.",
70
- "Select up to N topic files that are relevant to the user's current query.",
71
- "Response format: JSON with a 'selected_files' array of filenames.",
72
- "",
73
- "=== Topic Files ===",
74
- ...lines,
75
- "",
76
- "=== User Message ===",
77
- userPrompt,
78
- "",
79
- 'Return: {"selected_files": ["a.md", "b.md"]}',
80
- ].join("\n");
81
- }
82
64
 
83
65
  export async function injectSurfacedContent(
84
66
  memoryDir: string,
@@ -107,18 +89,27 @@ export async function injectSurfacedContent(
107
89
  return `<relevant_memories>\n${blocks.join("\n\n")}\n</relevant_memories>`;
108
90
  }
109
91
 
110
- /** Build the side-query task prompt. Extracted for testability. */
111
- export function buildSideQueryTask(prompt: string, maxFiles: number): string {
92
+ /** Build the side-query task prompt. */
93
+ export function buildSideQueryTask(
94
+ manifest: TopicManifest[],
95
+ userPrompt: string,
96
+ maxFiles: number,
97
+ ): string {
98
+ const lines = manifest.map((t) =>
99
+ `[${t.type}] ${t.filename} — ${t.description.slice(0, 80)}`,
100
+ );
101
+
112
102
  return [
113
- "Respond with ONLY a JSON object.",
103
+ `You are a memory relevance selector. Select up to ${maxFiles} topic files most relevant to the user query.`,
104
+ "If nothing matches, select none.",
114
105
  "",
115
- "Below is a list of memory topic files and a user query.",
116
- `Select up to ${maxFiles} topic files MOST relevant to the user's current query.`,
117
- 'If nothing is relevant, return {"selected_files": []}.',
106
+ "=== Topic Files ===",
107
+ ...lines,
118
108
  "",
119
- prompt,
109
+ "=== User Query ===",
110
+ userPrompt,
120
111
  "",
121
- 'Respond with EXACTLY: {"selected_files": [...]}',
112
+ 'Respond with ONLY a JSON object: {"selected_files": ["filename.md", ...]}',
122
113
  ].join("\n");
123
114
  }
124
115
 
@@ -151,8 +142,7 @@ export async function runSideQuery(
151
142
  ): Promise<string[]> {
152
143
  const candidates = manifest.filter((t) => !injectedTopics.has(t.filename));
153
144
  if (candidates.length === 0) return [];
154
- const surfacingPrompt = buildSurfacingPrompt(candidates, userPrompt);
155
- const task = buildSideQueryTask(surfacingPrompt, maxFiles);
145
+ const task = buildSideQueryTask(candidates, userPrompt, maxFiles);
156
146
  try {
157
147
  const result = await runHeadlessAgent({
158
148
  task,