Add /remember, /config commands and memory helper scripts
New commands: - /remember: Quick shortcut to save to memory (auto-categorizes) - /config: View and manage configuration settings New automation scripts: - memory-add.py: Add items to PA memory with auto-categorization - memory-list.py: List memory items by category The /remember command provides a quick way to save: - "Always use X" → preferences - "Decided to use X" → decisions - "Project at ~/path" → projects - Other → facts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
112
automation/memory-add.py
Executable file
112
automation/memory-add.py
Executable file
@@ -0,0 +1,112 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Add an item to PA memory.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
memory-add.py <category> <content>
|
||||||
|
memory-add.py preference "Always use dark mode"
|
||||||
|
memory-add.py fact "Server IP is 192.168.1.100"
|
||||||
|
memory-add.py auto "Some text to auto-categorize"
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
import uuid
|
||||||
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
MEMORY_DIR = Path.home() / ".claude/state/personal-assistant/memory"
|
||||||
|
|
||||||
|
CATEGORIES = {
|
||||||
|
"preference": "preferences.json",
|
||||||
|
"decision": "decisions.json",
|
||||||
|
"project": "projects.json",
|
||||||
|
"fact": "facts.json",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Keywords for auto-categorization
|
||||||
|
PREFERENCE_KEYWORDS = ["prefer", "always", "never", "like", "want", "should"]
|
||||||
|
DECISION_KEYWORDS = ["decided", "chose", "chosen", "use", "using", "switched"]
|
||||||
|
PROJECT_KEYWORDS = ["repo", "project", "codebase", "~/", "/home/", "github"]
|
||||||
|
|
||||||
|
|
||||||
|
def auto_categorize(content: str) -> str:
|
||||||
|
"""Determine category based on content."""
|
||||||
|
content_lower = content.lower()
|
||||||
|
|
||||||
|
if any(kw in content_lower for kw in PREFERENCE_KEYWORDS):
|
||||||
|
return "preference"
|
||||||
|
if any(kw in content_lower for kw in DECISION_KEYWORDS):
|
||||||
|
return "decision"
|
||||||
|
if any(kw in content_lower for kw in PROJECT_KEYWORDS):
|
||||||
|
return "project"
|
||||||
|
return "fact"
|
||||||
|
|
||||||
|
|
||||||
|
def load_memory(category: str) -> list:
|
||||||
|
"""Load existing memory items."""
|
||||||
|
filepath = MEMORY_DIR / CATEGORIES[category]
|
||||||
|
if filepath.exists():
|
||||||
|
with open(filepath) as f:
|
||||||
|
data = json.load(f)
|
||||||
|
return data.get("items", [])
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def save_memory(category: str, items: list):
|
||||||
|
"""Save memory items."""
|
||||||
|
filepath = MEMORY_DIR / CATEGORIES[category]
|
||||||
|
filepath.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"version": "1.0",
|
||||||
|
"category": category,
|
||||||
|
"items": items
|
||||||
|
}
|
||||||
|
|
||||||
|
with open(filepath, "w") as f:
|
||||||
|
json.dump(data, f, indent=2)
|
||||||
|
|
||||||
|
|
||||||
|
def add_item(category: str, content: str) -> dict:
|
||||||
|
"""Add an item to memory."""
|
||||||
|
if category == "auto":
|
||||||
|
category = auto_categorize(content)
|
||||||
|
|
||||||
|
if category not in CATEGORIES:
|
||||||
|
print(f"Error: Invalid category '{category}'")
|
||||||
|
print(f"Valid categories: {', '.join(CATEGORIES.keys())}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Create new item
|
||||||
|
item = {
|
||||||
|
"id": str(uuid.uuid4()),
|
||||||
|
"date": datetime.now().strftime("%Y-%m-%d"),
|
||||||
|
"content": content,
|
||||||
|
"status": "active"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load, append, save
|
||||||
|
items = load_memory(category)
|
||||||
|
items.append(item)
|
||||||
|
save_memory(category, items)
|
||||||
|
|
||||||
|
return {"category": category, "item": item}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
print(__doc__)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
category = sys.argv[1]
|
||||||
|
content = " ".join(sys.argv[2:])
|
||||||
|
|
||||||
|
result = add_item(category, content)
|
||||||
|
|
||||||
|
print(f"✓ Saved to {result['category']}s:")
|
||||||
|
print(f" \"{result['item']['content']}\"")
|
||||||
|
print(f" ID: {result['item']['id'][:8]}...")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
88
automation/memory-list.py
Executable file
88
automation/memory-list.py
Executable file
@@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""List items from PA memory.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
memory-list.py [category] [--all]
|
||||||
|
memory-list.py # All active items
|
||||||
|
memory-list.py preferences # Just preferences
|
||||||
|
memory-list.py --all # Include deprecated items
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
MEMORY_DIR = Path.home() / ".claude/state/personal-assistant/memory"
|
||||||
|
|
||||||
|
CATEGORIES = {
|
||||||
|
"preferences": "preferences.json",
|
||||||
|
"decisions": "decisions.json",
|
||||||
|
"projects": "projects.json",
|
||||||
|
"facts": "facts.json",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def load_memory(category: str) -> list:
|
||||||
|
"""Load memory items from a category."""
|
||||||
|
filepath = MEMORY_DIR / CATEGORIES.get(category, f"{category}.json")
|
||||||
|
if filepath.exists():
|
||||||
|
with open(filepath) as f:
|
||||||
|
data = json.load(f)
|
||||||
|
return data.get("items", [])
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def print_items(category: str, items: list, show_all: bool):
|
||||||
|
"""Print items in a category."""
|
||||||
|
if not items:
|
||||||
|
return
|
||||||
|
|
||||||
|
active = [i for i in items if i.get("status") == "active"]
|
||||||
|
deprecated = [i for i in items if i.get("status") == "deprecated"]
|
||||||
|
|
||||||
|
if not active and not (show_all and deprecated):
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"\n📁 {category.title()}")
|
||||||
|
print("─" * 40)
|
||||||
|
|
||||||
|
for item in active:
|
||||||
|
date = item.get("date", "unknown")
|
||||||
|
content = item.get("content", "")
|
||||||
|
print(f" [{date}] {content}")
|
||||||
|
|
||||||
|
if show_all and deprecated:
|
||||||
|
print(f"\n (deprecated: {len(deprecated)} items)")
|
||||||
|
for item in deprecated[:3]:
|
||||||
|
content = item.get("content", "")
|
||||||
|
print(f" ✗ {content[:50]}...")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
show_all = "--all" in sys.argv
|
||||||
|
args = [a for a in sys.argv[1:] if not a.startswith("--")]
|
||||||
|
|
||||||
|
category_filter = args[0] if args else None
|
||||||
|
|
||||||
|
print("📝 PA Memory")
|
||||||
|
|
||||||
|
if category_filter:
|
||||||
|
# Single category
|
||||||
|
if category_filter not in CATEGORIES:
|
||||||
|
print(f"Error: Unknown category '{category_filter}'")
|
||||||
|
print(f"Valid: {', '.join(CATEGORIES.keys())}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
items = load_memory(category_filter)
|
||||||
|
print_items(category_filter, items, show_all)
|
||||||
|
else:
|
||||||
|
# All categories
|
||||||
|
for category in CATEGORIES:
|
||||||
|
items = load_memory(category)
|
||||||
|
print_items(category, items, show_all)
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -12,6 +12,8 @@ Slash commands for quick actions. User-invoked (type `/command` to trigger).
|
|||||||
| `/help` | `/commands`, `/skills` | Show available commands and skills |
|
| `/help` | `/commands`, `/skills` | Show available commands and skills |
|
||||||
| `/status` | `/overview`, `/dashboard` | Quick status across all domains |
|
| `/status` | `/overview`, `/dashboard` | Quick status across all domains |
|
||||||
| `/summarize` | `/save-session` | Summarize and save session to memory |
|
| `/summarize` | `/save-session` | Summarize and save session to memory |
|
||||||
|
| `/remember` | `/save`, `/note` | Quick save to memory |
|
||||||
|
| `/config` | `/settings`, `/prefs` | View/manage configuration |
|
||||||
| `/maintain` | `/maintenance`, `/admin` | Configuration maintenance |
|
| `/maintain` | `/maintenance`, `/admin` | Configuration maintenance |
|
||||||
| `/programmer` | | Code development tasks |
|
| `/programmer` | | Code development tasks |
|
||||||
| `/gcal` | `/calendar`, `/cal` | Google Calendar access |
|
| `/gcal` | `/calendar`, `/cal` | Google Calendar access |
|
||||||
|
|||||||
111
commands/config.md
Normal file
111
commands/config.md
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
---
|
||||||
|
name: config
|
||||||
|
description: View and manage configuration settings
|
||||||
|
aliases: [settings, prefs]
|
||||||
|
---
|
||||||
|
|
||||||
|
# /config Command
|
||||||
|
|
||||||
|
View and manage Claude Code configuration.
|
||||||
|
|
||||||
|
## Subcommands
|
||||||
|
|
||||||
|
| Subcommand | Description |
|
||||||
|
|------------|-------------|
|
||||||
|
| (none) | Show current configuration summary |
|
||||||
|
| `show` | Show full configuration |
|
||||||
|
| `autonomy` | View/set autonomy level |
|
||||||
|
| `context` | View/set context level |
|
||||||
|
| `model` | View current model policy |
|
||||||
|
| `plugins` | List installed plugins |
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
/config # Summary view
|
||||||
|
/config show # Full configuration
|
||||||
|
/config autonomy # Current autonomy level
|
||||||
|
/config autonomy moderate # Set autonomy level
|
||||||
|
/config context # Current context level
|
||||||
|
/config context minimal # Set for session
|
||||||
|
/config model # Model policy
|
||||||
|
/config plugins # Installed plugins
|
||||||
|
```
|
||||||
|
|
||||||
|
## Implementation
|
||||||
|
|
||||||
|
### Summary View (/config)
|
||||||
|
|
||||||
|
```
|
||||||
|
⚙️ Configuration Summary
|
||||||
|
|
||||||
|
Autonomy: conservative (default)
|
||||||
|
Context: moderate (default)
|
||||||
|
Model: opus (primary)
|
||||||
|
|
||||||
|
Plugins: 6 installed
|
||||||
|
Skills: 6 available
|
||||||
|
Commands: 16 available
|
||||||
|
|
||||||
|
Config files:
|
||||||
|
~/.claude/settings.json
|
||||||
|
~/.claude/state/autonomy-levels.json
|
||||||
|
~/.claude/state/model-policy.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Autonomy (/config autonomy)
|
||||||
|
|
||||||
|
Read from: `~/.claude/state/sysadmin/session-autonomy.json`
|
||||||
|
|
||||||
|
Levels:
|
||||||
|
- `conservative` - Confirm all write operations
|
||||||
|
- `moderate` - Auto-approve routine writes
|
||||||
|
- `trusted` - Auto-approve most operations
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# View
|
||||||
|
cat ~/.claude/state/sysadmin/session-autonomy.json
|
||||||
|
|
||||||
|
# Set (writes to session-autonomy.json)
|
||||||
|
echo '{"level": "moderate", "set_at": "timestamp"}' > session-autonomy.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Context (/config context)
|
||||||
|
|
||||||
|
Read from: `~/.claude/state/personal-assistant/session-context.json`
|
||||||
|
|
||||||
|
Levels:
|
||||||
|
- `none` - Skip context gathering
|
||||||
|
- `minimal` - Light context
|
||||||
|
- `moderate` - Balanced (default)
|
||||||
|
- `comprehensive` - Deep context scan
|
||||||
|
|
||||||
|
### Model (/config model)
|
||||||
|
|
||||||
|
Read from: `~/.claude/state/model-policy.json`
|
||||||
|
|
||||||
|
Shows:
|
||||||
|
- Default models per agent
|
||||||
|
- Escalation rules
|
||||||
|
- Cost considerations
|
||||||
|
|
||||||
|
### Plugins (/config plugins)
|
||||||
|
|
||||||
|
Read from: `~/.claude/plugins/installed_plugins.json`
|
||||||
|
|
||||||
|
```
|
||||||
|
Installed Plugins:
|
||||||
|
|
||||||
|
• superpowers (4.0.2) - superpowers-marketplace
|
||||||
|
• frontend-design (6d3752c) - claude-plugins-official
|
||||||
|
• commit-commands (6d3752c) - claude-plugins-official
|
||||||
|
• typescript-lsp (1.0.0) - claude-plugins-official
|
||||||
|
• pyright-lsp (1.0.0) - claude-plugins-official
|
||||||
|
• superpowers-developing-for-claude-code (0.3.1) - superpowers-marketplace
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Changes to autonomy/context are session-only unless using `--set-default`
|
||||||
|
- Model policy changes require editing model-policy.json directly
|
||||||
|
- Plugin management via `/plugin` command
|
||||||
76
commands/remember.md
Normal file
76
commands/remember.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
---
|
||||||
|
name: remember
|
||||||
|
description: Quick shortcut to save something to memory
|
||||||
|
aliases: [save, note]
|
||||||
|
---
|
||||||
|
|
||||||
|
# /remember Command
|
||||||
|
|
||||||
|
Quick shortcut to save information to PA memory.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
/remember <what to remember>
|
||||||
|
/remember Always use dark mode in editors
|
||||||
|
/remember Project X uses PostgreSQL 15
|
||||||
|
/remember Prefer functional style over OOP
|
||||||
|
```
|
||||||
|
|
||||||
|
## Implementation
|
||||||
|
|
||||||
|
This is a shortcut for `/pa --remember -- "<instruction>"`.
|
||||||
|
|
||||||
|
When invoked:
|
||||||
|
|
||||||
|
1. Parse the text after `/remember`
|
||||||
|
2. Determine the category:
|
||||||
|
- Contains "prefer", "always", "never" → **preference**
|
||||||
|
- Contains "decided", "chose", "use" → **decision**
|
||||||
|
- Contains project/path references → **project**
|
||||||
|
- Otherwise → **fact**
|
||||||
|
|
||||||
|
3. Generate entry:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "<uuid>",
|
||||||
|
"date": "YYYY-MM-DD",
|
||||||
|
"content": "<the text>",
|
||||||
|
"status": "active"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Append to appropriate file:
|
||||||
|
- `~/.claude/state/personal-assistant/memory/preferences.json`
|
||||||
|
- `~/.claude/state/personal-assistant/memory/decisions.json`
|
||||||
|
- `~/.claude/state/personal-assistant/memory/projects.json`
|
||||||
|
- `~/.claude/state/personal-assistant/memory/facts.json`
|
||||||
|
|
||||||
|
5. Confirm to user:
|
||||||
|
```
|
||||||
|
✓ Saved to preferences:
|
||||||
|
"Always use dark mode in editors"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
| Input | Category | File |
|
||||||
|
|-------|----------|------|
|
||||||
|
| "Always use tabs not spaces" | preference | preferences.json |
|
||||||
|
| "Decided to use Rust for CLI tools" | decision | decisions.json |
|
||||||
|
| "homelab repo is at ~/repos/homelab" | project | projects.json |
|
||||||
|
| "Server IP is 192.168.1.100" | fact | facts.json |
|
||||||
|
|
||||||
|
## Quick Access
|
||||||
|
|
||||||
|
This is the fastest way to save something:
|
||||||
|
|
||||||
|
```
|
||||||
|
/remember SSH key is in ~/.ssh/homelab_key
|
||||||
|
```
|
||||||
|
|
||||||
|
vs the full command:
|
||||||
|
|
||||||
|
```
|
||||||
|
/pa --remember -- "SSH key is in ~/.ssh/homelab_key"
|
||||||
|
```
|
||||||
@@ -149,6 +149,16 @@
|
|||||||
"description": "Configuration maintenance (backup, validate, etc.)",
|
"description": "Configuration maintenance (backup, validate, etc.)",
|
||||||
"aliases": ["/maintenance", "/admin"],
|
"aliases": ["/maintenance", "/admin"],
|
||||||
"invokes": "command:maintain"
|
"invokes": "command:maintain"
|
||||||
|
},
|
||||||
|
"/remember": {
|
||||||
|
"description": "Quick shortcut to save something to memory",
|
||||||
|
"aliases": ["/save", "/note"],
|
||||||
|
"invokes": "command:remember"
|
||||||
|
},
|
||||||
|
"/config": {
|
||||||
|
"description": "View and manage configuration settings",
|
||||||
|
"aliases": ["/settings", "/prefs"],
|
||||||
|
"invokes": "command:config"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"agents": {
|
"agents": {
|
||||||
|
|||||||
Reference in New Issue
Block a user