Skip to content

Commit 5f80454

Browse files
phernandezclaude
andcommitted
feat: bundle skills in plugin and seed Task schema on startup
- Bundle 4 skills (memory-tasks, memory-reflect, memory-defrag, memory-schema) directly in the plugin via openclaw.plugin.json skills array - Seed Task schema note on first startup (check-before-write, non-fatal) - Add schema/task-schema.ts with canonical Task Picoschema definition - Update docs: bundled skills replace manual cp instructions, add npx skills as update path for users who want latest upstream skills - Add readNote/writeNote mocks to index.test.ts for schema seed coverage Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1265e1c commit 5f80454

File tree

11 files changed

+645
-29
lines changed

11 files changed

+645
-29
lines changed

MEMORY_TASK_FLOW.md

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -134,24 +134,19 @@ Use `bm_edit` (`find_replace`) to change `status: active` to `status: done`.
134134
3. Ensure `memoryDir` points to the directory that contains your `tasks/` folder.
135135
4. If task search looks wrong, verify `bm watch` is running and notes exist in expected paths.
136136

137-
## Companion Skills (Optional)
137+
## Bundled Skills
138138

139-
The companion repo
140-
[`basic-memory-skills`](https://github.com/basicmachines-co/basic-memory-skills)
141-
adds workflow-oriented skills that fit this plugin:
139+
This plugin ships with workflow-oriented skills that are automatically loaded when the plugin is enabled:
142140

143-
- `memory-tasks`: standardized task creation/resume/update flow
144-
- `memory-reflect`: periodic memory consolidation from recent notes
145-
- `memory-defrag`: periodic cleanup/reorganization of memory files
141+
- **`memory-tasks`** — standardized task creation/resume/update flow
142+
- **`memory-reflect`** — periodic memory consolidation from recent notes
143+
- **`memory-defrag`** — periodic cleanup/reorganization of memory files
144+
- **`memory-schema`** — schema lifecycle management (infer, create, validate, diff, evolve)
146145

147-
Install into your workspace:
146+
No manual installation needed. To update skills or install new ones as they become available:
148147

149148
```bash
150-
git clone https://github.com/basicmachines-co/basic-memory-skills.git
151-
cp -r basic-memory-skills/memory-tasks ~/.openclaw/workspace/skills/
152-
cp -r basic-memory-skills/memory-reflect ~/.openclaw/workspace/skills/
153-
cp -r basic-memory-skills/memory-defrag ~/.openclaw/workspace/skills/
149+
npx skills add basicmachines-co/basic-memory-skills --agent openclaw
154150
```
155151

156-
Use `~/.openclaw/skills/` instead if you want shared skills across agents/workspaces.
157-
After installing, start a new session so OpenClaw reloads the skill snapshot.
152+
See the upstream source at [`basic-memory-skills`](https://github.com/basicmachines-co/basic-memory-skills).

README.md

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -84,28 +84,30 @@ If you prefer loading directly from a path in config instead of `plugins install
8484
}
8585
```
8686

87-
### Optional: Install Companion Skills
87+
### Bundled Skills
8888

89-
You can pair this plugin with skills from
90-
[`basic-memory-skills`](https://github.com/basicmachines-co/basic-memory-skills):
89+
This plugin ships with four skills that are automatically available when the plugin is enabled — no manual installation needed:
9190

92-
- `memory-tasks` — structured task tracking that survives compaction
93-
- `memory-reflect` — periodic consolidation of recent notes into durable memory
94-
- `memory-defrag` — periodic cleanup/reorganization of memory files
91+
- **`memory-tasks`** — structured task tracking that survives context compaction
92+
- **`memory-reflect`** — periodic consolidation of recent notes into durable memory
93+
- **`memory-defrag`** — periodic cleanup/reorganization of memory files
94+
- **`memory-schema`** — schema lifecycle management (infer, create, validate, diff, evolve)
9595

96-
Install (workspace-local):
96+
Skills are loaded from the plugin's `skills/` directory. See the upstream source at [`basic-memory-skills`](https://github.com/basicmachines-co/basic-memory-skills).
97+
98+
#### Updating or adding skills with `npx skills`
99+
100+
You can update bundled skills or install new ones as they become available using the [Skills CLI](https://github.com/vercel-labs/skills):
97101

98102
```bash
99-
git clone https://github.com/basicmachines-co/basic-memory-skills.git
100-
cp -r basic-memory-skills/memory-tasks ~/.openclaw/workspace/skills/
101-
cp -r basic-memory-skills/memory-reflect ~/.openclaw/workspace/skills/
102-
cp -r basic-memory-skills/memory-defrag ~/.openclaw/workspace/skills/
103-
```
103+
# Update all basic-memory skills to latest
104+
npx skills add basicmachines-co/basic-memory-skills --agent openclaw
104105

105-
If you want these skills available to multiple workspaces/agents on the same machine,
106-
install to `~/.openclaw/skills/` instead.
106+
# Install a specific skill
107+
npx skills add basicmachines-co/basic-memory-skills --name memory-tasks --agent openclaw
108+
```
107109

108-
After installation, start a new OpenClaw session so the refreshed skill set is loaded.
110+
This installs to the same `skills/` directory the plugin reads from, so updated skills take effect on the next session.
109111

110112
## Configuration
111113

index.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ describe("plugin service lifecycle", () => {
1414
const ensureProjectSpy = jest
1515
.spyOn(BmClient.prototype, "ensureProject")
1616
.mockResolvedValue(undefined)
17+
const readNoteSpy = jest
18+
.spyOn(BmClient.prototype, "readNote")
19+
.mockRejectedValue(new Error("Entity not found"))
20+
const writeNoteSpy = jest
21+
.spyOn(BmClient.prototype, "writeNote")
22+
.mockResolvedValue(undefined as any)
1723
const stopSpy = jest
1824
.spyOn(BmClient.prototype, "stop")
1925
.mockResolvedValue(undefined)
@@ -53,6 +59,14 @@ describe("plugin service lifecycle", () => {
5359
expect(startSpy).toHaveBeenCalledWith({ cwd: "/tmp/workspace" })
5460
expect(ensureProjectSpy).toHaveBeenCalledWith("/tmp/workspace/memory")
5561

62+
// Schema seed: readNote throws "not found" → writeNote called
63+
expect(readNoteSpy).toHaveBeenCalledWith("schema/Task")
64+
expect(writeNoteSpy).toHaveBeenCalledWith(
65+
"Task",
66+
expect.stringContaining("type: schema"),
67+
"schema",
68+
)
69+
5670
await services[0].stop()
5771

5872
expect(stopSpy).toHaveBeenCalledTimes(1)

index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
} from "./config.ts"
1010
import { buildCaptureHandler } from "./hooks/capture.ts"
1111
import { initLogger, log } from "./logger.ts"
12+
import { TASK_SCHEMA_CONTENT } from "./schema/task-schema.ts"
1213
import { registerContextTool } from "./tools/context.ts"
1314
import { registerDeleteTool } from "./tools/delete.ts"
1415
import { registerEditTool } from "./tools/edit.ts"
@@ -83,6 +84,19 @@ export default {
8384
await client.ensureProject(projectPath)
8485
log.debug(`project "${cfg.project}" at ${projectPath}`)
8586

87+
// Seed Task schema if not already present
88+
try {
89+
await client.readNote("schema/Task")
90+
log.debug("Task schema already exists, skipping seed")
91+
} catch {
92+
try {
93+
await client.writeNote("Task", TASK_SCHEMA_CONTENT, "schema")
94+
log.debug("seeded Task schema note")
95+
} catch (err) {
96+
log.debug("Task schema seed failed (non-fatal)", err)
97+
}
98+
}
99+
86100
setWorkspaceDir(workspace)
87101

88102
log.info("connected — BM MCP stdio session running")

openclaw.plugin.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
{
22
"id": "basic-memory",
33
"kind": "memory",
4+
"skills": [
5+
"skills/memory-tasks",
6+
"skills/memory-reflect",
7+
"skills/memory-defrag",
8+
"skills/memory-schema"
9+
],
410
"uiHints": {
511
"project": {
612
"label": "Project Name",

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
"tools/search.ts",
2626
"tools/write.ts",
2727
"types/openclaw.d.ts",
28+
"schema/task-schema.ts",
29+
"skills/",
2830
"openclaw.plugin.json",
2931
"README.md",
3032
"LICENSE"

schema/task-schema.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Canonical Task schema note content, seeded into new projects on first startup.
3+
* If the schema already exists (user may have customized it), seeding is skipped.
4+
*/
5+
export const TASK_SCHEMA_CONTENT = `---
6+
title: Task
7+
type: schema
8+
entity: Task
9+
version: 1
10+
schema:
11+
description: string, what needs to be done
12+
status?(enum): [active, blocked, done, abandoned], current state
13+
assigned_to?: string, who is working on this
14+
steps?(array): string, ordered steps to complete
15+
current_step?: integer, which step number we're on (1-indexed)
16+
context?: string, key context needed to resume after memory loss
17+
started?: string, when work began
18+
completed?: string, when work finished
19+
blockers?(array): string, what's preventing progress
20+
parent_task?: Task, parent task if this is a subtask
21+
settings:
22+
validation: warn
23+
---
24+
25+
# Task
26+
27+
Structured task note for tracking multi-step work that survives context compaction.
28+
29+
## Observations
30+
- [convention] Task files live in memory/tasks/ with format YYYY-MM-DD-short-name.md
31+
- [convention] Status transitions: active → blocked → done or abandoned
32+
- [convention] Include a ## Context section for resumption after memory loss
33+
- [convention] Include a ## Steps section with numbered checkbox items for step tracking
34+
`

skills/memory-defrag/SKILL.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
name: memory-defrag
3+
description: "Defragment and reorganize agent memory files: split bloated files, merge duplicates, remove stale information, and restructure the memory hierarchy. Use when memory files have grown unwieldy, contain redundancies, or need reorganization. Run periodically (weekly) or on demand."
4+
---
5+
6+
# Memory Defrag
7+
8+
Reorganize memory files for clarity, efficiency, and relevance. Like filesystem defragmentation but for knowledge.
9+
10+
## When to Run
11+
12+
- **Periodic**: Weekly or biweekly via cron (recommended)
13+
- **On demand**: User asks to clean up, reorganize, or defrag memory
14+
- **Threshold**: When MEMORY.md exceeds ~500 lines or daily notes accumulate without consolidation
15+
16+
## Process
17+
18+
### 1. Audit Current State
19+
20+
Inventory all memory files:
21+
```
22+
MEMORY.md — long-term memory
23+
memory/ — daily notes, tasks, topical files
24+
memory/tasks/ — active and completed tasks
25+
```
26+
27+
For each file, note: line count, last modified, topic coverage, staleness.
28+
29+
### 2. Identify Problems
30+
31+
Look for these common issues:
32+
33+
| Problem | Signal | Fix |
34+
|---------|--------|-----|
35+
| **Bloated file** | >300 lines, covers many topics | Split into focused files |
36+
| **Duplicate info** | Same fact in multiple places | Consolidate to one location |
37+
| **Stale entries** | References to completed work, old dates, resolved issues | Remove or archive |
38+
| **Orphan files** | Files in memory/ never referenced or updated | Review, merge, or remove |
39+
| **Inconsistencies** | Contradictory information across files | Resolve to ground truth |
40+
| **Poor organization** | Related info scattered across files | Restructure by topic |
41+
| **Recursive nesting** | `memory/memory/memory/...` directories | Delete nested dirs (indexer bug artifact) |
42+
43+
### 3. Plan Changes
44+
45+
Before making edits, write a brief plan:
46+
```markdown
47+
## Defrag Plan
48+
- [ ] Split MEMORY.md "Key People" section → memory/people.md
49+
- [ ] Remove completed tasks older than 30 days from memory/tasks/
50+
- [ ] Merge memory/bm-marketing-ideas.md into memory/competitive/
51+
- [ ] Update stale project status entries in MEMORY.md
52+
```
53+
54+
### 4. Execute
55+
56+
Apply changes one at a time:
57+
- **Split**: Extract sections from large files into focused topical files
58+
- **Merge**: Combine related small files into coherent documents
59+
- **Prune**: Remove information that is no longer relevant or accurate
60+
- **Restructure**: Move files to appropriate directories, rename for clarity
61+
- **Update**: Fix outdated facts, dates, statuses
62+
63+
### 5. Verify & Log
64+
65+
After changes:
66+
- Verify no information was lost (compare before/after)
67+
- Update any cross-references between files
68+
- Log what was done in today's daily note:
69+
70+
```markdown
71+
## Memory Defrag (HH:MM)
72+
- Files reviewed: N
73+
- Split: [list]
74+
- Merged: [list]
75+
- Pruned: [list]
76+
- Net result: X files, Y total lines (was Z lines)
77+
```
78+
79+
## Guidelines
80+
81+
- **Back up first.** If git is available, commit before defragging. If not, note the pre-defrag state.
82+
- **Preserve raw daily notes.** Don't delete or modify `memory/YYYY-MM-DD.md` files — they're the audit trail.
83+
- **Target 15-25 focused files.** Too few means bloated files; too many means fragmentation. Aim for the sweet spot.
84+
- **File names should be scannable.** Use descriptive names: `people.md`, `project-status.md`, `competitive-landscape.md` — not `notes-2.md`.
85+
- **Don't over-organize.** One level of directories is usually enough. `memory/tasks/` and `memory/competitive/` are fine; `memory/work/projects/active/basic-memory/notes/` is not.
86+
- **Completed tasks**: Tasks with `status: done` older than 14 days can be removed. Their insights should already be in MEMORY.md via reflection.
87+
- **Ask before destructive changes.** If uncertain whether information is still relevant, keep it with a `(review needed)` tag rather than deleting.

skills/memory-reflect/SKILL.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
name: memory-reflect
3+
description: "Sleep-time memory reflection: review recent conversations and daily notes, extract insights, and consolidate into long-term memory. Use when triggered by cron, heartbeat, or explicit request to reflect on recent activity. Runs as background processing to improve memory quality over time."
4+
---
5+
6+
# Memory Reflect
7+
8+
Review recent activity and consolidate valuable insights into long-term memory.
9+
10+
Inspired by sleep-time compute — the idea that memory formation happens best *between* active sessions, not during them.
11+
12+
## When to Run
13+
14+
- **Cron/heartbeat**: Schedule as a periodic background task (recommended: 1-2x daily)
15+
- **On demand**: User asks to reflect, consolidate, or review recent memory
16+
- **Post-compaction**: After context window compaction events
17+
18+
## Process
19+
20+
### 1. Gather Recent Material
21+
22+
Read the last 2-3 days of daily notes from `memory/YYYY-MM-DD.md`. Also check:
23+
- Recent conversation transcripts (if accessible)
24+
- Any files modified in `memory/` in the last 48 hours
25+
- Active tasks in `memory/tasks/`
26+
27+
### 2. Evaluate What Matters
28+
29+
For each piece of information, ask:
30+
- Is this a **decision** that affects future work? → Keep
31+
- Is this a **lesson learned** or mistake to avoid? → Keep
32+
- Is this a **preference** or working style insight? → Keep
33+
- Is this a **relationship** detail (who does what, contact info)? → Keep
34+
- Is this **transient** (weather checked, heartbeat ran, routine task)? → Skip
35+
- Is this **already captured** in MEMORY.md or another long-term file? → Skip
36+
37+
### 3. Update Long-Term Memory
38+
39+
Write consolidated insights to `MEMORY.md` following its existing structure:
40+
- Add new sections or update existing ones
41+
- Use concise, factual language
42+
- Include dates for temporal context
43+
- Remove or update outdated entries that the new information supersedes
44+
45+
### 4. Log the Reflection
46+
47+
Append a brief entry to today's daily note:
48+
```markdown
49+
## Reflection (HH:MM)
50+
- Reviewed: [list of files reviewed]
51+
- Added to MEMORY.md: [brief summary of what was consolidated]
52+
- Removed/updated: [anything cleaned up]
53+
```
54+
55+
## Guidelines
56+
57+
- **Be selective.** The goal is distillation, not duplication. MEMORY.md should be curated wisdom, not a copy of daily notes.
58+
- **Preserve voice.** If the agent has a personality/soul file, reflections should match that voice.
59+
- **Don't delete daily notes.** They're the raw record. Reflection extracts from them; it doesn't replace them.
60+
- **Merge, don't append.** If MEMORY.md already has a section about a topic, update it in place rather than adding a duplicate entry.
61+
- **Flag uncertainty.** If something seems important but you're not sure, add it with a note like "(needs confirmation)" rather than skipping it entirely.
62+
- **Restructure over time.** If MEMORY.md is a chronological dump, restructure it into topical sections during reflection. Curated knowledge > raw logs.
63+
- **Check for filesystem issues.** Look for recursive nesting (memory/memory/memory/...), orphaned files, or bloat while gathering material.

0 commit comments

Comments
 (0)