pi-hermes-memory 0.7.6 → 0.7.8
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/README.md +80 -33
- package/docs/PUBLISHING.md +1 -1
- package/docs/ROADMAP.md +1 -1
- package/package.json +5 -4
- package/src/constants.ts +7 -3
- package/src/handlers/auto-consolidate.ts +1 -1
- package/src/handlers/background-review.ts +1 -1
- package/src/handlers/correction-detector.ts +1 -1
- package/src/handlers/index-sessions.ts +1 -1
- package/src/handlers/insights.ts +1 -1
- package/src/handlers/interview.ts +1 -1
- package/src/handlers/learn-memory.ts +4 -4
- package/src/handlers/preview-context.ts +5 -15
- package/src/handlers/session-flush.ts +1 -1
- package/src/handlers/skill-auto-trigger.ts +24 -4
- package/src/handlers/skills-command.ts +749 -23
- package/src/handlers/switch-project.ts +1 -1
- package/src/handlers/sync-markdown-memories.ts +1 -1
- package/src/index.ts +58 -27
- package/src/project.ts +13 -0
- package/src/prompt-context.ts +0 -4
- package/src/skills/procedural-skill-creator/SKILL.md +146 -0
- package/src/store/skill-store.ts +600 -181
- package/src/store/skill-utils.ts +116 -0
- package/src/tools/memory-search-tool.ts +2 -2
- package/src/tools/memory-tool.ts +2 -2
- package/src/tools/session-search-tool.ts +2 -2
- package/src/tools/skill-tool.ts +23 -20
- package/src/types.ts +22 -4
package/README.md
CHANGED
|
@@ -69,7 +69,7 @@ The extension manages three types of knowledge:
|
|
|
69
69
|
|---|---|---|---|
|
|
70
70
|
| **Memory** (MEMORY.md) | Facts — env details, project conventions, tool quirks | 5,000 chars max | Searchable by default |
|
|
71
71
|
| **User Profile** (USER.md) | Who you are — name, preferences, communication style | 5,000 chars max | Searchable by default |
|
|
72
|
-
| **Skills** (
|
|
72
|
+
| **Skills** (Pi-native `SKILL.md`) | Procedures — *how* to do something, reusable across sessions | Unlimited | Discoverable by Pi + manageable via the skill tool |
|
|
73
73
|
|
|
74
74
|

|
|
75
75
|
|
|
@@ -119,7 +119,7 @@ System Prompt
|
|
|
119
119
|
└─────────────────────────────────────────┘
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
-
Set `"memoryPolicyStyle"` to `"full"`, `"compact"`, `"custom"`, or `"none"` to choose policy verbosity while keeping policy-only mode. Set `"memoryMode": "legacy-inject"` to restore the old behavior that injects MEMORY.md, USER.md, project memory, recent failures
|
|
122
|
+
Set `"memoryPolicyStyle"` to `"full"`, `"compact"`, `"custom"`, or `"none"` to choose policy verbosity while keeping policy-only mode. Set `"memoryMode": "legacy-inject"` to restore the old behavior that injects MEMORY.md, USER.md, project memory, and recent failures into the prompt.
|
|
123
123
|
|
|
124
124
|
## Failure Memory
|
|
125
125
|
|
|
@@ -177,13 +177,29 @@ The agent also gets a `skill` tool for saving reusable procedures:
|
|
|
177
177
|
|
|
178
178
|
| Action | What it does |
|
|
179
179
|
|---|---|
|
|
180
|
-
| `create` | Save a new skill (name, description, step-by-step body) |
|
|
181
|
-
| `view` | Read a skill's full content
|
|
182
|
-
| `patch` | Update one section of an existing skill
|
|
183
|
-
| `edit` | Replace the description and/or full body of a skill |
|
|
184
|
-
| `delete` | Remove a skill |
|
|
180
|
+
| `create` | Save a new skill (name, description, step-by-step body, optional `scope`) |
|
|
181
|
+
| `view` | Read a skill's full content by `skill_id`, or list all skills if no id is given |
|
|
182
|
+
| `patch` | Update one section of an existing skill by `skill_id` |
|
|
183
|
+
| `edit` | Replace the description and/or full body of a skill by `skill_id` |
|
|
184
|
+
| `delete` | Remove a skill by `skill_id` |
|
|
185
185
|
|
|
186
|
-
Skills are stored
|
|
186
|
+
Skills are stored in Pi-native locations:
|
|
187
|
+
|
|
188
|
+
- Global skills: `~/.pi/agent/skills/<slug>/SKILL.md`
|
|
189
|
+
- Project skills: `~/.pi/agent/projects-memory/<project>/skills/<slug>/SKILL.md`
|
|
190
|
+
|
|
191
|
+
The extension classifies new skills automatically:
|
|
192
|
+
|
|
193
|
+
- `global` for transferable procedures
|
|
194
|
+
- `project` for repo-specific workflows tied to local paths, scripts, architecture, deploy steps, or conventions
|
|
195
|
+
|
|
196
|
+
Global skill creation also has duplicate/similarity guards:
|
|
197
|
+
|
|
198
|
+
- exact slug match → blocked (update existing via `patch`/`edit`)
|
|
199
|
+
- near-name + high description similarity → blocked as similar (enhance existing)
|
|
200
|
+
- near-name + low description similarity → blocked as name collision (rename to a clearer distinct skill name)
|
|
201
|
+
|
|
202
|
+
Each skill uses a structured `SKILL.md` body:
|
|
187
203
|
|
|
188
204
|
```markdown
|
|
189
205
|
---
|
|
@@ -209,13 +225,23 @@ When you see TypeScript compilation errors, especially in monorepo setups.
|
|
|
209
225
|
Run `tsc --noEmit` and confirm zero errors.
|
|
210
226
|
```
|
|
211
227
|
|
|
228
|
+
### Project Skill Discovery (`resources_discover`)
|
|
229
|
+
|
|
230
|
+
Project-scoped skills are loaded via Pi's `resources_discover` hook.
|
|
231
|
+
|
|
232
|
+
On discovery, the extension returns the active project's skills directory as a skill path:
|
|
233
|
+
|
|
234
|
+
- `~/.pi/agent/projects-memory/<project>/skills/`
|
|
235
|
+
|
|
236
|
+
This lets Pi discover project skills as native skills without copying them into the global skills folder.
|
|
237
|
+
|
|
212
238
|
### Memory vs User Profile vs Skills
|
|
213
239
|
|
|
214
240
|
| Store | File | What goes here | Limit |
|
|
215
241
|
|---|---|---|---|
|
|
216
242
|
| **memory** | `MEMORY.md` | Agent's notes — env facts, project conventions, tool quirks, lessons learned | 5,000 chars |
|
|
217
243
|
| **user** | `USER.md` | User profile — name, preferences, communication style, habits | 5,000 chars |
|
|
218
|
-
| **skills** | `skills
|
|
244
|
+
| **skills** | `~/.pi/agent/skills/<slug>/SKILL.md` or `projects-memory/<project>/skills/<slug>/SKILL.md` | Procedures — *how* to debug, deploy, test, or fix something | Unlimited |
|
|
219
245
|
| **extended** | `sessions.db` | Searchable memories beyond the core limit | Unlimited |
|
|
220
246
|
| **sessions** | `sessions.db` | Past conversation history (searchable via FTS5) | Unlimited |
|
|
221
247
|
|
|
@@ -295,13 +321,13 @@ This means skills build up naturally over time without you having to ask.
|
|
|
295
321
|
| Command | What it does |
|
|
296
322
|
|---|---|
|
|
297
323
|
| `/memory-insights` | Shows everything stored in memory and user profile |
|
|
298
|
-
| `/memory-skills` |
|
|
324
|
+
| `/memory-skills` | Opens an interactive skills manager for search, multi-select, move, and delete |
|
|
299
325
|
| `/memory-consolidate` | Manually trigger memory consolidation to free space |
|
|
300
326
|
| `/memory-interview` | Answer a few questions to pre-fill your user profile |
|
|
301
327
|
| `/memory-switch-project` | List all project memories and their entry counts |
|
|
302
328
|
| `/memory-index-sessions` | Import past Pi sessions into the search database |
|
|
303
329
|
| `/memory-sync-markdown` | Backfill Markdown memories into the SQLite search store |
|
|
304
|
-
| `/memory-preview-context` | Preview the memory policy or legacy memory
|
|
330
|
+
| `/memory-preview-context` | Preview the memory policy or legacy memory blocks appended to the system prompt |
|
|
305
331
|
| `/learn-memory-tool` | Skill that teaches users how to use the memory system |
|
|
306
332
|
|
|
307
333
|
### `/memory-insights` Output
|
|
@@ -324,21 +350,34 @@ This means skills build up naturally over time without you having to ask.
|
|
|
324
350
|
3. codes primarily in TypeScript
|
|
325
351
|
```
|
|
326
352
|
|
|
327
|
-
### `/memory-skills`
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
353
|
+
### `/memory-skills` Manager
|
|
354
|
+
|
|
355
|
+
`/memory-skills` now opens an interactive TUI modal for skill management.
|
|
356
|
+
|
|
357
|
+
Features:
|
|
358
|
+
- fuzzy search by skill name
|
|
359
|
+
- single-list view with scope badges (`[G]` global, `[P]` project)
|
|
360
|
+
- multi-select with spacebar
|
|
361
|
+
- batch move to global or current project
|
|
362
|
+
- batch delete with one confirmation
|
|
363
|
+
- inline action summaries for partial success/conflicts
|
|
364
|
+
|
|
365
|
+
Keybindings:
|
|
366
|
+
- `↑` / `↓` — move focus
|
|
367
|
+
- `space` — toggle selection
|
|
368
|
+
- `/` — focus search
|
|
369
|
+
- `tab` — switch between search and list
|
|
370
|
+
- `g` — move selected skills to global
|
|
371
|
+
- `p` — move selected skills to project
|
|
372
|
+
- `d` — delete selected skills
|
|
373
|
+
- `a` — select all filtered skills
|
|
374
|
+
- `n` — clear selection
|
|
375
|
+
- `esc` — close the modal
|
|
376
|
+
|
|
377
|
+
Move behavior:
|
|
378
|
+
- moves are **conflict-safe**
|
|
379
|
+
- if the destination already contains the same slug, the conflicting skill stays in place
|
|
380
|
+
- batch moves use partial-success semantics: non-conflicting skills move, blocked skills are reported in the summary
|
|
342
381
|
|
|
343
382
|
## Configuration
|
|
344
383
|
|
|
@@ -373,7 +412,7 @@ Create `~/.pi/agent/hermes-memory-config.json`:
|
|
|
373
412
|
|
|
374
413
|
| Setting | Default | Description |
|
|
375
414
|
|---|---|---|
|
|
376
|
-
| `memoryMode` | `policy-only` | Prompt behavior: `policy-only` injects only memory policy; `legacy-inject` restores full memory
|
|
415
|
+
| `memoryMode` | `policy-only` | Prompt behavior: `policy-only` injects only memory policy; `legacy-inject` restores full memory prompt injection |
|
|
377
416
|
| `memoryPolicyStyle` | `full` | Policy text used in `policy-only` mode: `full` preserves the default v0.7 policy; `compact` uses shorter built-in guidance; `custom` uses `memoryPolicyCustomText`; `none` injects no policy text |
|
|
378
417
|
| `memoryPolicyCustomText` | unset | Custom policy text used when `memoryPolicyStyle` is `custom`; blank or missing text falls back to `compact` |
|
|
379
418
|
| `memoryCharLimit` | `5000` | Max characters in MEMORY.md |
|
|
@@ -405,23 +444,29 @@ Create `~/.pi/agent/hermes-memory-config.json`:
|
|
|
405
444
|
|
|
406
445
|
```
|
|
407
446
|
~/.pi/agent/
|
|
447
|
+
├── skills/ ← Global Pi-native skills
|
|
448
|
+
│ ├── debug-typescript-errors/
|
|
449
|
+
│ │ └── SKILL.md
|
|
450
|
+
│ └── testing-checklist/
|
|
451
|
+
│ └── SKILL.md
|
|
408
452
|
├── projects-memory/ ← ALL project-scoped memories (one subfolder per project)
|
|
409
453
|
│ ├── my-project/
|
|
410
|
-
│ │
|
|
454
|
+
│ │ ├── MEMORY.md
|
|
455
|
+
│ │ └── skills/
|
|
456
|
+
│ │ └── deploy-checklist/
|
|
457
|
+
│ │ └── SKILL.md
|
|
411
458
|
│ └── another-project/
|
|
412
459
|
│ └── MEMORY.md
|
|
413
460
|
├── memory/ ← Global memory
|
|
414
461
|
│ ├── MEMORY.md ← Agent's personal notes (env facts, patterns, lessons)
|
|
415
462
|
│ ├── USER.md ← User profile (name, preferences, habits)
|
|
416
463
|
│ ├── sessions.db ← SQLite database (session history + extended memory)
|
|
417
|
-
│ └── skills
|
|
418
|
-
│ ├── debug-typescript-errors.md
|
|
419
|
-
│ └── deploy-checklist.md
|
|
464
|
+
│ └── .skills-migrated-to-pi-native
|
|
420
465
|
├── hermes-memory-config.json
|
|
421
466
|
└── ...
|
|
422
467
|
```
|
|
423
468
|
|
|
424
|
-
These are plain markdown files. You can read and edit them directly if you want to curate what the agent remembers. Memory entries are separated by `§` (section sign). Skills use
|
|
469
|
+
These are plain markdown files. You can read and edit them directly if you want to curate what the agent remembers. Memory entries are separated by `§` (section sign). Skills use Pi-compatible `SKILL.md` files with frontmatter.
|
|
425
470
|
|
|
426
471
|
If you are upgrading from a version that stored project memory directly at `~/.pi/agent/<project>/MEMORY.md`, the extension copies or merges those entries into `~/.pi/agent/projects-memory/<project>/MEMORY.md` on startup. The old folders are left in place as a backup.
|
|
427
472
|
|
|
@@ -435,7 +480,9 @@ The `sessions.db` SQLite database stores session history and extended memory ent
|
|
|
435
480
|
- **Older Markdown memories may need backfill**: If you saved memories before the SQLite mirror existed or search looks stale, run `/memory-sync-markdown`.
|
|
436
481
|
- **Core memory limits still apply**: SQLite search mirroring does not bypass the 5,000-char core Markdown limit. If consolidation cannot free space, the write fails instead of becoming SQLite-only memory invisibly.
|
|
437
482
|
- **System prompts are invisible**: Pi's TUI does not display the system prompt. Use `/memory-preview-context` to inspect whether policy-only or legacy memory injection is active.
|
|
438
|
-
- **
|
|
483
|
+
- **Project skill visibility depends on Pi discovery cycles**: project skills are exposed through `resources_discover` using the active project's `skills/` path. If a moved or newly created project skill doesn't show up immediately in a running session, trigger a reload/new session so Pi refreshes discovered resources.
|
|
484
|
+
- **Project move requires active project context**: in `/memory-skills`, the `p` hotkey is disabled when Pi is not currently in a detected project directory.
|
|
485
|
+
- **Skills are agent-generated**: Skills are created by the agent based on its experience. They may not always be perfectly structured. You can move, delete, or still edit them directly in `~/.pi/agent/skills/` or the active project's `skills/` folder.
|
|
439
486
|
|
|
440
487
|
## Architecture
|
|
441
488
|
|
package/docs/PUBLISHING.md
CHANGED
|
@@ -45,7 +45,7 @@ Target state:
|
|
|
45
45
|
"image": "https://raw.githubusercontent.com/chandra447/pi-hermes-memory/main/docs/assets/hermes-memory-preview.png"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"@
|
|
48
|
+
"@earendil-works/pi-coding-agent": "*"
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
```
|
package/docs/ROADMAP.md
CHANGED
|
@@ -131,7 +131,7 @@ Hermes creates skills after complex tasks (5+ tool calls). Skills are SKILL.md f
|
|
|
131
131
|
**Key insight**: Pi already has a skill system. Our skill tool should write SKILL.md files that are compatible with Pi's skill discovery. This means our skills are immediately usable as Pi slash commands — no separate ecosystem needed.
|
|
132
132
|
|
|
133
133
|
- [ ] `skill` tool — register via `pi.registerTool()` with actions: `create`, `patch`, `edit`, `delete`
|
|
134
|
-
- [
|
|
134
|
+
- [x] Skill storage split by scope: global skills in `~/.pi/agent/skills/<slug>/SKILL.md`, project skills in `~/.pi/agent/projects-memory/<project>/skills/<slug>/SKILL.md` (discovered via `resources_discover`)
|
|
135
135
|
- [ ] SKILL.md format — compatible with Pi's SKILL.md spec (frontmatter + markdown body)
|
|
136
136
|
- [ ] Progressive disclosure — skill index (name + description only) injected into system prompt, full content loaded on demand via `skill_view` action
|
|
137
137
|
- [ ] Auto-trigger after complex tasks — track tool calls per turn, trigger skill extraction at 5+ tool calls
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-hermes-memory",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.8",
|
|
4
4
|
"description": "🧠 Persistent memory + 🔍 session search + 🛡️ secret scanning for Pi. Token-aware policy-only memory by default, SQLite FTS5 search, auto-consolidation, procedural skills. 368 tests. Ported from Hermes agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -45,17 +45,18 @@
|
|
|
45
45
|
"url": "https://github.com/chandra447/pi-hermes-memory"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"@
|
|
48
|
+
"@earendil-works/pi-coding-agent": ">=0.74.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@
|
|
52
|
-
"@
|
|
51
|
+
"@earendil-works/pi-ai": "^0.74.0",
|
|
52
|
+
"@earendil-works/pi-coding-agent": "^0.74.0",
|
|
53
53
|
"@types/better-sqlite3": "^7.6.13",
|
|
54
54
|
"tsx": "^4.21.0",
|
|
55
55
|
"typebox": "^1.1.33",
|
|
56
56
|
"typescript": "^6.0.3"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
+
"@earendil-works/pi-tui": "^0.74.0",
|
|
59
60
|
"better-sqlite3": "^12.9.0"
|
|
60
61
|
}
|
|
61
62
|
}
|
package/src/constants.ts
CHANGED
|
@@ -134,7 +134,7 @@ export const COMBINED_REVIEW_PROMPT = `Review the conversation above and conside
|
|
|
134
134
|
|
|
135
135
|
For failures, include: what was tried, why it failed, what error occurred, and what worked instead.
|
|
136
136
|
|
|
137
|
-
**Skills**: Was a complex, non-trivial approach used to complete a task — one that required trial and error, multiple tool calls, or changing course? If so, save a reusable procedure using the skill tool with action 'create'. Include: when to use it, step-by-step procedure, pitfalls to avoid, and how to verify success. If a related skill already exists, use action 'patch'
|
|
137
|
+
**Skills**: Was a complex, non-trivial approach used to complete a task — one that required trial and error, multiple tool calls, or changing course? If so, save a reusable procedure using the skill tool with action 'create'. Always pass scope explicitly on create (scope='global' or scope='project'). Choose scope='global' for transferable procedures and scope='project' when the workflow depends on this repo's paths, scripts, architecture, deploy steps, or conventions. Include: when to use it, step-by-step procedure, pitfalls to avoid, and how to verify success. If a related skill already exists, use action 'patch' with its skill_id instead of creating a duplicate.
|
|
138
138
|
|
|
139
139
|
Only act if there's something genuinely worth saving. If nothing stands out, just say 'Nothing to save.' and stop.`;
|
|
140
140
|
|
|
@@ -221,13 +221,17 @@ Priority:
|
|
|
221
221
|
Use the memory tool to save. If this contradicts an existing entry, use 'replace' to update it.`;
|
|
222
222
|
|
|
223
223
|
// ─── Skill tool description ───
|
|
224
|
-
export const SKILL_TOOL_DESCRIPTION = `Save reusable procedures and patterns as skills that survive across sessions. Skills are procedural memory — they capture HOW to do something, not just what happened.
|
|
224
|
+
export const SKILL_TOOL_DESCRIPTION = `Save reusable procedures and patterns as Pi-native skills that survive across sessions. Skills are procedural memory — they capture HOW to do something, not just what happened.
|
|
225
225
|
|
|
226
226
|
WHEN TO CREATE A SKILL:
|
|
227
227
|
- After completing a complex task that required trial and error or multiple tool calls
|
|
228
228
|
- When you discover a non-obvious approach that could be reused
|
|
229
229
|
- When the user teaches you a specific workflow or procedure
|
|
230
230
|
|
|
231
|
+
SCOPE:
|
|
232
|
+
- 'global': transferable procedures that can be reused across repositories
|
|
233
|
+
- 'project': procedures tied to this repo's paths, scripts, architecture, deploy flow, or conventions
|
|
234
|
+
|
|
231
235
|
WHEN TO UPDATE A SKILL (use 'patch'):
|
|
232
236
|
- You discover a better approach for an existing skill
|
|
233
237
|
- A pitfall or edge case not covered by the skill
|
|
@@ -238,7 +242,7 @@ SKILL FORMAT:
|
|
|
238
242
|
- description: one-line summary of when to use it
|
|
239
243
|
- body: structured with sections — ## When to Use, ## Procedure, ## Pitfalls, ## Verification
|
|
240
244
|
|
|
241
|
-
ACTIONS: create (new skill), view (read full content), patch (update a section), edit (replace description + body), delete (remove
|
|
245
|
+
ACTIONS: create (new skill), view (read full content or list), patch (update a section by skill_id), edit (replace description + body by skill_id), delete (remove by skill_id).`;
|
|
242
246
|
|
|
243
247
|
// ─── Interview prompt (onboarding) ───
|
|
244
248
|
export const INTERVIEW_PROMPT = `You are conducting a brief onboarding interview with a new user. Your goal is to pre-fill their USER PROFILE so future sessions start with context instead of a blank slate.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* from disk after consolidation completes.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type { ExtensionAPI } from "@
|
|
10
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
11
11
|
import { MemoryStore } from "../store/memory-store.js";
|
|
12
12
|
import { CONSOLIDATION_PROMPT, ENTRY_DELIMITER } from "../constants.js";
|
|
13
13
|
import type { ConsolidationResult } from "../types.js";
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* keeping us within Pi's intended extension API.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type { ExtensionAPI } from "@
|
|
10
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
11
11
|
import { MemoryStore } from "../store/memory-store.js";
|
|
12
12
|
import { COMBINED_REVIEW_PROMPT } from "../constants.js";
|
|
13
13
|
import type { MemoryConfig } from "../types.js";
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - Negative patterns: suppress even if a positive pattern matched
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type { ExtensionAPI } from "@
|
|
11
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
12
12
|
import { MemoryStore } from "../store/memory-store.js";
|
|
13
13
|
import { DatabaseManager } from "../store/db.js";
|
|
14
14
|
import {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import fs from 'node:fs';
|
|
7
7
|
import os from 'node:os';
|
|
8
|
-
import type { ExtensionAPI, ExtensionCommandContext } from "@
|
|
8
|
+
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
9
9
|
import { DatabaseManager } from '../store/db.js';
|
|
10
10
|
import { indexAllSessions, getSessionStats } from '../store/session-indexer.js';
|
|
11
11
|
|
package/src/handlers/insights.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Insights command — /memory-insights shows what's stored in persistent memory.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type { ExtensionAPI } from "@
|
|
5
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
6
6
|
import { MemoryStore } from "../store/memory-store.js";
|
|
7
7
|
|
|
8
8
|
export function registerInsightsCommand(pi: ExtensionAPI, store: MemoryStore, projectStore: MemoryStore | null, projectName: string): void {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* zero value until multiple sessions accumulate facts organically.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type { ExtensionAPI } from "@
|
|
9
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
10
10
|
import { MemoryStore } from "../store/memory-store.js";
|
|
11
11
|
import { INTERVIEW_PROMPT } from "../constants.js";
|
|
12
12
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Learn memory tool command — /learn-memory-tool teaches users about the memory system.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type { ExtensionAPI, ExtensionCommandContext } from "@
|
|
5
|
+
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
6
6
|
|
|
7
7
|
export function registerLearnMemoryCommand(pi: ExtensionAPI): void {
|
|
8
8
|
pi.registerCommand("learn-memory-tool", {
|
|
@@ -34,7 +34,7 @@ export function registerLearnMemoryCommand(pi: ExtensionAPI): void {
|
|
|
34
34
|
lines.push(" 🧠 Memory │ MEMORY.md │ 5,000 chars");
|
|
35
35
|
lines.push(" 👤 User Profile │ USER.md │ 5,000 chars");
|
|
36
36
|
lines.push(" ⚠️ Failures │ failures.md │ 10,000 chars");
|
|
37
|
-
lines.push(" 📚 Skills │
|
|
37
|
+
lines.push(" 📚 Skills │ Pi-native skill dirs │ Unlimited");
|
|
38
38
|
lines.push(" 💾 Extended │ sessions.db │ Unlimited");
|
|
39
39
|
lines.push("");
|
|
40
40
|
lines.push(" Memory: Facts — env details, project conventions, tool quirks");
|
|
@@ -126,7 +126,7 @@ export function registerLearnMemoryCommand(pi: ExtensionAPI): void {
|
|
|
126
126
|
lines.push(" 8. Session ends → Final flush");
|
|
127
127
|
lines.push("");
|
|
128
128
|
lines.push(" Legacy mode: set memoryMode=\"legacy-inject\" to restore full");
|
|
129
|
-
lines.push(" MEMORY.md, USER.md, project memory,
|
|
129
|
+
lines.push(" MEMORY.md, USER.md, project memory, and failure prompt blocks.");
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
if (section.startsWith("🏗️")) {
|
|
@@ -153,7 +153,7 @@ export function registerLearnMemoryCommand(pi: ExtensionAPI): void {
|
|
|
153
153
|
lines.push(" │ memory_search(\"auth\", cat:\"failure\")│");
|
|
154
154
|
lines.push(" └─────────────────────────────────────┘");
|
|
155
155
|
lines.push("");
|
|
156
|
-
lines.push(" Legacy mode can still inject full memory
|
|
156
|
+
lines.push(" Legacy mode can still inject full memory blocks for users");
|
|
157
157
|
lines.push(" who explicitly opt into memoryMode=\"legacy-inject\".");
|
|
158
158
|
}
|
|
159
159
|
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Preview context command — /memory-preview-context shows the policy-only prompt
|
|
3
|
-
* or legacy memory
|
|
3
|
+
* or legacy memory blocks appended to the system prompt.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { ExtensionAPI } from "@
|
|
6
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
7
7
|
import { MemoryStore } from "../store/memory-store.js";
|
|
8
|
-
import { SkillStore } from "../store/skill-store.js";
|
|
9
8
|
import { resolveMemoryPolicyPrompt } from "../prompt-context.js";
|
|
10
9
|
import type { MemoryConfig } from "../types.js";
|
|
11
10
|
|
|
@@ -13,12 +12,11 @@ export function registerPreviewContextCommand(
|
|
|
13
12
|
pi: ExtensionAPI,
|
|
14
13
|
store: MemoryStore,
|
|
15
14
|
projectStore: MemoryStore | null,
|
|
16
|
-
skillStore: SkillStore,
|
|
17
15
|
projectName: string,
|
|
18
16
|
config: Pick<MemoryConfig, "memoryMode" | "memoryPolicyStyle" | "memoryPolicyCustomText"> = { memoryMode: "policy-only" },
|
|
19
17
|
): void {
|
|
20
18
|
pi.registerCommand("memory-preview-context", {
|
|
21
|
-
description: "Preview the memory policy or legacy memory
|
|
19
|
+
description: "Preview the memory policy or legacy memory context blocks",
|
|
22
20
|
handler: async (_args, ctx) => {
|
|
23
21
|
if (config.memoryMode === "policy-only") {
|
|
24
22
|
const policyPrompt = resolveMemoryPolicyPrompt(config);
|
|
@@ -48,7 +46,6 @@ export function registerPreviewContextCommand(
|
|
|
48
46
|
|
|
49
47
|
const memoryBlock = store.formatForSystemPrompt();
|
|
50
48
|
const projectBlock = projectStore ? projectStore.formatProjectBlock(projectName) : "";
|
|
51
|
-
const skillIndex = await skillStore.formatIndexForSystemPrompt();
|
|
52
49
|
|
|
53
50
|
const lines: string[] = [];
|
|
54
51
|
lines.push("");
|
|
@@ -56,7 +53,7 @@ export function registerPreviewContextCommand(
|
|
|
56
53
|
lines.push(" ║ 👀 Injected Context Preview ║");
|
|
57
54
|
lines.push(" ╚══════════════════════════════════════════════╝");
|
|
58
55
|
lines.push("");
|
|
59
|
-
lines.push(" This is the memory
|
|
56
|
+
lines.push(" This is the memory context appended to the system prompt.");
|
|
60
57
|
lines.push(" (Core hidden system instructions are NOT shown.)");
|
|
61
58
|
lines.push("");
|
|
62
59
|
|
|
@@ -76,16 +73,9 @@ export function registerPreviewContextCommand(
|
|
|
76
73
|
lines.push("");
|
|
77
74
|
}
|
|
78
75
|
|
|
79
|
-
if (skillIndex) {
|
|
80
|
-
blockCount++;
|
|
81
|
-
lines.push(" ── SKILL INDEX ─────────────────────────────────────────────");
|
|
82
|
-
lines.push(skillIndex);
|
|
83
|
-
lines.push("");
|
|
84
|
-
}
|
|
85
|
-
|
|
86
76
|
if (blockCount === 0) {
|
|
87
77
|
lines.push(" No memory context blocks are currently injected.");
|
|
88
|
-
lines.push(" Add memory entries
|
|
78
|
+
lines.push(" Add memory entries, then run this command again.");
|
|
89
79
|
lines.push("");
|
|
90
80
|
}
|
|
91
81
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* See PLAN.md → "Hermes Source File Reference Map" for source lines.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { ExtensionAPI } from "@
|
|
7
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
8
8
|
import { MemoryStore } from "../store/memory-store.js";
|
|
9
9
|
import { FLUSH_PROMPT } from "../constants.js";
|
|
10
10
|
import type { MemoryConfig } from "../types.js";
|
|
@@ -5,13 +5,22 @@
|
|
|
5
5
|
* This implements Hermes' "self-evaluation checkpoint" pattern.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
9
11
|
import { MemoryStore } from "../store/memory-store.js";
|
|
10
12
|
import { SkillStore } from "../store/skill-store.js";
|
|
11
13
|
import { COMBINED_REVIEW_PROMPT, DEFAULT_SKILL_TRIGGER_TOOL_CALLS, ENTRY_DELIMITER } from "../constants.js";
|
|
12
14
|
import type { MemoryConfig } from "../types.js";
|
|
13
15
|
import { getMessageText } from "../types.js";
|
|
14
16
|
|
|
17
|
+
const proceduralSkillCreatorPath = path.join(
|
|
18
|
+
path.dirname(fileURLToPath(import.meta.url)),
|
|
19
|
+
"..",
|
|
20
|
+
"skills",
|
|
21
|
+
"procedural-skill-creator",
|
|
22
|
+
);
|
|
23
|
+
|
|
15
24
|
export function setupSkillAutoTrigger(
|
|
16
25
|
pi: ExtensionAPI,
|
|
17
26
|
store: MemoryStore,
|
|
@@ -71,10 +80,21 @@ export function setupSkillAutoTrigger(
|
|
|
71
80
|
|
|
72
81
|
const currentMemory = store.getMemoryEntries().join(ENTRY_DELIMITER);
|
|
73
82
|
const skillIndex = await skillStore.loadIndex();
|
|
74
|
-
const skillSummary = skillIndex
|
|
83
|
+
const skillSummary = skillIndex
|
|
84
|
+
.map((skill) => `${skill.skillId} [${skill.scope}]: ${skill.displayName || skill.name} - ${skill.description}`)
|
|
85
|
+
.join("\n");
|
|
86
|
+
|
|
87
|
+
const activeProjectName = skillStore.getProjectName();
|
|
88
|
+
const scopeLine = activeProjectName
|
|
89
|
+
? `Active project context: '${activeProjectName}'. If workflow details depend on this project, use scope='project'; otherwise use scope='global'.`
|
|
90
|
+
: "No active project context detected. Use scope='global' unless the workflow is clearly project-specific.";
|
|
75
91
|
|
|
76
92
|
const prompt = [
|
|
77
93
|
"This was a complex task that required multiple tool calls. Extract any reusable procedures as skills.",
|
|
94
|
+
"A bundled skill named procedural-skill-creator is loaded for you. Read and follow it before deciding whether to create or patch a skill.",
|
|
95
|
+
"Always pass scope explicitly when creating a skill: scope='global' or scope='project'.",
|
|
96
|
+
"Choose scope='global' for transferable procedures and scope='project' when the workflow depends on this repo's paths, scripts, architecture, deploy steps, or conventions.",
|
|
97
|
+
scopeLine,
|
|
78
98
|
"",
|
|
79
99
|
"--- Existing Skills ---",
|
|
80
100
|
skillSummary || "(none)",
|
|
@@ -86,11 +106,11 @@ export function setupSkillAutoTrigger(
|
|
|
86
106
|
recentParts.join("\n\n"),
|
|
87
107
|
"",
|
|
88
108
|
"If a skill should be created, use the skill tool with action 'create'.",
|
|
89
|
-
"If a related skill already exists, use 'patch' to update it.",
|
|
109
|
+
"If a related skill already exists, use 'patch' with its skill_id to update it.",
|
|
90
110
|
"If nothing reusable happened, say 'Nothing to extract.' and stop.",
|
|
91
111
|
].join("\n");
|
|
92
112
|
|
|
93
|
-
const result = await pi.exec("pi", ["-p", "--no-session", prompt], {
|
|
113
|
+
const result = await pi.exec("pi", ["-p", "--no-session", "--skill", proceduralSkillCreatorPath, prompt], {
|
|
94
114
|
signal: ctx.signal,
|
|
95
115
|
timeout: 60000,
|
|
96
116
|
});
|