solstone 0.1.1__py3-none-any.whl
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.
- solstone/__init__.py +4 -0
- solstone/apps/__init__.py +350 -0
- solstone/apps/activities/_day.html +998 -0
- solstone/apps/activities/_dev_screens_detail.html +445 -0
- solstone/apps/activities/_dev_screens_list.html +191 -0
- solstone/apps/activities/app.json +6 -0
- solstone/apps/activities/call.py +637 -0
- solstone/apps/activities/routes.py +495 -0
- solstone/apps/activities/talent/activities/SKILL.md +171 -0
- solstone/apps/activities/talent/activities_review.md +43 -0
- solstone/apps/activities/tests/conftest.py +54 -0
- solstone/apps/activities/tests/test_call.py +324 -0
- solstone/apps/activities/workspace.html +13 -0
- solstone/apps/awareness/__init__.py +2 -0
- solstone/apps/awareness/call.py +141 -0
- solstone/apps/chat/_chat_event.html +45 -0
- solstone/apps/chat/app.json +6 -0
- solstone/apps/chat/routes.py +79 -0
- solstone/apps/chat/tests/test_routes.py +299 -0
- solstone/apps/chat/workspace.html +438 -0
- solstone/apps/entities/app.json +4 -0
- solstone/apps/entities/call.py +588 -0
- solstone/apps/entities/events.py +4 -0
- solstone/apps/entities/maint/001_migrate_to_journal_entities.py +424 -0
- solstone/apps/entities/routes.py +1015 -0
- solstone/apps/entities/talent/entities/SKILL.md +349 -0
- solstone/apps/entities/talent/entities.md +227 -0
- solstone/apps/entities/talent/entities_review.md +229 -0
- solstone/apps/entities/talent/entity_assist.md +160 -0
- solstone/apps/entities/talent/entity_describe.md +68 -0
- solstone/apps/entities/talent/entity_observer.md +110 -0
- solstone/apps/entities/talent/entity_observer.py +93 -0
- solstone/apps/entities/talent/entity_observer.schema.json +51 -0
- solstone/apps/entities/tests/conftest.py +182 -0
- solstone/apps/entities/tests/test_all_facets_cache.py +92 -0
- solstone/apps/entities/tests/test_call.py +590 -0
- solstone/apps/entities/tests/test_delete_journal_entity.py +139 -0
- solstone/apps/entities/tests/test_merge.py +435 -0
- solstone/apps/entities/workspace.html +3568 -0
- solstone/apps/events.py +342 -0
- solstone/apps/graph/app.json +4 -0
- solstone/apps/graph/routes.py +366 -0
- solstone/apps/graph/workspace.html +1255 -0
- solstone/apps/health/app.json +5 -0
- solstone/apps/health/routes.py +59 -0
- solstone/apps/health/talent/health/SKILL.md +211 -0
- solstone/apps/health/tests/__init__.py +1 -0
- solstone/apps/health/tests/conftest.py +57 -0
- solstone/apps/health/tests/test_routes.py +68 -0
- solstone/apps/health/workspace.html +3177 -0
- solstone/apps/home/app.json +5 -0
- solstone/apps/home/routes.py +1521 -0
- solstone/apps/home/workspace.html +1928 -0
- solstone/apps/import/_detail.html +660 -0
- solstone/apps/import/app.json +4 -0
- solstone/apps/import/call.py +659 -0
- solstone/apps/import/facet_ingest.py +751 -0
- solstone/apps/import/guides/chatgpt.md +10 -0
- solstone/apps/import/guides/claude.md +10 -0
- solstone/apps/import/guides/gemini.md +11 -0
- solstone/apps/import/guides/granola.md +25 -0
- solstone/apps/import/guides/ics.md +24 -0
- solstone/apps/import/guides/journal_archive.md +38 -0
- solstone/apps/import/guides/kindle.md +10 -0
- solstone/apps/import/guides/obsidian.md +21 -0
- solstone/apps/import/ingest.py +1026 -0
- solstone/apps/import/journal_sources.py +130 -0
- solstone/apps/import/routes.py +968 -0
- solstone/apps/import/talent/review.md +89 -0
- solstone/apps/import/talent/review_config.md +85 -0
- solstone/apps/import/talent/review_entities.md +90 -0
- solstone/apps/import/talent/review_facets.md +91 -0
- solstone/apps/import/workspace.html +1974 -0
- solstone/apps/link/app.json +5 -0
- solstone/apps/link/call.py +194 -0
- solstone/apps/link/routes.py +301 -0
- solstone/apps/link/tests/__init__.py +0 -0
- solstone/apps/link/tests/conftest.py +49 -0
- solstone/apps/link/tests/test_workspace_modals.py +21 -0
- solstone/apps/link/workspace.html +367 -0
- solstone/apps/observer/app.json +5 -0
- solstone/apps/observer/events.py +107 -0
- solstone/apps/observer/maint/000_migrate_remote_to_observer.py +125 -0
- solstone/apps/observer/routes.py +1079 -0
- solstone/apps/observer/tests/conftest.py +59 -0
- solstone/apps/observer/tests/test_events.py +257 -0
- solstone/apps/observer/tests/test_observer_client.py +388 -0
- solstone/apps/observer/tests/test_routes.py +2366 -0
- solstone/apps/observer/tests/test_utils.py +397 -0
- solstone/apps/observer/utils.py +240 -0
- solstone/apps/observer/workspace.html +1006 -0
- solstone/apps/photos/__init__.py +2 -0
- solstone/apps/photos/call.py +118 -0
- solstone/apps/photos/reader.py +71 -0
- solstone/apps/photos/tests/__init__.py +1 -0
- solstone/apps/photos/tests/test_call.py +269 -0
- solstone/apps/reflections/app.json +9 -0
- solstone/apps/reflections/pdf.html +61 -0
- solstone/apps/reflections/routes.py +210 -0
- solstone/apps/reflections/workspace.html +245 -0
- solstone/apps/search/app.json +4 -0
- solstone/apps/search/maint/003_migrate_index_stream.py +109 -0
- solstone/apps/search/maint/004_migrate_topic_to_agent.py +163 -0
- solstone/apps/search/routes.py +294 -0
- solstone/apps/search/tests/test_maint_migrate_index.py +121 -0
- solstone/apps/search/workspace.html +933 -0
- solstone/apps/settings/app.json +4 -0
- solstone/apps/settings/call.py +871 -0
- solstone/apps/settings/copy.py +68 -0
- solstone/apps/settings/maint/001_backfill_streams.py +508 -0
- solstone/apps/settings/maint/002_restructure_stream_dirs.py +185 -0
- solstone/apps/settings/maint/__init__.py +2 -0
- solstone/apps/settings/routes.py +2413 -0
- solstone/apps/settings/tests/conftest.py +90 -0
- solstone/apps/settings/tests/test_call.py +572 -0
- solstone/apps/settings/workspace.html +6466 -0
- solstone/apps/skills/__init__.py +4 -0
- solstone/apps/skills/call.py +476 -0
- solstone/apps/skills/talent/skill_editor.md +100 -0
- solstone/apps/skills/talent/skill_editor.py +595 -0
- solstone/apps/skills/talent/skill_observer.md +77 -0
- solstone/apps/sol/app.json +5 -0
- solstone/apps/sol/call.py +198 -0
- solstone/apps/sol/maint/000_migrate_agent_layout.py +206 -0
- solstone/apps/sol/maint/001_migrate_agent_run_logs.py +259 -0
- solstone/apps/sol/maint/002_migrate_chronicle.py +120 -0
- solstone/apps/sol/maint/004_rename_agents_to_talents.py +124 -0
- solstone/apps/sol/maint/005_migrate_dream_to_think_schedules.py +137 -0
- solstone/apps/sol/maint/006_rename_unified_triage_providers.py +152 -0
- solstone/apps/sol/maint/__init__.py +2 -0
- solstone/apps/sol/routes.py +677 -0
- solstone/apps/sol/workspace.html +2534 -0
- solstone/apps/speakers/_overlap.py +33 -0
- solstone/apps/speakers/app.json +8 -0
- solstone/apps/speakers/attribution.py +787 -0
- solstone/apps/speakers/bootstrap.py +743 -0
- solstone/apps/speakers/call.py +663 -0
- solstone/apps/speakers/discovery.py +504 -0
- solstone/apps/speakers/encoder_config.py +22 -0
- solstone/apps/speakers/owner.py +1102 -0
- solstone/apps/speakers/routes.py +1344 -0
- solstone/apps/speakers/status.py +222 -0
- solstone/apps/speakers/suggest.py +407 -0
- solstone/apps/speakers/talent/speakers/SKILL.md +275 -0
- solstone/apps/speakers/tests/conftest.py +480 -0
- solstone/apps/speakers/tests/test_attribution.py +690 -0
- solstone/apps/speakers/tests/test_call.py +379 -0
- solstone/apps/speakers/tests/test_discovery.py +301 -0
- solstone/apps/speakers/tests/test_encoder_config.py +45 -0
- solstone/apps/speakers/tests/test_import_composition.py +234 -0
- solstone/apps/speakers/tests/test_merge_names.py +780 -0
- solstone/apps/speakers/tests/test_owner.py +1109 -0
- solstone/apps/speakers/tests/test_routes.py +1370 -0
- solstone/apps/speakers/tests/test_seed_imports.py +292 -0
- solstone/apps/speakers/tests/test_status.py +132 -0
- solstone/apps/speakers/tests/test_suggest.py +301 -0
- solstone/apps/speakers/tests/test_wipe.py +83 -0
- solstone/apps/speakers/voiceprint_io.py +119 -0
- solstone/apps/speakers/wipe.py +88 -0
- solstone/apps/speakers/workspace.html +2435 -0
- solstone/apps/stats/app.json +5 -0
- solstone/apps/stats/routes.py +47 -0
- solstone/apps/stats/static/dashboard.js +785 -0
- solstone/apps/stats/workspace.html +617 -0
- solstone/apps/support/app.json +5 -0
- solstone/apps/support/background.html +39 -0
- solstone/apps/support/call.py +414 -0
- solstone/apps/support/diagnostics.py +193 -0
- solstone/apps/support/events.py +89 -0
- solstone/apps/support/portal.py +683 -0
- solstone/apps/support/routes.py +279 -0
- solstone/apps/support/talent/support/SKILL.md +185 -0
- solstone/apps/support/talent/support.md +79 -0
- solstone/apps/support/tools.py +171 -0
- solstone/apps/support/workspace.html +1265 -0
- solstone/apps/todos/app.json +6 -0
- solstone/apps/todos/background.html +78 -0
- solstone/apps/todos/call.py +535 -0
- solstone/apps/todos/maint/000_time_to_nudge.py +83 -0
- solstone/apps/todos/routes.py +725 -0
- solstone/apps/todos/talent/daily.md +132 -0
- solstone/apps/todos/talent/todo.md +116 -0
- solstone/apps/todos/talent/todos/SKILL.md +206 -0
- solstone/apps/todos/talent/weekly.md +81 -0
- solstone/apps/todos/tests/conftest.py +131 -0
- solstone/apps/todos/tests/test_call.py +613 -0
- solstone/apps/todos/tests/test_logging.py +129 -0
- solstone/apps/todos/tests/test_todo.py +792 -0
- solstone/apps/todos/todo.py +884 -0
- solstone/apps/todos/workspace.html +1536 -0
- solstone/apps/tokens/app.json +6 -0
- solstone/apps/tokens/routes.py +377 -0
- solstone/apps/tokens/workspace.html +859 -0
- solstone/apps/transcripts/__init__.py +2 -0
- solstone/apps/transcripts/app.json +6 -0
- solstone/apps/transcripts/call.py +202 -0
- solstone/apps/transcripts/routes.py +650 -0
- solstone/apps/transcripts/talent/transcripts/SKILL.md +131 -0
- solstone/apps/transcripts/tests/__init__.py +2 -0
- solstone/apps/transcripts/tests/conftest.py +56 -0
- solstone/apps/transcripts/tests/test_call.py +129 -0
- solstone/apps/transcripts/tests/test_segment_routes.py +382 -0
- solstone/apps/transcripts/tests/test_serve_file.py +29 -0
- solstone/apps/transcripts/workspace.html +3555 -0
- solstone/apps/utils.py +160 -0
- solstone/convey/__init__.py +179 -0
- solstone/convey/apps.py +347 -0
- solstone/convey/auth.py +108 -0
- solstone/convey/bridge.py +142 -0
- solstone/convey/chat.py +1130 -0
- solstone/convey/chat_stream.py +333 -0
- solstone/convey/cli.py +116 -0
- solstone/convey/config.py +462 -0
- solstone/convey/copy.py +55 -0
- solstone/convey/gentag.py +73 -0
- solstone/convey/maint_cli.py +250 -0
- solstone/convey/pairing.py +256 -0
- solstone/convey/push.py +128 -0
- solstone/convey/restart.py +210 -0
- solstone/convey/root.py +313 -0
- solstone/convey/state.py +4 -0
- solstone/convey/static/Comfortaa-Variable.woff2 +0 -0
- solstone/convey/static/api.js +247 -0
- solstone/convey/static/app.css +2860 -0
- solstone/convey/static/app.js +2535 -0
- solstone/convey/static/colors.js +4 -0
- solstone/convey/static/error-handler.js +104 -0
- solstone/convey/static/month-picker.js +548 -0
- solstone/convey/static/pairing-qr.js +18 -0
- solstone/convey/static/pairing.css +191 -0
- solstone/convey/static/pairing.js +192 -0
- solstone/convey/static/relative-time.js +43 -0
- solstone/convey/static/tags/tag-2.png +0 -0
- solstone/convey/static/tags/tag-4.png +0 -0
- solstone/convey/static/tags/tag-6.png +0 -0
- solstone/convey/static/tags/tag-7.png +0 -0
- solstone/convey/static/tests/README.md +5 -0
- solstone/convey/static/tests/api.html +126 -0
- solstone/convey/static/tests/register-task.html +98 -0
- solstone/convey/static/tests/relative-time.html +58 -0
- solstone/convey/static/tests/surface-state.html +64 -0
- solstone/convey/static/tests/ws-listen.html +97 -0
- solstone/convey/static/vendor/VENDOR.md +107 -0
- solstone/convey/static/vendor/dompurify/dompurify.min.js +3 -0
- solstone/convey/static/vendor/marked/marked.min.js +69 -0
- solstone/convey/static/vendor/vis-network/vis-network.min.js +34 -0
- solstone/convey/static/websocket.js +381 -0
- solstone/convey/system.py +103 -0
- solstone/convey/templates/app.html +781 -0
- solstone/convey/templates/chat_bar.html +16 -0
- solstone/convey/templates/date_nav.html +133 -0
- solstone/convey/templates/init.html +417 -0
- solstone/convey/templates/login.html +59 -0
- solstone/convey/templates/menu_bar.html +26 -0
- solstone/convey/templates/pairing.html +72 -0
- solstone/convey/templates/status_pane.html +395 -0
- solstone/convey/utils.py +274 -0
- solstone/convey/voice.py +197 -0
- solstone/observe/README.md +108 -0
- solstone/observe/__init__.py +6 -0
- solstone/observe/aruco.py +182 -0
- solstone/observe/categories/__init__.py +13 -0
- solstone/observe/categories/browsing.md +33 -0
- solstone/observe/categories/code.md +33 -0
- solstone/observe/categories/gaming.md +30 -0
- solstone/observe/categories/media.md +34 -0
- solstone/observe/categories/meeting.md +52 -0
- solstone/observe/categories/meeting.py +67 -0
- solstone/observe/categories/messaging.md +38 -0
- solstone/observe/categories/productivity.md +34 -0
- solstone/observe/categories/reading.md +35 -0
- solstone/observe/categories/terminal.md +33 -0
- solstone/observe/categories/tmux.py +73 -0
- solstone/observe/copy.py +25 -0
- solstone/observe/describe.md +24 -0
- solstone/observe/describe.py +1017 -0
- solstone/observe/describe.schema.json +13 -0
- solstone/observe/enrich.md +58 -0
- solstone/observe/enrich.py +156 -0
- solstone/observe/enrich.schema.json +23 -0
- solstone/observe/export.py +1147 -0
- solstone/observe/extract.md +42 -0
- solstone/observe/extract.py +314 -0
- solstone/observe/extract.schema.json +5 -0
- solstone/observe/grab.py +766 -0
- solstone/observe/hear.py +334 -0
- solstone/observe/observer_cli.py +598 -0
- solstone/observe/observer_client.py +278 -0
- solstone/observe/observer_install/__init__.py +53 -0
- solstone/observe/observer_install/common.py +313 -0
- solstone/observe/observer_install/linux.py +557 -0
- solstone/observe/observer_install/macos.py +43 -0
- solstone/observe/observer_install/tmux.py +384 -0
- solstone/observe/screen.py +274 -0
- solstone/observe/see.py +150 -0
- solstone/observe/sense.py +1196 -0
- solstone/observe/transcribe/__init__.py +213 -0
- solstone/observe/transcribe/_parakeet_coreml.py +374 -0
- solstone/observe/transcribe/_parakeet_onnx.py +357 -0
- solstone/observe/transcribe/assets/pyannote-segmentation-3.0.onnx +0 -0
- solstone/observe/transcribe/assets/wespeaker-resnet34-256.onnx +0 -0
- solstone/observe/transcribe/gemini.md +42 -0
- solstone/observe/transcribe/gemini.py +403 -0
- solstone/observe/transcribe/gemini.schema.json +30 -0
- solstone/observe/transcribe/main.py +986 -0
- solstone/observe/transcribe/overlap.py +127 -0
- solstone/observe/transcribe/parakeet.py +57 -0
- solstone/observe/transcribe/parakeet_helper/Package.swift +24 -0
- solstone/observe/transcribe/parakeet_helper/README.md +99 -0
- solstone/observe/transcribe/parakeet_helper/Sources/parakeet-helper/main.swift +350 -0
- solstone/observe/transcribe/revai.py +417 -0
- solstone/observe/transcribe/utils.py +90 -0
- solstone/observe/transcribe/whisper.py +249 -0
- solstone/observe/transfer.py +758 -0
- solstone/observe/utils.py +597 -0
- solstone/observe/vad.py +525 -0
- solstone/talent/__init__.py +4 -0
- solstone/talent/_routine_context.py +228 -0
- solstone/talent/activities.py +547 -0
- solstone/talent/activity_state.py +677 -0
- solstone/talent/awareness_tender.md +57 -0
- solstone/talent/chat.md +104 -0
- solstone/talent/chat.schema.json +28 -0
- solstone/talent/chat_context.py +339 -0
- solstone/talent/coder.md +78 -0
- solstone/talent/conversation.md +54 -0
- solstone/talent/daily_schedule.md +59 -0
- solstone/talent/daily_schedule.py +232 -0
- solstone/talent/daily_schedule.schema.json +16 -0
- solstone/talent/digest.md +34 -0
- solstone/talent/documents.md +44 -0
- solstone/talent/documents.py +13 -0
- solstone/talent/entities.md +42 -0
- solstone/talent/entities.py +140 -0
- solstone/talent/event.md +53 -0
- solstone/talent/exec.md +198 -0
- solstone/talent/exec_context.py +39 -0
- solstone/talent/facet_newsletter.md +116 -0
- solstone/talent/heartbeat.md +93 -0
- solstone/talent/joke_bot.md +87 -0
- solstone/talent/journal/SKILL.md +65 -0
- solstone/talent/journal/references/captures.md +282 -0
- solstone/talent/journal/references/cli.md +288 -0
- solstone/talent/journal/references/config.md +320 -0
- solstone/talent/journal/references/facets.md +304 -0
- solstone/talent/journal/references/logs.md +144 -0
- solstone/talent/journal/references/storage.md +47 -0
- solstone/talent/morning_briefing.md +161 -0
- solstone/talent/naming.md +86 -0
- solstone/talent/participation.md +60 -0
- solstone/talent/participation.py +107 -0
- solstone/talent/participation.schema.json +46 -0
- solstone/talent/participation_entry.schema.json +31 -0
- solstone/talent/partner.md +126 -0
- solstone/talent/pulse.md +77 -0
- solstone/talent/reflection.md +104 -0
- solstone/talent/routine.md +23 -0
- solstone/talent/routines/SKILL.md +148 -0
- solstone/talent/schedule.md +167 -0
- solstone/talent/schedule.py +203 -0
- solstone/talent/schedule.schema.json +103 -0
- solstone/talent/screen.md +84 -0
- solstone/talent/sense.md +140 -0
- solstone/talent/sense.schema.json +53 -0
- solstone/talent/speaker_attribution.md +55 -0
- solstone/talent/speaker_attribution.py +201 -0
- solstone/talent/speaker_attribution.schema.json +14 -0
- solstone/talent/story.py +233 -0
- solstone/talent/story.schema.json +61 -0
- solstone/talent/vit/SKILL.md +92 -0
- solstone/talent/weekly_reflection.md +100 -0
- solstone/talent/work.md +53 -0
- solstone/think/README.md +273 -0
- solstone/think/__init__.py +4 -0
- solstone/think/_extraction_utils.py +56 -0
- solstone/think/activities.py +1522 -0
- solstone/think/activity_state_machine.py +287 -0
- solstone/think/awareness.py +444 -0
- solstone/think/batch.py +332 -0
- solstone/think/call.py +94 -0
- solstone/think/callosum.py +558 -0
- solstone/think/capture_health.py +83 -0
- solstone/think/chat_cli.py +145 -0
- solstone/think/chat_formatter.py +75 -0
- solstone/think/cluster.py +759 -0
- solstone/think/cogitate_policy.py +155 -0
- solstone/think/config_cli.py +691 -0
- solstone/think/cortex.py +914 -0
- solstone/think/cortex_client.py +416 -0
- solstone/think/deferred_deletes.py +60 -0
- solstone/think/detect_created.md +26 -0
- solstone/think/detect_created.py +131 -0
- solstone/think/detect_created.schema.json +27 -0
- solstone/think/detect_transcript.py +218 -0
- solstone/think/detect_transcript_json.md +59 -0
- solstone/think/detect_transcript_json.schema.json +24 -0
- solstone/think/detect_transcript_segment.md +27 -0
- solstone/think/detect_transcript_segment.schema.json +14 -0
- solstone/think/doctor.py +928 -0
- solstone/think/engage.py +105 -0
- solstone/think/entities/__init__.py +200 -0
- solstone/think/entities/activity.py +280 -0
- solstone/think/entities/consolidation.py +158 -0
- solstone/think/entities/context.py +127 -0
- solstone/think/entities/core.py +226 -0
- solstone/think/entities/formatting.py +289 -0
- solstone/think/entities/journal.py +418 -0
- solstone/think/entities/loading.py +463 -0
- solstone/think/entities/matching.py +627 -0
- solstone/think/entities/merge.py +732 -0
- solstone/think/entities/observations.py +230 -0
- solstone/think/entities/relationships.py +289 -0
- solstone/think/entities/saving.py +315 -0
- solstone/think/entities/seeding.py +109 -0
- solstone/think/entities/voiceprints.py +189 -0
- solstone/think/event_formatter.py +166 -0
- solstone/think/facets.py +1271 -0
- solstone/think/formatters.py +414 -0
- solstone/think/health_cli.py +155 -0
- solstone/think/heartbeat.py +147 -0
- solstone/think/identity.py +489 -0
- solstone/think/importers/__init__.py +2 -0
- solstone/think/importers/audio.py +194 -0
- solstone/think/importers/chatgpt.py +332 -0
- solstone/think/importers/claude_chat.py +290 -0
- solstone/think/importers/cli.py +1363 -0
- solstone/think/importers/documents.py +328 -0
- solstone/think/importers/file_importer.py +128 -0
- solstone/think/importers/formatting.py +281 -0
- solstone/think/importers/gemini.py +388 -0
- solstone/think/importers/granola.py +500 -0
- solstone/think/importers/ics.py +599 -0
- solstone/think/importers/journal_archive.py +691 -0
- solstone/think/importers/journal_source_cli.py +308 -0
- solstone/think/importers/kindle.py +429 -0
- solstone/think/importers/obsidian.py +737 -0
- solstone/think/importers/plaud.py +579 -0
- solstone/think/importers/shared.py +684 -0
- solstone/think/importers/sync.py +83 -0
- solstone/think/importers/text.py +151 -0
- solstone/think/importers/utils.py +666 -0
- solstone/think/indexer/__init__.py +41 -0
- solstone/think/indexer/__main__.py +9 -0
- solstone/think/indexer/cli.py +225 -0
- solstone/think/indexer/journal.py +2748 -0
- solstone/think/install_guard.py +423 -0
- solstone/think/install_models.py +641 -0
- solstone/think/journal_default.json +66 -0
- solstone/think/journal_export.py +129 -0
- solstone/think/journal_stats.py +554 -0
- solstone/think/link/__init__.py +24 -0
- solstone/think/link/__main__.py +9 -0
- solstone/think/link/auth.py +194 -0
- solstone/think/link/ca.py +254 -0
- solstone/think/link/framing.py +187 -0
- solstone/think/link/mux.py +290 -0
- solstone/think/link/nonces.py +176 -0
- solstone/think/link/paths.py +164 -0
- solstone/think/link/relay_client.py +391 -0
- solstone/think/link/service.py +130 -0
- solstone/think/link/tcp_pipe.py +137 -0
- solstone/think/link/tls_adapter.py +199 -0
- solstone/think/logs_cli.py +321 -0
- solstone/think/maint.py +463 -0
- solstone/think/markdown.py +402 -0
- solstone/think/media.py +25 -0
- solstone/think/merge.py +932 -0
- solstone/think/models.py +1519 -0
- solstone/think/notify_cli.py +67 -0
- solstone/think/pairing/__init__.py +4 -0
- solstone/think/pairing/config.py +90 -0
- solstone/think/pairing/devices.py +209 -0
- solstone/think/pairing/keys.py +55 -0
- solstone/think/pairing/tokens.py +105 -0
- solstone/think/password_cli.py +67 -0
- solstone/think/pipeline_health.py +185 -0
- solstone/think/planner.md +133 -0
- solstone/think/planner.py +26 -0
- solstone/think/policies/cogitate.toml +32 -0
- solstone/think/prompts.py +409 -0
- solstone/think/providers/__init__.py +257 -0
- solstone/think/providers/anthropic.py +739 -0
- solstone/think/providers/cli.py +820 -0
- solstone/think/providers/google.py +934 -0
- solstone/think/providers/ollama.py +620 -0
- solstone/think/providers/openai.py +532 -0
- solstone/think/providers/shared.py +246 -0
- solstone/think/providers_cli.py +337 -0
- solstone/think/push/__init__.py +20 -0
- solstone/think/push/config.py +92 -0
- solstone/think/push/devices.py +153 -0
- solstone/think/push/dispatch.py +381 -0
- solstone/think/push/runtime.py +145 -0
- solstone/think/push/triggers.py +300 -0
- solstone/think/retention.py +483 -0
- solstone/think/routines.py +552 -0
- solstone/think/runner.py +553 -0
- solstone/think/scheduler.py +668 -0
- solstone/think/segment.py +878 -0
- solstone/think/sense_splitter.py +86 -0
- solstone/think/service.py +589 -0
- solstone/think/setup.py +1236 -0
- solstone/think/skills.py +212 -0
- solstone/think/skills_cli.py +614 -0
- solstone/think/sol_cli.py +347 -0
- solstone/think/stats_schema.py +78 -0
- solstone/think/streams.py +439 -0
- solstone/think/supervisor.py +2015 -0
- solstone/think/surfaces/__init__.py +2 -0
- solstone/think/surfaces/health.py +518 -0
- solstone/think/surfaces/ledger.py +620 -0
- solstone/think/surfaces/profile.py +281 -0
- solstone/think/surfaces/types.py +127 -0
- solstone/think/talent.py +731 -0
- solstone/think/talent_cli.py +1244 -0
- solstone/think/talents.py +1382 -0
- solstone/think/templates/activity_preamble.md +7 -0
- solstone/think/templates/daily_preamble.md +3 -0
- solstone/think/templates/segment_preamble.md +3 -0
- solstone/think/thinking.py +3365 -0
- solstone/think/tools/__init__.py +2 -0
- solstone/think/tools/call.py +1378 -0
- solstone/think/tools/facets.py +127 -0
- solstone/think/tools/health.py +182 -0
- solstone/think/tools/journal_merge.py +11 -0
- solstone/think/tools/ledger.py +188 -0
- solstone/think/tools/navigate.py +42 -0
- solstone/think/tools/profile.py +195 -0
- solstone/think/tools/routines.py +441 -0
- solstone/think/tools/search.py +201 -0
- solstone/think/tools/sol.py +410 -0
- solstone/think/top.py +1031 -0
- solstone/think/user_config.py +57 -0
- solstone/think/utils.py +1076 -0
- solstone/think/voice/__init__.py +24 -0
- solstone/think/voice/brain.py +397 -0
- solstone/think/voice/config.py +51 -0
- solstone/think/voice/nav_queue.py +93 -0
- solstone/think/voice/observer_queue.py +102 -0
- solstone/think/voice/runtime.py +127 -0
- solstone/think/voice/sideband.py +61 -0
- solstone/think/voice/tools.py +759 -0
- solstone-0.1.1.dist-info/METADATA +214 -0
- solstone-0.1.1.dist-info/RECORD +548 -0
- solstone-0.1.1.dist-info/WHEEL +5 -0
- solstone-0.1.1.dist-info/entry_points.txt +2 -0
- solstone-0.1.1.dist-info/licenses/LICENSE +661 -0
- solstone-0.1.1.dist-info/top_level.txt +1 -0
solstone/__init__.py
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
# SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
# Copyright (c) 2026 sol pbc
|
|
3
|
+
|
|
4
|
+
"""App plugin system for solstone.
|
|
5
|
+
|
|
6
|
+
Convention-based app discovery with minimal configuration:
|
|
7
|
+
|
|
8
|
+
Directory Structure:
|
|
9
|
+
apps/my_app/ # Use underscores, not hyphens!
|
|
10
|
+
workspace.html # Required: Main template
|
|
11
|
+
routes.py # Optional: Flask blueprint (for custom routes beyond index)
|
|
12
|
+
background.html # Optional: Background service
|
|
13
|
+
app.json # Optional: Metadata overrides
|
|
14
|
+
agents/ # Optional: Custom agents
|
|
15
|
+
tests/ # Optional: App-specific tests
|
|
16
|
+
|
|
17
|
+
Naming Rules:
|
|
18
|
+
- App directory names must use underscores (my_app), not hyphens (my-app)
|
|
19
|
+
- App name = directory name (e.g., "my_app")
|
|
20
|
+
- Blueprint variable must be named {app_name}_bp (e.g., my_app_bp)
|
|
21
|
+
- Blueprint name must use "app:{name}" pattern for consistency
|
|
22
|
+
(e.g., Blueprint("app:home", ...), use url_for('app:home.index'))
|
|
23
|
+
- URL prefix convention: /app/{app_name}
|
|
24
|
+
|
|
25
|
+
app.json fields (all optional):
|
|
26
|
+
{
|
|
27
|
+
"icon": "🏠", # Emoji icon for menu bar (default: "📦")
|
|
28
|
+
"label": "Custom Label", # Display label (default: title-cased app name)
|
|
29
|
+
"facets": {}, # Facet options: {"disabled": true} to hide facet bar
|
|
30
|
+
"date_nav": true, # Show date navigation bar (default: false)
|
|
31
|
+
"app_bar": false, # Hide the universal chat bar on this app (default: true)
|
|
32
|
+
"allow_future_dates": true # Allow future dates in month picker (default: false)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
See the App dataclass below for the complete field list with types and defaults.
|
|
36
|
+
|
|
37
|
+
Apps are automatically discovered and registered.
|
|
38
|
+
All apps are served at /app/{name} via shared handler.
|
|
39
|
+
Apps with routes.py can define custom routes beyond the index route.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
from __future__ import annotations
|
|
43
|
+
|
|
44
|
+
import importlib
|
|
45
|
+
import json
|
|
46
|
+
import logging
|
|
47
|
+
from dataclasses import dataclass, field
|
|
48
|
+
from pathlib import Path
|
|
49
|
+
from typing import Any, Optional
|
|
50
|
+
|
|
51
|
+
from flask import Blueprint
|
|
52
|
+
|
|
53
|
+
logger = logging.getLogger(__name__)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass
|
|
57
|
+
class App:
|
|
58
|
+
"""Convention-based app configuration."""
|
|
59
|
+
|
|
60
|
+
name: str
|
|
61
|
+
icon: str
|
|
62
|
+
label: str
|
|
63
|
+
blueprint: Optional[Blueprint] = None
|
|
64
|
+
|
|
65
|
+
# Template paths (relative to Flask template root)
|
|
66
|
+
workspace_template: str = ""
|
|
67
|
+
background_template: Optional[str] = None
|
|
68
|
+
|
|
69
|
+
# Facet configuration (optional, default {})
|
|
70
|
+
# Options:
|
|
71
|
+
# - disabled: If true, facets bar is hidden for this app
|
|
72
|
+
facets_config: dict = field(default_factory=dict)
|
|
73
|
+
|
|
74
|
+
# Date navigation (renders date nav below facet bar)
|
|
75
|
+
date_nav: bool = False
|
|
76
|
+
|
|
77
|
+
# Hide the universal chat bar on this app
|
|
78
|
+
app_bar: bool = True
|
|
79
|
+
|
|
80
|
+
# Allow clicking future dates in month picker (for todos)
|
|
81
|
+
allow_future_dates: bool = False
|
|
82
|
+
|
|
83
|
+
def facets_enabled(self) -> bool:
|
|
84
|
+
"""Check if facets are enabled for this app."""
|
|
85
|
+
return not self.facets_config.get("disabled", False)
|
|
86
|
+
|
|
87
|
+
def date_nav_enabled(self) -> bool:
|
|
88
|
+
"""Check if date nav is enabled for this app."""
|
|
89
|
+
return self.date_nav
|
|
90
|
+
|
|
91
|
+
def get_blueprint(self) -> Optional[Blueprint]:
|
|
92
|
+
"""Return Flask Blueprint with app routes, or None if app has no custom routes."""
|
|
93
|
+
return self.blueprint
|
|
94
|
+
|
|
95
|
+
def get_workspace_template(self) -> str:
|
|
96
|
+
"""Return path to workspace template."""
|
|
97
|
+
return self.workspace_template
|
|
98
|
+
|
|
99
|
+
def get_background_template(self) -> Optional[str]:
|
|
100
|
+
"""Return path to background service template, or None."""
|
|
101
|
+
return self.background_template
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class AppRegistry:
|
|
105
|
+
"""Registry for discovering and managing solstone apps."""
|
|
106
|
+
|
|
107
|
+
def __init__(self):
|
|
108
|
+
self.apps: dict[str, App] = {}
|
|
109
|
+
|
|
110
|
+
def discover(self) -> None:
|
|
111
|
+
"""Auto-discover apps using convention over configuration.
|
|
112
|
+
|
|
113
|
+
For each directory in apps/:
|
|
114
|
+
1. Check for workspace.html (required)
|
|
115
|
+
2. Load app.json if present (for icon, label overrides)
|
|
116
|
+
3. Import routes.py and get blueprint (optional - for custom routes)
|
|
117
|
+
4. Check for background.html (optional)
|
|
118
|
+
"""
|
|
119
|
+
apps_dir = Path(__file__).parent
|
|
120
|
+
|
|
121
|
+
for app_path in sorted(apps_dir.iterdir()):
|
|
122
|
+
# Skip non-directories and private/internal directories
|
|
123
|
+
if not app_path.is_dir() or app_path.name.startswith("_"):
|
|
124
|
+
continue
|
|
125
|
+
|
|
126
|
+
app_name = app_path.name
|
|
127
|
+
|
|
128
|
+
# Skip if workspace.html doesn't exist (required)
|
|
129
|
+
if not (app_path / "workspace.html").exists():
|
|
130
|
+
logger.debug(f"Skipping {app_name}/ - no workspace.html found")
|
|
131
|
+
continue
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
app = self._load_app(app_name, app_path)
|
|
135
|
+
self.apps[app_name] = app
|
|
136
|
+
logger.info(f"Discovered app: {app_name}")
|
|
137
|
+
except Exception as e:
|
|
138
|
+
logger.error(f"Failed to load app {app_name}: {e}", exc_info=True)
|
|
139
|
+
|
|
140
|
+
def _load_app(self, app_name: str, app_path: Path) -> App:
|
|
141
|
+
"""Load a single app from its directory.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
app_name: Name of the app (directory name)
|
|
145
|
+
app_path: Path to app directory
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
App instance
|
|
149
|
+
|
|
150
|
+
Raises:
|
|
151
|
+
Exception: If app cannot be loaded
|
|
152
|
+
"""
|
|
153
|
+
# Validate app name
|
|
154
|
+
if "-" in app_name:
|
|
155
|
+
logger.warning(
|
|
156
|
+
f"App '{app_name}' uses hyphens. Use underscores instead (e.g., 'my_app')"
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
# Load metadata from app.json (optional)
|
|
160
|
+
metadata = self._load_metadata(app_path)
|
|
161
|
+
|
|
162
|
+
# Get icon and label (with defaults)
|
|
163
|
+
icon = metadata.get("icon", "📦")
|
|
164
|
+
label = metadata.get("label", app_name.replace("_", " "))
|
|
165
|
+
|
|
166
|
+
# Parse facets config
|
|
167
|
+
facets_config = metadata.get("facets", {})
|
|
168
|
+
if not isinstance(facets_config, dict):
|
|
169
|
+
facets_config = {}
|
|
170
|
+
|
|
171
|
+
# Date navigation
|
|
172
|
+
date_nav = metadata.get("date_nav", False)
|
|
173
|
+
|
|
174
|
+
# Universal app bar
|
|
175
|
+
app_bar = metadata.get("app_bar", True)
|
|
176
|
+
|
|
177
|
+
# Allow future dates in month picker
|
|
178
|
+
allow_future_dates = metadata.get("allow_future_dates", False)
|
|
179
|
+
|
|
180
|
+
# Import routes module and get blueprint (optional)
|
|
181
|
+
blueprint = None
|
|
182
|
+
routes_module = None
|
|
183
|
+
routes_file = app_path / "routes.py"
|
|
184
|
+
|
|
185
|
+
if routes_file.exists():
|
|
186
|
+
routes_module = importlib.import_module(f"solstone.apps.{app_name}.routes")
|
|
187
|
+
|
|
188
|
+
# Find blueprint - look for *_bp attribute
|
|
189
|
+
expected_bp_var = f"{app_name}_bp"
|
|
190
|
+
|
|
191
|
+
for attr_name in dir(routes_module):
|
|
192
|
+
if attr_name.endswith("_bp"):
|
|
193
|
+
bp = getattr(routes_module, attr_name)
|
|
194
|
+
if isinstance(bp, Blueprint):
|
|
195
|
+
blueprint = bp
|
|
196
|
+
|
|
197
|
+
# Warn if variable name doesn't match convention
|
|
198
|
+
if attr_name != expected_bp_var:
|
|
199
|
+
logger.warning(
|
|
200
|
+
f"App '{app_name}': Blueprint variable '{attr_name}' should be '{expected_bp_var}'"
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
break
|
|
204
|
+
|
|
205
|
+
if not blueprint:
|
|
206
|
+
raise ValueError(
|
|
207
|
+
f"No blueprint found in apps.{app_name}.routes - "
|
|
208
|
+
f"expected variable named '{expected_bp_var}'"
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
# Verify blueprint name uses "app:{name}" pattern for consistency
|
|
212
|
+
expected_name = f"app:{app_name}"
|
|
213
|
+
if blueprint.name != expected_name:
|
|
214
|
+
raise ValueError(
|
|
215
|
+
f"App '{app_name}': Blueprint name must be '{expected_name}', "
|
|
216
|
+
f"got '{blueprint.name}'. Update Blueprint() declaration in routes.py"
|
|
217
|
+
)
|
|
218
|
+
else:
|
|
219
|
+
# No routes.py - create a minimal blueprint
|
|
220
|
+
blueprint = self._create_minimal_blueprint(app_name)
|
|
221
|
+
logger.debug(
|
|
222
|
+
f"Created minimal blueprint for app '{app_name}' (no routes.py)"
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
# Inject default index route if app doesn't define one
|
|
226
|
+
self._inject_index_if_needed(blueprint, routes_module, app_name)
|
|
227
|
+
|
|
228
|
+
# Resolve template paths (relative to apps/ directory since that's in the loader)
|
|
229
|
+
workspace_template = f"{app_name}/workspace.html"
|
|
230
|
+
|
|
231
|
+
background_template = None
|
|
232
|
+
if (app_path / "background.html").exists():
|
|
233
|
+
background_template = f"{app_name}/background.html"
|
|
234
|
+
|
|
235
|
+
return App(
|
|
236
|
+
name=app_name,
|
|
237
|
+
icon=icon,
|
|
238
|
+
label=label,
|
|
239
|
+
blueprint=blueprint,
|
|
240
|
+
workspace_template=workspace_template,
|
|
241
|
+
background_template=background_template,
|
|
242
|
+
facets_config=facets_config,
|
|
243
|
+
date_nav=date_nav,
|
|
244
|
+
app_bar=app_bar,
|
|
245
|
+
allow_future_dates=allow_future_dates,
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
def _load_metadata(self, app_path: Path) -> dict[str, Any]:
|
|
249
|
+
"""Load app.json metadata file if it exists.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
app_path: Path to app directory
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
Dict with metadata, or empty dict if no app.json
|
|
256
|
+
"""
|
|
257
|
+
metadata_file = app_path / "app.json"
|
|
258
|
+
if metadata_file.exists():
|
|
259
|
+
try:
|
|
260
|
+
with open(metadata_file) as f:
|
|
261
|
+
return json.load(f)
|
|
262
|
+
except Exception as e:
|
|
263
|
+
logger.warning(f"Failed to load {metadata_file}: {e}")
|
|
264
|
+
return {}
|
|
265
|
+
|
|
266
|
+
def _create_minimal_blueprint(self, app_name: str) -> Blueprint:
|
|
267
|
+
"""Create a minimal blueprint for apps without routes.py.
|
|
268
|
+
|
|
269
|
+
Args:
|
|
270
|
+
app_name: Name of the app
|
|
271
|
+
|
|
272
|
+
Returns:
|
|
273
|
+
Blueprint with proper naming and URL prefix
|
|
274
|
+
"""
|
|
275
|
+
blueprint = Blueprint(
|
|
276
|
+
f"app:{app_name}",
|
|
277
|
+
__name__,
|
|
278
|
+
url_prefix=f"/app/{app_name}",
|
|
279
|
+
)
|
|
280
|
+
return blueprint
|
|
281
|
+
|
|
282
|
+
def _inject_index_if_needed(
|
|
283
|
+
self, blueprint: Blueprint, routes_module: Any, app_name: str
|
|
284
|
+
) -> None:
|
|
285
|
+
"""Inject default index route if app doesn't define one.
|
|
286
|
+
|
|
287
|
+
Checks if routes module has an 'index' function. If not, adds a
|
|
288
|
+
default index route that renders app.html using blueprint.record()
|
|
289
|
+
to support multiple app registrations.
|
|
290
|
+
|
|
291
|
+
Args:
|
|
292
|
+
blueprint: The Flask blueprint to inject into
|
|
293
|
+
routes_module: The imported routes module (or None if no routes.py)
|
|
294
|
+
app_name: Name of the app
|
|
295
|
+
"""
|
|
296
|
+
import inspect
|
|
297
|
+
|
|
298
|
+
has_index = False
|
|
299
|
+
|
|
300
|
+
if routes_module:
|
|
301
|
+
# Get functions defined in this module (not imported)
|
|
302
|
+
module_functions = [
|
|
303
|
+
name
|
|
304
|
+
for name, obj in inspect.getmembers(routes_module)
|
|
305
|
+
if inspect.isfunction(obj) and obj.__module__ == routes_module.__name__
|
|
306
|
+
]
|
|
307
|
+
has_index = "index" in module_functions
|
|
308
|
+
|
|
309
|
+
if not has_index:
|
|
310
|
+
# No index function, inject default one using record() for deferred setup
|
|
311
|
+
# Only inject if blueprint hasn't been registered yet
|
|
312
|
+
if not blueprint._got_registered_once:
|
|
313
|
+
|
|
314
|
+
def index():
|
|
315
|
+
from flask import render_template
|
|
316
|
+
|
|
317
|
+
return render_template("app.html")
|
|
318
|
+
|
|
319
|
+
def setup_index(state):
|
|
320
|
+
"""Deferred setup function called when blueprint is registered."""
|
|
321
|
+
state.app.add_url_rule(
|
|
322
|
+
f"{blueprint.url_prefix}/",
|
|
323
|
+
endpoint=f"{blueprint.name}.index",
|
|
324
|
+
view_func=index,
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
blueprint.record(setup_index)
|
|
328
|
+
logger.debug(f"Injected default index route for app '{app_name}'")
|
|
329
|
+
|
|
330
|
+
def register_blueprints(self, flask_app) -> None:
|
|
331
|
+
"""Register all app blueprints with Flask.
|
|
332
|
+
|
|
333
|
+
Args:
|
|
334
|
+
flask_app: Flask application instance
|
|
335
|
+
"""
|
|
336
|
+
for app in self.apps.values():
|
|
337
|
+
if not app.blueprint:
|
|
338
|
+
logger.error(
|
|
339
|
+
f"App '{app.name}' has no blueprint - this should not happen"
|
|
340
|
+
)
|
|
341
|
+
continue
|
|
342
|
+
|
|
343
|
+
try:
|
|
344
|
+
flask_app.register_blueprint(app.blueprint)
|
|
345
|
+
logger.info(f"Registered blueprint: {app.blueprint.name}")
|
|
346
|
+
except Exception as e:
|
|
347
|
+
logger.error(
|
|
348
|
+
f"Failed to register blueprint for app {app.name}: {e}",
|
|
349
|
+
exc_info=True,
|
|
350
|
+
)
|