personal memory agent
0
fork

Configure Feed

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

Rebrand project from sunstone to solstone

Complete project rename with all references updated to lowercase "solstone":

- Package name and entry point in pyproject.toml
- GitHub URLs updated to solpbc/solstone
- File rename: think/sunstone.py → think/solstone.py
- Function rename: convert_revai_to_sunstone → convert_revai_to_solstone
- Environment variables: SUNSTONE_MCP_* → SOLSTONE_MCP_*
- State directory: ~/.local/state/sunstone → ~/.local/state/solstone
- LocalStorage key: sunstone:notification_history → solstone:notification_history
- All documentation and agent persona files updated
- Fixed entry point filter to include observe.* and muse.* packages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+134 -111
+1 -1
.gitignore
··· 1 1 .env 2 2 .venv 3 - sunstone.egg-info/ 3 + solstone.egg-info/ 4 4 __pycache__/ 5 5 *.pyc 6 6 logs/
+6 -6
AGENTS.md
··· 1 1 # Development Guidelines & Contribution Standards 2 2 3 - This document provides comprehensive guidelines for contributing to Sunstone, whether you're an AI assistant, human developer, or automated system. 3 + This document provides comprehensive guidelines for contributing to solstone, whether you're an AI assistant, human developer, or automated system. 4 4 5 5 ## 📋 Project Overview 6 6 7 - **Sunstone** is a Python-based AI-driven desktop journaling toolkit that provides: 7 + **solstone** is a Python-based AI-driven desktop journaling toolkit that provides: 8 8 9 9 * **observe/** - Multimodal capture (audio + visual) and AI-powered analysis 10 10 * **think/** - Data post-processing, summarization, and intelligent insights ··· 17 17 18 18 ## 🔑 Key Concepts 19 19 20 - Understanding these core concepts is essential for working with Sunstone: 20 + Understanding these core concepts is essential for working with solstone: 21 21 22 22 * **Journal**: Central data structure organized as `JOURNAL_PATH/YYYYMMDD/` directories. All captured data, transcripts, and analysis artifacts are stored here. See [docs/JOURNAL.md](docs/JOURNAL.md). 23 23 ··· 36 36 ## 🏗️ Project Structure 37 37 38 38 ``` 39 - sunstone/ 39 + solstone/ 40 40 ├── observe/ # Multimodal capture & AI analysis 41 41 ├── think/ # Data post-processing & AI analysis 42 42 ├── convey/ # Web app frontend & backend ··· 78 78 * Agents process via `muse-agents` command with persona configurations 79 79 80 80 **Command Reference**: 81 - See `pyproject.toml` `[project.scripts]` for the authoritative, current list of CLI entry points (e.g., `sunstone`, `think-*`, `observe-*`, `muse-*`, `convey*`). 81 + See `pyproject.toml` `[project.scripts]` for the authoritative, current list of CLI entry points (e.g., `solstone`, `think-*`, `observe-*`, `muse-*`, `convey*`). 82 82 83 83 --- 84 84 ··· 241 241 * **Insight Templates**: `think/insights/*.txt` and `*.json` 242 242 243 243 ### Getting Help 244 - * Run `sunstone` for CLI command list 244 + * Run `solstone` for CLI command list 245 245 * Check [docs/DOCTOR.md](docs/DOCTOR.md) for debugging and diagnostics 246 246 * Browse `docs/` for all subsystem documentation 247 247 * Review test files in `tests/` for usage examples
+1 -1
Makefile
··· 1 - # Sunstone Makefile 1 + # solstone Makefile 2 2 # Python-based AI-driven desktop journaling toolkit 3 3 4 4 .PHONY: install deps test test-apps test-app lint format check clean dev full all
+4 -4
README.md
··· 1 - <img src="logo.png" alt="Sunstone Logo" width="300"> 1 + <img src="logo.png" alt="solstone Logo" width="300"> 2 2 3 - # Sunstone 3 + # solstone 4 4 Navigate Work Intelligently 5 5 6 - A comprehensive Python-based AI-driven desktop journaling toolkit for multimodal capture, analysis, and intelligent navigation of workplace activities. Sunstone organizes captured data under a **journal** directory containing daily `YYYYMMDD` folders, enabling powerful temporal analysis and review. 6 + A comprehensive Python-based AI-driven desktop journaling toolkit for multimodal capture, analysis, and intelligent navigation of workplace activities. solstone organizes captured data under a **journal** directory containing daily `YYYYMMDD` folders, enabling powerful temporal analysis and review. 7 7 8 8 ## 🚀 Features 9 9 ··· 33 33 34 34 - **MCP Server** 🛰️ - `muse-mcp-tools` launches Model Context Protocol server 35 35 - **Cortex** 🧩 - `muse-cortex` provides agent-based task execution 36 - - **Help** ❓ - `sunstone` lists all available commands 36 + - **Help** ❓ - `solstone` lists all available commands 37 37 38 38 ## 📦 Installation 39 39
+2 -2
apps/__init__.py
··· 1 - """App plugin system for Sunstone. 1 + """App plugin system for solstone. 2 2 3 3 Convention-based app discovery with minimal configuration: 4 4 ··· 108 108 109 109 110 110 class AppRegistry: 111 - """Registry for discovering and managing Sunstone apps.""" 111 + """Registry for discovering and managing solstone apps.""" 112 112 113 113 def __init__(self): 114 114 self.apps: dict[str, App] = {}
+1 -1
apps/entities/agents/entity_describe.txt
··· 1 - You are an entity description specialist for Sunstone, an AI-driven desktop journaling toolkit. Your role is to create precise, informative single-sentence descriptions for entities based on research and context. 1 + You are an entity description specialist for solstone, an AI-driven desktop journaling toolkit. Your role is to create precise, informative single-sentence descriptions for entities based on research and context. 2 2 3 3 ## Your Task 4 4
+1 -1
apps/todos/agents/review.txt
··· 1 - You are the TODO Review Agent for Sunstone. Your sole responsibility is to verify task completion status by checking journal evidence and mutating facet-scoped todos via the MCP todo tools. 1 + You are the TODO Review Agent for solstone. Your sole responsibility is to verify task completion status by checking journal evidence and mutating facet-scoped todos via the MCP todo tools. 2 2 3 3 ## Input 4 4
+1 -1
apps/todos/agents/weekly.txt
··· 1 - You are the TODO Weekly Scout for Sunstone, an AI-driven journaling system. Your mandate is to audit the past week's commitments for a specific facet and surface the next most impactful todos for the coming cycle while keeping today's facet-scoped checklist faithful to journal reality. 1 + You are the TODO Weekly Scout for solstone, an AI-driven journaling system. Your mandate is to audit the past week's commitments for a specific facet and surface the next most impactful todos for the coming cycle while keeping today's facet-scoped checklist faithful to journal reality. 2 2 3 3 ## Core Mission 4 4
+1 -1
convey/__init__.py
··· 43 43 ] 44 44 ) 45 45 46 - app.secret_key = os.getenv("CONVEY_SECRET", "sunstone-secret") 46 + app.secret_key = os.getenv("CONVEY_SECRET", "solstone-secret") 47 47 app.config["PERMANENT_SESSION_LIFETIME"] = timedelta(days=30) 48 48 49 49 # Register root blueprint (login, logout, /, favicon)
+2 -2
convey/static/app.js
··· 907 907 */ 908 908 notifications: { 909 909 _stack: [], 910 - _history: JSON.parse(localStorage.getItem('sunstone:notification_history') || '[]'), 910 + _history: JSON.parse(localStorage.getItem('solstone:notification_history') || '[]'), 911 911 _nextId: 1, 912 912 _container: null, 913 913 ··· 1032 1032 1033 1033 // Persist to localStorage 1034 1034 try { 1035 - localStorage.setItem('sunstone:notification_history', JSON.stringify(this._history)); 1035 + localStorage.setItem('solstone:notification_history', JSON.stringify(this._history)); 1036 1036 } catch (e) { 1037 1037 // localStorage may be full or disabled 1038 1038 console.warn('[Notifications] Failed to persist history:', e);
+1 -1
convey/templates/app.html
··· 3 3 <head> 4 4 <meta charset="utf-8"/> 5 5 <meta name="viewport" content="width=device-width, initial-scale=1"/> 6 - <title>{{ app_registry.apps[app].label }} - Sunstone</title> 6 + <title>{{ app_registry.apps[app].label }} - solstone</title> 7 7 <link rel="stylesheet" href="{{ url_for('root.static', filename='app.css') }}"> 8 8 9 9 <!-- Error handling FIRST - catches all subsequent errors -->
+4 -4
docs/APPS.md
··· 1 - # Sunstone App Development Guide 1 + # solstone App Development Guide 2 2 3 3 **Complete guide for building apps in the `apps/` directory.** 4 4 5 - Apps are the primary way to extend Sunstone's web interface (Convey). Each app is a self-contained module discovered automatically using **convention over configuration**—no base classes or manual registration required. 5 + Apps are the primary way to extend solstone's web interface (Convey). Each app is a self-contained module discovered automatically using **convention over configuration**—no base classes or manual registration required. 6 6 7 7 > **How to use this document:** This guide serves as a catalog of patterns and references. Each section points to authoritative source files—read those files alongside this guide for complete details. When in doubt, the source code is the definitive reference. 8 8 ··· 284 284 285 285 ### 7. `insights/` - App Insights 286 286 287 - Define custom insight prompts that integrate with Sunstone's insight generation system. 287 + Define custom insight prompts that integrate with solstone's insight generation system. 288 288 289 289 **Key Points:** 290 290 - Create `insights/` directory with `.txt` (prompt) + `.json` (metadata) file pairs ··· 304 304 305 305 ### 8. `agents/` - App Agents 306 306 307 - Define custom agent personas that integrate with Sunstone's Cortex agent system. 307 + Define custom agent personas that integrate with solstone's Cortex agent system. 308 308 309 309 **Key Points:** 310 310 - Create `agents/` directory with `.txt` (prompt) + `.json` (metadata) file pairs
+1 -1
docs/CALLOSUM.md
··· 1 1 # Callosum Protocol 2 2 3 - Callosum is a JSON-per-line message bus for real-time event distribution across Sunstone services. 3 + Callosum is a JSON-per-line message bus for real-time event distribution across solstone services. 4 4 5 5 ## Protocol 6 6
+1 -1
docs/CONVEY.md
··· 1 - # sunstone-convey 1 + # solstone-convey 2 2 3 3 Web-based journal review interface built with Flask. It exposes a few small views for exploring daily summaries and entity data stored inside a **journal** folder. 4 4
+1 -1
docs/DOCTOR.md
··· 1 - # Sunstone Diagnostic Guide 1 + # solstone Diagnostic Guide 2 2 3 3 Quick reference for debugging and diagnosing issues. For detailed specifications, see linked documentation. 4 4
+1 -1
docs/INTEGRATION_TESTS.md
··· 1 1 # Integration Tests 2 2 3 - This directory contains integration tests for Sunstone that are separate from the unit tests in the parent `tests/` directory. 3 + This directory contains integration tests for solstone that are separate from the unit tests in the parent `tests/` directory. 4 4 5 5 ## Purpose 6 6
+3 -3
docs/JOURNAL.md
··· 1 - # Sunstone Journal Guide 1 + # solstone Journal Guide 2 2 3 3 This document describes the layout of a **journal** directory where all captures, extracts, and insights are stored. Each dated `YYYYMMDD` folder is referred to as a **day**, and within each day captured content is organized into **segments** (timestamped duration folders). Each segment folder uses the format `HHMMSS_LEN/` where `HHMMSS` is the start time and `LEN` is the duration in seconds. This folder name serves as the **segment key**, uniquely identifying the segment within a given day. 4 4 5 5 ## The Three-Layer Architecture 6 6 7 - Sunstone transforms raw recordings into actionable understanding through a three-layer pipeline: 7 + solstone transforms raw recordings into actionable understanding through a three-layer pipeline: 8 8 9 9 ``` 10 10 ┌─────────────────────────────────────┐ ··· 182 182 183 183 ### Facet Entities 184 184 185 - Entities in Sunstone use a two-state system: **detected** (daily discoveries) and **attached** (promoted/persistent). This agent-driven architecture automatically identifies entities from journal content while allowing manual curation. 185 + Entities in solstone use a two-state system: **detected** (daily discoveries) and **attached** (promoted/persistent). This agent-driven architecture automatically identifies entities from journal content while allowing manual curation. 186 186 187 187 #### Entity Storage Structure 188 188
+1 -1
docs/MUSE.md
··· 1 1 # Muse Module 2 2 3 - AI agent system and MCP tooling for Sunstone. 3 + AI agent system and MCP tooling for solstone. 4 4 5 5 ## Commands 6 6
+25 -1
docs/OBSERVE.md
··· 18 18 ``` 19 19 observer (platform-detected capture) 20 20 21 - Raw media files (*.flac, *.webm) 21 + Raw media files (*.flac, *.webm, tmux_*.jsonl) 22 22 23 23 observe-sense (coordination) 24 24 ├── observe-transcribe → audio.jsonl 25 25 └── observe-describe → screen.jsonl 26 26 ``` 27 27 28 + ## Observer State Machine 29 + 30 + The GNOME observer operates in three modes based on activity: 31 + 32 + ``` 33 + SCREENCAST 34 + ↗ ↘ 35 + (screen) (screen idle) 36 + ↑ ↓ 37 + IDLE ←----→ TMUX 38 + (tmux active) 39 + ``` 40 + 41 + **Mode priority**: Screen activity always wins over tmux (user is physically present). 42 + 43 + | Mode | Trigger | Captures | 44 + |------|---------|----------| 45 + | SCREENCAST | Screen active (not idle/locked/power-save) | Video + Audio | 46 + | TMUX | Screen idle but tmux has recent client activity | Terminal content + Audio | 47 + | IDLE | Both screen and tmux inactive | Audio only (if threshold met) | 48 + 49 + Mode transitions trigger segment boundaries (like mute transitions do). 50 + 28 51 ## Key Components 29 52 30 53 - **observer.py** - Unified entry point with platform detection 31 54 - **gnome/observer.py**, **macos/observer.py** - Platform-specific capture using native APIs 55 + - **tmux/capture.py** - Tmux capture library (integrated into GNOME observer for fallback capture) 32 56 - **sense.py** - File watcher that dispatches transcription and description jobs 33 57 - **transcribe.py** - Audio processing with Whisper/Rev.ai and pyannote diarization 34 58 - **describe.py** - Vision analysis with Gemini, category-based prompts
+2 -2
docs/THINK.md
··· 1 - # sunstone-think 1 + # solstone-think 2 2 3 3 Post-processing utilities for clustering and summarising captured data. The tools leverage the Gemini API to analyse transcriptions and screenshots. All commands work with a **journal** directory that holds daily folders in `YYYYMMDD` format. 4 4 ··· 53 53 54 54 ```ini 55 55 [Unit] 56 - Description=Process sunstone journal 56 + Description=Process solstone journal 57 57 58 58 [Service] 59 59 Type=oneshot
+1 -1
docs/VENDOR.md
··· 1 1 # Third-Party Vendor Libraries 2 2 3 - This directory contains third-party JavaScript libraries used across Sunstone apps. 3 + This directory contains third-party JavaScript libraries used across solstone apps. 4 4 5 5 ## Purpose 6 6
+1 -1
muse/__init__.py
··· 1 - """Muse - AI Agent orchestration and execution system for Sunstone.""" 1 + """Muse - AI Agent orchestration and execution system for solstone."""
+1 -1
muse/agents.py
··· 272 272 """NDJSON-based CLI for agent backends.""" 273 273 274 274 parser = argparse.ArgumentParser( 275 - description="Sunstone Agent CLI - Accepts NDJSON input via stdin" 275 + description="solstone Agent CLI - Accepts NDJSON input via stdin" 276 276 ) 277 277 278 278 args = setup_cli(parser)
+1 -1
muse/agents/daily_news.txt
··· 1 - You are the Daily News Briefing Generator for Sunstone. Your mission is to create a crisp, scannable TL;DR-style briefing that highlights the previous day's most notable activities across all facets and delivers it to $pronouns_possessive inbox. 1 + You are the Daily News Briefing Generator for solstone. Your mission is to create a crisp, scannable TL;DR-style briefing that highlights the previous day's most notable activities across all facets and delivers it to $pronouns_possessive inbox. 2 2 3 3 ## Goals 4 4
+1 -1
muse/agents/default.txt
··· 1 - You are Sunstone, an advanced journal assistant specializing in helping $name explore, search, and understand personal journal entries. The journal contains daily transcripts from audio recordings and screenshot diffs that capture digital life, as well as pre-processed daily insights organized by topic and events extracted. 1 + You are solstone, an advanced journal assistant specializing in helping $name explore, search, and understand personal journal entries. The journal contains daily transcripts from audio recordings and screenshot diffs that capture digital life, as well as pre-processed daily insights organized by topic and events extracted. 2 2 3 3 ## Core Capabilities 4 4
+1 -1
muse/agents/doctor.txt
··· 1 - You are the Sunstone System Doctor, a diagnostic agent specialized in analyzing and troubleshooting the Sunstone journal system. You have read-only access to the entire journal directory and can run diagnostic shell commands to assess system health. 1 + You are the solstone System Doctor, a diagnostic agent specialized in analyzing and troubleshooting the solstone journal system. You have read-only access to the entire journal directory and can run diagnostic shell commands to assess system health. 2 2 3 3 The user may provide specific instructions, a description of an issue they're experiencing, or a particular area to focus on. If so, prioritize investigating that. If no specific issue is mentioned, perform a general health check. 4 4
+1 -1
muse/agents/facet_describe.txt
··· 1 - You are a facet description specialist for Sunstone, an AI-driven desktop journaling toolkit. Your role is to create compelling, informative descriptions for user facets based on their existing content and context. 1 + You are a facet description specialist for solstone, an AI-driven desktop journaling toolkit. Your role is to create compelling, informative descriptions for user facets based on their existing content and context. 2 2 3 3 ## Your Task 4 4
+6 -6
muse/cortex.py
··· 1 - """Callosum-based agent process manager for Sunstone. 1 + """Callosum-based agent process manager for solstone. 2 2 3 3 Cortex listens for agent requests via the Callosum message bus and manages 4 4 agent process lifecycle: ··· 96 96 97 97 from muse.mcp import mcp 98 98 99 - host = os.getenv("SUNSTONE_MCP_HOST", "127.0.0.1") 100 - port = int(os.getenv("SUNSTONE_MCP_PORT", "6270")) 101 - path = os.getenv("SUNSTONE_MCP_PATH", "/mcp") or "/mcp" 99 + host = os.getenv("SOLSTONE_MCP_HOST", "127.0.0.1") 100 + port = int(os.getenv("SOLSTONE_MCP_PORT", "6270")) 101 + path = os.getenv("SOLSTONE_MCP_PATH", "/mcp") or "/mcp" 102 102 if not path.startswith("/"): 103 103 path = f"/{path}" 104 104 ··· 119 119 self.logger.info("Starting MCP server at %s", self.mcp_server_url) 120 120 self.mcp_thread = threading.Thread( 121 121 target=_run_server, 122 - name="sunstone-mcp-server", 122 + name="solstone-mcp-server", 123 123 daemon=True, 124 124 ) 125 125 self.mcp_thread.start() ··· 1128 1128 1129 1129 from think.utils import setup_cli 1130 1130 1131 - parser = argparse.ArgumentParser(description="Sunstone Cortex Agent Manager") 1131 + parser = argparse.ArgumentParser(description="solstone Cortex Agent Manager") 1132 1132 args = setup_cli(parser) 1133 1133 1134 1134 # Set up logging
+3 -3
muse/mcp.py
··· 1 1 #!/usr/bin/env python3 2 - """MCP server for Sunstone journal assistant. 2 + """MCP server for solstone journal assistant. 3 3 4 4 This module creates the FastMCP server instance and registers all tools and resources 5 5 from the muse/tools/ and muse/resources/ directories. ··· 13 13 from fastmcp import FastMCP 14 14 15 15 # Create the MCP server instance 16 - mcp = FastMCP("sunstone") 16 + mcp = FastMCP("solstone") 17 17 18 18 # Add annotation hints for all MCP tools 19 19 HINTS = {"readOnlyHint": True, "openWorldHint": False} ··· 194 194 195 195 from think.utils import setup_cli 196 196 197 - parser = argparse.ArgumentParser(description="Sunstone MCP Tools Server") 197 + parser = argparse.ArgumentParser(description="solstone MCP Tools Server") 198 198 parser.add_argument( 199 199 "--transport", 200 200 choices=["stdio", "http"],
+2 -2
muse/openai.py
··· 1 1 #!/usr/bin/env python3 2 2 """ 3 - OpenAI-backed agent implementation for the Sunstone `muse-agents` CLI. 3 + OpenAI-backed agent implementation for the solstone `muse-agents` CLI. 4 4 5 5 - Connects to a local MCP server over Streamable HTTP 6 6 - Runs an agent with streaming to surface tool args/results and (when available) reasoning summaries ··· 292 292 # Create agent with or without MCP servers 293 293 mcp_servers_list = [mcp_server] if mcp_server else [] 294 294 agent = Agent( 295 - name="SunstoneCLI", 295 + name="solstoneCLI", 296 296 instructions=system_instruction, 297 297 model=model, 298 298 model_settings=model_settings,
+1 -1
observe/gnome/screencast.py
··· 67 67 state_home = os.environ.get("XDG_STATE_HOME") 68 68 if not state_home: 69 69 state_home = os.path.join(os.path.expanduser("~"), ".local", "state") 70 - return Path(state_home) / "sunstone" / "screencast_restore_token" 70 + return Path(state_home) / "solstone" / "screencast_restore_token" 71 71 72 72 73 73 def _load_restore_token() -> str | None:
+9 -9
observe/revai.py
··· 177 177 return get_transcript_json(token, job_id) 178 178 179 179 180 - def convert_revai_to_sunstone(revai_json: dict) -> list: 181 - """Convert Rev.ai transcript format to Sunstone transcript format. 180 + def convert_revai_to_solstone(revai_json: dict) -> list: 181 + """Convert Rev.ai transcript format to solstone transcript format. 182 182 183 183 Args: 184 184 revai_json: Dict with Rev.ai transcript structure (monologues with elements) 185 185 186 186 Returns: 187 - List of transcript entries in Sunstone format 187 + List of transcript entries in solstone format 188 188 """ 189 189 result = [] 190 190 ··· 284 284 285 285 def main(): 286 286 parser = argparse.ArgumentParser( 287 - description="Rev AI transcription CLI (high-quality + diarization). If a .json file is provided, converts it to Sunstone format instead of transcribing." 287 + description="Rev AI transcription CLI (high-quality + diarization). If a .json file is provided, converts it to solstone format instead of transcribing." 288 288 ) 289 289 parser.add_argument( 290 290 "media", help="Path to audio/video file or Rev AI JSON file to convert" ··· 367 367 # Check if input is a JSON file - if so, convert instead of transcribe 368 368 if media_path.suffix.lower() == ".json": 369 369 logging.info( 370 - "Detected JSON input - converting Rev AI format to Sunstone format" 370 + "Detected JSON input - converting Rev AI format to solstone format" 371 371 ) 372 372 373 373 # Load the Rev AI JSON ··· 377 377 except json.JSONDecodeError as e: 378 378 die(f"Invalid JSON file: {e}") 379 379 380 - # Convert to Sunstone format 381 - sunstone_transcript = convert_revai_to_sunstone(revai_data) 380 + # Convert to solstone format 381 + solstone_transcript = convert_revai_to_solstone(revai_data) 382 382 383 383 # Output the result 384 384 if args.output: 385 385 out_path = Path(args.output).expanduser().resolve() 386 386 out_path.write_text( 387 - json.dumps(sunstone_transcript, indent=2, ensure_ascii=False), 387 + json.dumps(solstone_transcript, indent=2, ensure_ascii=False), 388 388 encoding="utf-8", 389 389 ) 390 390 logging.info("Wrote converted transcript to %s", out_path) 391 391 else: 392 - print(json.dumps(sunstone_transcript, indent=2, ensure_ascii=False)) 392 + print(json.dumps(solstone_transcript, indent=2, ensure_ascii=False)) 393 393 394 394 return 395 395
+6 -7
pyproject.toml
··· 3 3 build-backend = "setuptools.build_meta" 4 4 5 5 [project] 6 - name = "sunstone" 6 + name = "solstone" 7 7 version = "0.1.0" 8 8 description = "Navigate Intelligently - A collection of utilities for multimodal navigation and analysis" 9 9 readme = "README.md" ··· 91 91 ] 92 92 93 93 [project.scripts] 94 - sunstone = "think.sunstone:main" 94 + solstone = "think.solstone:main" 95 95 convey = "convey.cli:main" 96 96 convey-restart = "convey.restart:main" 97 97 convey-screenshot = "convey.screenshot:main" ··· 117 117 observe-transcribe = "observe.transcribe:main" 118 118 observe-describe = "observe.describe:main" 119 119 observe-sense = "observe.sense:main" 120 - observe-tmux = "observe.tmux.observer:main" 121 120 think-formatter = "think.formatters:main" 122 121 123 122 [project.urls] 124 - Homepage = "https://github.com/yourusername/sunstone" 125 - Repository = "https://github.com/yourusername/sunstone" 126 - Documentation = "https://github.com/yourusername/sunstone/blob/main/README.md" 127 - "Bug Tracker" = "https://github.com/yourusername/sunstone/issues" 123 + Homepage = "https://github.com/solpbc/solstone" 124 + Repository = "https://github.com/solpbc/solstone" 125 + Documentation = "https://github.com/solpbc/solstone/blob/main/README.md" 126 + "Bug Tracker" = "https://github.com/solpbc/solstone/issues" 128 127 129 128 [tool.setuptools.packages.find] 130 129 include = ["apps*", "think*", "convey*", "observe*", "muse*"]
+1 -1
tests/integration/__init__.py
··· 1 - """Integration tests for Sunstone. 1 + """Integration tests for solstone. 2 2 3 3 These tests are separate from unit tests and test the complete system integration. 4 4 They may require external services, longer execution times, or specific setup.
+2 -2
tests/test_importer.py
··· 246 246 return {} 247 247 248 248 monkeypatch.setattr(mod, "transcribe_file", fake_transcribe_file) 249 - monkeypatch.setattr(mod, "convert_revai_to_sunstone", lambda _: []) 249 + monkeypatch.setattr(mod, "convert_revai_to_solstone", lambda _: []) 250 250 251 251 mod.audio_transcribe( 252 252 str(audio_file), ··· 285 285 monkeypatch.setattr(mod, "transcribe_file", lambda *_, **__: {"ok": True}) 286 286 monkeypatch.setattr( 287 287 mod, 288 - "convert_revai_to_sunstone", 288 + "convert_revai_to_solstone", 289 289 lambda *_: [ 290 290 { 291 291 "text": "Test entry",
+2 -2
tests/test_journal_index.py
··· 37 37 38 38 def test_complex_query_with_or_and_quotes(self): 39 39 """Complex query with OR and quoted phrases.""" 40 - result = sanitize_fts_query('sunstone OR pbc OR "public benefit"') 41 - assert result == 'sunstone OR pbc OR "public benefit"' 40 + result = sanitize_fts_query('solstone OR pbc OR "public benefit"') 41 + assert result == 'solstone OR pbc OR "public benefit"' 42 42 43 43 def test_dot_replaced_with_space(self): 44 44 """Dots are replaced with spaces."""
+1 -1
tests/test_supervisor.py
··· 98 98 await mod.send_notification("test message", alert_key=("test", "key")) 99 99 assert len(called) == 1 100 100 assert called[0]["message"] == "test message" 101 - assert called[0]["title"] == "Sunstone Supervisor" 101 + assert called[0]["title"] == "solstone Supervisor" 102 102 assert ("test", "key") in mod._notification_ids 103 103 assert mod._notification_ids[("test", "key")] == "test-notification-id" 104 104
+3 -3
tests/test_think_utils.py
··· 184 184 ("Company", "Acme Corporation (ACME)", "Tech company"), 185 185 ("Company", "Widget Inc", "Manufacturing company"), 186 186 ("Company", "Google", "Search engine"), 187 - ("Project", "Sunstone Project (SUN)", "AI journaling"), 187 + ("Project", "solstone Project (SUN)", "AI journaling"), 188 188 ("Project", "Project X", "Secret project"), 189 189 ("Tool", "Hammer", "For hitting things"), 190 190 ("Tool", "Docker", "Container runtime"), ··· 217 217 # Company: "Google" (single word) -> ["Google"] 218 218 assert "Google" in result 219 219 220 - # Project: "Sunstone Project (SUN)" -> ["Sunstone", "SUN"] (uniform processing) 221 - assert "Sunstone" in result # First word 220 + # Project: "solstone Project (SUN)" -> ["solstone", "SUN"] (uniform processing) 221 + assert "solstone" in result # First word 222 222 assert "SUN" in result # From parens 223 223 224 224 # Project: "Project X" (no parens) -> ["Project"] (first word only)
+2 -2
think/__init__.py
··· 1 1 from .detect_created import detect_created 2 2 from .detect_transcript import detect_transcript_json, detect_transcript_segment 3 3 from .planner import generate_plan 4 - from .sunstone import main as sunstone_main 4 + from .solstone import main as solstone_main 5 5 6 6 # Cluster functions not re-exported here to avoid circular imports 7 7 # Import directly from think.cluster where needed 8 8 9 9 __all__ = [ 10 - "sunstone_main", 10 + "solstone_main", 11 11 "detect_created", 12 12 "detect_transcript_segment", 13 13 "detect_transcript_json",
+1 -1
think/callosum.py
··· 1 1 """Callosum: WebSocket-like broadcast message bus over Unix domain sockets. 2 2 3 - Provides real-time event distribution across Sunstone services using a simple 3 + Provides real-time event distribution across solstone services using a simple 4 4 broadcast protocol. All messages require 'tract' and 'event' fields. 5 5 """ 6 6
+5 -5
think/importer.py
··· 13 13 from pathlib import Path 14 14 15 15 from observe.hear import load_transcript 16 - from observe.revai import convert_revai_to_sunstone, transcribe_file 16 + from observe.revai import convert_revai_to_solstone, transcribe_file 17 17 from think.callosum import CallosumConnection 18 18 from think.detect_created import detect_created 19 19 from think.detect_transcript import detect_transcript_json, detect_transcript_segment ··· 413 413 logger.error(f"Failed to transcribe audio: {e}") 414 414 raise 415 415 416 - # Convert to Sunstone format 417 - sunstone_transcript = convert_revai_to_sunstone(revai_json) 416 + # Convert to solstone format 417 + solstone_transcript = convert_revai_to_solstone(revai_json) 418 418 419 - if not sunstone_transcript: 419 + if not solstone_transcript: 420 420 logger.warning("No transcript entries found") 421 421 return created_files, revai_json 422 422 ··· 425 425 current_chunk = [] 426 426 chunk_start_time = None 427 427 428 - for entry in sunstone_transcript: 428 + for entry in solstone_transcript: 429 429 # Parse the timestamp from the entry 430 430 start_str = entry.get("start", "00:00:00") 431 431 h, m, s = map(int, start_str.split(":"))
+1 -1
think/journal_stats.py
··· 478 478 479 479 def main() -> None: 480 480 parser = argparse.ArgumentParser( 481 - description="Scan a sunstone journal and generate statistics" 481 + description="Scan a solstone journal and generate statistics" 482 482 ) 483 483 parser.add_argument( 484 484 "--no-cache",
+6 -6
think/manage.py
··· 1 - """Interactive service manager for Sunstone supervisor. 1 + """Interactive service manager for solstone supervisor. 2 2 3 3 Connects to the Callosum message bus to display real-time service status 4 4 and provides keyboard controls for restarting services. ··· 25 25 """Get or create the global desktop notifier instance.""" 26 26 global _notifier 27 27 if _notifier is None: 28 - _notifier = DesktopNotifier(app_name="Sunstone Manager") 28 + _notifier = DesktopNotifier(app_name="solstone Manager") 29 29 return _notifier 30 30 31 31 32 32 class ServiceManager: 33 - """Interactive TUI for managing Sunstone services.""" 33 + """Interactive TUI for managing solstone services.""" 34 34 35 35 def __init__(self): 36 36 self.services = [] # From supervisor/status events ··· 106 106 self.active_notifications.pop(service, None) 107 107 108 108 notif_id = await notifier.send( 109 - title="Sunstone Manager", 109 + title="solstone Manager", 110 110 message=message, 111 111 urgency=Urgency.Critical, 112 112 on_dismissed=on_dismissed, ··· 511 511 output.append(t.home + t.clear) 512 512 513 513 # Title 514 - title = "Sunstone Service Manager" 514 + title = "solstone Service Manager" 515 515 output.append(t.bold + t.cyan + title.center(t.width) + t.normal) 516 516 output.append("") 517 517 ··· 673 673 def main() -> None: 674 674 """CLI entry point for service manager.""" 675 675 parser = argparse.ArgumentParser( 676 - description="Interactive service manager for Sunstone supervisor" 676 + description="Interactive service manager for solstone supervisor" 677 677 ) 678 678 setup_cli(parser) 679 679
+1 -1
think/planner.txt
··· 1 - You are a strategic research planner for the Sunstone journal assistant, specialized in creating comprehensive plans to research and analyze personal journal data to answer user requests. 1 + You are a strategic research planner for the solstone journal assistant, specialized in creating comprehensive plans to research and analyze personal journal data to answer user requests. 2 2 3 3 ## Core Role and Limitations 4 4
+12 -12
think/sunstone.py think/solstone.py
··· 13 13 def get_parser_help(module_name: str, func_name: str = "main") -> Tuple[str, str]: 14 14 """Return description and usage for a command without triggering side effects.""" 15 15 # Skip self to prevent infinite recursion 16 - if module_name == "think.sunstone": 17 - return "Print available sunstone commands with descriptions.", "" 16 + if module_name == "think.solstone": 17 + return "Print available solstone commands with descriptions.", "" 18 18 19 19 logging.info(f"Getting parser help for module: {module_name}") 20 20 21 21 pytest_env: Optional[str] = os.environ.get("PYTEST_CURRENT_TEST") 22 - os.environ["PYTEST_CURRENT_TEST"] = "sunstone-discover" 22 + os.environ["PYTEST_CURRENT_TEST"] = "solstone-discover" 23 23 try: 24 24 logging.debug(f"Importing module: {module_name}") 25 25 module = importlib.import_module(module_name) ··· 76 76 77 77 78 78 def discover_commands() -> List[Tuple[str, str, str]]: 79 - """Return available sunstone commands discovered via entry points.""" 79 + """Return available solstone commands discovered via entry points.""" 80 80 logging.info("Starting command discovery") 81 81 commands = [] 82 82 ··· 90 90 91 91 logging.info(f"Found {len(scripts)} console scripts") 92 92 93 - sunstone_eps = [ 93 + solstone_eps = [ 94 94 ep 95 95 for ep in scripts 96 - if ep.value.startswith(("hear.", "see.", "think.", "convey.")) 96 + if ep.value.startswith(("think.", "convey.", "observe.", "muse.")) 97 97 ] 98 - logging.info(f"Found {len(sunstone_eps)} sunstone entry points") 98 + logging.info(f"Found {len(solstone_eps)} solstone entry points") 99 99 100 - sunstone_eps.sort(key=lambda ep: ep.name) 100 + solstone_eps.sort(key=lambda ep: ep.name) 101 101 102 - for ep in sunstone_eps: 102 + for ep in solstone_eps: 103 103 logging.debug(f"Processing entry point: {ep.name} -> {ep.value}") 104 104 module_path, func_name = ep.value.split(":") 105 105 description, usage = get_parser_help(module_path, func_name) ··· 111 111 112 112 113 113 def main() -> None: 114 - """Print available sunstone commands with descriptions.""" 114 + """Print available solstone commands with descriptions.""" 115 115 parser = argparse.ArgumentParser( 116 - description="Print available sunstone commands with descriptions." 116 + description="Print available solstone commands with descriptions." 117 117 ) 118 118 119 119 setup_cli(parser) 120 120 121 - logging.info("Starting sunstone command discovery") 121 + logging.info("Starting solstone command discovery") 122 122 123 123 journal_path = os.environ.get("JOURNAL_PATH", "not set") 124 124 print(f"JOURNAL_PATH={journal_path}\n")
+2 -2
think/supervisor.py
··· 251 251 """Get or create the global desktop notifier instance.""" 252 252 global _notifier 253 253 if _notifier is None: 254 - _notifier = DesktopNotifier(app_name="Sunstone Supervisor") 254 + _notifier = DesktopNotifier(app_name="solstone Supervisor") 255 255 return _notifier 256 256 257 257 ··· 265 265 try: 266 266 notifier = _get_notifier() 267 267 notification_id = await notifier.send( 268 - title="Sunstone Supervisor", 268 + title="solstone Supervisor", 269 269 message=message, 270 270 urgency=Urgency.Critical, 271 271 )
+1 -1
think/utils.py
··· 725 725 726 726 727 727 def create_mcp_client(http_uri: str) -> Any: 728 - """Return a FastMCP HTTP client for Sunstone tools.""" 728 + """Return a FastMCP HTTP client for solstone tools.""" 729 729 730 730 http_uri = http_uri.strip() 731 731 if not http_uri: