palaia 2.4.dev2__tar.gz → 2.5__tar.gz
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.
- {palaia-2.4.dev2/palaia.egg-info → palaia-2.5}/PKG-INFO +1 -1
- {palaia-2.4.dev2 → palaia-2.5}/SKILL.md +106 -5
- {palaia-2.4.dev2 → palaia-2.5}/palaia/SKILL.md +106 -5
- {palaia-2.4.dev2 → palaia-2.5}/palaia/__init__.py +1 -1
- {palaia-2.4.dev2 → palaia-2.5}/palaia/backends/migrate.py +38 -2
- {palaia-2.4.dev2 → palaia-2.5}/palaia/cli.py +84 -17
- {palaia-2.4.dev2 → palaia-2.5}/palaia/cli_args.py +8 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/cli_commands.py +74 -37
- {palaia-2.4.dev2 → palaia-2.5}/palaia/cli_helpers.py +9 -5
- {palaia-2.4.dev2 → palaia-2.5}/palaia/doctor/checks.py +2 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/doctor/fixes.py +18 -0
- palaia-2.5/palaia/doctor/report.py +66 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/embed_server.py +2 -1
- {palaia-2.4.dev2 → palaia-2.5}/palaia/nudge.py +16 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/priorities.py +29 -1
- {palaia-2.4.dev2 → palaia-2.5}/palaia/scope.py +20 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/search.py +9 -4
- {palaia-2.4.dev2 → palaia-2.5}/palaia/services/admin.py +17 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/services/misc.py +18 -1
- {palaia-2.4.dev2 → palaia-2.5}/palaia/services/write.py +30 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/store.py +78 -6
- palaia-2.5/palaia/ui.py +424 -0
- {palaia-2.4.dev2 → palaia-2.5/palaia.egg-info}/PKG-INFO +1 -1
- {palaia-2.4.dev2 → palaia-2.5}/palaia.egg-info/SOURCES.txt +3 -0
- {palaia-2.4.dev2 → palaia-2.5}/pyproject.toml +1 -1
- palaia-2.5/tests/test_backup_restore.py +137 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_concurrent_writes.py +10 -1
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_detect.py +1 -2
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_doctor.py +1 -1
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_init_no_agent.py +1 -1
- palaia-2.5/tests/test_isolation_nudges.py +172 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_priorities.py +118 -0
- palaia-2.5/tests/test_prune.py +131 -0
- palaia-2.5/tests/test_scope.py +106 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_search_cache.py +9 -9
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_temporal_queries.py +0 -2
- palaia-2.4.dev2/palaia/doctor/report.py +0 -67
- palaia-2.4.dev2/palaia/ui.py +0 -297
- palaia-2.4.dev2/tests/test_scope.py +0 -62
- {palaia-2.4.dev2 → palaia-2.5}/CHANGELOG.md +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/LICENSE +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/MANIFEST.in +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/README.md +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/__main__.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/backends/__init__.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/backends/postgres.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/backends/protocol.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/backends/sqlite.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/bm25.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/cli_nudge.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/config.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/curate.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/decay.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/doctor/__init__.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/embed_client.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/embeddings.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/entry.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/enums.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/frontmatter.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/index.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/ingest.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/lock.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/locking.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/mcp/__init__.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/mcp/server.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/memo.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/metadata_index.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/migrate.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/packages.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/process_runner.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/project.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/project_lock.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/services/__init__.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/services/curate.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/services/ingest.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/services/memo.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/services/package.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/services/priorities.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/services/process.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/services/project.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/services/query.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/services/status.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/significance.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/sync.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia/wal.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia.egg-info/dependency_links.txt +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia.egg-info/entry_points.txt +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia.egg-info/requires.txt +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/palaia.egg-info/top_level.txt +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/setup.cfg +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_agent_aliases.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_agent_flag.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_audit_fixes.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_auto_title.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_backend_migrate.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_backend_postgres.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_backend_sqlite.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_bm25.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_bounded_gc.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_capture_level.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_chain_cli.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_config.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_config_detection.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_cross_platform_lock.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_cross_project.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_curate.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_decay.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_doctor_fix_chain.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_doctor_memos.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_doctor_staleness.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_doctor_version.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_embed_server.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_embed_server_socket.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_embeddings.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_entry_classes.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_frontmatter.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_gemini_embeddings.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_hit_decay.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_incremental_indexing.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_index.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_ingest.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_init_gatekeeper.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_list_filters.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_locking.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_mcp_server.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_memo.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_metadata_index.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_migrate.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_multi_agent.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_nudge_tracker.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_packages.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_plugin_defaults_upgrade.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_process_nudge.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_process_runner.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_project.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_project_owner.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_scope_enforcement.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_search.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_search_chain.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_significance.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_skill.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_ssrf.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_status_index_hint.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_store.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_sync.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_unicode.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_ux_improvements.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_wal.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_wal_corruption.py +0 -0
- {palaia-2.4.dev2 → palaia-2.5}/tests/test_warmup_reindex.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: palaia
|
|
3
|
-
version: "2.
|
|
3
|
+
version: "2.5"
|
|
4
4
|
description: >
|
|
5
5
|
Local, crash-safe persistent memory for OpenClaw agents.
|
|
6
6
|
SQLite-backed by default. Semantic search, projects, scopes, auto-capture.
|
|
@@ -25,17 +25,18 @@ metadata:
|
|
|
25
25
|
- command: "python3 -m pip install --upgrade 'palaia[fastembed]' && (npm install -g @byte5ai/palaia@latest 2>/dev/null || true) && palaia doctor --fix && palaia warmup"
|
|
26
26
|
label: "Upgrade Palaia with semantic search (pip + npm plugin) and run health checks"
|
|
27
27
|
postUpdateMessage: >
|
|
28
|
-
Palaia has been updated to v2.
|
|
29
|
-
|
|
28
|
+
Palaia has been updated to v2.4. New: session continuity (automatic briefings and
|
|
29
|
+
summaries), privacy markers, recency boost, progressive disclosure. Run `palaia doctor --fix` to upgrade.
|
|
30
30
|
plugin:
|
|
31
31
|
slot: memory
|
|
32
32
|
package: "@byte5ai/palaia"
|
|
33
33
|
---
|
|
34
34
|
|
|
35
|
-
# Palaia v2.
|
|
35
|
+
# Palaia v2.4 — Agent Memory Skill
|
|
36
36
|
|
|
37
37
|
Palaia is the memory system for OpenClaw agents. It gives you persistent, searchable, crash-safe memory across sessions. You don't need to understand how it works — just use the commands below.
|
|
38
38
|
|
|
39
|
+
<!-- begin:install -->
|
|
39
40
|
## First-Time Setup
|
|
40
41
|
|
|
41
42
|
When a user asks you to "set up palaia", "enable memory", or "remember things across sessions", run these steps:
|
|
@@ -136,6 +137,7 @@ npm install -g @byte5ai/palaia@latest
|
|
|
136
137
|
```
|
|
137
138
|
|
|
138
139
|
After the manual update, `palaia upgrade` will be available for future updates.
|
|
140
|
+
<!-- end:install -->
|
|
139
141
|
|
|
140
142
|
## Auto-Check (run every time this skill is loaded)
|
|
141
143
|
|
|
@@ -290,6 +292,9 @@ palaia query "what's the rate limit"
|
|
|
290
292
|
# Filter by type and status
|
|
291
293
|
palaia query "tasks" --type task --status open
|
|
292
294
|
|
|
295
|
+
# Filter by tags
|
|
296
|
+
palaia query "session-summary" --tags session-summary
|
|
297
|
+
|
|
293
298
|
# Search within a project
|
|
294
299
|
palaia query "deploy steps" --project myapp
|
|
295
300
|
|
|
@@ -324,6 +329,9 @@ palaia list
|
|
|
324
329
|
# Filter by tier, type, status
|
|
325
330
|
palaia list --tier warm --type task --status open --priority high
|
|
326
331
|
|
|
332
|
+
# Limit results
|
|
333
|
+
palaia list --type task --status open --limit 5
|
|
334
|
+
|
|
327
335
|
# Filter by project or assignee
|
|
328
336
|
palaia list --project myapp --assignee Elliot
|
|
329
337
|
```
|
|
@@ -575,6 +583,66 @@ Distinguish sessions of the same agent:
|
|
|
575
583
|
palaia instance set Claw-Main
|
|
576
584
|
```
|
|
577
585
|
|
|
586
|
+
### Agent Isolation Mode
|
|
587
|
+
|
|
588
|
+
For focused agents (Sonnet/Codex) that should only see their own memories:
|
|
589
|
+
|
|
590
|
+
**1. Configure in `priorities.json`:**
|
|
591
|
+
```json
|
|
592
|
+
{
|
|
593
|
+
"agents": {
|
|
594
|
+
"dev-worker": {
|
|
595
|
+
"scopeVisibility": ["private"],
|
|
596
|
+
"captureScope": "private",
|
|
597
|
+
"maxInjectedChars": 2000,
|
|
598
|
+
"recallMinScore": 0.85
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
```
|
|
603
|
+
Or via CLI:
|
|
604
|
+
```bash
|
|
605
|
+
palaia priorities set scopeVisibility private --agent dev-worker
|
|
606
|
+
palaia priorities set captureScope private --agent dev-worker
|
|
607
|
+
palaia priorities set maxInjectedChars 2000 --agent dev-worker
|
|
608
|
+
palaia priorities set recallMinScore 0.85 --agent dev-worker
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
**2. Set agent identity:**
|
|
612
|
+
```bash
|
|
613
|
+
export PALAIA_AGENT=dev-worker
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
**3. Auto-capture stays on** (crash safety net). Cleanup happens after the work package.
|
|
617
|
+
|
|
618
|
+
**4. After accepting work:**
|
|
619
|
+
```bash
|
|
620
|
+
palaia prune --agent dev-worker --tags auto-capture --protect-type process
|
|
621
|
+
```
|
|
622
|
+
This removes session noise while preserving learned SOPs.
|
|
623
|
+
|
|
624
|
+
#### Pre-configured Agent Profiles
|
|
625
|
+
|
|
626
|
+
| Profile | scopeVisibility | captureScope | maxInjectedChars | recallMinScore | autoCapture |
|
|
627
|
+
|---------|----------------|--------------|-----------------|----------------|-------------|
|
|
628
|
+
| **Isolated Worker** | `["private"]` | `private` | 2000 | 0.85 | true |
|
|
629
|
+
| **Orchestrator** | `["private","team","public"]` | `team` | 4000 | 0.7 | true |
|
|
630
|
+
| **Lean Worker** | `["private"]` | `private` | 1000 | 0.9 | false |
|
|
631
|
+
|
|
632
|
+
#### Orchestrator Lifecycle (process template)
|
|
633
|
+
|
|
634
|
+
Save this as a process entry for the orchestrator to recall:
|
|
635
|
+
```bash
|
|
636
|
+
palaia write "## Dev-Agent Lifecycle
|
|
637
|
+
1. Create agent identity: export PALAIA_AGENT=dev-worker-{task-id}
|
|
638
|
+
2. Configure isolation: palaia priorities set scopeVisibility private --agent dev-worker-{task-id}
|
|
639
|
+
3. Configure capture: palaia priorities set captureScope private --agent dev-worker-{task-id}
|
|
640
|
+
4. Assign work package via prompt
|
|
641
|
+
5. After acceptance: palaia prune --agent dev-worker-{task-id} --tags auto-capture --protect-type process
|
|
642
|
+
6. Verify: palaia list --agent dev-worker-{task-id} --type process
|
|
643
|
+
7. Process knowledge persists for future tasks" --type process --tags workflow,orchestration --scope private
|
|
644
|
+
```
|
|
645
|
+
|
|
578
646
|
---
|
|
579
647
|
|
|
580
648
|
## When to Use What
|
|
@@ -590,10 +658,11 @@ palaia instance set Claw-Main
|
|
|
590
658
|
| Check system health | `palaia status` |
|
|
591
659
|
| Something is wrong | `palaia doctor --fix` |
|
|
592
660
|
| Clean up old entries | `palaia gc` |
|
|
661
|
+
| Clean up agent session noise | `palaia prune --agent NAME --tags auto-capture --protect-type process` |
|
|
593
662
|
| Review accumulated knowledge | `palaia curate analyze` |
|
|
594
663
|
| Share knowledge | `palaia sync export` or `palaia package export` |
|
|
595
664
|
| Check for messages | `palaia memo inbox` |
|
|
596
|
-
| Start of session |
|
|
665
|
+
| Start of session | Session briefing is now automatic. Just run `palaia doctor` and check `palaia memo inbox`. |
|
|
597
666
|
|
|
598
667
|
**Do NOT manually write:** facts, decisions, or preferences that came up in the current conversation. Auto-Capture handles these.
|
|
599
668
|
|
|
@@ -632,6 +701,33 @@ palaia init --capture-level <off|minimal|normal|aggressive>
|
|
|
632
701
|
|
|
633
702
|
---
|
|
634
703
|
|
|
704
|
+
## Session Continuity (NEW in v2.4)
|
|
705
|
+
|
|
706
|
+
Session continuity gives agents automatic context restoration across sessions. These features work out of the box with the OpenClaw plugin -- no manual setup needed.
|
|
707
|
+
|
|
708
|
+
### Session Briefings
|
|
709
|
+
On session start, Palaia automatically injects a briefing with the last session summary and any open tasks. This means agents resume work without needing to manually search for context.
|
|
710
|
+
|
|
711
|
+
### Session Summaries
|
|
712
|
+
When a session ends or resets, Palaia auto-saves a summary of what happened. These are stored as entries with the `session-summary` tag and can be queried:
|
|
713
|
+
```bash
|
|
714
|
+
palaia query "session-summary" --tags session-summary
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
### Privacy Markers
|
|
718
|
+
Wrap sensitive content in `<private>...</private>` blocks to exclude it from auto-capture. Private blocks are stripped before any extraction runs.
|
|
719
|
+
|
|
720
|
+
### Recency Boost
|
|
721
|
+
Fresh memories are ranked higher in recall results. The boost factor is configurable via `recallRecencyBoost` (default `0.3`, set to `0` to disable).
|
|
722
|
+
|
|
723
|
+
### Progressive Disclosure
|
|
724
|
+
When result sets exceed 100 entries, Palaia uses compact mode to keep context manageable. Use `--limit` to control result size explicitly:
|
|
725
|
+
```bash
|
|
726
|
+
palaia list --type task --status open --limit 5
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
---
|
|
730
|
+
|
|
635
731
|
## Plugin Configuration (OpenClaw)
|
|
636
732
|
|
|
637
733
|
Set in `openclaw.json` under `plugins.entries.palaia.config`:
|
|
@@ -649,6 +745,11 @@ Set in `openclaw.json` under `plugins.entries.palaia.config`:
|
|
|
649
745
|
| `embeddingServer` | `true` | Keep embedding model loaded for fast queries |
|
|
650
746
|
| `showMemorySources` | `true` | Show memory source footnotes |
|
|
651
747
|
| `showCaptureConfirm` | `true` | Show capture confirmations |
|
|
748
|
+
| `sessionSummary` | `true` | Auto-save session summaries on end/reset |
|
|
749
|
+
| `sessionBriefing` | `true` | Load session context on session start |
|
|
750
|
+
| `sessionBriefingMaxChars` | `1500` | Max chars for session briefing injection |
|
|
751
|
+
| `captureToolObservations` | `true` | Track tool usage as session context |
|
|
752
|
+
| `recallRecencyBoost` | `0.3` | Boost factor for fresh memories (0=off) |
|
|
652
753
|
|
|
653
754
|
---
|
|
654
755
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: palaia
|
|
3
|
-
version: "2.
|
|
3
|
+
version: "2.5"
|
|
4
4
|
description: >
|
|
5
5
|
Local, crash-safe persistent memory for OpenClaw agents.
|
|
6
6
|
SQLite-backed by default. Semantic search, projects, scopes, auto-capture.
|
|
@@ -25,17 +25,18 @@ metadata:
|
|
|
25
25
|
- command: "python3 -m pip install --upgrade 'palaia[fastembed]' && (npm install -g @byte5ai/palaia@latest 2>/dev/null || true) && palaia doctor --fix && palaia warmup"
|
|
26
26
|
label: "Upgrade Palaia with semantic search (pip + npm plugin) and run health checks"
|
|
27
27
|
postUpdateMessage: >
|
|
28
|
-
Palaia has been updated to v2.
|
|
29
|
-
|
|
28
|
+
Palaia has been updated to v2.4. New: session continuity (automatic briefings and
|
|
29
|
+
summaries), privacy markers, recency boost, progressive disclosure. Run `palaia doctor --fix` to upgrade.
|
|
30
30
|
plugin:
|
|
31
31
|
slot: memory
|
|
32
32
|
package: "@byte5ai/palaia"
|
|
33
33
|
---
|
|
34
34
|
|
|
35
|
-
# Palaia v2.
|
|
35
|
+
# Palaia v2.4 — Agent Memory Skill
|
|
36
36
|
|
|
37
37
|
Palaia is the memory system for OpenClaw agents. It gives you persistent, searchable, crash-safe memory across sessions. You don't need to understand how it works — just use the commands below.
|
|
38
38
|
|
|
39
|
+
<!-- begin:install -->
|
|
39
40
|
## First-Time Setup
|
|
40
41
|
|
|
41
42
|
When a user asks you to "set up palaia", "enable memory", or "remember things across sessions", run these steps:
|
|
@@ -136,6 +137,7 @@ npm install -g @byte5ai/palaia@latest
|
|
|
136
137
|
```
|
|
137
138
|
|
|
138
139
|
After the manual update, `palaia upgrade` will be available for future updates.
|
|
140
|
+
<!-- end:install -->
|
|
139
141
|
|
|
140
142
|
## Auto-Check (run every time this skill is loaded)
|
|
141
143
|
|
|
@@ -290,6 +292,9 @@ palaia query "what's the rate limit"
|
|
|
290
292
|
# Filter by type and status
|
|
291
293
|
palaia query "tasks" --type task --status open
|
|
292
294
|
|
|
295
|
+
# Filter by tags
|
|
296
|
+
palaia query "session-summary" --tags session-summary
|
|
297
|
+
|
|
293
298
|
# Search within a project
|
|
294
299
|
palaia query "deploy steps" --project myapp
|
|
295
300
|
|
|
@@ -324,6 +329,9 @@ palaia list
|
|
|
324
329
|
# Filter by tier, type, status
|
|
325
330
|
palaia list --tier warm --type task --status open --priority high
|
|
326
331
|
|
|
332
|
+
# Limit results
|
|
333
|
+
palaia list --type task --status open --limit 5
|
|
334
|
+
|
|
327
335
|
# Filter by project or assignee
|
|
328
336
|
palaia list --project myapp --assignee Elliot
|
|
329
337
|
```
|
|
@@ -575,6 +583,66 @@ Distinguish sessions of the same agent:
|
|
|
575
583
|
palaia instance set Claw-Main
|
|
576
584
|
```
|
|
577
585
|
|
|
586
|
+
### Agent Isolation Mode
|
|
587
|
+
|
|
588
|
+
For focused agents (Sonnet/Codex) that should only see their own memories:
|
|
589
|
+
|
|
590
|
+
**1. Configure in `priorities.json`:**
|
|
591
|
+
```json
|
|
592
|
+
{
|
|
593
|
+
"agents": {
|
|
594
|
+
"dev-worker": {
|
|
595
|
+
"scopeVisibility": ["private"],
|
|
596
|
+
"captureScope": "private",
|
|
597
|
+
"maxInjectedChars": 2000,
|
|
598
|
+
"recallMinScore": 0.85
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
```
|
|
603
|
+
Or via CLI:
|
|
604
|
+
```bash
|
|
605
|
+
palaia priorities set scopeVisibility private --agent dev-worker
|
|
606
|
+
palaia priorities set captureScope private --agent dev-worker
|
|
607
|
+
palaia priorities set maxInjectedChars 2000 --agent dev-worker
|
|
608
|
+
palaia priorities set recallMinScore 0.85 --agent dev-worker
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
**2. Set agent identity:**
|
|
612
|
+
```bash
|
|
613
|
+
export PALAIA_AGENT=dev-worker
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
**3. Auto-capture stays on** (crash safety net). Cleanup happens after the work package.
|
|
617
|
+
|
|
618
|
+
**4. After accepting work:**
|
|
619
|
+
```bash
|
|
620
|
+
palaia prune --agent dev-worker --tags auto-capture --protect-type process
|
|
621
|
+
```
|
|
622
|
+
This removes session noise while preserving learned SOPs.
|
|
623
|
+
|
|
624
|
+
#### Pre-configured Agent Profiles
|
|
625
|
+
|
|
626
|
+
| Profile | scopeVisibility | captureScope | maxInjectedChars | recallMinScore | autoCapture |
|
|
627
|
+
|---------|----------------|--------------|-----------------|----------------|-------------|
|
|
628
|
+
| **Isolated Worker** | `["private"]` | `private` | 2000 | 0.85 | true |
|
|
629
|
+
| **Orchestrator** | `["private","team","public"]` | `team` | 4000 | 0.7 | true |
|
|
630
|
+
| **Lean Worker** | `["private"]` | `private` | 1000 | 0.9 | false |
|
|
631
|
+
|
|
632
|
+
#### Orchestrator Lifecycle (process template)
|
|
633
|
+
|
|
634
|
+
Save this as a process entry for the orchestrator to recall:
|
|
635
|
+
```bash
|
|
636
|
+
palaia write "## Dev-Agent Lifecycle
|
|
637
|
+
1. Create agent identity: export PALAIA_AGENT=dev-worker-{task-id}
|
|
638
|
+
2. Configure isolation: palaia priorities set scopeVisibility private --agent dev-worker-{task-id}
|
|
639
|
+
3. Configure capture: palaia priorities set captureScope private --agent dev-worker-{task-id}
|
|
640
|
+
4. Assign work package via prompt
|
|
641
|
+
5. After acceptance: palaia prune --agent dev-worker-{task-id} --tags auto-capture --protect-type process
|
|
642
|
+
6. Verify: palaia list --agent dev-worker-{task-id} --type process
|
|
643
|
+
7. Process knowledge persists for future tasks" --type process --tags workflow,orchestration --scope private
|
|
644
|
+
```
|
|
645
|
+
|
|
578
646
|
---
|
|
579
647
|
|
|
580
648
|
## When to Use What
|
|
@@ -590,10 +658,11 @@ palaia instance set Claw-Main
|
|
|
590
658
|
| Check system health | `palaia status` |
|
|
591
659
|
| Something is wrong | `palaia doctor --fix` |
|
|
592
660
|
| Clean up old entries | `palaia gc` |
|
|
661
|
+
| Clean up agent session noise | `palaia prune --agent NAME --tags auto-capture --protect-type process` |
|
|
593
662
|
| Review accumulated knowledge | `palaia curate analyze` |
|
|
594
663
|
| Share knowledge | `palaia sync export` or `palaia package export` |
|
|
595
664
|
| Check for messages | `palaia memo inbox` |
|
|
596
|
-
| Start of session |
|
|
665
|
+
| Start of session | Session briefing is now automatic. Just run `palaia doctor` and check `palaia memo inbox`. |
|
|
597
666
|
|
|
598
667
|
**Do NOT manually write:** facts, decisions, or preferences that came up in the current conversation. Auto-Capture handles these.
|
|
599
668
|
|
|
@@ -632,6 +701,33 @@ palaia init --capture-level <off|minimal|normal|aggressive>
|
|
|
632
701
|
|
|
633
702
|
---
|
|
634
703
|
|
|
704
|
+
## Session Continuity (NEW in v2.4)
|
|
705
|
+
|
|
706
|
+
Session continuity gives agents automatic context restoration across sessions. These features work out of the box with the OpenClaw plugin -- no manual setup needed.
|
|
707
|
+
|
|
708
|
+
### Session Briefings
|
|
709
|
+
On session start, Palaia automatically injects a briefing with the last session summary and any open tasks. This means agents resume work without needing to manually search for context.
|
|
710
|
+
|
|
711
|
+
### Session Summaries
|
|
712
|
+
When a session ends or resets, Palaia auto-saves a summary of what happened. These are stored as entries with the `session-summary` tag and can be queried:
|
|
713
|
+
```bash
|
|
714
|
+
palaia query "session-summary" --tags session-summary
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
### Privacy Markers
|
|
718
|
+
Wrap sensitive content in `<private>...</private>` blocks to exclude it from auto-capture. Private blocks are stripped before any extraction runs.
|
|
719
|
+
|
|
720
|
+
### Recency Boost
|
|
721
|
+
Fresh memories are ranked higher in recall results. The boost factor is configurable via `recallRecencyBoost` (default `0.3`, set to `0` to disable).
|
|
722
|
+
|
|
723
|
+
### Progressive Disclosure
|
|
724
|
+
When result sets exceed 100 entries, Palaia uses compact mode to keep context manageable. Use `--limit` to control result size explicitly:
|
|
725
|
+
```bash
|
|
726
|
+
palaia list --type task --status open --limit 5
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
---
|
|
730
|
+
|
|
635
731
|
## Plugin Configuration (OpenClaw)
|
|
636
732
|
|
|
637
733
|
Set in `openclaw.json` under `plugins.entries.palaia.config`:
|
|
@@ -649,6 +745,11 @@ Set in `openclaw.json` under `plugins.entries.palaia.config`:
|
|
|
649
745
|
| `embeddingServer` | `true` | Keep embedding model loaded for fast queries |
|
|
650
746
|
| `showMemorySources` | `true` | Show memory source footnotes |
|
|
651
747
|
| `showCaptureConfirm` | `true` | Show capture confirmations |
|
|
748
|
+
| `sessionSummary` | `true` | Auto-save session summaries on end/reset |
|
|
749
|
+
| `sessionBriefing` | `true` | Load session context on session start |
|
|
750
|
+
| `sessionBriefingMaxChars` | `1500` | Max chars for session briefing injection |
|
|
751
|
+
| `captureToolObservations` | `true` | Track tool usage as session context |
|
|
752
|
+
| `recallRecencyBoost` | `0.3` | Boost factor for fresh memories (0=off) |
|
|
652
753
|
|
|
653
754
|
---
|
|
654
755
|
|
|
@@ -51,7 +51,13 @@ def _should_rename(error_count: int, total_count: int) -> bool:
|
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
def needs_migration(palaia_root: Path) -> bool:
|
|
54
|
-
"""Check if there are flat-file indexes that should be migrated.
|
|
54
|
+
"""Check if there are flat-file indexes that should be migrated.
|
|
55
|
+
|
|
56
|
+
Detects three scenarios:
|
|
57
|
+
1. Old-style metadata.json / embeddings.json exist (pre-SQLite migration)
|
|
58
|
+
2. WAL JSON files exist
|
|
59
|
+
3. Entries on disk but 0 in the database (e.g. backup restore into hot/)
|
|
60
|
+
"""
|
|
55
61
|
metadata_json = palaia_root / "index" / "metadata.json"
|
|
56
62
|
embeddings_json = palaia_root / "index" / "embeddings.json"
|
|
57
63
|
wal_dir = palaia_root / "wal"
|
|
@@ -59,7 +65,37 @@ def needs_migration(palaia_root: Path) -> bool:
|
|
|
59
65
|
has_json = metadata_json.exists() or embeddings_json.exists()
|
|
60
66
|
has_wal_files = wal_dir.exists() and any(wal_dir.glob("*.json"))
|
|
61
67
|
|
|
62
|
-
|
|
68
|
+
if has_json or has_wal_files:
|
|
69
|
+
return True
|
|
70
|
+
|
|
71
|
+
# Scenario 3: Disk entries exist but DB is empty (backup restore)
|
|
72
|
+
disk_count = 0
|
|
73
|
+
for tier in ("hot", "warm", "cold"):
|
|
74
|
+
tier_dir = palaia_root / tier
|
|
75
|
+
if tier_dir.exists():
|
|
76
|
+
try:
|
|
77
|
+
disk_count += sum(1 for _ in tier_dir.glob("*.md"))
|
|
78
|
+
except (PermissionError, OSError):
|
|
79
|
+
pass
|
|
80
|
+
if disk_count > 0:
|
|
81
|
+
break # At least one entry found, check DB
|
|
82
|
+
|
|
83
|
+
if disk_count > 0:
|
|
84
|
+
import sqlite3
|
|
85
|
+
|
|
86
|
+
db_path = palaia_root / "palaia.db"
|
|
87
|
+
if db_path.exists():
|
|
88
|
+
try:
|
|
89
|
+
conn = sqlite3.connect(str(db_path))
|
|
90
|
+
row = conn.execute("SELECT COUNT(*) FROM entries").fetchone()
|
|
91
|
+
db_count = row[0] if row else 0
|
|
92
|
+
conn.close()
|
|
93
|
+
if db_count == 0:
|
|
94
|
+
return True
|
|
95
|
+
except Exception:
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
return False
|
|
63
99
|
|
|
64
100
|
|
|
65
101
|
def migrate_to_backend(palaia_root: Path, backend: object) -> MigrationResult:
|
|
@@ -49,7 +49,17 @@ from palaia.config import ( # noqa: E402
|
|
|
49
49
|
from palaia.doctor import apply_fixes, format_doctor_report, run_doctor # noqa: E402
|
|
50
50
|
from palaia.migrate import format_result, migrate # noqa: E402
|
|
51
51
|
from palaia.store import Store # noqa: E402
|
|
52
|
-
from palaia.ui import
|
|
52
|
+
from palaia.ui import ( # noqa: E402
|
|
53
|
+
bold,
|
|
54
|
+
dim,
|
|
55
|
+
error_msg,
|
|
56
|
+
print_header,
|
|
57
|
+
section,
|
|
58
|
+
success,
|
|
59
|
+
sym_arrow,
|
|
60
|
+
table_multi,
|
|
61
|
+
)
|
|
62
|
+
|
|
53
63
|
|
|
54
64
|
# Commands that require a valid init (agent identity set)
|
|
55
65
|
GATED_COMMANDS = frozenset(
|
|
@@ -60,6 +70,7 @@ GATED_COMMANDS = frozenset(
|
|
|
60
70
|
"edit",
|
|
61
71
|
"memo",
|
|
62
72
|
"gc",
|
|
73
|
+
"prune",
|
|
63
74
|
"export",
|
|
64
75
|
"import",
|
|
65
76
|
"ingest",
|
|
@@ -178,9 +189,9 @@ def cmd_init(args):
|
|
|
178
189
|
args,
|
|
179
190
|
):
|
|
180
191
|
return 0
|
|
181
|
-
print(f"Initialized
|
|
192
|
+
print(success(f"Initialized at {dim(result['path'])}"))
|
|
182
193
|
if result.get("used_default"):
|
|
183
|
-
print("
|
|
194
|
+
print(f" Agent: default {dim('(use --agent NAME to customize)')}")
|
|
184
195
|
|
|
185
196
|
# Print all messages from service (chain info, capture level, setup instructions)
|
|
186
197
|
if not getattr(args, "json", False):
|
|
@@ -243,7 +254,10 @@ def cmd_write(args):
|
|
|
243
254
|
):
|
|
244
255
|
return 0
|
|
245
256
|
|
|
246
|
-
|
|
257
|
+
short_id = result['id'][:12]
|
|
258
|
+
scope = result.get('scope', 'team')
|
|
259
|
+
tier = result.get('tier', 'hot')
|
|
260
|
+
print(success(f"Written {dim(short_id)} {sym_arrow()} {tier}/{scope}"))
|
|
247
261
|
|
|
248
262
|
if significance_detected:
|
|
249
263
|
tags_str = ", ".join(significance_detected)
|
|
@@ -294,7 +308,7 @@ def cmd_edit(args):
|
|
|
294
308
|
if _json_out(result, args):
|
|
295
309
|
return 0
|
|
296
310
|
|
|
297
|
-
print(f"Updated
|
|
311
|
+
print(success(f"Updated {dim(result['id'][:12])}"))
|
|
298
312
|
changes = []
|
|
299
313
|
if body is not None:
|
|
300
314
|
changes.append("content")
|
|
@@ -304,7 +318,7 @@ def cmd_edit(args):
|
|
|
304
318
|
if getattr(args, field, None) is not None:
|
|
305
319
|
changes.append(field)
|
|
306
320
|
if changes:
|
|
307
|
-
print(f"
|
|
321
|
+
print(f" Changed: {', '.join(changes)}")
|
|
308
322
|
return 0
|
|
309
323
|
|
|
310
324
|
|
|
@@ -506,17 +520,68 @@ def cmd_gc(args):
|
|
|
506
520
|
|
|
507
521
|
skip_keys = {"wal_cleaned", "pruned", "pruned_entries"}
|
|
508
522
|
total_moves = sum(v for k, v in result.items() if k not in skip_keys and isinstance(v, int))
|
|
509
|
-
print("GC complete.")
|
|
510
523
|
if total_moves:
|
|
524
|
+
print(success("GC complete"))
|
|
511
525
|
for k, v in result.items():
|
|
512
526
|
if v and k not in skip_keys and isinstance(v, int):
|
|
513
|
-
print(f"
|
|
527
|
+
print(f" {k}: {v}")
|
|
514
528
|
else:
|
|
515
|
-
print("
|
|
529
|
+
print(success("GC complete — no tier changes needed"))
|
|
516
530
|
if result.get("wal_cleaned"):
|
|
517
|
-
print(f"
|
|
531
|
+
print(f" WAL cleaned: {result['wal_cleaned']} old entries")
|
|
518
532
|
if result.get("pruned"):
|
|
519
|
-
print(f"
|
|
533
|
+
print(f" Pruned (budget): {result['pruned']} entries")
|
|
534
|
+
return 0
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
def cmd_prune(args):
|
|
538
|
+
"""Selectively delete entries by agent + tags."""
|
|
539
|
+
from palaia.services.admin import run_prune
|
|
540
|
+
|
|
541
|
+
root = get_root()
|
|
542
|
+
agent = args.agent
|
|
543
|
+
tags = [t.strip() for t in args.tags.split(",") if t.strip()]
|
|
544
|
+
protect_types = None
|
|
545
|
+
if args.protect_type:
|
|
546
|
+
protect_types = [t.strip() for t in args.protect_type.split(",") if t.strip()]
|
|
547
|
+
dry_run = getattr(args, "dry_run", False)
|
|
548
|
+
|
|
549
|
+
result = run_prune(root, agent=agent, tags=tags, protect_types=protect_types, dry_run=dry_run)
|
|
550
|
+
|
|
551
|
+
if _json_out(result, args):
|
|
552
|
+
return 0
|
|
553
|
+
|
|
554
|
+
entries = result.get("entries", [])
|
|
555
|
+
count = result.get("pruned", 0)
|
|
556
|
+
|
|
557
|
+
if count == 0:
|
|
558
|
+
print("No matching entries found.")
|
|
559
|
+
return 0
|
|
560
|
+
|
|
561
|
+
if dry_run:
|
|
562
|
+
rows = [(e["id"], e["title"][:30], e["type"], e["tier"], ",".join(e.get("tags", []))) for e in entries]
|
|
563
|
+
print(
|
|
564
|
+
table_multi(
|
|
565
|
+
headers=("ID", "Title", "Type", "Tier", "Tags"),
|
|
566
|
+
rows=rows,
|
|
567
|
+
min_widths=(8, 30, 8, 4, 15),
|
|
568
|
+
)
|
|
569
|
+
)
|
|
570
|
+
print(f"\n{count} entries would be deleted (dry-run).")
|
|
571
|
+
else:
|
|
572
|
+
print(f"Pruned {count} entries for agent '{agent}'.")
|
|
573
|
+
for e in entries:
|
|
574
|
+
print(f" {e['id']} {e['title'][:40]}")
|
|
575
|
+
|
|
576
|
+
# Record prune success for prune_reminder graduation (#148)
|
|
577
|
+
try:
|
|
578
|
+
from palaia.nudge import NudgeTracker
|
|
579
|
+
caller = os.environ.get("PALAIA_AGENT") or "default"
|
|
580
|
+
tracker = NudgeTracker(root)
|
|
581
|
+
tracker.record_success("prune_reminder", caller)
|
|
582
|
+
except Exception:
|
|
583
|
+
pass
|
|
584
|
+
|
|
520
585
|
return 0
|
|
521
586
|
|
|
522
587
|
|
|
@@ -541,9 +606,9 @@ def cmd_doctor(args):
|
|
|
541
606
|
print(format_doctor_report(results, show_fix=show_fix))
|
|
542
607
|
|
|
543
608
|
if fix_actions:
|
|
544
|
-
print("\
|
|
609
|
+
print(f"\n {bold('Fixes applied:')}")
|
|
545
610
|
for action in fix_actions:
|
|
546
|
-
print(
|
|
611
|
+
print(success(action))
|
|
547
612
|
print()
|
|
548
613
|
|
|
549
614
|
return 0
|
|
@@ -742,17 +807,18 @@ def cmd_setup(args):
|
|
|
742
807
|
|
|
743
808
|
# Print action details
|
|
744
809
|
if not getattr(args, "json", False):
|
|
810
|
+
from palaia.ui import status_label
|
|
745
811
|
for action in result.get("actions", []):
|
|
746
812
|
label = action["action"]
|
|
747
813
|
agent = action["agent"]
|
|
748
814
|
if label == "skip":
|
|
749
|
-
print(f"
|
|
815
|
+
print(f" {status_label('skip')} {agent}: {dim(action.get('reason', ''))}")
|
|
750
816
|
elif label == "plan":
|
|
751
|
-
print(f"
|
|
817
|
+
print(f" {status_label('info')} {agent}: would create .palaia {sym_arrow()} {action.get('target', '')}")
|
|
752
818
|
elif label == "ok":
|
|
753
|
-
print(f"
|
|
819
|
+
print(success(f"{agent}: .palaia {sym_arrow()} {action.get('target', '')}"))
|
|
754
820
|
elif label == "error":
|
|
755
|
-
print(f"
|
|
821
|
+
print(error_msg(f"{agent}: {action.get('error', '')}"))
|
|
756
822
|
|
|
757
823
|
if _json_out(
|
|
758
824
|
{
|
|
@@ -1372,6 +1438,7 @@ def main():
|
|
|
1372
1438
|
"list": cmd_list,
|
|
1373
1439
|
"status": cmd_status,
|
|
1374
1440
|
"gc": cmd_gc,
|
|
1441
|
+
"prune": cmd_prune,
|
|
1375
1442
|
"setup": cmd_setup,
|
|
1376
1443
|
"doctor": cmd_doctor,
|
|
1377
1444
|
"export": cmd_export,
|
|
@@ -169,6 +169,14 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
169
169
|
p_gc.add_argument("--budget", action="store_true", help="Prune entries to meet configured budget limits")
|
|
170
170
|
p_gc.add_argument("--json", action="store_true", help="Output as JSON")
|
|
171
171
|
|
|
172
|
+
# prune
|
|
173
|
+
p_prune = sub.add_parser("prune", help="Selectively delete entries by agent + tags")
|
|
174
|
+
p_prune.add_argument("--agent", required=True, help="Agent name to prune entries for (required)")
|
|
175
|
+
p_prune.add_argument("--tags", required=True, help="Comma-separated tags to match (required, e.g. auto-capture)")
|
|
176
|
+
p_prune.add_argument("--protect-type", default=None, help="Comma-separated types to preserve (e.g. process,task)")
|
|
177
|
+
p_prune.add_argument("--dry-run", action="store_true", help="Show what would be deleted without changing anything")
|
|
178
|
+
p_prune.add_argument("--json", action="store_true", help="Output as JSON")
|
|
179
|
+
|
|
172
180
|
# project
|
|
173
181
|
_add_project_subparser(sub)
|
|
174
182
|
|