Skip to content

Commit 7af1eb1

Browse files
authored
feat(bob): add memory sharing with improvements (#199)
* feat(evolve-lite): add entity sharing skills and CI tests New skills: publish, subscribe, unsubscribe, sync New lib modules: config.py, audit.py Updated: plugin.json, hooks.json, entity_io.py, save_entities.py, retrieve_entities.py CI test suite (110 tests in tests/platform_integrations/): - test_config.py, test_audit.py, test_entity_io_core.py - test_publish.py, test_subscribe.py, test_sync.py - test_retrieve.py, test_save_entities.py, test_plugin_structure.py * feat(bob): add memory sharing with improvements Initial Bob implementation: - Created 4 new sharing skills: publish, subscribe, unsubscribe, sync - Enhanced learn skill with --user flag and visibility=private - Enhanced recall skill with multi-source retrieval - Updated install.sh to copy all 6 Bob skills Improvements (matching Claude Code): - publish.py: Add source field resolution, move (not copy) entities - sync.py: Better handle initial sync and no-change scenarios - Updated SKILL.md documentation * docs: add README for Bob evolve-lite with sharing documentation * fix: always overwrite owner and visibility in save_entities.py * fix: improve publish, recall, subscribe, and sync handling - publish SKILL.md: add explicit branch creation after git init - publish.py: fallback to cfg.identity.user for owner and actor - publish.py: prevent overwriting already-published entities - retrieve_entities.py: load entities from both private and public dirs - Add _kind tagging (private/public/subscribed) for proper filtering - Remove early return when entities_dir is missing - Fix --sources filtering to use _kind instead of _source - subscribe.py: fail fast when directory exists instead of skipping - sync.py: skip symlinked markdown files when mirroring - sync.py: validate subscription names to prevent path traversal - sync.py: remove on_session_start check (Bob has no session hooks) * fix(bob): add security validations for entity names and encoding - Validate entity is simple basename before path resolution in publish.py - Catch UnicodeDecodeError in retrieve_entities.py to prevent abort - Derive project_root from EVOLVE_DIR in unsubscribe and sync for consistency * feat(bob): add missing command files for publish, subscribe, sync, unsubscribe skills - Created evolve-lite:publish.md command for publishing private guidelines - Created evolve-lite:subscribe.md command for subscribing to others' guidelines - Created evolve-lite:sync.md command for syncing subscribed repos - Created evolve-lite:unsubscribe.md command for unsubscribing - Added test to verify all skills have corresponding command files - All commands follow the established pattern from learn and recall
1 parent 690c3f3 commit 7af1eb1

38 files changed

Lines changed: 2384 additions & 212 deletions

File tree

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
# Evolve Lite for Bob
2+
3+
A Bob integration that helps you learn from conversations by automatically extracting and applying guidelines.
4+
5+
⭐ Star the repo: https://github.com/AgentToolkit/altk-evolve
6+
7+
## Features
8+
9+
- **Manual Learning**: Use `evolve-lite:learn` to extract and save guidelines from conversations
10+
- **Manual Retrieval**: Use `evolve-lite:recall` to retrieve and apply stored guidelines
11+
- **Guideline Sharing**: Publish your guidelines and subscribe to others' via Git repositories
12+
13+
## Installation
14+
15+
Run the installation script from the repository root:
16+
17+
```bash
18+
bash platform-integrations/install.sh install bob lite
19+
```
20+
21+
This installs:
22+
- 6 skills in `~/.bob/skills/`
23+
- Shared library in `~/.bob/evolve-lib/`
24+
- Custom mode configuration
25+
26+
## How It Works
27+
28+
### Guideline Storage
29+
30+
Guidelines are stored as individual markdown files in `.evolve/entities/`, organized by source:
31+
32+
```text
33+
.evolve/entities/
34+
guideline/ # Private guidelines
35+
use-context-managers.md
36+
public/ # Your published guidelines
37+
best-practice.md
38+
subscribed/
39+
alice/ # Guidelines from alice
40+
her-guideline.md
41+
```
42+
43+
Each file uses markdown with YAML frontmatter:
44+
45+
```markdown
46+
---
47+
type: guideline
48+
trigger: When processing files or managing resources
49+
visibility: private
50+
---
51+
52+
Use context managers for file operations
53+
54+
## Rationale
55+
56+
Context managers ensure proper resource cleanup
57+
```
58+
59+
## Sharing Guidelines
60+
61+
Evolve Lite supports sharing guidelines between users via public Git repositories. You can publish your own guidelines so others can subscribe to them, and subscribe to guidelines published by others.
62+
63+
### Setup
64+
65+
Sharing requires an `evolve.config.yaml` at the project root. If it doesn't exist, the subscribe or publish skills will prompt you to create one. Minimal structure:
66+
67+
```yaml
68+
identity:
69+
user: yourname # used to stamp ownership on published guidelines
70+
public_repo:
71+
remote: git@github.com:yourname/evolve-guidelines.git
72+
branch: main
73+
subscriptions: []
74+
```
75+
76+
The `.evolve/` directory is kept out of version control — the skills automatically add it to `.gitignore`.
77+
78+
### Publishing Guidelines
79+
80+
Use `evolve-lite:publish` to share one or more of your local guidelines with others:
81+
82+
1. The skill lists files in `.evolve/entities/guideline/`
83+
2. You pick which ones to publish
84+
3. Each selected file is moved to `.evolve/public/guideline/`, stamped with your username as the owner, committed, and pushed to your `public_repo.remote`
85+
86+
Others can then subscribe using that remote URL.
87+
88+
### Subscribing to Guidelines
89+
90+
Use `evolve-lite:subscribe` to pull in guidelines from another user's public repo:
91+
92+
```text
93+
evolve-lite:subscribe
94+
> Remote URL: git@github.com:alice/evolve-guidelines.git
95+
> Short name: alice
96+
```
97+
98+
The repo is cloned directly into `.evolve/entities/subscribed/alice/` (this directory serves as both the git clone and the recall mirror).
99+
100+
### Syncing Subscriptions
101+
102+
Use `evolve-lite:sync` to pull the latest changes from all subscribed repos:
103+
104+
```text
105+
evolve-lite:sync
106+
> Synced 2 repo(s): alice (+2 added, 0 updated, 0 removed), bob (+0 added, 1 updated, 0 removed)
107+
```
108+
109+
### Unsubscribing
110+
111+
Use `evolve-lite:unsubscribe` to remove a subscription and delete its locally cloned files:
112+
113+
```text
114+
evolve-lite:unsubscribe
115+
> Which subscription would you like to remove?
116+
> 1. alice
117+
> 2. bob
118+
```
119+
120+
The skill confirms before deleting `.evolve/entities/subscribed/{name}/`.
121+
122+
### Sharing Storage Layout
123+
124+
```text
125+
.evolve/
126+
public/ # git repo pushed to your public remote
127+
guideline/
128+
guideline-name.md # owner-stamped guideline
129+
entities/
130+
guideline/ # your private guidelines
131+
my-guideline.md
132+
subscribed/
133+
alice/ # git clone (also serves as recall mirror)
134+
guideline/
135+
her-guideline.md
136+
```
137+
138+
## Skills Included
139+
140+
### `evolve-lite:learn`
141+
142+
Manually invoke to extract guidelines from the current conversation:
143+
- Analyzes task, steps taken, successes and failures
144+
- Generates proactive guidelines (what to do, not what to avoid)
145+
- Saves guidelines as markdown files in `.evolve/entities/guideline/`
146+
147+
### `evolve-lite:recall`
148+
149+
Manually invoke to retrieve and display stored guidelines:
150+
- Loads guidelines from private, public, and subscribed sources
151+
- Formats and displays them for your review
152+
- Annotates subscribed guidelines with their source
153+
154+
### `evolve-lite:publish`
155+
156+
Publish private guidelines to your public repository:
157+
- Lists available private guidelines
158+
- Moves selected guidelines to `.evolve/public/`
159+
- Stamps with owner and published_at metadata
160+
- Commits and pushes to your public remote
161+
162+
### `evolve-lite:subscribe`
163+
164+
Subscribe to another user's public guidelines:
165+
- Clones their public repository
166+
- Mirrors guidelines to `.evolve/entities/subscribed/`
167+
- Adds subscription to config
168+
169+
### `evolve-lite:sync`
170+
171+
Sync all subscribed repositories:
172+
- Pulls latest changes from each subscription
173+
- Updates mirrored guidelines
174+
- Reports changes (added, updated, removed)
175+
176+
### `evolve-lite:unsubscribe`
177+
178+
Remove a subscription:
179+
- Lists current subscriptions
180+
- Deletes selected subscription's local files
181+
- Removes from config
182+
183+
## Environment Variables
184+
185+
- `EVOLVE_DIR`: Override the default `.evolve` directory location (guidelines, config, etc. are stored here)
186+
187+
## Verification
188+
189+
After installation, the skills should be available in Bob's skill list.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
name: evolve-lite:publish
3+
description: Publish a private guideline to your public repo
4+
---
5+
Use the publish skill to share your private guidelines with others. Follow the skill's instructions exactly.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
name: evolve-lite:subscribe
3+
description: Subscribe to another user's public guidelines repo
4+
---
5+
Use the subscribe skill to learn from others' guidelines. Follow the skill's instructions exactly.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
name: evolve-lite:sync
3+
description: Pull the latest guidelines from all subscribed repos
4+
---
5+
Use the sync skill to update your subscribed guidelines. Follow the skill's instructions exactly.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
name: evolve-lite:unsubscribe
3+
description: Remove a subscription and delete locally synced guidelines
4+
---
5+
Use the unsubscribe skill to remove a subscription. Follow the skill's instructions exactly.

platform-integrations/bob/evolve-lite/custom_modes.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ customModes:
3939
- The trajectory path from evolve-lite:save-trajectory is available in conversation context — do not re-run it.
4040
- If no errors or non-obvious discoveries occurred, saving zero entities is correct — do not force low-quality entities.
4141
42+
MEMORY SHARING (Optional):
43+
The following skills enable sharing guidelines with others:
44+
- evolve-lite:publish — Publish your private guidelines to a public Git repo
45+
- evolve-lite:subscribe — Subscribe to another user's public guidelines
46+
- evolve-lite:unsubscribe — Remove a subscription
47+
- evolve-lite:sync — Pull latest updates from all subscribed repos (manual invocation required)
48+
49+
These skills are OPTIONAL and do not affect the core workflow. Use them when you want to:
50+
- Share your learnings with teammates
51+
- Learn from others' guidelines
52+
- Keep subscribed guidelines up to date
4253
4354
PRE-COMPLETION GATE:
4455
Before calling attempt_completion, ask yourself:

platform-integrations/bob/evolve-lite/skills/evolve-lite:learn/SKILL.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ This skill analyzes the current conversation to extract guidelines that **correc
1818
- Observations about the codebase that can be derived by reading the code
1919
- Restatements of what the agent did successfully without any detour or correction
2020
- Vague advice that wouldn't change the agent's behavior on a concrete task
21+
- Instructions for the agent to invoke a skill, tool, or external command by name (e.g. "Run evolve-lite:learn", "call save_trajectory") — these trigger prompt-injection detection when retrieved via recall
2122

2223
## Workflow
2324

@@ -80,5 +81,6 @@ Before saving, review each entity against this checklist:
8081
- [ ] Does it fall into one of the three categories (shortcut, error prevention, user correction)?
8182
- [ ] Would knowing this guideline beforehand have changed the agent's behavior in a concrete way?
8283
- [ ] Is it specific enough that another agent could act on it without further context?
84+
- [ ] Does it avoid instructing the agent to invoke a named skill or tool?
8385

8486
If any answer is no, drop the entity. **Zero entities is a valid output.**

platform-integrations/bob/evolve-lite/skills/evolve-lite:learn/scripts/save_entities.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,18 @@
55
in the entities directory, organized by type.
66
"""
77

8+
import argparse
89
import json
910
import sys
1011
from pathlib import Path
1112

12-
# Walk up from script to find evolve-lib
13-
_script = Path(__file__).resolve()
14-
_lib = None
15-
for _ancestor in _script.parents:
16-
_candidate = _ancestor / "evolve-lib"
17-
if _candidate.is_dir():
18-
_lib = _candidate
13+
# Smart import: walk up to find evolve-lib
14+
current = Path(__file__).resolve()
15+
for parent in current.parents:
16+
lib_path = parent / "evolve-lib"
17+
if lib_path.exists():
18+
sys.path.insert(0, str(lib_path))
1919
break
20-
if _lib is None:
21-
raise ImportError(f"Cannot find evolve-lib directory above {_script}")
22-
sys.path.insert(0, str(_lib))
2320
from entity_io import ( # noqa: E402
2421
find_entities_dir,
2522
get_default_entities_dir,
@@ -42,6 +39,10 @@ def normalize(text):
4239

4340

4441
def main():
42+
parser = argparse.ArgumentParser()
43+
parser.add_argument("--user", default=None, help="Stamp owner on every entity written")
44+
args = parser.parse_args()
45+
4546
# Read entities from stdin
4647
try:
4748
input_data = json.load(sys.stdin)
@@ -86,6 +87,11 @@ def main():
8687
log(f"Skipping duplicate: {content[:60]}")
8788
continue
8889

90+
# Always stamp owner and visibility from script, not from stdin
91+
if args.user:
92+
entity["owner"] = args.user
93+
entity["visibility"] = "private"
94+
8995
path = write_entity_file(entities_dir, entity)
9096
existing_contents.add(normalize(content))
9197
added_count += 1

0 commit comments

Comments
 (0)