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.
Files changed (548) hide show
  1. solstone/__init__.py +4 -0
  2. solstone/apps/__init__.py +350 -0
  3. solstone/apps/activities/_day.html +998 -0
  4. solstone/apps/activities/_dev_screens_detail.html +445 -0
  5. solstone/apps/activities/_dev_screens_list.html +191 -0
  6. solstone/apps/activities/app.json +6 -0
  7. solstone/apps/activities/call.py +637 -0
  8. solstone/apps/activities/routes.py +495 -0
  9. solstone/apps/activities/talent/activities/SKILL.md +171 -0
  10. solstone/apps/activities/talent/activities_review.md +43 -0
  11. solstone/apps/activities/tests/conftest.py +54 -0
  12. solstone/apps/activities/tests/test_call.py +324 -0
  13. solstone/apps/activities/workspace.html +13 -0
  14. solstone/apps/awareness/__init__.py +2 -0
  15. solstone/apps/awareness/call.py +141 -0
  16. solstone/apps/chat/_chat_event.html +45 -0
  17. solstone/apps/chat/app.json +6 -0
  18. solstone/apps/chat/routes.py +79 -0
  19. solstone/apps/chat/tests/test_routes.py +299 -0
  20. solstone/apps/chat/workspace.html +438 -0
  21. solstone/apps/entities/app.json +4 -0
  22. solstone/apps/entities/call.py +588 -0
  23. solstone/apps/entities/events.py +4 -0
  24. solstone/apps/entities/maint/001_migrate_to_journal_entities.py +424 -0
  25. solstone/apps/entities/routes.py +1015 -0
  26. solstone/apps/entities/talent/entities/SKILL.md +349 -0
  27. solstone/apps/entities/talent/entities.md +227 -0
  28. solstone/apps/entities/talent/entities_review.md +229 -0
  29. solstone/apps/entities/talent/entity_assist.md +160 -0
  30. solstone/apps/entities/talent/entity_describe.md +68 -0
  31. solstone/apps/entities/talent/entity_observer.md +110 -0
  32. solstone/apps/entities/talent/entity_observer.py +93 -0
  33. solstone/apps/entities/talent/entity_observer.schema.json +51 -0
  34. solstone/apps/entities/tests/conftest.py +182 -0
  35. solstone/apps/entities/tests/test_all_facets_cache.py +92 -0
  36. solstone/apps/entities/tests/test_call.py +590 -0
  37. solstone/apps/entities/tests/test_delete_journal_entity.py +139 -0
  38. solstone/apps/entities/tests/test_merge.py +435 -0
  39. solstone/apps/entities/workspace.html +3568 -0
  40. solstone/apps/events.py +342 -0
  41. solstone/apps/graph/app.json +4 -0
  42. solstone/apps/graph/routes.py +366 -0
  43. solstone/apps/graph/workspace.html +1255 -0
  44. solstone/apps/health/app.json +5 -0
  45. solstone/apps/health/routes.py +59 -0
  46. solstone/apps/health/talent/health/SKILL.md +211 -0
  47. solstone/apps/health/tests/__init__.py +1 -0
  48. solstone/apps/health/tests/conftest.py +57 -0
  49. solstone/apps/health/tests/test_routes.py +68 -0
  50. solstone/apps/health/workspace.html +3177 -0
  51. solstone/apps/home/app.json +5 -0
  52. solstone/apps/home/routes.py +1521 -0
  53. solstone/apps/home/workspace.html +1928 -0
  54. solstone/apps/import/_detail.html +660 -0
  55. solstone/apps/import/app.json +4 -0
  56. solstone/apps/import/call.py +659 -0
  57. solstone/apps/import/facet_ingest.py +751 -0
  58. solstone/apps/import/guides/chatgpt.md +10 -0
  59. solstone/apps/import/guides/claude.md +10 -0
  60. solstone/apps/import/guides/gemini.md +11 -0
  61. solstone/apps/import/guides/granola.md +25 -0
  62. solstone/apps/import/guides/ics.md +24 -0
  63. solstone/apps/import/guides/journal_archive.md +38 -0
  64. solstone/apps/import/guides/kindle.md +10 -0
  65. solstone/apps/import/guides/obsidian.md +21 -0
  66. solstone/apps/import/ingest.py +1026 -0
  67. solstone/apps/import/journal_sources.py +130 -0
  68. solstone/apps/import/routes.py +968 -0
  69. solstone/apps/import/talent/review.md +89 -0
  70. solstone/apps/import/talent/review_config.md +85 -0
  71. solstone/apps/import/talent/review_entities.md +90 -0
  72. solstone/apps/import/talent/review_facets.md +91 -0
  73. solstone/apps/import/workspace.html +1974 -0
  74. solstone/apps/link/app.json +5 -0
  75. solstone/apps/link/call.py +194 -0
  76. solstone/apps/link/routes.py +301 -0
  77. solstone/apps/link/tests/__init__.py +0 -0
  78. solstone/apps/link/tests/conftest.py +49 -0
  79. solstone/apps/link/tests/test_workspace_modals.py +21 -0
  80. solstone/apps/link/workspace.html +367 -0
  81. solstone/apps/observer/app.json +5 -0
  82. solstone/apps/observer/events.py +107 -0
  83. solstone/apps/observer/maint/000_migrate_remote_to_observer.py +125 -0
  84. solstone/apps/observer/routes.py +1079 -0
  85. solstone/apps/observer/tests/conftest.py +59 -0
  86. solstone/apps/observer/tests/test_events.py +257 -0
  87. solstone/apps/observer/tests/test_observer_client.py +388 -0
  88. solstone/apps/observer/tests/test_routes.py +2366 -0
  89. solstone/apps/observer/tests/test_utils.py +397 -0
  90. solstone/apps/observer/utils.py +240 -0
  91. solstone/apps/observer/workspace.html +1006 -0
  92. solstone/apps/photos/__init__.py +2 -0
  93. solstone/apps/photos/call.py +118 -0
  94. solstone/apps/photos/reader.py +71 -0
  95. solstone/apps/photos/tests/__init__.py +1 -0
  96. solstone/apps/photos/tests/test_call.py +269 -0
  97. solstone/apps/reflections/app.json +9 -0
  98. solstone/apps/reflections/pdf.html +61 -0
  99. solstone/apps/reflections/routes.py +210 -0
  100. solstone/apps/reflections/workspace.html +245 -0
  101. solstone/apps/search/app.json +4 -0
  102. solstone/apps/search/maint/003_migrate_index_stream.py +109 -0
  103. solstone/apps/search/maint/004_migrate_topic_to_agent.py +163 -0
  104. solstone/apps/search/routes.py +294 -0
  105. solstone/apps/search/tests/test_maint_migrate_index.py +121 -0
  106. solstone/apps/search/workspace.html +933 -0
  107. solstone/apps/settings/app.json +4 -0
  108. solstone/apps/settings/call.py +871 -0
  109. solstone/apps/settings/copy.py +68 -0
  110. solstone/apps/settings/maint/001_backfill_streams.py +508 -0
  111. solstone/apps/settings/maint/002_restructure_stream_dirs.py +185 -0
  112. solstone/apps/settings/maint/__init__.py +2 -0
  113. solstone/apps/settings/routes.py +2413 -0
  114. solstone/apps/settings/tests/conftest.py +90 -0
  115. solstone/apps/settings/tests/test_call.py +572 -0
  116. solstone/apps/settings/workspace.html +6466 -0
  117. solstone/apps/skills/__init__.py +4 -0
  118. solstone/apps/skills/call.py +476 -0
  119. solstone/apps/skills/talent/skill_editor.md +100 -0
  120. solstone/apps/skills/talent/skill_editor.py +595 -0
  121. solstone/apps/skills/talent/skill_observer.md +77 -0
  122. solstone/apps/sol/app.json +5 -0
  123. solstone/apps/sol/call.py +198 -0
  124. solstone/apps/sol/maint/000_migrate_agent_layout.py +206 -0
  125. solstone/apps/sol/maint/001_migrate_agent_run_logs.py +259 -0
  126. solstone/apps/sol/maint/002_migrate_chronicle.py +120 -0
  127. solstone/apps/sol/maint/004_rename_agents_to_talents.py +124 -0
  128. solstone/apps/sol/maint/005_migrate_dream_to_think_schedules.py +137 -0
  129. solstone/apps/sol/maint/006_rename_unified_triage_providers.py +152 -0
  130. solstone/apps/sol/maint/__init__.py +2 -0
  131. solstone/apps/sol/routes.py +677 -0
  132. solstone/apps/sol/workspace.html +2534 -0
  133. solstone/apps/speakers/_overlap.py +33 -0
  134. solstone/apps/speakers/app.json +8 -0
  135. solstone/apps/speakers/attribution.py +787 -0
  136. solstone/apps/speakers/bootstrap.py +743 -0
  137. solstone/apps/speakers/call.py +663 -0
  138. solstone/apps/speakers/discovery.py +504 -0
  139. solstone/apps/speakers/encoder_config.py +22 -0
  140. solstone/apps/speakers/owner.py +1102 -0
  141. solstone/apps/speakers/routes.py +1344 -0
  142. solstone/apps/speakers/status.py +222 -0
  143. solstone/apps/speakers/suggest.py +407 -0
  144. solstone/apps/speakers/talent/speakers/SKILL.md +275 -0
  145. solstone/apps/speakers/tests/conftest.py +480 -0
  146. solstone/apps/speakers/tests/test_attribution.py +690 -0
  147. solstone/apps/speakers/tests/test_call.py +379 -0
  148. solstone/apps/speakers/tests/test_discovery.py +301 -0
  149. solstone/apps/speakers/tests/test_encoder_config.py +45 -0
  150. solstone/apps/speakers/tests/test_import_composition.py +234 -0
  151. solstone/apps/speakers/tests/test_merge_names.py +780 -0
  152. solstone/apps/speakers/tests/test_owner.py +1109 -0
  153. solstone/apps/speakers/tests/test_routes.py +1370 -0
  154. solstone/apps/speakers/tests/test_seed_imports.py +292 -0
  155. solstone/apps/speakers/tests/test_status.py +132 -0
  156. solstone/apps/speakers/tests/test_suggest.py +301 -0
  157. solstone/apps/speakers/tests/test_wipe.py +83 -0
  158. solstone/apps/speakers/voiceprint_io.py +119 -0
  159. solstone/apps/speakers/wipe.py +88 -0
  160. solstone/apps/speakers/workspace.html +2435 -0
  161. solstone/apps/stats/app.json +5 -0
  162. solstone/apps/stats/routes.py +47 -0
  163. solstone/apps/stats/static/dashboard.js +785 -0
  164. solstone/apps/stats/workspace.html +617 -0
  165. solstone/apps/support/app.json +5 -0
  166. solstone/apps/support/background.html +39 -0
  167. solstone/apps/support/call.py +414 -0
  168. solstone/apps/support/diagnostics.py +193 -0
  169. solstone/apps/support/events.py +89 -0
  170. solstone/apps/support/portal.py +683 -0
  171. solstone/apps/support/routes.py +279 -0
  172. solstone/apps/support/talent/support/SKILL.md +185 -0
  173. solstone/apps/support/talent/support.md +79 -0
  174. solstone/apps/support/tools.py +171 -0
  175. solstone/apps/support/workspace.html +1265 -0
  176. solstone/apps/todos/app.json +6 -0
  177. solstone/apps/todos/background.html +78 -0
  178. solstone/apps/todos/call.py +535 -0
  179. solstone/apps/todos/maint/000_time_to_nudge.py +83 -0
  180. solstone/apps/todos/routes.py +725 -0
  181. solstone/apps/todos/talent/daily.md +132 -0
  182. solstone/apps/todos/talent/todo.md +116 -0
  183. solstone/apps/todos/talent/todos/SKILL.md +206 -0
  184. solstone/apps/todos/talent/weekly.md +81 -0
  185. solstone/apps/todos/tests/conftest.py +131 -0
  186. solstone/apps/todos/tests/test_call.py +613 -0
  187. solstone/apps/todos/tests/test_logging.py +129 -0
  188. solstone/apps/todos/tests/test_todo.py +792 -0
  189. solstone/apps/todos/todo.py +884 -0
  190. solstone/apps/todos/workspace.html +1536 -0
  191. solstone/apps/tokens/app.json +6 -0
  192. solstone/apps/tokens/routes.py +377 -0
  193. solstone/apps/tokens/workspace.html +859 -0
  194. solstone/apps/transcripts/__init__.py +2 -0
  195. solstone/apps/transcripts/app.json +6 -0
  196. solstone/apps/transcripts/call.py +202 -0
  197. solstone/apps/transcripts/routes.py +650 -0
  198. solstone/apps/transcripts/talent/transcripts/SKILL.md +131 -0
  199. solstone/apps/transcripts/tests/__init__.py +2 -0
  200. solstone/apps/transcripts/tests/conftest.py +56 -0
  201. solstone/apps/transcripts/tests/test_call.py +129 -0
  202. solstone/apps/transcripts/tests/test_segment_routes.py +382 -0
  203. solstone/apps/transcripts/tests/test_serve_file.py +29 -0
  204. solstone/apps/transcripts/workspace.html +3555 -0
  205. solstone/apps/utils.py +160 -0
  206. solstone/convey/__init__.py +179 -0
  207. solstone/convey/apps.py +347 -0
  208. solstone/convey/auth.py +108 -0
  209. solstone/convey/bridge.py +142 -0
  210. solstone/convey/chat.py +1130 -0
  211. solstone/convey/chat_stream.py +333 -0
  212. solstone/convey/cli.py +116 -0
  213. solstone/convey/config.py +462 -0
  214. solstone/convey/copy.py +55 -0
  215. solstone/convey/gentag.py +73 -0
  216. solstone/convey/maint_cli.py +250 -0
  217. solstone/convey/pairing.py +256 -0
  218. solstone/convey/push.py +128 -0
  219. solstone/convey/restart.py +210 -0
  220. solstone/convey/root.py +313 -0
  221. solstone/convey/state.py +4 -0
  222. solstone/convey/static/Comfortaa-Variable.woff2 +0 -0
  223. solstone/convey/static/api.js +247 -0
  224. solstone/convey/static/app.css +2860 -0
  225. solstone/convey/static/app.js +2535 -0
  226. solstone/convey/static/colors.js +4 -0
  227. solstone/convey/static/error-handler.js +104 -0
  228. solstone/convey/static/month-picker.js +548 -0
  229. solstone/convey/static/pairing-qr.js +18 -0
  230. solstone/convey/static/pairing.css +191 -0
  231. solstone/convey/static/pairing.js +192 -0
  232. solstone/convey/static/relative-time.js +43 -0
  233. solstone/convey/static/tags/tag-2.png +0 -0
  234. solstone/convey/static/tags/tag-4.png +0 -0
  235. solstone/convey/static/tags/tag-6.png +0 -0
  236. solstone/convey/static/tags/tag-7.png +0 -0
  237. solstone/convey/static/tests/README.md +5 -0
  238. solstone/convey/static/tests/api.html +126 -0
  239. solstone/convey/static/tests/register-task.html +98 -0
  240. solstone/convey/static/tests/relative-time.html +58 -0
  241. solstone/convey/static/tests/surface-state.html +64 -0
  242. solstone/convey/static/tests/ws-listen.html +97 -0
  243. solstone/convey/static/vendor/VENDOR.md +107 -0
  244. solstone/convey/static/vendor/dompurify/dompurify.min.js +3 -0
  245. solstone/convey/static/vendor/marked/marked.min.js +69 -0
  246. solstone/convey/static/vendor/vis-network/vis-network.min.js +34 -0
  247. solstone/convey/static/websocket.js +381 -0
  248. solstone/convey/system.py +103 -0
  249. solstone/convey/templates/app.html +781 -0
  250. solstone/convey/templates/chat_bar.html +16 -0
  251. solstone/convey/templates/date_nav.html +133 -0
  252. solstone/convey/templates/init.html +417 -0
  253. solstone/convey/templates/login.html +59 -0
  254. solstone/convey/templates/menu_bar.html +26 -0
  255. solstone/convey/templates/pairing.html +72 -0
  256. solstone/convey/templates/status_pane.html +395 -0
  257. solstone/convey/utils.py +274 -0
  258. solstone/convey/voice.py +197 -0
  259. solstone/observe/README.md +108 -0
  260. solstone/observe/__init__.py +6 -0
  261. solstone/observe/aruco.py +182 -0
  262. solstone/observe/categories/__init__.py +13 -0
  263. solstone/observe/categories/browsing.md +33 -0
  264. solstone/observe/categories/code.md +33 -0
  265. solstone/observe/categories/gaming.md +30 -0
  266. solstone/observe/categories/media.md +34 -0
  267. solstone/observe/categories/meeting.md +52 -0
  268. solstone/observe/categories/meeting.py +67 -0
  269. solstone/observe/categories/messaging.md +38 -0
  270. solstone/observe/categories/productivity.md +34 -0
  271. solstone/observe/categories/reading.md +35 -0
  272. solstone/observe/categories/terminal.md +33 -0
  273. solstone/observe/categories/tmux.py +73 -0
  274. solstone/observe/copy.py +25 -0
  275. solstone/observe/describe.md +24 -0
  276. solstone/observe/describe.py +1017 -0
  277. solstone/observe/describe.schema.json +13 -0
  278. solstone/observe/enrich.md +58 -0
  279. solstone/observe/enrich.py +156 -0
  280. solstone/observe/enrich.schema.json +23 -0
  281. solstone/observe/export.py +1147 -0
  282. solstone/observe/extract.md +42 -0
  283. solstone/observe/extract.py +314 -0
  284. solstone/observe/extract.schema.json +5 -0
  285. solstone/observe/grab.py +766 -0
  286. solstone/observe/hear.py +334 -0
  287. solstone/observe/observer_cli.py +598 -0
  288. solstone/observe/observer_client.py +278 -0
  289. solstone/observe/observer_install/__init__.py +53 -0
  290. solstone/observe/observer_install/common.py +313 -0
  291. solstone/observe/observer_install/linux.py +557 -0
  292. solstone/observe/observer_install/macos.py +43 -0
  293. solstone/observe/observer_install/tmux.py +384 -0
  294. solstone/observe/screen.py +274 -0
  295. solstone/observe/see.py +150 -0
  296. solstone/observe/sense.py +1196 -0
  297. solstone/observe/transcribe/__init__.py +213 -0
  298. solstone/observe/transcribe/_parakeet_coreml.py +374 -0
  299. solstone/observe/transcribe/_parakeet_onnx.py +357 -0
  300. solstone/observe/transcribe/assets/pyannote-segmentation-3.0.onnx +0 -0
  301. solstone/observe/transcribe/assets/wespeaker-resnet34-256.onnx +0 -0
  302. solstone/observe/transcribe/gemini.md +42 -0
  303. solstone/observe/transcribe/gemini.py +403 -0
  304. solstone/observe/transcribe/gemini.schema.json +30 -0
  305. solstone/observe/transcribe/main.py +986 -0
  306. solstone/observe/transcribe/overlap.py +127 -0
  307. solstone/observe/transcribe/parakeet.py +57 -0
  308. solstone/observe/transcribe/parakeet_helper/Package.swift +24 -0
  309. solstone/observe/transcribe/parakeet_helper/README.md +99 -0
  310. solstone/observe/transcribe/parakeet_helper/Sources/parakeet-helper/main.swift +350 -0
  311. solstone/observe/transcribe/revai.py +417 -0
  312. solstone/observe/transcribe/utils.py +90 -0
  313. solstone/observe/transcribe/whisper.py +249 -0
  314. solstone/observe/transfer.py +758 -0
  315. solstone/observe/utils.py +597 -0
  316. solstone/observe/vad.py +525 -0
  317. solstone/talent/__init__.py +4 -0
  318. solstone/talent/_routine_context.py +228 -0
  319. solstone/talent/activities.py +547 -0
  320. solstone/talent/activity_state.py +677 -0
  321. solstone/talent/awareness_tender.md +57 -0
  322. solstone/talent/chat.md +104 -0
  323. solstone/talent/chat.schema.json +28 -0
  324. solstone/talent/chat_context.py +339 -0
  325. solstone/talent/coder.md +78 -0
  326. solstone/talent/conversation.md +54 -0
  327. solstone/talent/daily_schedule.md +59 -0
  328. solstone/talent/daily_schedule.py +232 -0
  329. solstone/talent/daily_schedule.schema.json +16 -0
  330. solstone/talent/digest.md +34 -0
  331. solstone/talent/documents.md +44 -0
  332. solstone/talent/documents.py +13 -0
  333. solstone/talent/entities.md +42 -0
  334. solstone/talent/entities.py +140 -0
  335. solstone/talent/event.md +53 -0
  336. solstone/talent/exec.md +198 -0
  337. solstone/talent/exec_context.py +39 -0
  338. solstone/talent/facet_newsletter.md +116 -0
  339. solstone/talent/heartbeat.md +93 -0
  340. solstone/talent/joke_bot.md +87 -0
  341. solstone/talent/journal/SKILL.md +65 -0
  342. solstone/talent/journal/references/captures.md +282 -0
  343. solstone/talent/journal/references/cli.md +288 -0
  344. solstone/talent/journal/references/config.md +320 -0
  345. solstone/talent/journal/references/facets.md +304 -0
  346. solstone/talent/journal/references/logs.md +144 -0
  347. solstone/talent/journal/references/storage.md +47 -0
  348. solstone/talent/morning_briefing.md +161 -0
  349. solstone/talent/naming.md +86 -0
  350. solstone/talent/participation.md +60 -0
  351. solstone/talent/participation.py +107 -0
  352. solstone/talent/participation.schema.json +46 -0
  353. solstone/talent/participation_entry.schema.json +31 -0
  354. solstone/talent/partner.md +126 -0
  355. solstone/talent/pulse.md +77 -0
  356. solstone/talent/reflection.md +104 -0
  357. solstone/talent/routine.md +23 -0
  358. solstone/talent/routines/SKILL.md +148 -0
  359. solstone/talent/schedule.md +167 -0
  360. solstone/talent/schedule.py +203 -0
  361. solstone/talent/schedule.schema.json +103 -0
  362. solstone/talent/screen.md +84 -0
  363. solstone/talent/sense.md +140 -0
  364. solstone/talent/sense.schema.json +53 -0
  365. solstone/talent/speaker_attribution.md +55 -0
  366. solstone/talent/speaker_attribution.py +201 -0
  367. solstone/talent/speaker_attribution.schema.json +14 -0
  368. solstone/talent/story.py +233 -0
  369. solstone/talent/story.schema.json +61 -0
  370. solstone/talent/vit/SKILL.md +92 -0
  371. solstone/talent/weekly_reflection.md +100 -0
  372. solstone/talent/work.md +53 -0
  373. solstone/think/README.md +273 -0
  374. solstone/think/__init__.py +4 -0
  375. solstone/think/_extraction_utils.py +56 -0
  376. solstone/think/activities.py +1522 -0
  377. solstone/think/activity_state_machine.py +287 -0
  378. solstone/think/awareness.py +444 -0
  379. solstone/think/batch.py +332 -0
  380. solstone/think/call.py +94 -0
  381. solstone/think/callosum.py +558 -0
  382. solstone/think/capture_health.py +83 -0
  383. solstone/think/chat_cli.py +145 -0
  384. solstone/think/chat_formatter.py +75 -0
  385. solstone/think/cluster.py +759 -0
  386. solstone/think/cogitate_policy.py +155 -0
  387. solstone/think/config_cli.py +691 -0
  388. solstone/think/cortex.py +914 -0
  389. solstone/think/cortex_client.py +416 -0
  390. solstone/think/deferred_deletes.py +60 -0
  391. solstone/think/detect_created.md +26 -0
  392. solstone/think/detect_created.py +131 -0
  393. solstone/think/detect_created.schema.json +27 -0
  394. solstone/think/detect_transcript.py +218 -0
  395. solstone/think/detect_transcript_json.md +59 -0
  396. solstone/think/detect_transcript_json.schema.json +24 -0
  397. solstone/think/detect_transcript_segment.md +27 -0
  398. solstone/think/detect_transcript_segment.schema.json +14 -0
  399. solstone/think/doctor.py +928 -0
  400. solstone/think/engage.py +105 -0
  401. solstone/think/entities/__init__.py +200 -0
  402. solstone/think/entities/activity.py +280 -0
  403. solstone/think/entities/consolidation.py +158 -0
  404. solstone/think/entities/context.py +127 -0
  405. solstone/think/entities/core.py +226 -0
  406. solstone/think/entities/formatting.py +289 -0
  407. solstone/think/entities/journal.py +418 -0
  408. solstone/think/entities/loading.py +463 -0
  409. solstone/think/entities/matching.py +627 -0
  410. solstone/think/entities/merge.py +732 -0
  411. solstone/think/entities/observations.py +230 -0
  412. solstone/think/entities/relationships.py +289 -0
  413. solstone/think/entities/saving.py +315 -0
  414. solstone/think/entities/seeding.py +109 -0
  415. solstone/think/entities/voiceprints.py +189 -0
  416. solstone/think/event_formatter.py +166 -0
  417. solstone/think/facets.py +1271 -0
  418. solstone/think/formatters.py +414 -0
  419. solstone/think/health_cli.py +155 -0
  420. solstone/think/heartbeat.py +147 -0
  421. solstone/think/identity.py +489 -0
  422. solstone/think/importers/__init__.py +2 -0
  423. solstone/think/importers/audio.py +194 -0
  424. solstone/think/importers/chatgpt.py +332 -0
  425. solstone/think/importers/claude_chat.py +290 -0
  426. solstone/think/importers/cli.py +1363 -0
  427. solstone/think/importers/documents.py +328 -0
  428. solstone/think/importers/file_importer.py +128 -0
  429. solstone/think/importers/formatting.py +281 -0
  430. solstone/think/importers/gemini.py +388 -0
  431. solstone/think/importers/granola.py +500 -0
  432. solstone/think/importers/ics.py +599 -0
  433. solstone/think/importers/journal_archive.py +691 -0
  434. solstone/think/importers/journal_source_cli.py +308 -0
  435. solstone/think/importers/kindle.py +429 -0
  436. solstone/think/importers/obsidian.py +737 -0
  437. solstone/think/importers/plaud.py +579 -0
  438. solstone/think/importers/shared.py +684 -0
  439. solstone/think/importers/sync.py +83 -0
  440. solstone/think/importers/text.py +151 -0
  441. solstone/think/importers/utils.py +666 -0
  442. solstone/think/indexer/__init__.py +41 -0
  443. solstone/think/indexer/__main__.py +9 -0
  444. solstone/think/indexer/cli.py +225 -0
  445. solstone/think/indexer/journal.py +2748 -0
  446. solstone/think/install_guard.py +423 -0
  447. solstone/think/install_models.py +641 -0
  448. solstone/think/journal_default.json +66 -0
  449. solstone/think/journal_export.py +129 -0
  450. solstone/think/journal_stats.py +554 -0
  451. solstone/think/link/__init__.py +24 -0
  452. solstone/think/link/__main__.py +9 -0
  453. solstone/think/link/auth.py +194 -0
  454. solstone/think/link/ca.py +254 -0
  455. solstone/think/link/framing.py +187 -0
  456. solstone/think/link/mux.py +290 -0
  457. solstone/think/link/nonces.py +176 -0
  458. solstone/think/link/paths.py +164 -0
  459. solstone/think/link/relay_client.py +391 -0
  460. solstone/think/link/service.py +130 -0
  461. solstone/think/link/tcp_pipe.py +137 -0
  462. solstone/think/link/tls_adapter.py +199 -0
  463. solstone/think/logs_cli.py +321 -0
  464. solstone/think/maint.py +463 -0
  465. solstone/think/markdown.py +402 -0
  466. solstone/think/media.py +25 -0
  467. solstone/think/merge.py +932 -0
  468. solstone/think/models.py +1519 -0
  469. solstone/think/notify_cli.py +67 -0
  470. solstone/think/pairing/__init__.py +4 -0
  471. solstone/think/pairing/config.py +90 -0
  472. solstone/think/pairing/devices.py +209 -0
  473. solstone/think/pairing/keys.py +55 -0
  474. solstone/think/pairing/tokens.py +105 -0
  475. solstone/think/password_cli.py +67 -0
  476. solstone/think/pipeline_health.py +185 -0
  477. solstone/think/planner.md +133 -0
  478. solstone/think/planner.py +26 -0
  479. solstone/think/policies/cogitate.toml +32 -0
  480. solstone/think/prompts.py +409 -0
  481. solstone/think/providers/__init__.py +257 -0
  482. solstone/think/providers/anthropic.py +739 -0
  483. solstone/think/providers/cli.py +820 -0
  484. solstone/think/providers/google.py +934 -0
  485. solstone/think/providers/ollama.py +620 -0
  486. solstone/think/providers/openai.py +532 -0
  487. solstone/think/providers/shared.py +246 -0
  488. solstone/think/providers_cli.py +337 -0
  489. solstone/think/push/__init__.py +20 -0
  490. solstone/think/push/config.py +92 -0
  491. solstone/think/push/devices.py +153 -0
  492. solstone/think/push/dispatch.py +381 -0
  493. solstone/think/push/runtime.py +145 -0
  494. solstone/think/push/triggers.py +300 -0
  495. solstone/think/retention.py +483 -0
  496. solstone/think/routines.py +552 -0
  497. solstone/think/runner.py +553 -0
  498. solstone/think/scheduler.py +668 -0
  499. solstone/think/segment.py +878 -0
  500. solstone/think/sense_splitter.py +86 -0
  501. solstone/think/service.py +589 -0
  502. solstone/think/setup.py +1236 -0
  503. solstone/think/skills.py +212 -0
  504. solstone/think/skills_cli.py +614 -0
  505. solstone/think/sol_cli.py +347 -0
  506. solstone/think/stats_schema.py +78 -0
  507. solstone/think/streams.py +439 -0
  508. solstone/think/supervisor.py +2015 -0
  509. solstone/think/surfaces/__init__.py +2 -0
  510. solstone/think/surfaces/health.py +518 -0
  511. solstone/think/surfaces/ledger.py +620 -0
  512. solstone/think/surfaces/profile.py +281 -0
  513. solstone/think/surfaces/types.py +127 -0
  514. solstone/think/talent.py +731 -0
  515. solstone/think/talent_cli.py +1244 -0
  516. solstone/think/talents.py +1382 -0
  517. solstone/think/templates/activity_preamble.md +7 -0
  518. solstone/think/templates/daily_preamble.md +3 -0
  519. solstone/think/templates/segment_preamble.md +3 -0
  520. solstone/think/thinking.py +3365 -0
  521. solstone/think/tools/__init__.py +2 -0
  522. solstone/think/tools/call.py +1378 -0
  523. solstone/think/tools/facets.py +127 -0
  524. solstone/think/tools/health.py +182 -0
  525. solstone/think/tools/journal_merge.py +11 -0
  526. solstone/think/tools/ledger.py +188 -0
  527. solstone/think/tools/navigate.py +42 -0
  528. solstone/think/tools/profile.py +195 -0
  529. solstone/think/tools/routines.py +441 -0
  530. solstone/think/tools/search.py +201 -0
  531. solstone/think/tools/sol.py +410 -0
  532. solstone/think/top.py +1031 -0
  533. solstone/think/user_config.py +57 -0
  534. solstone/think/utils.py +1076 -0
  535. solstone/think/voice/__init__.py +24 -0
  536. solstone/think/voice/brain.py +397 -0
  537. solstone/think/voice/config.py +51 -0
  538. solstone/think/voice/nav_queue.py +93 -0
  539. solstone/think/voice/observer_queue.py +102 -0
  540. solstone/think/voice/runtime.py +127 -0
  541. solstone/think/voice/sideband.py +61 -0
  542. solstone/think/voice/tools.py +759 -0
  543. solstone-0.1.1.dist-info/METADATA +214 -0
  544. solstone-0.1.1.dist-info/RECORD +548 -0
  545. solstone-0.1.1.dist-info/WHEEL +5 -0
  546. solstone-0.1.1.dist-info/entry_points.txt +2 -0
  547. solstone-0.1.1.dist-info/licenses/LICENSE +661 -0
  548. solstone-0.1.1.dist-info/top_level.txt +1 -0
solstone/__init__.py ADDED
@@ -0,0 +1,4 @@
1
+ # SPDX-License-Identifier: AGPL-3.0-only
2
+ # Copyright (c) 2026 sol pbc
3
+
4
+ """solstone namespace package."""
@@ -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
+ )