interlatch 0.23.2__tar.gz → 0.23.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (403) hide show
  1. {interlatch-0.23.2 → interlatch-0.23.3}/.pre-commit-config.yaml +1 -1
  2. {interlatch-0.23.2 → interlatch-0.23.3}/CHANGELOG.md +14 -0
  3. {interlatch-0.23.2 → interlatch-0.23.3}/CONTRIBUTING.md +2 -2
  4. {interlatch-0.23.2 → interlatch-0.23.3}/PKG-INFO +1 -1
  5. interlatch-0.23.3/changelog.d/gemini-prices.md +3 -0
  6. interlatch-0.23.3/changelog.d/home-agents.md +4 -0
  7. interlatch-0.23.3/changelog.d/python-package.md +3 -0
  8. {interlatch-0.23.2 → interlatch-0.23.3}/dev.sh +1 -1
  9. {interlatch-0.23.2 → interlatch-0.23.3}/docs/analysis.md +2 -1
  10. {interlatch-0.23.2 → interlatch-0.23.3}/docs/dashboard.md +4 -2
  11. {interlatch-0.23.2 → interlatch-0.23.3}/docs/demo/make_demo.py +2 -2
  12. {interlatch-0.23.2 → interlatch-0.23.3}/docs/demo/record_demo.py +1 -1
  13. {interlatch-0.23.2 → interlatch-0.23.3}/docs/development.md +33 -8
  14. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/development.md +30 -6
  15. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/privacy.md +1 -1
  16. {interlatch-0.23.2 → interlatch-0.23.3}/docs/privacy.md +1 -1
  17. {interlatch-0.23.2 → interlatch-0.23.3}/docs/sources.md +3 -1
  18. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/README.md +1 -1
  19. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/render.py +2 -2
  20. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/Interlatch.spec +7 -7
  21. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/icon-blueprint-prompt.md +2 -2
  22. interlatch-0.23.2/packaging/macos/chronicle_app.py → interlatch-0.23.3/packaging/macos/interlatch_app.py +2 -2
  23. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/make_icon.py +1 -1
  24. {interlatch-0.23.2 → interlatch-0.23.3}/pyproject.toml +3 -3
  25. interlatch-0.23.3/src/chronicle/__init__.py +8 -0
  26. interlatch-0.23.3/src/chronicle/__main__.py +3 -0
  27. interlatch-0.23.3/src/chronicle/windows.py +11 -0
  28. interlatch-0.23.3/src/interlatch/__main__.py +3 -0
  29. interlatch-0.23.3/src/interlatch/analysis/__init__.py +2 -0
  30. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/analysis}/digest.py +3 -3
  31. interlatch-0.23.3/src/interlatch/analysis/language.py +22 -0
  32. interlatch-0.23.3/src/interlatch/analysis/queue.py +132 -0
  33. interlatch-0.23.3/src/interlatch/analysis/runners/__init__.py +2 -0
  34. interlatch-0.23.2/src/chronicle/providers.py → interlatch-0.23.3/src/interlatch/analysis/runners/api.py +15 -134
  35. interlatch-0.23.3/src/interlatch/analysis/runners/base.py +148 -0
  36. interlatch-0.23.3/src/interlatch/analysis/runners/bob.py +121 -0
  37. interlatch-0.23.3/src/interlatch/analysis/runners/claude.py +89 -0
  38. interlatch-0.23.3/src/interlatch/analysis/runners/codex.py +127 -0
  39. interlatch-0.23.3/src/interlatch/analysis/runners/factory.py +25 -0
  40. interlatch-0.23.3/src/interlatch/analysis/runners/process.py +67 -0
  41. interlatch-0.23.3/src/interlatch/analysis/runners/replies.py +38 -0
  42. interlatch-0.23.3/src/interlatch/analysis/runners/settings.py +131 -0
  43. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/analysis}/screen.py +7 -5
  44. interlatch-0.23.2/src/chronicle/analyze.py → interlatch-0.23.3/src/interlatch/analysis/session.py +12 -10
  45. interlatch-0.23.3/src/interlatch/analysis/worker.py +116 -0
  46. interlatch-0.23.3/src/interlatch/application/__init__.py +2 -0
  47. interlatch-0.23.3/src/interlatch/application/records.py +54 -0
  48. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/application}/search.py +5 -5
  49. interlatch-0.23.3/src/interlatch/application/workflows.py +180 -0
  50. interlatch-0.23.3/src/interlatch/artifacts/__init__.py +2 -0
  51. interlatch-0.23.3/src/interlatch/artifacts/files.py +123 -0
  52. interlatch-0.23.3/src/interlatch/artifacts/queries.py +183 -0
  53. interlatch-0.23.3/src/interlatch/cli.py +4 -0
  54. interlatch-0.23.3/src/interlatch/core/__init__.py +2 -0
  55. interlatch-0.23.2/src/chronicle/artifacts.py → interlatch-0.23.3/src/interlatch/core/artifact_records.py +5 -296
  56. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/core}/config.py +3 -3
  57. interlatch-0.23.3/src/interlatch/core/diagrams.py +124 -0
  58. interlatch-0.23.2/src/chronicle/i18n.py → interlatch-0.23.3/src/interlatch/core/i18n/__init__.py +1 -1
  59. interlatch-0.23.3/src/interlatch/core/machine.py +54 -0
  60. interlatch-0.23.3/src/interlatch/core/paths.py +86 -0
  61. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/core}/pricing.py +51 -0
  62. interlatch-0.23.3/src/interlatch/core/process.py +20 -0
  63. interlatch-0.23.3/src/interlatch/core/sessions.py +238 -0
  64. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/core}/util.py +0 -73
  65. interlatch-0.23.3/src/interlatch/ingestion/__init__.py +2 -0
  66. interlatch-0.23.3/src/interlatch/ingestion/analyses.py +75 -0
  67. interlatch-0.23.3/src/interlatch/ingestion/archive.py +176 -0
  68. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/ingestion}/chat_import.py +17 -37
  69. interlatch-0.23.3/src/interlatch/ingestion/deletion.py +76 -0
  70. interlatch-0.23.3/src/interlatch/ingestion/history.py +66 -0
  71. interlatch-0.23.3/src/interlatch/ingestion/memory.py +150 -0
  72. interlatch-0.23.3/src/interlatch/ingestion/persistence.py +274 -0
  73. interlatch-0.23.3/src/interlatch/ingestion/report.py +30 -0
  74. interlatch-0.23.3/src/interlatch/ingestion/service.py +485 -0
  75. interlatch-0.23.3/src/interlatch/interfaces/__init__.py +2 -0
  76. interlatch-0.23.3/src/interlatch/interfaces/cli/__init__.py +2 -0
  77. interlatch-0.23.3/src/interlatch/interfaces/cli/commands/__init__.py +3 -0
  78. interlatch-0.23.3/src/interlatch/interfaces/cli/commands/archive.py +311 -0
  79. interlatch-0.23.3/src/interlatch/interfaces/cli/commands/knowledge.py +599 -0
  80. interlatch-0.23.3/src/interlatch/interfaces/cli/commands/operations.py +259 -0
  81. interlatch-0.23.3/src/interlatch/interfaces/cli/commands/recording.py +312 -0
  82. interlatch-0.23.3/src/interlatch/interfaces/cli/commands/setup.py +679 -0
  83. interlatch-0.23.3/src/interlatch/interfaces/cli/commands/sharing.py +913 -0
  84. interlatch-0.23.3/src/interlatch/interfaces/cli/common.py +85 -0
  85. interlatch-0.23.3/src/interlatch/interfaces/cli/main.py +52 -0
  86. interlatch-0.23.3/src/interlatch/interfaces/cli/parser.py +45 -0
  87. interlatch-0.23.3/src/interlatch/interfaces/exports/__init__.py +1 -0
  88. interlatch-0.23.2/src/chronicle/diagram.py → interlatch-0.23.3/src/interlatch/interfaces/exports/diagrams.py +13 -129
  89. interlatch-0.23.2/src/chronicle/views.py → interlatch-0.23.3/src/interlatch/interfaces/exports/markdown.py +5 -85
  90. interlatch-0.23.2/src/chronicle/session_export.py → interlatch-0.23.3/src/interlatch/interfaces/exports/sessions.py +7 -6
  91. interlatch-0.23.2/src/chronicle/export_md.py → interlatch-0.23.3/src/interlatch/interfaces/exports/vault.py +9 -7
  92. interlatch-0.23.2/src/chronicle/mcp_server.py → interlatch-0.23.3/src/interlatch/interfaces/mcp.py +19 -17
  93. interlatch-0.23.3/src/interlatch/knowledge/__init__.py +2 -0
  94. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/cases.py +1 -1
  95. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/friction.py +2 -2
  96. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/glossary.py +11 -9
  97. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/instructions.py +8 -8
  98. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/ladder.py +2 -2
  99. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/learning.py +3 -3
  100. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/reviews.py +7 -5
  101. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/suggest.py +4 -4
  102. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/synthesize.py +6 -4
  103. interlatch-0.23.3/src/interlatch/projects/__init__.py +2 -0
  104. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/projects}/groups.py +3 -3
  105. interlatch-0.23.3/src/interlatch/projects/labels.py +17 -0
  106. interlatch-0.23.3/src/interlatch/projects/routing.py +201 -0
  107. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/projects}/systems.py +2 -2
  108. interlatch-0.23.3/src/interlatch/runtime/__init__.py +2 -0
  109. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/connectors.py +14 -36
  110. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/container.py +19 -17
  111. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/hooks.py +10 -21
  112. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/install.py +18 -17
  113. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/migrate.py +12 -10
  114. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/notify.py +3 -3
  115. interlatch-0.23.3/src/interlatch/runtime/platforms/__init__.py +2 -0
  116. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime/platforms}/desktop.py +21 -19
  117. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime/platforms}/menubar.py +15 -14
  118. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime/platforms}/windows.py +8 -8
  119. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/statusline.py +4 -4
  120. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/update.py +7 -7
  121. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/server.py +272 -213
  122. interlatch-0.23.3/src/interlatch/sharing/__init__.py +20 -0
  123. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/sharing}/access.py +1 -1
  124. interlatch-0.23.3/src/interlatch/sharing/client.py +400 -0
  125. interlatch-0.23.3/src/interlatch/sharing/identity.py +91 -0
  126. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/sharing}/leaderboard.py +4 -4
  127. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/sharing}/news.py +2 -2
  128. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/sharing}/people.py +3 -2
  129. interlatch-0.23.3/src/interlatch/sharing/projects.py +370 -0
  130. interlatch-0.23.3/src/interlatch/sharing/protocol.py +111 -0
  131. interlatch-0.23.3/src/interlatch/sharing/pull.py +162 -0
  132. interlatch-0.23.3/src/interlatch/sharing/push.py +320 -0
  133. interlatch-0.23.3/src/interlatch/sharing/receiver.py +620 -0
  134. interlatch-0.23.3/src/interlatch/sources/__init__.py +2 -0
  135. interlatch-0.23.2/src/chronicle/antigravity_parser.py → interlatch-0.23.3/src/interlatch/sources/antigravity.py +6 -6
  136. interlatch-0.23.2/src/chronicle/bob_parser.py → interlatch-0.23.3/src/interlatch/sources/bob.py +10 -10
  137. interlatch-0.23.3/src/interlatch/sources/builder.py +179 -0
  138. interlatch-0.23.2/src/chronicle/chatgpt_export.py → interlatch-0.23.3/src/interlatch/sources/chatgpt.py +4 -4
  139. interlatch-0.23.3/src/interlatch/sources/chats.py +33 -0
  140. interlatch-0.23.3/src/interlatch/sources/claude/__init__.py +1 -0
  141. interlatch-0.23.2/src/chronicle/claude_export.py → interlatch-0.23.3/src/interlatch/sources/claude/export.py +7 -7
  142. interlatch-0.23.3/src/interlatch/sources/claude/files.py +71 -0
  143. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/sources/claude}/parser.py +10 -242
  144. interlatch-0.23.3/src/interlatch/sources/codex/__init__.py +1 -0
  145. interlatch-0.23.2/src/chronicle/codex_cloud.py → interlatch-0.23.3/src/interlatch/sources/codex/cloud.py +7 -7
  146. interlatch-0.23.2/src/chronicle/codex_parser.py → interlatch-0.23.3/src/interlatch/sources/codex/parser.py +9 -20
  147. interlatch-0.23.2/src/chronicle/copilot_parser.py → interlatch-0.23.3/src/interlatch/sources/copilot.py +9 -174
  148. interlatch-0.23.3/src/interlatch/sources/discovery.py +39 -0
  149. interlatch-0.23.3/src/interlatch/sources/prompts.py +23 -0
  150. interlatch-0.23.3/src/interlatch/storage/__init__.py +2 -0
  151. interlatch-0.23.3/src/interlatch/storage/fts.py +21 -0
  152. interlatch-0.23.3/src/interlatch/storage/kv.py +17 -0
  153. interlatch-0.23.3/src/interlatch/storage/migrations.py +66 -0
  154. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/storage}/mirror.py +8 -7
  155. interlatch-0.23.2/src/chronicle/db.py → interlatch-0.23.3/src/interlatch/storage/schema.py +1 -112
  156. interlatch-0.23.3/src/interlatch/storage/sqlite.py +33 -0
  157. interlatch-0.23.2/src/chronicle/team_store.py → interlatch-0.23.3/src/interlatch/storage/team.py +4 -4
  158. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/app.css +17 -0
  159. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/app.js +89 -8
  160. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/ja.js +6 -0
  161. interlatch-0.23.3/src/interlatch/windows.py +10 -0
  162. {interlatch-0.23.2 → interlatch-0.23.3}/tests/conftest.py +5 -5
  163. {interlatch-0.23.2 → interlatch-0.23.3}/tests/friction_fixture.py +5 -5
  164. {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/parsers/antigravity.json +4 -4
  165. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_analysis.py +31 -25
  166. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_antigravity.py +7 -7
  167. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_artifacts.py +21 -20
  168. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_bob_analysis.py +11 -9
  169. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_boot_web.py +1 -1
  170. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_case_files.py +5 -4
  171. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_cases.py +6 -6
  172. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_chat_import.py +9 -7
  173. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_cli_pins.py +4 -4
  174. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_codex.py +6 -6
  175. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_codex_analysis.py +9 -6
  176. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_codex_cloud.py +6 -6
  177. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_container.py +13 -10
  178. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_copilot_bob.py +11 -11
  179. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_dedicated_hub.py +1 -1
  180. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_dedupe.py +3 -3
  181. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_desktop.py +11 -11
  182. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_diagram.py +5 -4
  183. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_ee_boundary.py +3 -3
  184. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_friction.py +1 -1
  185. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_glossary.py +9 -9
  186. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_group_sharing.py +25 -20
  187. interlatch-0.23.3/tests/test_home_agents.py +59 -0
  188. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_hub.py +105 -94
  189. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_hub_accept.py +7 -5
  190. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_hub_news.py +17 -13
  191. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_hub_projects.py +44 -36
  192. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_hub_projects_listed.py +7 -7
  193. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_hub_purge.py +24 -18
  194. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_hub_sharing_race.py +25 -19
  195. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_i18n_web.py +1 -1
  196. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_ingest.py +9 -7
  197. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_instructions.py +9 -9
  198. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_integration.py +21 -21
  199. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_ladder.py +7 -6
  200. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_language.py +36 -29
  201. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_leaderboard.py +8 -7
  202. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_learning_glance.py +3 -3
  203. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_learning_interests.py +7 -5
  204. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_learning_web.py +1 -1
  205. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_leave_project.py +41 -33
  206. interlatch-0.23.3/tests/test_legacy_package.py +39 -0
  207. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_map_goldens.py +3 -2
  208. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_menubar.py +41 -35
  209. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_migrate.py +21 -20
  210. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_mirror.py +8 -8
  211. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_notify.py +11 -11
  212. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_parser.py +19 -2
  213. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_parser_goldens.py +7 -6
  214. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_people.py +2 -2
  215. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_people_hub.py +59 -54
  216. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_people_web.py +12 -9
  217. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_project_groups.py +4 -3
  218. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_providers.py +11 -9
  219. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_queue.py +9 -9
  220. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_regressions.py +10 -9
  221. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_release.py +3 -3
  222. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_route_matrix.py +11 -8
  223. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_screen.py +5 -5
  224. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_security.py +52 -45
  225. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_setup.py +26 -26
  226. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_statusline.py +6 -6
  227. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_suggest.py +5 -4
  228. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_suggest_cli.py +9 -9
  229. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_systems.py +3 -3
  230. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_team.py +31 -25
  231. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_team_home.py +6 -5
  232. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_update.py +8 -7
  233. {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_windows.py +29 -24
  234. interlatch-0.23.2/changelog.d/agent-icons.md +0 -3
  235. interlatch-0.23.2/changelog.d/devices-admin-only.md +0 -3
  236. interlatch-0.23.2/changelog.d/windows-polish.md +0 -5
  237. interlatch-0.23.2/src/chronicle/__main__.py +0 -3
  238. interlatch-0.23.2/src/chronicle/cli.py +0 -3058
  239. interlatch-0.23.2/src/chronicle/hub.py +0 -2308
  240. interlatch-0.23.2/src/chronicle/ingest.py +0 -1190
  241. interlatch-0.23.2/src/chronicle/llm.py +0 -577
  242. interlatch-0.23.2/src/chronicle/worker.py +0 -390
  243. {interlatch-0.23.2 → interlatch-0.23.3}/.github/dependabot.yml +0 -0
  244. {interlatch-0.23.2 → interlatch-0.23.3}/.github/workflows/changelog.yml +0 -0
  245. {interlatch-0.23.2 → interlatch-0.23.3}/.github/workflows/ci.yml +0 -0
  246. {interlatch-0.23.2 → interlatch-0.23.3}/.github/workflows/docs.yml +0 -0
  247. {interlatch-0.23.2 → interlatch-0.23.3}/.github/workflows/release.yml +0 -0
  248. {interlatch-0.23.2 → interlatch-0.23.3}/.gitignore +0 -0
  249. {interlatch-0.23.2 → interlatch-0.23.3}/.python-version +0 -0
  250. {interlatch-0.23.2 → interlatch-0.23.3}/LICENSE +0 -0
  251. {interlatch-0.23.2 → interlatch-0.23.3}/README.ja.md +0 -0
  252. {interlatch-0.23.2 → interlatch-0.23.3}/README.md +0 -0
  253. {interlatch-0.23.2 → interlatch-0.23.3}/ROADMAP.ja.md +0 -0
  254. {interlatch-0.23.2 → interlatch-0.23.3}/ROADMAP.md +0 -0
  255. {interlatch-0.23.2 → interlatch-0.23.3}/SECURITY.md +0 -0
  256. {interlatch-0.23.2 → interlatch-0.23.3}/changelog.d/README.md +0 -0
  257. {interlatch-0.23.2 → interlatch-0.23.3}/docker/.dockerignore +0 -0
  258. {interlatch-0.23.2 → interlatch-0.23.3}/docker/.env.example +0 -0
  259. {interlatch-0.23.2 → interlatch-0.23.3}/docker/Caddyfile +0 -0
  260. {interlatch-0.23.2 → interlatch-0.23.3}/docker/Dockerfile +0 -0
  261. {interlatch-0.23.2 → interlatch-0.23.3}/docker/compose.yaml +0 -0
  262. {interlatch-0.23.2 → interlatch-0.23.3}/docker/wheels/.gitignore +0 -0
  263. {interlatch-0.23.2 → interlatch-0.23.3}/docs/README.md +0 -0
  264. {interlatch-0.23.2 → interlatch-0.23.3}/docs/_site/hooks.py +0 -0
  265. {interlatch-0.23.2 → interlatch-0.23.3}/docs/cli.md +0 -0
  266. {interlatch-0.23.2 → interlatch-0.23.3}/docs/configuration.md +0 -0
  267. {interlatch-0.23.2 → interlatch-0.23.3}/docs/design/ja/learning.md +0 -0
  268. {interlatch-0.23.2 → interlatch-0.23.3}/docs/design/learning.md +0 -0
  269. {interlatch-0.23.2 → interlatch-0.23.3}/docs/devices.md +0 -0
  270. {interlatch-0.23.2 → interlatch-0.23.3}/docs/diagrams/analysis.excalidraw.svg +0 -0
  271. {interlatch-0.23.2 → interlatch-0.23.3}/docs/diagrams/architecture.excalidraw.svg +0 -0
  272. {interlatch-0.23.2 → interlatch-0.23.3}/docs/docker.md +0 -0
  273. {interlatch-0.23.2 → interlatch-0.23.3}/docs/images/demo.gif +0 -0
  274. {interlatch-0.23.2 → interlatch-0.23.3}/docs/images/home.png +0 -0
  275. {interlatch-0.23.2 → interlatch-0.23.3}/docs/images/map.png +0 -0
  276. {interlatch-0.23.2 → interlatch-0.23.3}/docs/images/palette.png +0 -0
  277. {interlatch-0.23.2 → interlatch-0.23.3}/docs/images/session.png +0 -0
  278. {interlatch-0.23.2 → interlatch-0.23.3}/docs/install.md +0 -0
  279. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/README.md +0 -0
  280. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/analysis.md +0 -0
  281. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/cli.md +0 -0
  282. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/configuration.md +0 -0
  283. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/dashboard.md +0 -0
  284. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/devices.md +0 -0
  285. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/docker.md +0 -0
  286. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/install.md +0 -0
  287. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/join-a-hub.md +0 -0
  288. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/mcp.md +0 -0
  289. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/moving-from-chronicle.md +0 -0
  290. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/postgres.md +0 -0
  291. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/sources.md +0 -0
  292. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/suggestions.md +0 -0
  293. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/troubleshooting.md +0 -0
  294. {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/vscode.md +0 -0
  295. {interlatch-0.23.2 → interlatch-0.23.3}/docs/join-a-hub.md +0 -0
  296. {interlatch-0.23.2 → interlatch-0.23.3}/docs/mcp.md +0 -0
  297. {interlatch-0.23.2 → interlatch-0.23.3}/docs/moving-from-chronicle.md +0 -0
  298. {interlatch-0.23.2 → interlatch-0.23.3}/docs/postgres.md +0 -0
  299. {interlatch-0.23.2 → interlatch-0.23.3}/docs/suggestions.md +0 -0
  300. {interlatch-0.23.2 → interlatch-0.23.3}/docs/troubleshooting.md +0 -0
  301. {interlatch-0.23.2 → interlatch-0.23.3}/docs/vscode.md +0 -0
  302. {interlatch-0.23.2 → interlatch-0.23.3}/leaderboard/.firebaserc +0 -0
  303. {interlatch-0.23.2 → interlatch-0.23.3}/leaderboard/.gitignore +0 -0
  304. {interlatch-0.23.2 → interlatch-0.23.3}/leaderboard/README.md +0 -0
  305. {interlatch-0.23.2 → interlatch-0.23.3}/leaderboard/firebase.json +0 -0
  306. {interlatch-0.23.2 → interlatch-0.23.3}/leaderboard/firestore.indexes.json +0 -0
  307. {interlatch-0.23.2 → interlatch-0.23.3}/leaderboard/firestore.rules +0 -0
  308. {interlatch-0.23.2 → interlatch-0.23.3}/mkdocs.yml +0 -0
  309. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/art.json +0 -0
  310. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/filing.html +0 -0
  311. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/loops.json +0 -0
  312. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/loops.py +0 -0
  313. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/members.js +0 -0
  314. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/render.html +0 -0
  315. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/scenes-more.js +0 -0
  316. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/scenes.html +0 -0
  317. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/Chronicle.icns +0 -0
  318. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/build.sh +0 -0
  319. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/entitlements.plist +0 -0
  320. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/icon-3d.webp +0 -0
  321. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/icon-blueprint.webp +0 -0
  322. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/icon.png +0 -0
  323. {interlatch-0.23.2 → interlatch-0.23.3}/packaging/release.py +0 -0
  324. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/__init__.py +0 -0
  325. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/core}/agents.py +0 -0
  326. /interlatch-0.23.2/src/chronicle/i18n_ja.py → /interlatch-0.23.3/src/interlatch/core/i18n/ja.py +0 -0
  327. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/core}/redact.py +0 -0
  328. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/tailnet.py +0 -0
  329. /interlatch-0.23.2/src/chronicle/pg.py → /interlatch-0.23.3/src/interlatch/storage/postgres.py +0 -0
  330. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/AGENT-ICONS.txt +0 -0
  331. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/PLEX-OFL.txt +0 -0
  332. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/agent-antigravity.svg +0 -0
  333. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/agent-bob.svg +0 -0
  334. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/agent-chatgpt.svg +0 -0
  335. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/agent-claude-ai.svg +0 -0
  336. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/agent-claude.svg +0 -0
  337. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/agent-codex.svg +0 -0
  338. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/agent-copilot.svg +0 -0
  339. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-book.webp +0 -0
  340. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-camera.webp +0 -0
  341. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-chip.webp +0 -0
  342. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-clock.webp +0 -0
  343. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-cloud.webp +0 -0
  344. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-coins.webp +0 -0
  345. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-container.webp +0 -0
  346. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-dashboard.webp +0 -0
  347. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-dex.webp +0 -0
  348. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-document.webp +0 -0
  349. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-flag.webp +0 -0
  350. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-folder.webp +0 -0
  351. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-gateway.webp +0 -0
  352. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-gears.webp +0 -0
  353. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-glitch.webp +0 -0
  354. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-globe.webp +0 -0
  355. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-laptop.webp +0 -0
  356. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-log.webp +0 -0
  357. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-lumi.webp +0 -0
  358. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-magnifier.webp +0 -0
  359. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-pip.webp +0 -0
  360. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-plug.webp +0 -0
  361. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-rack.webp +0 -0
  362. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-tink.webp +0 -0
  363. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/boot.js +0 -0
  364. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/favicon.png +0 -0
  365. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/i18n.js +0 -0
  366. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/icon-180.png +0 -0
  367. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/icon-192.png +0 -0
  368. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/icon-512.png +0 -0
  369. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/icon.png +0 -0
  370. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/index.html +0 -0
  371. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/learning.js +0 -0
  372. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/manifest.webmanifest +0 -0
  373. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/panel.css +0 -0
  374. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/panel.html +0 -0
  375. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/panel.js +0 -0
  376. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/plex-mono-400.woff2 +0 -0
  377. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/plex-mono-500.woff2 +0 -0
  378. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/plex-mono-600.woff2 +0 -0
  379. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/plex-sans-400.woff2 +0 -0
  380. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/plex-sans-500.woff2 +0 -0
  381. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/plex-sans-600.woff2 +0 -0
  382. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/plex-sans-700.woff2 +0 -0
  383. {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/rough.js +0 -0
  384. {interlatch-0.23.2 → interlatch-0.23.3}/tests/antigravity_fixture.py +0 -0
  385. {interlatch-0.23.2 → interlatch-0.23.3}/tests/codex_fixture.py +0 -0
  386. {interlatch-0.23.2 → interlatch-0.23.3}/tests/copilot_fixture.py +0 -0
  387. {interlatch-0.23.2 → interlatch-0.23.3}/tests/golden.py +0 -0
  388. {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/cli.json +0 -0
  389. {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/diagram.json +0 -0
  390. {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/parsers/bob.json +0 -0
  391. {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/parsers/claude_code.json +0 -0
  392. {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/parsers/codex.json +0 -0
  393. {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/parsers/copilot.json +0 -0
  394. {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/systems.json +0 -0
  395. {interlatch-0.23.2 → interlatch-0.23.3}/tests/windows_smoke.py +0 -0
  396. {interlatch-0.23.2 → interlatch-0.23.3}/uv.lock +0 -0
  397. {interlatch-0.23.2 → interlatch-0.23.3}/vscode-extension/.vscodeignore +0 -0
  398. {interlatch-0.23.2 → interlatch-0.23.3}/vscode-extension/LICENSE +0 -0
  399. {interlatch-0.23.2 → interlatch-0.23.3}/vscode-extension/README.md +0 -0
  400. {interlatch-0.23.2 → interlatch-0.23.3}/vscode-extension/extension.js +0 -0
  401. {interlatch-0.23.2 → interlatch-0.23.3}/vscode-extension/media/icon.png +0 -0
  402. {interlatch-0.23.2 → interlatch-0.23.3}/vscode-extension/media/interlatch.svg +0 -0
  403. {interlatch-0.23.2 → interlatch-0.23.3}/vscode-extension/package.json +0 -0
@@ -45,4 +45,4 @@ repos:
45
45
  name: node --check (dashboard and VS Code extension JavaScript parses)
46
46
  language: system
47
47
  entry: node --check
48
- files: ^(src/chronicle/web|vscode-extension)/.*\.js$
48
+ files: ^(src/interlatch/web|vscode-extension)/.*\.js$
@@ -3,6 +3,20 @@
3
3
  <!-- Don't add lines here: a pull request puts its line in a new file in changelog.d/ (see changelog.d/README.md),
4
4
  and each release moves the files it took into a dated section below. -->
5
5
 
6
+ ## 0.23.2 (2026-10-14)
7
+
8
+ - **Hub computers stay with admins:** on a hub with people, a member or read-only person no longer receives the hub's
9
+ computers, its team store's database, host and status, or its allowed sign-ins; only admins (and the hub computer
10
+ itself) do.
11
+ - **Agent logos:** the Sessions list and its agent filter, Sources, MCP and the menu-bar panel mark each session and
12
+ source with its agent's own logo (Claude Code, Codex, GitHub Copilot, IBM Bob, Google Antigravity, claude.ai,
13
+ ChatGPT) instead of a colour dot.
14
+ - **Windows polish:** The dashboard can show an Interlatch icon in the notification area (turn on the menu-bar icon
15
+ under **Status › Recording**, or run `interlatch ui --menu-bar`): click it to open the dashboard, right-click for Sync
16
+ Now and Quit, which stops the dashboard until you next sign in. Release notifications show as Windows toasts. The VS
17
+ Code extension's file history and folder list, hub folders and projects, and a person's projects now match Windows
18
+ paths however they're spelled (`C:\work\app`, `c:/work/app`).
19
+
6
20
  ## 0.23.1 (2026-10-13)
7
21
 
8
22
  - **`agents-chronicle` is retired:** Interlatch is published only as `interlatch` now, and `agents-chronicle` is no
@@ -4,9 +4,9 @@ Thanks for helping. Interlatch is a small Python project with no build step for
4
4
 
5
5
  1. `uv sync && uv run pytest -q` runs the tests in about 40 seconds. They use a fake `claude` binary and synthetic
6
6
  Codex, Copilot, Bob and Antigravity stores, so they never touch your real data or spend tokens.
7
- 2. `uv run python -m chronicle ui --port 8799` serves the dashboard from your checkout. To work on it without your
7
+ 2. `uv run python -m interlatch ui --port 8799` serves the dashboard from your checkout. To work on it without your
8
8
  own sessions, build the demo home first (see [Demo data](docs/development.md#demo-data)).
9
- 3. `uv run --extra app python -m chronicle app` runs the macOS app from the checkout.
9
+ 3. `uv run --extra app python -m interlatch app` runs the macOS app from the checkout.
10
10
  4. `uvx pre-commit install` checks each commit the way CI does: secrets, `ruff check`, the lockfile, the workflows
11
11
  ([Pre-commit hooks](docs/development.md#pre-commit-hooks)).
12
12
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: interlatch
3
- Version: 0.23.2
3
+ Version: 0.23.3
4
4
  Summary: Shared memory for your coding agents: records every session (Claude Code, Codex, Copilot, Bob, Antigravity) locally and keeps what they learned, each lesson linked to the session it came from.
5
5
  Project-URL: Homepage, https://interlatch.com
6
6
  Project-URL: Documentation, https://interlatch.com/docs/
@@ -0,0 +1,3 @@
1
+ - **Gemini costs:** Google Antigravity sessions, and GitHub Copilot sessions on Gemini models, now show an estimated
2
+ cost at Google's Gemini API list prices instead of $0 ([Sources](docs/sources.md)). The next sync re-prices the
3
+ sessions already recorded. Analysis through an OpenAI-compatible provider on a Gemini model is priced the same way.
@@ -0,0 +1,4 @@
1
+ - **Agents on Home:** a table with one row per coding agent: whether it is connected (or imported, or has issues),
2
+ when it was last used, and its sessions, active time, prompts, tool calls, lines changed, tokens, est. cost and
3
+ knowledge for the period, each with an inline bar. A dash marks what an agent doesn't record (a ChatGPT export has
4
+ no tokens); click a row to see only that agent, or its status to open it in **Sources**.
@@ -0,0 +1,3 @@
1
+ - **`python -m interlatch`:** Interlatch's Python package is now `interlatch` too, so it runs as `python -m interlatch`.
2
+ Hooks, background tasks and MCP servers set up with `python -m chronicle` keep working, as does the `chronicle`
3
+ command.
@@ -39,7 +39,7 @@ while [ $# -gt 0 ]; do
39
39
  shift
40
40
  done
41
41
 
42
- [ -f "$TREE/pyproject.toml" ] && [ -d "$TREE/src/chronicle" ] || { echo "dev.sh: $TREE is not an Interlatch checkout" >&2; exit 1; }
42
+ [ -f "$TREE/pyproject.toml" ] && { [ -d "$TREE/src/interlatch" ] || [ -d "$TREE/src/chronicle" ]; } || { echo "dev.sh: $TREE is not an Interlatch checkout" >&2; exit 1; }
43
43
 
44
44
  listening() { lsof -nP -iTCP:"$1" -sTCP:LISTEN >/dev/null 2>&1; }
45
45
 
@@ -198,7 +198,8 @@ interlatch config set analysis.backend openai
198
198
  `max_output_tokens`. Anthropic and Bedrock calls send `effort` and allow 32,000 output tokens by default.
199
199
 
200
200
  Cost: with a provider, the cost is what the API reports (OpenRouter) or an estimate from the token counts at
201
- Anthropic's or OpenAI's list prices (Anthropic, Bedrock, OpenAI); Azure, Ollama and other servers show tokens only. Otherwise,
201
+ Anthropic's, OpenAI's or Google's list prices (Anthropic, Bedrock, OpenAI, and Gemini models on an OpenAI-compatible
202
+ server); Azure, Ollama and other models show tokens only. Otherwise,
202
203
  analysis runs through your own Claude Code or Codex login, or your Bob API key (Bob reports what each analysis cost).
203
204
  With Claude, the reported cost is the API
204
205
  list-price equivalent: sessions averaged about $0.38 each with Sonnet (digests average ~150k characters), and
@@ -71,8 +71,10 @@ There is no overdue counter or required backlog. Changed lesson material receive
71
71
  in progress are excluded.
72
72
 
73
73
  Pages: Home (active-time headline with active days and longest run; stat tiles with sparklines and a per-day rate
74
- until a full prior period exists to compare against; daily chart with a 7-day average; outcome breakdown; activity
75
- calendar with streaks; busiest hour; projects, tools with failed calls, models and agents), a sortable, filterable
74
+ until a full prior period exists to compare against; an **Agents** table with each agent's status from Sources, when
75
+ it was last used and its numbers for the period as inline bars, a dash where an agent doesn't record a metric (a chat
76
+ export has no tokens or cost), and a click on a row filtering Home to that agent; daily chart with a 7-day average;
77
+ outcome breakdown; activity calendar with streaks; busiest hour; projects, tools with failed calls and models), a sortable, filterable
76
78
  session list, project cards with 12 weeks of activity (in [your own groups](#project-groups)), the [Systems map](#systems-map), session pages (headline figures, the summary and the knowledge
77
79
  it produced up top, then **Details**, where a session opens: goal, highlights, open threads, the knowledge items,
78
80
  context-window chart with compactions, tools, files, subagents, and the [artifacts](#artifacts) the session made; or
@@ -1,7 +1,7 @@
1
1
  """Build a demo Interlatch home from made-up sessions, for screenshots and trying the dashboard without your own data.
2
2
 
3
3
  uv run python docs/demo/make_demo.py /tmp/interlatch-demo
4
- INTERLATCH_HOME=/tmp/interlatch-demo/home uv run python -m chronicle ui --port 8898 --open
4
+ INTERLATCH_HOME=/tmp/interlatch-demo/home uv run python -m interlatch ui --port 8898 --open
5
5
 
6
6
  It writes synthetic Claude Code transcripts for a fictional developer (five projects, about six weeks), then runs the
7
7
  real pipeline over them: sync, analysis, knowledge bases, glossary and weekly reviews. The only stand-in is `claude`:
@@ -529,7 +529,7 @@ def main() -> None:
529
529
  for w in range(1, WEEKS_REVIEWED + 1):
530
530
  week = (now - timedelta(weeks=w)).strftime("%G-W%V")
531
531
  chronicle("review", week)
532
- print(f"\nDemo ready. Open it with:\n INTERLATCH_HOME={home} uv run python -m chronicle ui --port 8898 --open")
532
+ print(f"\nDemo ready. Open it with:\n INTERLATCH_HOME={home} uv run python -m interlatch ui --port 8898 --open")
533
533
 
534
534
 
535
535
  if __name__ == "__main__":
@@ -1,7 +1,7 @@
1
1
  """Record the README demo video: a scripted walk through the dashboard on the demo data.
2
2
 
3
3
  uv run python docs/demo/make_demo.py /tmp/interlatch-demo
4
- INTERLATCH_HOME=/tmp/interlatch-demo/home uv run python -m chronicle ui --port 8898
4
+ INTERLATCH_HOME=/tmp/interlatch-demo/home uv run python -m interlatch ui --port 8898
5
5
  uv run --with playwright python docs/demo/record_demo.py --port 8898
6
6
 
7
7
  It drives headless Chromium through Home, a session (a glossary hover, an expanded tool call), the ⌘K palette, the
@@ -116,19 +116,44 @@ Excalidraw VS Code extension (`pomdtr.excalidraw-editor`) or on excalidraw.com;
116
116
 
117
117
  ## Code layout
118
118
 
119
- `parser.py` (Claude transcript format), `codex_parser.py` (Codex rollouts), `copilot_parser.py` (Copilot agent
120
- sessions + VS Code chat logs), `bob_parser.py` (Bob tasks), `antigravity_parser.py` (Antigravity step logs), `agents.py` (agent names), `connectors.py` (Sources),
121
- `ingest.py` (archive + store), `digest.py` / `analyze.py` /
122
- `llm.py` (analysis), `synthesize.py` (knowledge bases), `diagram.py` (architecture sketch: layout, Excalidraw and
123
- Mermaid export), `artifacts.py` (what sessions made, and where each stands), `glossary.py`, `reviews.py`, `worker.py` (queue), `server.py` + `web/`
124
- (dashboard), `mcp_server.py`, `export_md.py`, `hooks.py` / `install.py`, `desktop.py` (macOS app), `cli.py`; `packaging/macos/` builds the app.
119
+ The code is the `interlatch` package in `src/interlatch/` (`src/chronicle/` only forwards `python -m chronicle`,
120
+ which installs from before the rename still run):
121
+
122
+ - `core/`: configuration, session records, paths, translations, agent names, pricing, redaction, this computer's
123
+ identity, and what counts as an artifact a session made
124
+ - `storage/`: the SQLite archive (schema, migrations, connections) and the optional Postgres stores
125
+ - `sources/`: where each agent keeps its files (`discovery.py`), a reader per agent (`claude/`, `codex/`, `copilot.py`, `bob.py`, `antigravity.py`) and per chat export
126
+ (`claude/export.py`, `chatgpt.py`)
127
+ - `artifacts/`: what sessions made, where each stands, and opening it
128
+ - `ingestion/`: syncing every source (`service.py`): the raw-file archive, storing parsed sessions, chat imports,
129
+ agent memory and history, forgetting
130
+ - `analysis/`: condensing a transcript (`digest.py`), asking a model for its lessons (`session.py`), screening
131
+ imported chats, the queue and the worker; `analysis/runners/` asks the model, through an agent's CLI or a
132
+ provider's API
133
+ - `knowledge/`: per-project knowledge bases (`synthesize.py`), the maturity ladder, glossaries, case files, learning
134
+ topics, friction, suggestions, instruction files, the weekly review
135
+ - `projects/`: folders that belong together, project names, which project another computer's folder belongs to
136
+ (`routing.py`), the systems map
137
+ - `sharing/`: a hub and the computers that join it: the protocol, tokens, the client and what it pushes and pulls,
138
+ the hub's receiver, projects on the hub, people and what each may see, the Team page's news, the leaderboard
139
+ - `application/`: what a worker run does from start to finish (`workflows.py`), session records and search, which
140
+ span the features
141
+ - `interfaces/`: the MCP server (`mcp.py`) and the files Interlatch exports (`exports/`: the Markdown vault, session
142
+ exports, Excalidraw diagrams)
143
+ - `runtime/`: Interlatch on this computer: installing it (hooks, MCP servers, background jobs), connecting agents
144
+ (`connectors.py`), the status line, moving from Chronicle, updates, notifications, the hub in a container;
145
+ `runtime/platforms/`: Windows (Task Scheduler, the notification area), the macOS app and its menu-bar icon
146
+ - `interfaces/cli/`: the command line: `parser.py` assembles the commands, and each module in `commands/` holds a
147
+ group of them (recording, archive, knowledge, setup, sharing, operations), each command's options beside its code;
148
+ `cli.py` at the top is the entry point the `interlatch` command runs
149
+ - `server.py` + `web/` (dashboard); `packaging/macos/` builds the app
125
150
 
126
151
  The dashboard page runs under a Content-Security-Policy (`PAGE_CSP` in `server.py`) that allows scripts and styles
127
152
  from its own files only. Add no inline `<script>` or `on…=` attribute to `index.html`, and give `h()` a style as an
128
153
  object (`style: { "--h": "40px" }`), never a string: a string becomes a style attribute the policy refuses.
129
154
  `tests/test_security.py` checks both.
130
155
 
131
- `ee/` is Interlatch Enterprise: its own package (`chronicle_ee`) under the [Interlatch Enterprise License](../ee/LICENSE),
156
+ `ee/` is Interlatch Enterprise: its own package (`interlatch_ee`) under the [Interlatch Enterprise License](../ee/LICENSE),
132
157
  left out of the MIT wheel and sdist. The core never imports it; [ee/README.md](../ee/README.md) says what belongs there.
133
158
 
134
159
  ## Trying a change
@@ -155,7 +180,7 @@ come from it.
155
180
 
156
181
  ```bash
157
182
  uv run python docs/demo/make_demo.py /tmp/interlatch-demo
158
- INTERLATCH_HOME=/tmp/interlatch-demo/home uv run python -m chronicle ui --port 8898 --open
183
+ INTERLATCH_HOME=/tmp/interlatch-demo/home uv run python -m interlatch ui --port 8898 --open
159
184
  ```
160
185
 
161
186
  The README's GIF and tour video come from it too. With that dashboard running, `docs/demo/record_demo.py` drives
@@ -116,11 +116,35 @@ uv run --only-group docs mkdocs build --strict # CI と同じ:リンクや
116
116
 
117
117
  ## コードの構成
118
118
 
119
- `parser.py`(Claude のトランスクリプト形式)、`codex_parser.py`(Codex のロールアウト)、`copilot_parser.py`(Copilot の
120
- エージェントセッション+VS Code のチャットログ)、`bob_parser.py`(Bob のタスク)、`antigravity_parser.py`(Antigravity のステップログ)、`agents.py`(エージェント名)、`connectors.py`(ソース)、
121
- `ingest.py`(アーカイブ+保存)、`digest.py` / `analyze.py` /
122
- `llm.py`(分析)、`synthesize.py`(ナレッジベース)、`diagram.py`(アーキテクチャ図)、`artifacts.py`(セッションが作ったものと、その今の状態)、`glossary.py`、`reviews.py`、`worker.py`(キュー)、`server.py` + `web/`
123
- (ダッシュボード)、`mcp_server.py`、`export_md.py`、`hooks.py` / `install.py`、`desktop.py`(macOS アプリ)、`cli.py`。`packaging/macos/` がアプリをビルドします。
119
+ コードは `src/interlatch/` の `interlatch` パッケージです(`src/chronicle/` は、改名前のインストールがまだ実行する
120
+ `python -m chronicle` を転送するだけです)。
121
+
122
+ - `core/`:設定、セッションの記録、パス、翻訳、エージェント名、料金、伏せ字処理、このコンピューターの識別子、
123
+ セッションが作ったものの見分け方
124
+ - `storage/`:SQLite のアーカイブ(スキーマ、マイグレーション、接続)と、任意の Postgres ストア
125
+ - `sources/`:各エージェントがファイルを置く場所(`discovery.py`)、エージェントごとの読み取り(`claude/`、`codex/`、`copilot.py`、`bob.py`、`antigravity.py`)と、
126
+ チャットのエクスポートごとの読み取り(`claude/export.py`、`chatgpt.py`)
127
+ - `artifacts/`:セッションが作ったもの、その今の状態、開くこと
128
+ - `ingestion/`:すべてのソースの同期(`service.py`)。生ファイルのアーカイブ、解析したセッションの保存、チャットの
129
+ 取り込み、エージェントのメモリーと履歴、忘れること
130
+ - `analysis/`:トランスクリプトの要約(`digest.py`)、モデルに教訓を尋ねること(`session.py`)、取り込んだチャットの
131
+ 選別、キューとワーカー。`analysis/runners/` がエージェントの CLI かプロバイダーの API でモデルに尋ねます
132
+ - `knowledge/`:プロジェクトごとのナレッジベース(`synthesize.py`)、成熟度のはしご、用語集、ケースファイル、学習の
133
+ トピック、フリクション、提案、指示ファイル、週ごとの振り返り
134
+ - `projects/`:まとまるフォルダー、プロジェクト名、ほかのコンピューターのフォルダーがどのプロジェクトか
135
+ (`routing.py`)、システムマップ
136
+ - `sharing/`:ハブと参加するコンピューター。プロトコル、トークン、クライアントと送受信、ハブの受け取り側、ハブの
137
+ プロジェクト、人と見えるもの、チームページのニュース、リーダーボード
138
+ - `application/`:ワーカーの 1 回の実行で起きること(`workflows.py`)、機能をまたぐセッションの記録と検索
139
+ - `interfaces/`:MCP サーバー(`mcp.py`)と、Interlatch が書き出すファイル(`exports/`:Markdown の保管庫、
140
+ セッションのエクスポート、Excalidraw の図)
141
+ - `runtime/`:このコンピューター上の Interlatch。インストール(フック、MCP サーバー、バックグラウンドジョブ)、
142
+ エージェントの接続(`connectors.py`)、ステータスライン、Chronicle からの移行、更新、通知、コンテナーのハブ。
143
+ `runtime/platforms/`:Windows(タスク スケジューラ、通知領域)、macOS アプリとメニューバーのアイコン
144
+ - `interfaces/cli/`:コマンドライン。`parser.py` がコマンドをまとめ、`commands/` の各モジュールがコマンドの
145
+ グループ(記録、アーカイブ、ナレッジ、セットアップ、共有、運用)を持ち、各コマンドのオプションはその処理の隣に
146
+ あります。最上位の `cli.py` は `interlatch` コマンドが実行する入り口です
147
+ - `server.py` + `web/`(ダッシュボード)。`packaging/macos/` がアプリをビルドします
124
148
 
125
149
  ダッシュボードのページは Content-Security-Policy(`server.py` の `PAGE_CSP`)の下で動き、スクリプトとスタイルは自分のファイルの
126
150
  ものしか使えません。`index.html` にインラインの `<script>` や `on…=` 属性を加えないでください。また `h()` に渡すスタイルは
@@ -150,7 +174,7 @@ uv run --only-group docs mkdocs build --strict # CI と同じ:リンクや
150
174
 
151
175
  ```bash
152
176
  uv run python docs/demo/make_demo.py /tmp/interlatch-demo
153
- INTERLATCH_HOME=/tmp/interlatch-demo/home uv run python -m chronicle ui --port 8898 --open
177
+ INTERLATCH_HOME=/tmp/interlatch-demo/home uv run python -m interlatch ui --port 8898 --open
154
178
  ```
155
179
 
156
180
  README の GIF とツアー動画もこのデータから作ります。そのダッシュボードを動かしたまま `docs/demo/record_demo.py` を実行すると、
@@ -87,7 +87,7 @@ claude.ai や ChatGPT のエクスポートを取り込むときはチャット
87
87
 
88
88
  ## 伏せ字にされるもの
89
89
 
90
- 伏せ字処理は、パターンの一覧(`src/chronicle/redact.py`)に合うものを `[REDACTED]` に置き換えます。分析に送る要約と
90
+ 伏せ字処理は、パターンの一覧(`src/interlatch/core/redact.py`)に合うものを `[REDACTED]` に置き換えます。分析に送る要約と
91
91
  分析が書き戻すもの(タイトル、要約、教訓)、書き出し、Markdown ボールト、MCP ツールの答えにかかります。生のアーカイブ
92
92
  (ダッシュボードのトランスクリプト表示は、あなたのコンピューター上のそれをそのまま見せます)、**Original transcript** の
93
93
  ダウンロード、`share = "everything"` のコンピューターがハブに送るセッションファイルは変えません。
@@ -91,7 +91,7 @@ the internet the connection uses TLS (SSL mode `require`) unless you turn it off
91
91
 
92
92
  ## What redaction catches
93
93
 
94
- Redaction replaces what matches a list of patterns (`src/chronicle/redact.py`) with `[REDACTED]`. It runs on the
94
+ Redaction replaces what matches a list of patterns (`src/interlatch/core/redact.py`) with `[REDACTED]`. It runs on the
95
95
  digest sent for analysis and on what analysis writes back (titles, summaries, lessons), and on exports, the Markdown
96
96
  vault and what the MCP tools answer. It never changes the raw archive, which the dashboard's transcript view shows as
97
97
  it is on your computer, an **Original transcript** download, or the session files a computer sends a hub with
@@ -60,7 +60,9 @@ thinking, tool calls with their results and durations, background-task notices a
60
60
  newer version's conversation database, opened read-only, it adds the workspace folder, git branch and remote, and the
61
61
  model; the title comes from `annotations/<id>.pbtxt`. The log and the task, plan and walkthrough Markdown files are
62
62
  archived, generated images are not. A conversation kept only in the encrypted store cannot be read; the Sources card
63
- counts those. Antigravity records no prices, so sessions on Gemini models show tokens but no cost. Connecting
63
+ counts those. Antigravity records no prices, so the cost of a session on a Gemini model is estimated at Google's
64
+ Gemini API list prices (a Gemini model without a published price at those of its kind: Flash, Flash-Lite or Pro),
65
+ as are GitHub Copilot sessions on Gemini models. Connecting
64
66
  registers the MCP server in `~/.gemini/config/mcp_config.json`, Antigravity's global MCP config.
65
67
 
66
68
  **Chats on claude.ai and ChatGPT** are not stored on your Mac, so they come in from a data export: on claude.ai,
@@ -5,7 +5,7 @@ The 3D icons on the dashboard (page headers, Home tiles, empty states) and the a
5
5
  the studio's explainer films. The small line icons in the sidebar and on buttons stay as they are: they follow the
6
6
  theme colour and stay sharp at 14–20 px, where a render can't.
7
7
 
8
- - `art.json`: what to render. Keys become `src/chronicle/web/art-<key>.webp`; `app-icon` becomes
8
+ - `art.json`: what to render. Keys become `src/interlatch/web/art-<key>.webp`; `app-icon` becomes
9
9
  `packaging/macos/icon-3d.webp`. A spec names a cast object (`obj`), a character (`char`, `mood`) or one of the
10
10
  members in `members.js` (`custom`), plus optional camera `az`, `pitch` and `pad`.
11
11
  - `members.js`: Interlatch's own members built from the cast's parts: the open book (Knowledge) and the 3D emblem.
@@ -1,6 +1,6 @@
1
1
  """Render Interlatch's 3D art with the Chatixia Studio Blueprint Cast and export it.
2
2
 
3
- Writes src/chronicle/web/art-<name>.webp (dashboard art) and packaging/macos/icon-3d.webp (the app icon source,
3
+ Writes src/interlatch/web/art-<name>.webp (dashboard art) and packaging/macos/icon-3d.webp (the app icon source,
4
4
  which packaging/macos/make_icon.py turns into every app, dashboard and phone icon).
5
5
 
6
6
  uv run --no-project --with playwright --with pillow python packaging/icons3d/render.py
@@ -22,7 +22,7 @@ from playwright.sync_api import sync_playwright
22
22
 
23
23
  HERE = Path(__file__).parent
24
24
  ROOT = HERE.parents[1]
25
- WEB = ROOT / "src" / "chronicle" / "web"
25
+ WEB = ROOT / "src" / "interlatch" / "web"
26
26
  APP_ICON = ROOT / "packaging" / "macos" / "icon-3d.webp"
27
27
  ART_PX = 256 # shown at up to 112 CSS px, so 2x stays sharp
28
28
 
@@ -12,16 +12,16 @@ ROOT = Path(SPECPATH).parents[1]
12
12
  HERE = Path(SPECPATH)
13
13
  # the installed package's version (from the git tag); the bundle takes its release numbers only (0.7.1.dev3+g… -> 0.7.1)
14
14
  VERSION = re.match(r"\d+(?:\.\d+)*", version("interlatch")).group(0)
15
- BUNDLE_ID = "com.interlatch.app" # keep in sync with chronicle.install.APP_BUNDLE_ID
15
+ BUNDLE_ID = "com.interlatch.app" # keep in sync with interlatch.runtime.install.APP_BUNDLE_ID
16
16
  IDENTITY = os.environ.get("INTERLATCH_CODESIGN_IDENTITY") or None
17
17
 
18
18
  a = Analysis(
19
- [str(HERE / "chronicle_app.py")],
19
+ [str(HERE / "interlatch_app.py")],
20
20
  pathex=[str(ROOT / "src")],
21
- # the package metadata carries the version (chronicle.__version__ reads it)
22
- datas=[(str(ROOT / "src" / "chronicle" / "web"), "chronicle/web")] + copy_metadata("interlatch"),
23
- # chronicle imports most modules lazily inside functions, and rich loads some of its own on demand
24
- hiddenimports=collect_submodules("chronicle") + collect_submodules("rich"),
21
+ # the package metadata carries the version (interlatch.__version__ reads it)
22
+ datas=[(str(ROOT / "src" / "interlatch" / "web"), "interlatch/web")] + copy_metadata("interlatch"),
23
+ # interlatch imports most modules lazily inside functions, and rich loads some of its own on demand
24
+ hiddenimports=collect_submodules("interlatch") + collect_submodules("rich"),
25
25
  excludes=["tkinter", "pytest", "PIL"],
26
26
  noarchive=False,
27
27
  )
@@ -31,7 +31,7 @@ exe = EXE(
31
31
  a.scripts,
32
32
  [],
33
33
  exclude_binaries=True,
34
- name="Interlatch", # Contents/MacOS/Interlatch, which chronicle.install's shim runs
34
+ name="Interlatch", # Contents/MacOS/Interlatch, which interlatch.runtime.install's shim runs
35
35
  console=False,
36
36
  argv_emulation=False,
37
37
  target_arch=os.environ.get("INTERLATCH_TARGET_ARCH") or None,
@@ -10,8 +10,8 @@ Created with the built-in imagegen tool on October 3, 2026. The new Chatixia org
10
10
  - `icon-blueprint.webp`: 1024 × 1024 lossless source, resized once from the generated 1254px PNG.
11
11
  - `icon.png`: exported artwork with standard macOS Dock margins, also used by the repository READMEs and docs.
12
12
  - `Chronicle.icns`: macOS icon bundle at the standard icon sizes.
13
- - `src/chronicle/web/icon.png` and `favicon.png`: dashboard, source app, and browser icons.
14
- - `src/chronicle/web/icon-{180,192,512}.png`: opaque navy touch and maskable phone icons.
13
+ - `src/interlatch/web/icon.png` and `favicon.png`: dashboard, source app, and browser icons.
14
+ - `src/interlatch/web/icon-{180,192,512}.png`: opaque navy touch and maskable phone icons.
15
15
 
16
16
  Regenerate these exports with `uv run --group build python packaging/macos/make_icon.py`. The WebP stores the source
17
17
  pixels without further compression loss and stays below the repository's 600 KB limit for new files.
@@ -10,10 +10,10 @@ import sys
10
10
  def run() -> int:
11
11
  args = [a for a in sys.argv[1:] if not a.startswith("-psn_")] # Finder adds -psn_… on old macOS
12
12
  if args:
13
- from chronicle.cli import main
13
+ from interlatch.cli import main
14
14
 
15
15
  return main(args)
16
- from chronicle.desktop import main
16
+ from interlatch.runtime.platforms.desktop import main
17
17
 
18
18
  return main()
19
19
 
@@ -15,7 +15,7 @@ from pathlib import Path
15
15
  from PIL import Image, ImageOps
16
16
 
17
17
  HERE = Path(__file__).parent
18
- WEB = HERE.parents[1] / "src" / "chronicle" / "web"
18
+ WEB = HERE.parents[1] / "src" / "interlatch" / "web"
19
19
  SOURCE = HERE / "icon-3d.webp"
20
20
  S, M = 1024, 100 # macOS icon grid: artwork fits within an 824px square centred in 1024
21
21
  NAVY = (8, 26, 49)
@@ -30,8 +30,8 @@ Repository = "https://github.com/Chatixia-AI/interlatch"
30
30
  Issues = "https://github.com/Chatixia-AI/interlatch/issues"
31
31
 
32
32
  [project.scripts]
33
- interlatch = "chronicle.cli:main"
34
- chronicle = "chronicle.cli:main" # the command's name before the rename (Chronicle), kept as an alias
33
+ interlatch = "interlatch.cli:main"
34
+ chronicle = "interlatch.cli:main" # the command's name before the rename (Chronicle), kept as an alias
35
35
 
36
36
  [project.optional-dependencies]
37
37
  app = [
@@ -73,7 +73,7 @@ pattern = '(href="|\]\()(?!https?://|#)([^")]+)'
73
73
  replacement = '\1https://github.com/Chatixia-AI/interlatch/blob/main/\2'
74
74
 
75
75
  [tool.hatch.build.targets.wheel]
76
- packages = ["src/chronicle"]
76
+ packages = ["src/interlatch", "src/chronicle"] # chronicle: forwarding for installs from before the rename
77
77
 
78
78
  # ee/ is under its own enterprise license and builds its own package; keep it out of the MIT sdist
79
79
  [tool.hatch.build.targets.sdist]
@@ -0,0 +1,8 @@
1
+ """The package's name before the rename to Interlatch, kept only for what installs written then still run.
2
+
3
+ Hooks, MCP servers and background tasks set up before the rename may run `python -m chronicle …` (__main__.py), and
4
+ Windows tasks `pythonw -m chronicle.windows …` (windows.py). Both forward to the interlatch package, which holds the
5
+ implementation; nothing else belongs here.
6
+ """
7
+
8
+ from interlatch import __version__ as __version__
@@ -0,0 +1,3 @@
1
+ from interlatch.cli import main
2
+
3
+ raise SystemExit(main())
@@ -0,0 +1,11 @@
1
+ """`pythonw -m chronicle.windows …`, as Task Scheduler tasks registered before the rename run it: interlatch.windows.
2
+
3
+ RESTART_EXIT too: a dashboard that was started before an update and asks for its restart after it looks it up here."""
4
+
5
+ import sys
6
+
7
+ from interlatch.windows import RESTART_EXIT as RESTART_EXIT
8
+ from interlatch.windows import run_hidden
9
+
10
+ if __name__ == "__main__":
11
+ raise SystemExit(run_hidden(sys.argv[1:]))
@@ -0,0 +1,3 @@
1
+ from interlatch.cli import main
2
+
3
+ raise SystemExit(main())
@@ -0,0 +1,2 @@
1
+ """Analyzing sessions with a model: condensing a transcript (digest.py), asking for its lessons (session.py),
2
+ screening imported chats (screen.py), the queue of sessions waiting (queue.py) and the worker that runs them."""
@@ -10,9 +10,9 @@ import sqlite3
10
10
  from collections import Counter
11
11
  from dataclasses import dataclass
12
12
 
13
- from .redact import redact
14
- from .agents import full_name, speaker
15
- from .util import human_count, human_duration, local_str, loads, one_line, truncate
13
+ from ..core.redact import redact
14
+ from ..core.agents import full_name, speaker
15
+ from ..core.util import human_count, human_duration, local_str, loads, one_line, truncate
16
16
 
17
17
  CAPS = {
18
18
  # level: (prompt, assistant text, error result, ok result for Bash, agent result, notification)
@@ -0,0 +1,22 @@
1
+ """The language Interlatch writes analyses and knowledge in ([analysis] language), as a prompt says it."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ..core.config import Config
6
+
7
+ # What a prompt says instead of (or besides) its English-writing rule when [analysis] language is "ja"
8
+ JAPANESE = (
9
+ "Write all prose in Japanese: natural and concise. Short fields may be fragments and need not use です/ます. Put a "
10
+ "half-width space between Japanese and Latin letters or digits. Keep identifiers, commands, file paths, config keys, "
11
+ "URLs, error messages, quotes and code verbatim, in their original language. JSON keys and every enum or code value "
12
+ "the schema lists (kind, scope, confidence, outcome, reason, verdict and the like) stay exactly as listed, in English."
13
+ )
14
+
15
+
16
+ def written_in(cfg: Config, system: str, english: str = "", note: str = "") -> str:
17
+ """`system` in the language Interlatch writes in ([analysis] language). English leaves it exactly as it is; Japanese
18
+ swaps its English-writing sentence (`english`) for JAPANESE and `note`, or appends them when it has none."""
19
+ if cfg.analysis.language != "ja":
20
+ return system
21
+ rule = " ".join(x for x in (JAPANESE, note) if x)
22
+ return system.replace(english, rule) if english and english in system else f"{system}\n\n{rule}"
@@ -0,0 +1,132 @@
1
+ """The sessions waiting for analysis: which are ready, why the others wait (still active, retry later, held), and
2
+ whether the queue is paused."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from datetime import datetime, timedelta
7
+
8
+ from ..core.config import Config
9
+ from ..core.i18n import tr
10
+ from ..core.util import local_str, one_line, to_iso, utcnow
11
+ from ..storage.kv import kv_get
12
+ from .runners.base import Runner
13
+ from .runners.factory import make_runner
14
+
15
+ PAUSE_KEY = "analysis_paused_until"
16
+
17
+
18
+ def pending_sessions(conn, cfg: Config, limit: int) -> list[str]:
19
+ now = utcnow()
20
+ params = {
21
+ "now": to_iso(now),
22
+ "idle": to_iso(now - timedelta(minutes=cfg.analysis.idle_minutes)),
23
+ "min_prompts": cfg.analysis.min_prompts,
24
+ "installed": kv_get(conn, "installed_at") or "0000",
25
+ }
26
+ sql = (
27
+ "SELECT id, project_path FROM sessions WHERE source NOT IN ('history', 'remote') "
28
+ f"AND analysis_status IN ('pending', 'stale', 'error') AND analysis_attempts < {MAX_ATTEMPTS} "
29
+ "AND (analysis_not_before IS NULL OR analysis_not_before <= :now) "
30
+ "AND n_prompts >= :min_prompts AND (ended_flag = 1 OR ended_at <= :idle)"
31
+ )
32
+ if not cfg.analysis.backfill:
33
+ sql += " AND started_at >= :installed"
34
+ sql += " ORDER BY ended_flag DESC, ended_at DESC"
35
+ ids = []
36
+ for sid, project_path in conn.execute(sql, params):
37
+ if cfg.is_excluded(project_path): # excluded after it was queued: never send it to Claude
38
+ continue
39
+ ids.append(sid)
40
+ if len(ids) >= limit:
41
+ break
42
+ return ids
43
+
44
+
45
+ MAX_ATTEMPTS = 4
46
+ # Why a session that is not analyzed yet is waiting. "Queued" codes clear by themselves; "held" codes need a change
47
+ # (a setting, or a longer session) before the session is ever analyzed. One function computes them, mirroring
48
+ # pending_sessions(), so every surface (session page, Status, CLI) names the same reason.
49
+ QUEUED_CODES = ("ready", "active", "retry")
50
+ HELD_CODES = ("excluded", "too_short", "before_install", "gave_up")
51
+ QUEUE_REASON_LABEL = {"ready": "ready now", "active": "still active", "retry": "retry later", "excluded": "project excluded",
52
+ "too_short": "too few prompts", "before_install": "before install (backfill off)",
53
+ "gave_up": "failed, not retried"}
54
+
55
+
56
+ def waiting_reason(conn, cfg: Config, s) -> tuple[str, str] | None:
57
+ """(code, explanation) for a session still waiting for analysis, or None when it is not waiting."""
58
+ status = s["analysis_status"]
59
+ if s["source"] == "history" or status not in ("pending", "stale", "error"):
60
+ return None
61
+ attempts = s["analysis_attempts"] or 0
62
+ if attempts >= MAX_ATTEMPTS:
63
+ reason = one_line(s["analysis_reason"] or tr("no error recorded"), 160)
64
+ return "gave_up", (tr("analysis failed {n}; it will not be retried automatically ({reason})", n=attempts, reason=reason)
65
+ if attempts < 99 else
66
+ tr("analysis failed for good; it will not be retried automatically ({reason})", reason=reason))
67
+ if cfg.is_excluded(s["project_path"]):
68
+ return "excluded", tr("its project is excluded from analysis (sources.exclude_projects)")
69
+ if (s["n_prompts"] or 0) < cfg.analysis.min_prompts:
70
+ return "too_short", tr("fewer than {n} prompts (analysis.min_prompts)", n=cfg.analysis.min_prompts)
71
+ if not cfg.analysis.backfill and (s["started_at"] or "") < (kv_get(conn, "installed_at") or "0000"):
72
+ return "before_install", tr("it started before Interlatch was installed, and analysis.backfill is off")
73
+ now = utcnow()
74
+ if s["analysis_not_before"] and s["analysis_not_before"] > to_iso(now):
75
+ return "retry", tr("retrying at {when} after a failed attempt ({reason})",
76
+ when=local_str(s["analysis_not_before"], "%m-%d %H:%M"), reason=one_line(s["analysis_reason"] or "", 160))
77
+ idle_at = (s["ended_at"] or "")
78
+ if not s["ended_flag"] and idle_at > to_iso(now - timedelta(minutes=cfg.analysis.idle_minutes)):
79
+ ready_at = datetime.fromisoformat(idle_at.replace("Z", "+00:00")) + timedelta(minutes=cfg.analysis.idle_minutes)
80
+ return "active", tr("the session may still be going; it is analyzed once idle for {minutes} minutes (around {at})",
81
+ minutes=cfg.analysis.idle_minutes, at=local_str(to_iso(ready_at), "%H:%M"))
82
+ block = queue_block(conn, cfg)
83
+ if block:
84
+ return "ready", tr("ready, but {block}", block=block)
85
+ return "ready", (tr("ready: the background agent analyzes it on its next run (every 15 minutes)") if status != "stale"
86
+ else tr("ready to re-analyze: the session continued after it was analyzed"))
87
+
88
+
89
+ def queue_block(conn, cfg: Config, runner: Runner | None = None) -> str | None:
90
+ """What stops the whole queue right now, if anything."""
91
+ paused = kv_get(conn, PAUSE_KEY)
92
+ if paused and paused > to_iso(utcnow()):
93
+ return tr("analysis is paused until {when} (usage limit); it resumes by itself", when=local_str(paused, "%m-%d %H:%M"))
94
+ if not cfg.analysis.auto:
95
+ return tr("automatic analysis is off (analysis.auto); analyze it from its page or with `interlatch analyze`")
96
+ runner = runner or make_runner(cfg)
97
+ if not runner.available():
98
+ return tr("{reason}, so nothing can be analyzed", reason=runner.unavailable_reason())
99
+ return None
100
+
101
+
102
+ def count_pending(conn, cfg: Config) -> dict:
103
+ """The analysis queue: `ready` now, `queued` (everything that will be analyzed by itself, ready included),
104
+ `held` (needs a change first), each with a count per reason, and `block` when the whole queue is stopped."""
105
+ reasons: dict[str, int] = {}
106
+ for s in conn.execute(
107
+ "SELECT analysis_status, source, analysis_attempts, analysis_reason, analysis_not_before, project_path, n_prompts, "
108
+ "started_at, ended_at, ended_flag FROM sessions WHERE source NOT IN ('history', 'remote') "
109
+ "AND analysis_status IN ('pending','stale','error')"):
110
+ got = waiting_reason(conn, cfg, s)
111
+ if got:
112
+ reasons[got[0]] = reasons.get(got[0], 0) + 1
113
+ return {"ready": reasons.get("ready", 0), "queued": sum(reasons.get(c, 0) for c in QUEUED_CODES),
114
+ "held": sum(reasons.get(c, 0) for c in HELD_CODES), "reasons": reasons, "block": queue_block(conn, cfg),
115
+ "labels": {code: tr(label) for code, label in QUEUE_REASON_LABEL.items()}}
116
+
117
+
118
+ def queued_ids(conn, cfg: Config, code: str, limit: int) -> list[str]:
119
+ """The sessions waiting for one reason ("ready" or "active"), newest first: what the Queue's Analyze now covers."""
120
+ if code == "ready":
121
+ return pending_sessions(conn, cfg, limit)
122
+ ids = []
123
+ for s in conn.execute(
124
+ "SELECT id, analysis_status, source, analysis_attempts, analysis_reason, analysis_not_before, project_path, "
125
+ "n_prompts, started_at, ended_at, ended_flag FROM sessions WHERE source NOT IN ('history', 'remote') "
126
+ "AND analysis_status IN ('pending','stale','error') ORDER BY ended_at DESC"):
127
+ got = waiting_reason(conn, cfg, s)
128
+ if got and got[0] == code:
129
+ ids.append(s["id"])
130
+ if len(ids) >= limit:
131
+ break
132
+ return ids