personal memory agent
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: rename `sol call sol` → `sol call identity`, extract navigate module

+84 -70
+4 -4
AGENTS.md
··· 32 32 33 33 ### How to write 34 34 35 - Read current state: `sol call sol self` or `sol call sol agency` 35 + Read current state: `sol call identity self` or `sol call identity agency` 36 36 37 - Read partner profile: `sol call sol partner` (read-only — do not write in conversation) 37 + Read partner profile: `sol call identity partner` (read-only — do not write in conversation) 38 38 39 39 Update a section of self.md (preferred — preserves other sections): 40 40 ``` 41 - sol call sol self --update-section 'who I'\''m here for' --value 'Jer — founder-engineer, goes by Jer not Jeremie' 41 + sol call identity self --update-section 'who I'\''m here for' --value 'Jer — founder-engineer, goes by Jer not Jeremie' 42 42 ``` 43 43 44 - Full rewrite: `sol call sol self --write --value '...'` or `sol call sol agency --write --value '...'` 44 + Full rewrite: `sol call identity self --write --value '...'` or `sol call identity agency --write --value '...'` 45 45 46 46 Use `sol call` commands for identity writes — never use `apply_patch` or direct file editing for sol/ files. 47 47
+1 -1
docs/CALLOSUM.md
··· 140 140 ``` 141 141 142 142 ### `navigate` - Browser navigation control 143 - **Source:** `think/call.py` (`sol call navigate`) 143 + **Source:** `think/tools/navigate.py` (`sol call navigate`) 144 144 **Events:** `request` 145 145 **Key fields:** `path` (string, URL path), `facet` (string, facet name) — at least one required 146 146 **Consumer:** `convey/static/websocket.js` (built-in listener)
+6 -4
docs/SOLCLI.md
··· 92 92 ```python 93 93 # think/call.py 94 94 from think.tools.call import app as journal_app 95 + from think.tools.navigate import app as navigate_app 95 96 from think.tools.routines import app as routines_app 96 97 from think.tools.sol import app as sol_app 97 98 98 99 call_app.add_typer(journal_app, name="journal") 100 + call_app.add_typer(navigate_app, name="navigate") 99 101 call_app.add_typer(routines_app, name="routines") 100 - call_app.add_typer(sol_app, name="sol") 102 + call_app.add_typer(sol_app, name="identity") 101 103 ``` 102 104 103 105 These live under `think/tools/` because they import think-internal APIs directly. ··· 256 258 │ ├── tools/ 257 259 │ │ ├── call.py # sol call journal (built-in) 258 260 │ │ ├── routines.py # sol call routines (built-in) 259 - │ │ └── sol.py # sol call sol (built-in) 261 + │ │ └── sol.py # sol call identity (built-in) 260 262 │ └── *.py # Top-level command modules 261 263 ├── apps/ 262 264 │ ├── todos/ ··· 313 315 | `awareness` | `apps/awareness/call.py` | status, onboarding, imports, log, log-read | 314 316 | `journal` | `think/tools/call.py` | search, events, facets, facet (show/create/update/rename/mute/unmute/delete/merge), news, agents, read, imports, import, retention purge, storage-summary | 315 317 | `routines` | `think/tools/routines.py` | list, templates, create, edit, delete, run, output, suggestions, suggest-respond, suggest-state | 316 - | `sol` | `think/tools/sol.py` | self, partner, agency, pulse, briefing | 317 - | `navigate` | `think/call.py` (inline) | *(single command)* | 318 + | `identity` | `think/tools/sol.py` | self, partner, agency, pulse, briefing | 319 + | `navigate` | `think/tools/navigate.py` | *(single command)* | 318 320 319 321 ## Skill System 320 322
+7 -7
muse/heartbeat.md
··· 26 26 Note any service issues, capture gaps, or pipeline failures. 27 27 28 28 If you find issues: update agency.md's `## system` section via 29 - `sol call sol agency --write --value '...'`. 29 + `sol call identity agency --write --value '...'`. 30 30 31 31 ## Step 2: Check journal quality 32 32 ··· 39 39 If you find reprocessable issues (broken segments): reprocess them directly 40 40 with `sol dream --segment`. Log the action in agency.md. 41 41 42 - If you find curation issues: read current agency.md with `sol call sol agency`, 42 + If you find curation issues: read current agency.md with `sol call identity agency`, 43 43 add entries to the curation section, then write it back with 44 - `sol call sol agency --write --value '...'`. 44 + `sol call identity agency --write --value '...'`. 45 45 46 46 ## Step 2.5: Check routine health 47 47 ··· 56 56 57 57 ## Step 3: Tend agency.md 58 58 59 - Read agency.md with `sol call sol agency`. For each open item: 59 + Read agency.md with `sol call identity agency`. For each open item: 60 60 - **Resolved?** Check current state. If fixed, mark `[x]` with date. 61 61 - **Stale?** Open 30+ days with no activity? Flag or remove. 62 62 - **Actionable?** Within autonomous boundaries? Act on it. ··· 69 69 `sol call entities` queries on high-activity facets. 70 70 71 71 Add new curation suggestions to agency.md's `## curation` section (read with 72 - `sol call sol agency`, update and write back with `sol call sol agency --write --value '...'`). 72 + `sol call identity agency`, update and write back with `sol call identity agency --write --value '...'`). 73 73 Do NOT act on entity merges or facet changes — those are suggest-and-wait. 74 74 75 75 ## Step 5: Review self.md (brief) 76 76 77 - Read self.md with `sol call sol self`. Consider: 77 + Read self.md with `sol call identity self`. Consider: 78 78 - Did today's processing reveal a new pattern about the owner? 79 79 - Is anything in self.md now stale or inaccurate? 80 80 81 81 Update self.md ONLY if you have a genuine new observation from background 82 82 analysis. Most heartbeats should not touch self.md. Use 83 - `sol call sol self --update-section '<heading>' --value '...'` for targeted updates. 83 + `sol call identity self --update-section '<heading>' --value '...'` for targeted updates. 84 84 85 85 ## Step 6: Commit and close 86 86
+2 -2
muse/morning_briefing.md
··· 25 25 2. For each facet: `sol call journal news FACET --day $day_YYYYMMDD` — facet newsletter 26 26 3. `sol call calendar list $day_YYYYMMDD` — today's events with participants 27 27 4. `sol call todos list` — pending action items across all facets 28 - 5. `sol call sol pulse` — current pulse narrative and needs-you items 29 - 6. `sol call sol partner` — owner behavioral profile (informs tone and emphasis) 28 + 5. `sol call identity pulse` — current pulse narrative and needs-you items 29 + 6. `sol call identity partner` — owner behavioral profile (informs tone and emphasis) 30 30 7. `sol call journal search "" -d $day_YYYYMMDD -a followups -n 10` — follow-up items from today 31 31 8. `sol call journal search "" --day-from $day_YYYYMMDD -a anticipation -n 5` — forward-looking anticipations 32 32 9. `sol call journal search "" -d $day_YYYYMMDD -a decisions -n 10` — yesterday's consequential decisions
+4 -4
muse/partner.md
··· 21 21 ## Step 1: Read current state 22 22 23 23 ```bash 24 - sol call sol partner 24 + sol call identity partner 25 25 ``` 26 26 27 27 Note which sections have real observations vs `[observing]` placeholders. 28 28 Also read your own identity for context: 29 29 30 30 ```bash 31 - sol call sol self 31 + sol call identity self 32 32 ``` 33 33 34 34 ## Step 2: Gather recent data ··· 48 48 ## Step 3: Analyze and write observations 49 49 50 50 For each of the five profile sections, analyze the gathered data and write 51 - observations if you have sufficient evidence. Use `sol call sol partner --update-section` 51 + observations if you have sufficient evidence. Use `sol call identity partner --update-section` 52 52 for each section you update. 53 53 54 54 ### Section guidance ··· 107 107 For each section with new observations, write it: 108 108 109 109 ```bash 110 - sol call sol partner --update-section 'work patterns' --value 'My partner tends to batch meetings before noon and protects afternoon blocks for focused work. Calendar data from March 25-31 shows 85% of meetings before 12:00 (sol://20260328/archon/091500_300). 110 + sol call identity partner --update-section 'work patterns' --value 'My partner tends to batch meetings before noon and protects afternoon blocks for focused work. Calendar data from March 25-31 shows 85% of meetings before 12:00 (sol://20260328/archon/091500_300). 111 111 112 112 Deep work sessions typically run 2-3 hours — todo completion spikes correlate with these blocks.' 113 113 ```
+4 -4
muse/pulse.md
··· 24 24 25 25 Read current state using these tools: 26 26 27 - 1. `sol call sol pulse` — previous pulse (may not exist yet; that's fine) 28 - 2. `sol call sol self` — who the owner is 29 - 3. `sol call sol partner` — behavioral profile of the owner 27 + 1. `sol call identity pulse` — previous pulse (may not exist yet; that's fine) 28 + 2. `sol call identity self` — who the owner is 29 + 3. `sol call identity partner` — behavioral profile of the owner 30 30 4. `sol call calendar list` — today's events 31 31 5. `sol call todos list` — pending action items 32 32 6. `sol call entities search --recent` — recent entity activity ··· 63 63 Write the complete pulse (YAML frontmatter + narrative + needs-you section) via: 64 64 65 65 ```bash 66 - sol call sol pulse --write --value $'---\nupdated: 2026-03-22T14:35:00\nsegment: 143022_300\nsource: pulse-cogitate\n---\n\n[Your narrative here]\n\n## needs you\n- Item 1\n- Item 2' 66 + sol call identity pulse --write --value $'---\nupdated: 2026-03-22T14:35:00\nsegment: 143022_300\nsource: pulse-cogitate\n---\n\n[Your narrative here]\n\n## needs you\n- Item 1\n- Item 2' 67 67 ``` 68 68 69 69 The `updated` field must be an ISO 8601 datetime (no timezone). The `segment`
+1 -1
routines/templates/commitment-audit.md
··· 16 16 2. Use `sol call journal search "" -a followups -n 20` to find follow-up items from recent journal activity. 17 17 3. Use `sol call journal facets` if you need to map commitments back to facets. 18 18 4. Use `sol call journal news FACET --day $day_YYYYMMDD` when a facet summary helps explain why something is still open. 19 - 5. Use `sol call sol pulse` to compare explicit commitments with current focus and needs-you items. 19 + 5. Use `sol call identity pulse` to compare explicit commitments with current focus and needs-you items. 20 20 21 21 ## Synthesize 22 22
+1 -1
routines/templates/domain-watch.md
··· 15 15 1. Confirm the facets in scope with `sol call journal facets` if needed. 16 16 2. Use `sol call journal search QUERY --facet FACET --day-from START --day-to END -n 20` for each important topic or domain you can infer from the routine context. 17 17 3. Use `sol call journal news FACET --day $day_YYYYMMDD` when a facet newsletter can summarize recent movement. 18 - 4. Use `sol call sol pulse` to compare broad narrative priorities with the search results. 18 + 4. Use `sol call identity pulse` to compare broad narrative priorities with the search results. 19 19 20 20 ## Synthesize 21 21
+1 -1
routines/templates/meeting-prep.md
··· 18 18 4. Use `sol call journal search QUERY -n 10` to look for recent mentions of the meeting topic, project, or participants. 19 19 5. If a configured facet seems especially relevant, use `sol call journal news FACET --day $day_YYYYMMDD`. 20 20 6. Use `sol call todos list` only if pending action items are directly relevant to the meeting. 21 - 7. Use `sol call sol pulse` if it helps connect the meeting to current priorities or tensions. 21 + 7. Use `sol call identity pulse` if it helps connect the meeting to current priorities or tensions. 22 22 23 23 ## Synthesize 24 24
+1 -1
routines/templates/monthly-patterns.md
··· 17 17 3. Use `sol call journal news FACET --day YYYYMMDD` for representative weekly or recent snapshots when they help summarize a facet. 18 18 4. Use `sol call entities intelligence PERSON` for people who appear central to the month. 19 19 5. Use `sol call calendar list YYYYMMDD` on representative days if calendar load seems important. 20 - 6. Use `sol call sol pulse` to compare month-long patterns against the current state narrative. 20 + 6. Use `sol call identity pulse` to compare month-long patterns against the current state narrative. 21 21 22 22 ## Synthesize 23 23
+1 -1
routines/templates/morning-briefing.md
··· 15 15 1. Call `sol call journal facets` to see the active facets if you need broader context. 16 16 2. Call `sol call calendar list $day_YYYYMMDD` to review today's events and participants. 17 17 3. Call `sol call todos list` to see pending action items across facets. 18 - 4. Call `sol call sol pulse` to capture current narrative, priorities, and needs-you items. 18 + 4. Call `sol call identity pulse` to capture current narrative, priorities, and needs-you items. 19 19 5. Call `sol call journal search "" -a followups -n 10` to find recent follow-up items. 20 20 6. For each person on today's calendar, call `sol call entities intelligence PERSON`. 21 21 7. If a facet needs more detail, call `sol call journal news FACET --day $day_YYYYMMDD`.
+1 -1
routines/templates/relationship-pulse.md
··· 16 16 2. Use `sol call journal search "" --facet FACET -n 20` to identify frequently mentioned people or recent interactions in each relevant facet. 17 17 3. For each meaningful person, call `sol call entities intelligence PERSON`. 18 18 4. Use `sol call journal news FACET --day $day_YYYYMMDD` if a facet summary helps explain current context. 19 - 5. Use `sol call sol pulse` for broad priorities that may affect relationship maintenance. 19 + 5. Use `sol call identity pulse` for broad priorities that may affect relationship maintenance. 20 20 21 21 ## Synthesize 22 22
+1 -1
routines/templates/weekly-review.md
··· 16 16 2. Use `sol call journal search "" --day-from $day_minus_7_YYYYMMDD --day-to $day_YYYYMMDD -n 25` to find notable entries and themes. 17 17 3. Use `sol call todos list` to review outstanding work and infer what likely got completed or deferred. 18 18 4. Use `sol call calendar list YYYYMMDD` across the last 7 days to understand meeting load and major time commitments. 19 - 5. Use `sol call sol pulse` for the current state narrative. 19 + 5. Use `sol call identity pulse` for the current state narrative. 20 20 6. Use `sol call journal news FACET --day YYYYMMDD` for any facet that needs a richer summary. 21 21 22 22 ## Synthesize
+4 -4
sol/identity.md
··· 30 30 31 31 ### How to write 32 32 33 - Read current state: `sol call sol self` or `sol call sol agency` 33 + Read current state: `sol call identity self` or `sol call identity agency` 34 34 35 - Read partner profile: `sol call sol partner` (read-only — do not write in conversation) 35 + Read partner profile: `sol call identity partner` (read-only — do not write in conversation) 36 36 37 37 Update a section of self.md (preferred — preserves other sections): 38 38 ``` 39 - sol call sol self --update-section 'who I'\''m here for' --value 'Jer — founder-engineer, goes by Jer not Jeremie' 39 + sol call identity self --update-section 'who I'\''m here for' --value 'Jer — founder-engineer, goes by Jer not Jeremie' 40 40 ``` 41 41 42 - Full rewrite: `sol call sol self --write --value '...'` or `sol call sol agency --write --value '...'` 42 + Full rewrite: `sol call identity self --write --value '...'` or `sol call identity agency --write --value '...'` 43 43 44 44 Use `sol call` commands for identity writes — never use `apply_patch` or direct file editing for sol/ files. 45 45
+2 -2
tests/test_sol_call.py
··· 1 1 # SPDX-License-Identifier: AGPL-3.0-only 2 2 # Copyright (c) 2026 sol pbc 3 3 4 - """Tests for sol call sol — identity directory read/write commands.""" 4 + """Tests for sol call identity — identity directory read/write commands.""" 5 5 6 6 import json 7 7 ··· 306 306 307 307 308 308 class TestSolWriteDoesNotEscapeSolDir: 309 - """Verify that sol call sol only writes to sol/ directory files.""" 309 + """Verify that sol call identity only writes to sol/ directory files.""" 310 310 311 311 def test_self_write_stays_in_sol_dir(self, journal_with_sol): 312 312 """Write to self.md goes to sol/self.md, not anywhere else."""
+3 -30
think/call.py
··· 73 73 74 74 # Mount built-in CLIs (not auto-discovered since they live under think/) 75 75 from think.tools.call import app as journal_app 76 + from think.tools.navigate import app as navigate_app 76 77 from think.tools.routines import app as routines_app 77 78 from think.tools.sol import app as sol_app 78 79 79 80 call_app.add_typer(journal_app, name="journal") 81 + call_app.add_typer(navigate_app, name="navigate") 80 82 call_app.add_typer(routines_app, name="routines") 81 - call_app.add_typer(sol_app, name="sol") 82 - 83 - 84 - # General-purpose navigate command (migrated from apps/chat/call.py) 85 - @call_app.command("navigate") 86 - def navigate( 87 - path: str = typer.Argument(None, help="URL path to navigate to."), 88 - facet: str = typer.Option(None, "--facet", "-f", help="Facet to switch to."), 89 - ) -> None: 90 - """Navigate the browser to a path and/or switch facet.""" 91 - if not path and not facet: 92 - typer.echo("Error: provide a path and/or --facet", err=True) 93 - raise typer.Exit(1) 94 - 95 - from think.callosum import callosum_send 96 - 97 - fields: dict = {} 98 - if path is not None: 99 - fields["path"] = path 100 - if facet is not None: 101 - fields["facet"] = facet 102 - 103 - callosum_send("navigate", "request", **fields) 104 - 105 - parts = [] 106 - if path: 107 - parts.append(path) 108 - if facet: 109 - parts.append(f"[{facet}]") 110 - typer.echo(f"Navigate: {' '.join(parts)}") 83 + call_app.add_typer(sol_app, name="identity") 111 84 112 85 113 86 def main() -> None:
+39
think/tools/navigate.py
··· 1 + # SPDX-License-Identifier: AGPL-3.0-only 2 + # Copyright (c) 2026 sol pbc 3 + 4 + """CLI commands for browser navigation actions. 5 + 6 + Mounted by ``think.call`` as ``sol call navigate ...``. 7 + """ 8 + 9 + import typer 10 + 11 + app = typer.Typer() 12 + 13 + 14 + @app.callback(invoke_without_command=True) 15 + def navigate( 16 + path: str = typer.Argument(None, help="URL path to navigate to."), 17 + facet: str = typer.Option(None, "--facet", "-f", help="Facet to switch to."), 18 + ) -> None: 19 + """Navigate the browser to a path and/or switch facet.""" 20 + if not path and not facet: 21 + typer.echo("Error: provide a path and/or --facet", err=True) 22 + raise typer.Exit(1) 23 + 24 + from think.callosum import callosum_send 25 + 26 + fields: dict = {} 27 + if path is not None: 28 + fields["path"] = path 29 + if facet is not None: 30 + fields["facet"] = facet 31 + 32 + callosum_send("navigate", "request", **fields) 33 + 34 + parts = [] 35 + if path: 36 + parts.append(path) 37 + if facet: 38 + parts.append(f"[{facet}]") 39 + typer.echo(f"Navigate: {' '.join(parts)}")
+1 -1
think/tools/sol.py
··· 9 9 provides read access to the morning briefing at 10 10 ``{journal}/YYYYMMDD/agents/morning_briefing.md``. 11 11 12 - Mounted by ``think.call`` as ``sol call sol ...``. 12 + Mounted by ``think.call`` as ``sol call identity ...``. 13 13 """ 14 14 15 15 import sys