interlatch 0.28.0__tar.gz → 0.28.2__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 (502) hide show
  1. {interlatch-0.28.0 → interlatch-0.28.2}/CHANGELOG.md +52 -0
  2. {interlatch-0.28.0 → interlatch-0.28.2}/PKG-INFO +1 -1
  3. interlatch-0.28.2/changelog.d/hub-groups.md +6 -0
  4. interlatch-0.28.2/changelog.d/hub-take-back.md +6 -0
  5. interlatch-0.28.2/changelog.d/hubs-dashboard.md +3 -0
  6. {interlatch-0.28.0 → interlatch-0.28.2}/docs/README.md +1 -0
  7. {interlatch-0.28.0 → interlatch-0.28.2}/docs/analysis.md +16 -2
  8. {interlatch-0.28.0 → interlatch-0.28.2}/docs/cli.md +3 -0
  9. {interlatch-0.28.0 → interlatch-0.28.2}/docs/configuration.md +3 -2
  10. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/README.md +1 -0
  11. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/analysis.md +15 -2
  12. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/cli.md +3 -0
  13. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/configuration.md +3 -2
  14. interlatch-0.28.2/docs/ja/profiles.md +112 -0
  15. interlatch-0.28.2/docs/profiles.md +145 -0
  16. {interlatch-0.28.0 → interlatch-0.28.2}/mkdocs.yml +2 -0
  17. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/queue.py +3 -1
  18. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/runners/base.py +6 -2
  19. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/runners/bob.py +2 -4
  20. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/runners/factory.py +12 -3
  21. interlatch-0.28.2/src/interlatch/analysis/runners/off.py +35 -0
  22. interlatch-0.28.2/src/interlatch/analysis/runners/opencode.py +161 -0
  23. interlatch-0.28.2/src/interlatch/application/profiles.py +586 -0
  24. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/application/workflows.py +22 -0
  25. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/core/config.py +98 -4
  26. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/core/i18n/ja.py +4 -0
  27. interlatch-0.28.2/src/interlatch/core/profiles.py +275 -0
  28. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/ingestion/persistence.py +4 -0
  29. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/ingestion/service.py +7 -0
  30. interlatch-0.28.2/src/interlatch/interfaces/cli/commands/hubs.py +341 -0
  31. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/cli/commands/knowledge.py +8 -3
  32. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/cli/commands/setup.py +75 -10
  33. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/cli/commands/sharing.py +25 -2
  34. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/cli/main.py +28 -0
  35. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/cli/parser.py +5 -1
  36. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/mcp.py +13 -0
  37. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/__init__.py +1 -0
  38. interlatch-0.28.2/src/interlatch/interfaces/web/api/hubs.py +95 -0
  39. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/projects.py +33 -5
  40. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/settings.py +5 -1
  41. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/routes.py +5 -0
  42. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/instructions.py +31 -0
  43. interlatch-0.28.2/src/interlatch/projects/hubgroups.py +69 -0
  44. interlatch-0.28.2/src/interlatch/projects/owners.py +225 -0
  45. interlatch-0.28.2/src/interlatch/projects/scope.py +117 -0
  46. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/runtime/hooks.py +6 -0
  47. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/client.py +58 -13
  48. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/membership.py +37 -6
  49. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/projects.py +3 -3
  50. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/protocol.py +4 -0
  51. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/pull.py +19 -3
  52. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/push.py +67 -7
  53. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/receiver.py +39 -1
  54. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/app.css +9 -0
  55. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/app.js +176 -13
  56. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/ja.js +44 -0
  57. {interlatch-0.28.0 → interlatch-0.28.2}/tests/goldens/cli.json +291 -1
  58. interlatch-0.28.2/tests/hubs_fixture.py +22 -0
  59. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_cli_pins.py +4 -1
  60. interlatch-0.28.2/tests/test_hub_groups.py +229 -0
  61. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_instructions.py +28 -0
  62. interlatch-0.28.2/tests/test_opencode_analysis.py +286 -0
  63. interlatch-0.28.2/tests/test_profile_hubs.py +214 -0
  64. interlatch-0.28.2/tests/test_profile_scope.py +213 -0
  65. interlatch-0.28.2/tests/test_profiles.py +405 -0
  66. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_project_groups.py +1 -1
  67. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_route_matrix.py +2 -0
  68. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_security.py +7 -0
  69. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_setup.py +7 -5
  70. interlatch-0.28.0/changelog.d/config-subtable-set.md +0 -2
  71. interlatch-0.28.0/changelog.d/hub-cookie-name.md +0 -5
  72. interlatch-0.28.0/changelog.d/hub-inventory-scope.md +0 -5
  73. interlatch-0.28.0/changelog.d/hub-leave-join.md +0 -7
  74. interlatch-0.28.0/changelog.d/hub-payload-allowlist.md +0 -8
  75. {interlatch-0.28.0 → interlatch-0.28.2}/.github/dependabot.yml +0 -0
  76. {interlatch-0.28.0 → interlatch-0.28.2}/.github/windows-ja-qa/driver.ps1 +0 -0
  77. {interlatch-0.28.0 → interlatch-0.28.2}/.github/windows-ja-qa/ja_check.py +0 -0
  78. {interlatch-0.28.0 → interlatch-0.28.2}/.github/windows-ja-qa/report.py +0 -0
  79. {interlatch-0.28.0 → interlatch-0.28.2}/.github/windows-ja-qa/shots.py +0 -0
  80. {interlatch-0.28.0 → interlatch-0.28.2}/.github/windows-ja-qa/user.ps1 +0 -0
  81. {interlatch-0.28.0 → interlatch-0.28.2}/.github/workflows/changelog.yml +0 -0
  82. {interlatch-0.28.0 → interlatch-0.28.2}/.github/workflows/ci.yml +0 -0
  83. {interlatch-0.28.0 → interlatch-0.28.2}/.github/workflows/docs.yml +0 -0
  84. {interlatch-0.28.0 → interlatch-0.28.2}/.github/workflows/release.yml +0 -0
  85. {interlatch-0.28.0 → interlatch-0.28.2}/.github/workflows/windows-ja-qa.yml +0 -0
  86. {interlatch-0.28.0 → interlatch-0.28.2}/.gitignore +0 -0
  87. {interlatch-0.28.0 → interlatch-0.28.2}/.pre-commit-config.yaml +0 -0
  88. {interlatch-0.28.0 → interlatch-0.28.2}/.python-version +0 -0
  89. {interlatch-0.28.0 → interlatch-0.28.2}/CONTRIBUTING.md +0 -0
  90. {interlatch-0.28.0 → interlatch-0.28.2}/LICENSE +0 -0
  91. {interlatch-0.28.0 → interlatch-0.28.2}/README.ja.md +0 -0
  92. {interlatch-0.28.0 → interlatch-0.28.2}/README.md +0 -0
  93. {interlatch-0.28.0 → interlatch-0.28.2}/ROADMAP.ja.md +0 -0
  94. {interlatch-0.28.0 → interlatch-0.28.2}/ROADMAP.md +0 -0
  95. {interlatch-0.28.0 → interlatch-0.28.2}/SECURITY.md +0 -0
  96. {interlatch-0.28.0 → interlatch-0.28.2}/careers/README.md +0 -0
  97. {interlatch-0.28.0 → interlatch-0.28.2}/careers/boards.json +0 -0
  98. {interlatch-0.28.0 → interlatch-0.28.2}/careers/pipeline.py +0 -0
  99. {interlatch-0.28.0 → interlatch-0.28.2}/changelog.d/README.md +0 -0
  100. {interlatch-0.28.0 → interlatch-0.28.2}/dev.sh +0 -0
  101. {interlatch-0.28.0 → interlatch-0.28.2}/docker/.dockerignore +0 -0
  102. {interlatch-0.28.0 → interlatch-0.28.2}/docker/.env.example +0 -0
  103. {interlatch-0.28.0 → interlatch-0.28.2}/docker/Caddyfile +0 -0
  104. {interlatch-0.28.0 → interlatch-0.28.2}/docker/Dockerfile +0 -0
  105. {interlatch-0.28.0 → interlatch-0.28.2}/docker/compose.yaml +0 -0
  106. {interlatch-0.28.0 → interlatch-0.28.2}/docker/wheels/.gitignore +0 -0
  107. {interlatch-0.28.0 → interlatch-0.28.2}/docs/_site/hooks.py +0 -0
  108. {interlatch-0.28.0 → interlatch-0.28.2}/docs/dashboard.md +0 -0
  109. {interlatch-0.28.0 → interlatch-0.28.2}/docs/demo/make_demo.py +0 -0
  110. {interlatch-0.28.0 → interlatch-0.28.2}/docs/demo/record_demo.py +0 -0
  111. {interlatch-0.28.0 → interlatch-0.28.2}/docs/design/innerlatch.md +0 -0
  112. {interlatch-0.28.0 → interlatch-0.28.2}/docs/design/ja/innerlatch.md +0 -0
  113. {interlatch-0.28.0 → interlatch-0.28.2}/docs/design/ja/learning.md +0 -0
  114. {interlatch-0.28.0 → interlatch-0.28.2}/docs/design/learning.md +0 -0
  115. {interlatch-0.28.0 → interlatch-0.28.2}/docs/development.md +0 -0
  116. {interlatch-0.28.0 → interlatch-0.28.2}/docs/devices.md +0 -0
  117. {interlatch-0.28.0 → interlatch-0.28.2}/docs/diagrams/analysis.excalidraw.svg +0 -0
  118. {interlatch-0.28.0 → interlatch-0.28.2}/docs/diagrams/architecture.excalidraw.svg +0 -0
  119. {interlatch-0.28.0 → interlatch-0.28.2}/docs/docker.md +0 -0
  120. {interlatch-0.28.0 → interlatch-0.28.2}/docs/faq.md +0 -0
  121. {interlatch-0.28.0 → interlatch-0.28.2}/docs/images/demo.gif +0 -0
  122. {interlatch-0.28.0 → interlatch-0.28.2}/docs/images/home.png +0 -0
  123. {interlatch-0.28.0 → interlatch-0.28.2}/docs/images/map.png +0 -0
  124. {interlatch-0.28.0 → interlatch-0.28.2}/docs/images/palette.png +0 -0
  125. {interlatch-0.28.0 → interlatch-0.28.2}/docs/images/session.png +0 -0
  126. {interlatch-0.28.0 → interlatch-0.28.2}/docs/install.md +0 -0
  127. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/dashboard.md +0 -0
  128. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/development.md +0 -0
  129. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/devices.md +0 -0
  130. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/docker.md +0 -0
  131. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/faq.md +0 -0
  132. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/install.md +0 -0
  133. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/join-a-hub.md +0 -0
  134. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/mcp.md +0 -0
  135. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/moving-from-chronicle.md +0 -0
  136. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/party.md +0 -0
  137. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/postgres.md +0 -0
  138. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/privacy.md +0 -0
  139. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/sources.md +0 -0
  140. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/suggestions.md +0 -0
  141. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/troubleshooting.md +0 -0
  142. {interlatch-0.28.0 → interlatch-0.28.2}/docs/ja/vscode.md +0 -0
  143. {interlatch-0.28.0 → interlatch-0.28.2}/docs/join-a-hub.md +0 -0
  144. {interlatch-0.28.0 → interlatch-0.28.2}/docs/mcp.md +0 -0
  145. {interlatch-0.28.0 → interlatch-0.28.2}/docs/moving-from-chronicle.md +0 -0
  146. {interlatch-0.28.0 → interlatch-0.28.2}/docs/party.md +0 -0
  147. {interlatch-0.28.0 → interlatch-0.28.2}/docs/postgres.md +0 -0
  148. {interlatch-0.28.0 → interlatch-0.28.2}/docs/privacy.md +0 -0
  149. {interlatch-0.28.0 → interlatch-0.28.2}/docs/sources.md +0 -0
  150. {interlatch-0.28.0 → interlatch-0.28.2}/docs/suggestions.md +0 -0
  151. {interlatch-0.28.0 → interlatch-0.28.2}/docs/troubleshooting.md +0 -0
  152. {interlatch-0.28.0 → interlatch-0.28.2}/docs/vscode.md +0 -0
  153. {interlatch-0.28.0 → interlatch-0.28.2}/leaderboard/.firebaserc +0 -0
  154. {interlatch-0.28.0 → interlatch-0.28.2}/leaderboard/.gitignore +0 -0
  155. {interlatch-0.28.0 → interlatch-0.28.2}/leaderboard/README.md +0 -0
  156. {interlatch-0.28.0 → interlatch-0.28.2}/leaderboard/firebase.json +0 -0
  157. {interlatch-0.28.0 → interlatch-0.28.2}/leaderboard/firestore.indexes.json +0 -0
  158. {interlatch-0.28.0 → interlatch-0.28.2}/leaderboard/firestore.rules +0 -0
  159. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/icons3d/README.md +0 -0
  160. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/icons3d/art.json +0 -0
  161. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/icons3d/filing.html +0 -0
  162. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/icons3d/loops.json +0 -0
  163. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/icons3d/loops.py +0 -0
  164. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/icons3d/members.js +0 -0
  165. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/icons3d/render.html +0 -0
  166. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/icons3d/render.py +0 -0
  167. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/icons3d/scenes-more.js +0 -0
  168. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/icons3d/scenes.html +0 -0
  169. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/macos/Chronicle.icns +0 -0
  170. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/macos/Interlatch.spec +0 -0
  171. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/macos/build.sh +0 -0
  172. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/macos/entitlements.plist +0 -0
  173. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/macos/icon-3d.webp +0 -0
  174. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/macos/icon-blueprint-prompt.md +0 -0
  175. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/macos/icon-blueprint.webp +0 -0
  176. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/macos/icon.png +0 -0
  177. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/macos/interlatch_app.py +0 -0
  178. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/macos/make_icon.py +0 -0
  179. {interlatch-0.28.0 → interlatch-0.28.2}/packaging/release.py +0 -0
  180. {interlatch-0.28.0 → interlatch-0.28.2}/pyproject.toml +0 -0
  181. {interlatch-0.28.0 → interlatch-0.28.2}/src/chronicle/__init__.py +0 -0
  182. {interlatch-0.28.0 → interlatch-0.28.2}/src/chronicle/__main__.py +0 -0
  183. {interlatch-0.28.0 → interlatch-0.28.2}/src/chronicle/windows.py +0 -0
  184. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/__init__.py +0 -0
  185. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/__main__.py +0 -0
  186. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/__init__.py +0 -0
  187. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/digest.py +0 -0
  188. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/language.py +0 -0
  189. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/runners/__init__.py +0 -0
  190. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/runners/api.py +0 -0
  191. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/runners/claude.py +0 -0
  192. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/runners/codex.py +0 -0
  193. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/runners/process.py +0 -0
  194. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/runners/replies.py +0 -0
  195. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/runners/settings.py +0 -0
  196. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/screen.py +0 -0
  197. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/session.py +0 -0
  198. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/analysis/worker.py +0 -0
  199. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/application/__init__.py +0 -0
  200. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/application/records.py +0 -0
  201. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/application/search.py +0 -0
  202. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/artifacts/__init__.py +0 -0
  203. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/artifacts/files.py +0 -0
  204. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/artifacts/queries.py +0 -0
  205. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/cli.py +0 -0
  206. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/core/__init__.py +0 -0
  207. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/core/agents.py +0 -0
  208. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/core/artifact_records.py +0 -0
  209. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/core/diagrams.py +0 -0
  210. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/core/i18n/__init__.py +0 -0
  211. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/core/machine.py +0 -0
  212. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/core/paths.py +0 -0
  213. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/core/pricing.py +0 -0
  214. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/core/process.py +0 -0
  215. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/core/redact.py +0 -0
  216. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/core/sessions.py +0 -0
  217. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/core/util.py +0 -0
  218. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/ingestion/__init__.py +0 -0
  219. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/ingestion/analyses.py +0 -0
  220. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/ingestion/archive.py +0 -0
  221. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/ingestion/chat_import.py +0 -0
  222. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/ingestion/deletion.py +0 -0
  223. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/ingestion/history.py +0 -0
  224. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/ingestion/memory.py +0 -0
  225. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/ingestion/report.py +0 -0
  226. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/__init__.py +0 -0
  227. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/cli/__init__.py +0 -0
  228. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/cli/commands/__init__.py +0 -0
  229. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/cli/commands/archive.py +0 -0
  230. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/cli/commands/operations.py +0 -0
  231. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/cli/commands/recording.py +0 -0
  232. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/cli/common.py +0 -0
  233. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/exports/__init__.py +0 -0
  234. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/exports/diagrams.py +0 -0
  235. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/exports/markdown.py +0 -0
  236. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/exports/sessions.py +0 -0
  237. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/exports/vault.py +0 -0
  238. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/__init__.py +0 -0
  239. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/artifacts.py +0 -0
  240. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/common.py +0 -0
  241. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/devices.py +0 -0
  242. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/hub_admin.py +0 -0
  243. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/knowledge.py +0 -0
  244. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/leaderboard.py +0 -0
  245. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/party.py +0 -0
  246. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/sessions.py +0 -0
  247. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/sources.py +0 -0
  248. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/status.py +0 -0
  249. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/storage.py +0 -0
  250. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/api/team.py +0 -0
  251. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/app.py +0 -0
  252. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/assets.py +0 -0
  253. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/context.py +0 -0
  254. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/handler.py +0 -0
  255. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/jobs.py +0 -0
  256. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/interfaces/web/server.py +0 -0
  257. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/__init__.py +0 -0
  258. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/arena.py +0 -0
  259. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/bag.py +0 -0
  260. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/cases.py +0 -0
  261. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/formation.py +0 -0
  262. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/friction.py +0 -0
  263. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/glossary.py +0 -0
  264. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/group_graph.py +0 -0
  265. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/ladder.py +0 -0
  266. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/learning.py +0 -0
  267. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/market.json +0 -0
  268. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/party.py +0 -0
  269. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/reviews.py +0 -0
  270. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/roadmap.json +0 -0
  271. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/study.py +0 -0
  272. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/suggest.py +0 -0
  273. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/synthesize.py +0 -0
  274. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/knowledge/weekly.py +0 -0
  275. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/projects/__init__.py +0 -0
  276. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/projects/groups.py +0 -0
  277. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/projects/labels.py +0 -0
  278. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/projects/progress.py +0 -0
  279. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/projects/routing.py +0 -0
  280. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/projects/systems.py +0 -0
  281. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/runtime/__init__.py +0 -0
  282. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/runtime/connectors.py +0 -0
  283. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/runtime/container.py +0 -0
  284. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/runtime/install.py +0 -0
  285. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/runtime/migrate.py +0 -0
  286. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/runtime/notify.py +0 -0
  287. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/runtime/platforms/__init__.py +0 -0
  288. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/runtime/platforms/desktop.py +0 -0
  289. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/runtime/platforms/menubar.py +0 -0
  290. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/runtime/platforms/windows.py +0 -0
  291. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/runtime/statusline.py +0 -0
  292. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/runtime/tailnet.py +0 -0
  293. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/runtime/update.py +0 -0
  294. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/__init__.py +0 -0
  295. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/access.py +0 -0
  296. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/arena.py +0 -0
  297. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/identity.py +0 -0
  298. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/leaderboard.py +0 -0
  299. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/market.py +0 -0
  300. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/news.py +0 -0
  301. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sharing/people.py +0 -0
  302. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/__init__.py +0 -0
  303. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/antigravity.py +0 -0
  304. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/bob.py +0 -0
  305. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/builder.py +0 -0
  306. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/chatgpt.py +0 -0
  307. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/chats.py +0 -0
  308. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/claude/__init__.py +0 -0
  309. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/claude/export.py +0 -0
  310. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/claude/files.py +0 -0
  311. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/claude/parser.py +0 -0
  312. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/codex/__init__.py +0 -0
  313. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/codex/cloud.py +0 -0
  314. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/codex/parser.py +0 -0
  315. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/copilot.py +0 -0
  316. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/discovery.py +0 -0
  317. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/opencode.py +0 -0
  318. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/sources/prompts.py +0 -0
  319. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/storage/__init__.py +0 -0
  320. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/storage/fts.py +0 -0
  321. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/storage/kv.py +0 -0
  322. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/storage/migrations.py +0 -0
  323. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/storage/mirror.py +0 -0
  324. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/storage/postgres.py +0 -0
  325. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/storage/schema.py +0 -0
  326. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/storage/sqlite.py +0 -0
  327. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/storage/team.py +0 -0
  328. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/AGENT-ICONS.txt +0 -0
  329. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/PLEX-OFL.txt +0 -0
  330. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/adventure.js +0 -0
  331. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/agent-antigravity.svg +0 -0
  332. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/agent-bob.svg +0 -0
  333. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/agent-chatgpt.svg +0 -0
  334. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/agent-claude-ai.svg +0 -0
  335. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/agent-claude.svg +0 -0
  336. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/agent-codex.svg +0 -0
  337. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/agent-copilot.svg +0 -0
  338. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/agent-opencode.svg +0 -0
  339. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-book.webp +0 -0
  340. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-camera.webp +0 -0
  341. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-chip.webp +0 -0
  342. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-clock.webp +0 -0
  343. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-cloud.webp +0 -0
  344. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-coins.webp +0 -0
  345. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-container.webp +0 -0
  346. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-dashboard.webp +0 -0
  347. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-dex.webp +0 -0
  348. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-document.webp +0 -0
  349. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-flag.webp +0 -0
  350. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-folder.webp +0 -0
  351. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-gateway.webp +0 -0
  352. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-gears.webp +0 -0
  353. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-glitch.webp +0 -0
  354. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-globe.webp +0 -0
  355. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-laptop.webp +0 -0
  356. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-log.webp +0 -0
  357. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-lumi.webp +0 -0
  358. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-magnifier.webp +0 -0
  359. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-pip.webp +0 -0
  360. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-plug.webp +0 -0
  361. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-rack.webp +0 -0
  362. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/art-tink.webp +0 -0
  363. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/battle.js +0 -0
  364. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/boot.js +0 -0
  365. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/favicon.png +0 -0
  366. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/field.js +0 -0
  367. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/i18n.js +0 -0
  368. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/icon-180.png +0 -0
  369. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/icon-192.png +0 -0
  370. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/icon-512.png +0 -0
  371. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/icon.png +0 -0
  372. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/index.html +0 -0
  373. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/innerlatch.css +0 -0
  374. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/innerlatch.js +0 -0
  375. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/learning.js +0 -0
  376. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/manifest.webmanifest +0 -0
  377. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/panel.css +0 -0
  378. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/panel.html +0 -0
  379. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/panel.js +0 -0
  380. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/plex-mono-400.woff2 +0 -0
  381. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/plex-mono-500.woff2 +0 -0
  382. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/plex-mono-600.woff2 +0 -0
  383. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/plex-sans-400.woff2 +0 -0
  384. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/plex-sans-500.woff2 +0 -0
  385. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/plex-sans-600.woff2 +0 -0
  386. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/plex-sans-700.woff2 +0 -0
  387. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/rough.js +0 -0
  388. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/scene.js +0 -0
  389. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/web/sprites.js +0 -0
  390. {interlatch-0.28.0 → interlatch-0.28.2}/src/interlatch/windows.py +0 -0
  391. {interlatch-0.28.0 → interlatch-0.28.2}/tests/antigravity_fixture.py +0 -0
  392. {interlatch-0.28.0 → interlatch-0.28.2}/tests/codex_fixture.py +0 -0
  393. {interlatch-0.28.0 → interlatch-0.28.2}/tests/conftest.py +0 -0
  394. {interlatch-0.28.0 → interlatch-0.28.2}/tests/copilot_fixture.py +0 -0
  395. {interlatch-0.28.0 → interlatch-0.28.2}/tests/friction_fixture.py +0 -0
  396. {interlatch-0.28.0 → interlatch-0.28.2}/tests/golden.py +0 -0
  397. {interlatch-0.28.0 → interlatch-0.28.2}/tests/goldens/diagram.json +0 -0
  398. {interlatch-0.28.0 → interlatch-0.28.2}/tests/goldens/parsers/antigravity.json +0 -0
  399. {interlatch-0.28.0 → interlatch-0.28.2}/tests/goldens/parsers/bob.json +0 -0
  400. {interlatch-0.28.0 → interlatch-0.28.2}/tests/goldens/parsers/claude_code.json +0 -0
  401. {interlatch-0.28.0 → interlatch-0.28.2}/tests/goldens/parsers/codex.json +0 -0
  402. {interlatch-0.28.0 → interlatch-0.28.2}/tests/goldens/parsers/copilot.json +0 -0
  403. {interlatch-0.28.0 → interlatch-0.28.2}/tests/goldens/parsers/opencode.json +0 -0
  404. {interlatch-0.28.0 → interlatch-0.28.2}/tests/goldens/systems.json +0 -0
  405. {interlatch-0.28.0 → interlatch-0.28.2}/tests/opencode_fixture.py +0 -0
  406. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_adventure_web.py +0 -0
  407. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_analysis.py +0 -0
  408. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_antigravity.py +0 -0
  409. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_architecture.py +0 -0
  410. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_arena.py +0 -0
  411. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_artifacts.py +0 -0
  412. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_bag.py +0 -0
  413. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_battle_web.py +0 -0
  414. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_bob_analysis.py +0 -0
  415. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_boot_web.py +0 -0
  416. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_careers.py +0 -0
  417. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_case_files.py +0 -0
  418. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_cases.py +0 -0
  419. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_chat_import.py +0 -0
  420. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_codex.py +0 -0
  421. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_codex_analysis.py +0 -0
  422. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_codex_cloud.py +0 -0
  423. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_container.py +0 -0
  424. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_copilot_bob.py +0 -0
  425. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_dedicated_hub.py +0 -0
  426. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_dedupe.py +0 -0
  427. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_desktop.py +0 -0
  428. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_diagram.py +0 -0
  429. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_ee_boundary.py +0 -0
  430. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_field_web.py +0 -0
  431. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_fix_effect.py +0 -0
  432. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_formation.py +0 -0
  433. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_friction.py +0 -0
  434. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_game_mode.py +0 -0
  435. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_glossary.py +0 -0
  436. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_group_graph.py +0 -0
  437. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_group_sharing.py +0 -0
  438. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_guidance.py +0 -0
  439. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_home_agents.py +0 -0
  440. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_hub.py +0 -0
  441. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_hub_accept.py +0 -0
  442. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_hub_cookie.py +0 -0
  443. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_hub_inventory_scope.py +0 -0
  444. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_hub_leave_join.py +0 -0
  445. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_hub_news.py +0 -0
  446. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_hub_payload_privacy.py +0 -0
  447. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_hub_projects.py +0 -0
  448. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_hub_projects_listed.py +0 -0
  449. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_hub_purge.py +0 -0
  450. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_hub_send_problems.py +0 -0
  451. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_hub_sharing_race.py +0 -0
  452. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_i18n_web.py +0 -0
  453. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_ingest.py +0 -0
  454. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_integration.py +0 -0
  455. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_ladder.py +0 -0
  456. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_language.py +0 -0
  457. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_leaderboard.py +0 -0
  458. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_learning_glance.py +0 -0
  459. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_learning_interests.py +0 -0
  460. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_learning_web.py +0 -0
  461. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_leave_project.py +0 -0
  462. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_legacy_package.py +0 -0
  463. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_map_goldens.py +0 -0
  464. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_market.py +0 -0
  465. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_menubar.py +0 -0
  466. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_migrate.py +0 -0
  467. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_mirror.py +0 -0
  468. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_notify.py +0 -0
  469. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_opencode.py +0 -0
  470. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_parser.py +0 -0
  471. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_parser_goldens.py +0 -0
  472. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_party.py +0 -0
  473. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_party_map.py +0 -0
  474. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_people.py +0 -0
  475. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_people_hub.py +0 -0
  476. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_people_web.py +0 -0
  477. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_project_progress.py +0 -0
  478. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_providers.py +0 -0
  479. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_queue.py +0 -0
  480. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_regressions.py +0 -0
  481. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_release.py +0 -0
  482. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_roadmap_catalog.py +0 -0
  483. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_screen.py +0 -0
  484. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_statusline.py +0 -0
  485. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_study.py +0 -0
  486. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_suggest.py +0 -0
  487. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_suggest_cli.py +0 -0
  488. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_systems.py +0 -0
  489. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_team.py +0 -0
  490. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_team_home.py +0 -0
  491. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_update.py +0 -0
  492. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_weekly_reanalysis.py +0 -0
  493. {interlatch-0.28.0 → interlatch-0.28.2}/tests/test_windows.py +0 -0
  494. {interlatch-0.28.0 → interlatch-0.28.2}/tests/windows_smoke.py +0 -0
  495. {interlatch-0.28.0 → interlatch-0.28.2}/uv.lock +0 -0
  496. {interlatch-0.28.0 → interlatch-0.28.2}/vscode-extension/.vscodeignore +0 -0
  497. {interlatch-0.28.0 → interlatch-0.28.2}/vscode-extension/LICENSE +0 -0
  498. {interlatch-0.28.0 → interlatch-0.28.2}/vscode-extension/README.md +0 -0
  499. {interlatch-0.28.0 → interlatch-0.28.2}/vscode-extension/extension.js +0 -0
  500. {interlatch-0.28.0 → interlatch-0.28.2}/vscode-extension/media/icon.png +0 -0
  501. {interlatch-0.28.0 → interlatch-0.28.2}/vscode-extension/media/interlatch.svg +0 -0
  502. {interlatch-0.28.0 → interlatch-0.28.2}/vscode-extension/package.json +0 -0
@@ -3,6 +3,58 @@
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.28.1 (2026-10-19)
7
+
8
+ - **Profiles, first stage:** `interlatch profile create Acme --owns ~/work/acme` makes a named profile that owns a
9
+ folder (or repositories by git remote, `--remotes`). Its sessions stay off your Personal hub, a folder two profiles
10
+ could claim waits for you (`profile waiting`, `profile choose`), and `interlatch --profile Acme <command>` runs any
11
+ command for it. Sharing with each profile's own hub comes next ([Profiles](docs/profiles.md)).
12
+ - **Profiles: agents see only their profile.** With named profiles, the MCP server and the notes at session start
13
+ show an agent only what its folder's profile owns, and nothing in a folder that waits for you to choose. Lines
14
+ proposed for your user-level CLAUDE.md and AGENTS.md come only from Personal's lessons
15
+ ([What agents see](docs/profiles.md#what-agents-see)).
16
+ - **Profiles: one computer, several hubs.** A named profile joins a hub of its own
17
+ (`interlatch --profile Acme hub join …`) and sends it only the sessions it owns, read from your one archive, with its
18
+ own token and computer ID. Teammates' lessons from each hub reach only that profile's folders, and `interlatch push`
19
+ and the background job send for every hub ([Connect a profile to its hub](docs/profiles.md#connect-a-profile-to-its-hub)).
20
+ - **OpenCode analyzes sessions:** pick OpenCode as the analyzer (`interlatch install`, `--backend opencode`, or
21
+ **Status › Analysis**) and it runs `opencode run` headless with no tools, through the providers you set up in
22
+ OpenCode, with the model you choose as `provider/model`. Install asks for the model and offers a test call. The CLI
23
+ inside the OpenCode desktop app is found too ([Analysis](docs/analysis.md)).
24
+ - **Record only:** `interlatch install --no-analysis` (or **Record only** in install's list, or **Off** in
25
+ **Status › Analysis**) records sessions and never analyzes them: no model is called and nothing is sent anywhere for
26
+ analysis. Pick an analyzer later to analyze what was recorded ([Analysis](docs/analysis.md)).
27
+
28
+ ## 0.28.0 (2026-10-19)
29
+
30
+ - **Sharing knowledge only sends only what is about the project:** a computer with `share = "knowledge"` used to send
31
+ the hub the analysis model's full reply with each session, which held lessons about you (your preferences, global
32
+ lessons) that were meant to stay on your computer, and titles with secrets the summary had redacted. It now sends
33
+ only each session's details, title, summary, goal, outcome, highlights, open threads, tags and project lessons, with
34
+ secrets redacted again on the way out; never the full reply, the session's mood or friction notes. A hub drops those
35
+ from computers that haven't updated yet, and an updated hub clears what it already received, in its team store too.
36
+ Titles and friction notes are now stored redacted on your own computer as well
37
+ ([What is shared](docs/join-a-hub.md#what-is-shared)).
38
+ - **Leaving a hub leaves nothing behind for the next one:** `interlatch hub leave` (and **Leave the hub…** in
39
+ **Settings › Devices**) now also clears the folders, left projects and shared groups the computer had for that hub,
40
+ and its teammates' lessons, so a different hub joined later no longer gets the first one's folders and groups. They
41
+ are put aside, and joining the same hub again asks whether to bring them back (`--restore` / `--no-restore`).
42
+ `interlatch hub join` refuses a second hub while the computer is in one, before it sends anything there; joining the
43
+ same hub again still just renews the token. A hub that moved: `interlatch hub set-url <address>`
44
+ ([Joining your team's hub](docs/join-a-hub.md)).
45
+ - **Each hub has its own sign-in cookie:** two hubs reached under one host name (on different ports, say) no longer
46
+ sign each other's people out: a hub's cookie is named for that hub, with `__Host-` in front over HTTPS. A browser
47
+ still sends one host name's cookies to all its ports, so give every hub a host name of its own, sslip.io names
48
+ included. A browser already signed in stays signed in and moves to the new name on its next visit
49
+ ([One name per hub](docs/devices.md#one-name-per-hub)).
50
+ - **Less about your computer reaches a hub:** projects in `[sources] exclude_projects` no longer reach a hub in any
51
+ form: not their folders and git remotes, their prompts in `history.jsonl`, Codex's titles for them, or their
52
+ earlier analyses. A computer that shares knowledge of the hub's projects only now tells the hub just about the
53
+ repositories it can share from, and asks for teammates' lessons with just those. Invite codes and sign-in links are
54
+ now redacted like other credentials ([What the hub learns about this computer](docs/devices.md#what-the-hub-learns-about-this-computer)).
55
+ - **Hand-edited hub folders:** `interlatch hub leave` and `interlatch hub add-folder` no longer stop with an error
56
+ when `config.toml` lists the hub's folders in a `[hub.folders]` section of its own.
57
+
6
58
  ## 0.27.8 (2026-10-19)
7
59
 
8
60
  - **Projects sidebar reads like a tree:** groups and the hub now have headers in the sidebar's own type, each with its
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: interlatch
3
- Version: 0.28.0
3
+ Version: 0.28.2
4
4
  Summary: Shared memory for your coding agents: records every session (Claude Code, Codex, Copilot, Bob, Antigravity, OpenCode) 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,6 @@
1
+ - **Several hubs: connect your groups.** `interlatch profile` became `interlatch hubs` and `interlatch group`: add a
2
+ hub (`interlatch hubs add Acme <address> --code <code>`), then connect a group of projects to it
3
+ (`interlatch group connect "Acme work" Acme`). What the group holds goes to that hub, and changing the group on the
4
+ dashboard's Projects page moves its sessions with it. A project taken out of a connected group waits for you
5
+ instead of going back to Personal. `--profile` is now `--hub`; the old name still works
6
+ ([Several hubs on one computer](docs/profiles.md)).
@@ -0,0 +1,6 @@
1
+ - **Moving a folder takes its sessions back from the hub that had them.** When a group, a project or a waiting folder
2
+ moves to another hub (or a group is disconnected), the hub it left takes back the sessions this computer sent it,
3
+ before anything goes to the new one. One that can't be reached takes them back at the next send. Home now shows
4
+ folders that wait for you to choose a hub under **Needs you**
5
+ ([Moving takes sessions back](docs/profiles.md#moving-takes-sessions-back)). Update your hubs too: an older hub
6
+ can't take sessions back.
@@ -0,0 +1,3 @@
1
+ - **Several hubs on the dashboard.** Settings › Devices › Hubs lists this computer's hubs and their groups, adds and
2
+ joins one, and settles folders that wait for you; a group's page has **Goes to**, which connects the group to a hub
3
+ ([Several hubs on one computer](docs/profiles.md)).
@@ -14,6 +14,7 @@
14
14
  | [VS Code extension](vscode.md) | The sessions behind the open file and every file agents worked on, in VS Code's Explorer |
15
15
  | [Phone and other computers](devices.md) | The dashboard on your phone through Tailscale, and one archive for several computers (a hub) |
16
16
  | [A hub in Docker](docker.md) | Setting up a team's hub on a server, step by step: Azure, the first admin, projects, inviting the team, troubleshooting |
17
+ | [Several hubs on one computer](profiles.md) | Several teams with their own hubs on one computer: connect your groups of projects to the hub each belongs to, waiting folders, what agents see |
17
18
  | [Joining your team's hub](join-a-hub.md) | For teammates: join with the code your admin sent, add your project folder, get teammates' lessons back |
18
19
  | [A copy in Postgres](postgres.md) | Keep a copy of your archive in a Postgres database you choose (on this computer, in Docker, or in the cloud) for SQL and BI tools |
19
20
  | [What gets recorded and how analysis works](analysis.md) | Session data, knowledge kinds, the analysis pipeline and its cost |
@@ -60,6 +60,12 @@ instance, have no cache split (so no cost estimate), Bob tasks have no per-call
60
60
  background analysis and the dashboard don't see your shell's variables, so `interlatch install` offers to save it.
61
61
  Bob picks its own model. It keeps each analysis in its own task list;
62
62
  Interlatch doesn't import those as sessions.
63
+ - **OpenCode** (`backend = "opencode"`): `opencode run --standalone --format json` with an agent of Interlatch's
64
+ own that holds its instructions and denies every permission, so the model is offered no tool; a reply that
65
+ follows any tool call is thrown away. It runs through the providers you set up in OpenCode (`opencode auth
66
+ login`, or local models such as Ollama). OpenCode's free tier refuses headless runs. Interlatch finds `opencode`
67
+ on your PATH, or the CLI inside the OpenCode desktop app on a Mac. OpenCode saves each run as a session:
68
+ Interlatch reads its tokens and cost, then deletes it, and never imports runs from its work folder.
63
69
 
64
70
  - **A model provider's API** (`backend = "anthropic"`, `"bedrock"`, `"openai"`, `"azure"`, `"openrouter"`,
65
71
  `"ollama"` or `"openai-compatible"`): one plain HTTP request per call, with no tools in it, so the model can
@@ -68,10 +74,17 @@ instance, have no cache split (so no cost estimate), Bob tasks have no per-call
68
74
  Each agent's tab in **Status › Analysis** sets its model: for Claude Code, one for sessions (`analysis.model`), one
69
75
  for knowledge bases (`synthesis.model`) and one for screening imported chats (`analysis.screen_model`), each an
70
76
  alias (`sonnet`, `opus`, `haiku`, `fable`) or a full model id such as `claude-opus-5-5`; for Codex,
71
- `analysis.codex_model` (empty: Codex's default). Both share `analysis.effort`.
77
+ `analysis.codex_model` (empty: Codex's default). Both share `analysis.effort`. For OpenCode,
78
+ `analysis.opencode_model` as `provider/model`, e.g. `anthropic/claude-sonnet-5-5` or `ollama/qwen3.8` (empty:
79
+ OpenCode's default model); `opencode models` lists them.
72
80
 
73
81
  `INTERLATCH_INTERNAL=1` makes Interlatch's own hooks inert for these runs. Switch in **Status › Analysis**, with
74
82
  `interlatch config set analysis.backend codex`, or for one run with `interlatch analyze --backend codex`.
83
+
84
+ **Record only.** `backend = "none"` (`interlatch install --no-analysis`, or **Off** in **Status › Analysis**)
85
+ records sessions and never analyzes them: no model is called and nothing leaves your computer for analysis, not
86
+ for sessions, knowledge bases, weekly re-analyses, screening or glossaries. Sessions wait in the queue; pick an
87
+ analyzer later to analyze them, or analyze a few once with `interlatch analyze --backend NAME`.
75
88
  4. The JSON reply is validated leniently (with one repair pass) and stored. When a project gains
76
89
  `min_new_items` new items, its knowledge base is re-synthesized (or once a week, on the day you pick, with fewer, where you turned on
77
90
  [weekly re-analysis](dashboard.md#project-groups) for it); items that are outdated, contradicted or
@@ -210,7 +223,8 @@ interlatch config set analysis.backend openai
210
223
  Cost: with a provider, the cost is what the API reports (OpenRouter) or an estimate from the token counts at
211
224
  Anthropic's, OpenAI's or Google's list prices (Anthropic, Bedrock, OpenAI, and Gemini models on an OpenAI-compatible
212
225
  server); Azure, Ollama and other models show tokens only. Otherwise,
213
- analysis runs through your own Claude Code or Codex login, or your Bob API key (Bob reports what each analysis cost).
226
+ analysis runs through your own Claude Code, Codex or OpenCode login, or your Bob API key (Bob reports what each
227
+ analysis cost; OpenCode reports its price for the model, nothing for a subscription or a local model).
214
228
  With Claude, the reported cost is the API
215
229
  list-price equivalent: sessions averaged about $0.38 each with Sonnet (digests average ~150k characters), and
216
230
  `max_budget_usd` caps each call. Codex reports tokens but no price, so Codex analyses show no cost. On a Claude or
@@ -46,6 +46,9 @@
46
46
  | `interlatch hub people` / `hub role <email\|id> <role>` / `hub remove <email\|id>` / `hub shared-token on\|off` | On the hub: everyone with their role, the projects they see and their computers; change a role; remove someone; allow or refuse the shared token ([People and roles](devices.md#people-and-roles)) |
47
47
  | `interlatch hub add-folder <folder> --project <name>` / `hub remove-folder <folder>` / `hub folders [--list]` | On a computer that joined a hub: file a folder's sessions under a project on the hub, take a folder added by mistake back out, or show what goes where (`--list`: the hub's projects) ([Same project, different folders](devices.md#same-project-different-folders)). Sharing knowledge, `remove-folder` also has the hub delete what the computer shared from that folder ([Leaving](devices.md#leaving)) |
48
48
  | `interlatch hub leave --project <name>` / `hub rejoin --project <name>` | On a computer that shares knowledge: stop sharing to one of the hub's projects and getting its teammates' lessons, keeping what it already shared there; or start again ([Leaving](devices.md#leaving)) |
49
+ | `interlatch hubs` / `hubs add <name> [<address> --code <code>] [--all-folders]` / `hubs remove <name> [--delete-data]` | The hubs this computer sends to besides Personal's, with the groups connected to each; add one (and join it), remove one ([Several hubs on one computer](profiles.md)) |
50
+ | `interlatch group list` / `create <name> --folder <folder>…` / `add-folder` / `remove-folder <group> <folder>` / `connect <group> <hub>` / `disconnect <group>` / `where <folder>` / `waiting` / `choose <folder> <hub\|personal>` / `remove <group>` | Your groups of projects and the hub each goes to: connecting one moves its sessions so far to that hub; taking a project out of a connected group, or disconnecting it, makes it wait for you. `--dry-run` shows what would move; a hub that has sessions that move takes them back first; `--leave-on-hub` moves them even if it can't now |
51
+ | `interlatch --hub <name> hub … \| push \| config …` | Run a hub command for another of this computer's hubs: join it, push its sessions, change its settings. Recording and analysis are Personal's. `interlatch push` sends to Personal's hub and then each other one |
49
52
  | `interlatch push` | On a computer that joined a hub: send its new sessions now (the hook and the background sync do this) |
50
53
  | `interlatch container` | What the hub's Docker image runs: set the hub up from `INTERLATCH_*` variables, then serve the dashboard and sync every 15 minutes ([A hub in Docker](docker.md)) |
51
54
  | `interlatch config [edit]` | Show or edit `~/.interlatch/config.toml` |
@@ -25,9 +25,10 @@ the file. Changes apply on the next sync or worker run. `INTERLATCH_HOME` reloca
25
25
  | Key | Default | |
26
26
  | --- | --- | --- |
27
27
  | `auto` | `true` | analyze sessions automatically once they go idle |
28
- | `backend` | `claude` | what analyzes sessions: `claude` (Claude Code) or `codex` (Codex) through your own login, `bob` (IBM Bob Shell, with a Bob API key: `interlatch config set-key bob`), or a model provider's API: `anthropic`, `bedrock`, `openai`, `azure`, `openrouter`, `ollama`, `openai-compatible` (see [`[providers.<name>]`](#providers)). Also in **Status › Analysis** |
28
+ | `backend` | `claude` | what analyzes sessions: `claude` (Claude Code), `codex` (Codex) or `opencode` (OpenCode) through your own login, `bob` (IBM Bob Shell, with a Bob API key: `interlatch config set-key bob`), or a model provider's API: `anthropic`, `bedrock`, `openai`, `azure`, `openrouter`, `ollama`, `openai-compatible` (see [`[providers.<name>]`](#providers)). Or `none`: record sessions only, never analyze them (`interlatch install --no-analysis`). Also in **Status › Analysis** |
29
29
  | `model` / `effort` | `sonnet` / `medium` | Claude: any `claude --model` alias or full model id. `effort` also sets Codex's reasoning effort (`max` becomes `xhigh`). Both are in Claude Code's tab in **Status › Analysis** |
30
30
  | `codex_model` | `""` | Codex model, e.g. `gpt-5.5`; empty uses Codex's default |
31
+ | `opencode_model` | `""` | OpenCode model as `provider/model`, e.g. `ollama/qwen3.8`; empty uses OpenCode's default |
31
32
  | `screen_model` | `haiku` | model that screens imported chats (`interlatch screen`); it reads only each chat's opening, 60 chats a call |
32
33
  | `language` | `en` | the language Interlatch writes in: summaries, knowledge, knowledge bases, the playbook, glossary definitions, weekly reviews, screening reasons and the lines it proposes for `CLAUDE.md` / `AGENTS.md`. `en` or `ja`; applies to what is analyzed from then on. Also in **Status › Analysis**. The dashboard's own language is chosen in the dashboard, per browser |
33
34
  | `max_budget_usd` | `3.0` | spend cap per `claude -p` call, API-equivalent USD (Codex reports tokens only) |
@@ -37,7 +38,7 @@ the file. Changes apply on the next sync or worker run. `INTERLATCH_HOME` reloca
37
38
  | `backfill` | `true` | also analyze sessions recorded before install (newest first) |
38
39
  | `chunk_chars` | `150000` | characters of condensed transcript per call; longer sessions are map-reduced |
39
40
  | `timeout_seconds` | `900` | wall-clock limit per call |
40
- | `claude_bin` / `codex_bin` / `bob_bin` | `""` | path to `claude` / `codex` / Bob Shell's `bob` (found automatically when empty) |
41
+ | `claude_bin` / `codex_bin` / `bob_bin` / `opencode_bin` | `""` | path to `claude` / `codex` / Bob Shell's `bob` / `opencode` (found automatically when empty; for OpenCode, also the CLI inside its desktop app) |
41
42
 
42
43
  ## `[providers.*]`
43
44
 
@@ -14,6 +14,7 @@
14
14
  | [VS Code 拡張機能](vscode.md) | 開いているファイルと、エージェントが作業したすべてのファイルの背後にあるセッションを、VS Code のエクスプローラーに表示 |
15
15
  | [スマートフォンとほかのコンピューター](devices.md) | Tailscale 経由でスマートフォンからダッシュボードを開く、複数のコンピューターで 1 つのアーカイブ(ハブ) |
16
16
  | [Docker でハブを動かす](docker.md) | サーバーでチームのハブを用意する手順:Azure、最初の管理者、プロジェクト、チームの招待、トラブルシューティング |
17
+ | [1 台のコンピューターで複数のハブ](profiles.md) | それぞれにハブがある複数のチームを 1 台で:プロジェクトのグループをそれぞれのハブにつなぐ、選択を待つフォルダー、エージェントに見えるもの |
17
18
  | [チームのハブに参加する](join-a-hub.md) | チームメイト向け:管理者から届いたコードで参加し、プロジェクトのフォルダーを加え、チームメイトのナレッジを受け取る |
18
19
  | [Postgres へのコピー](postgres.md) | アーカイブのコピーを、選んだ Postgres データベース(このコンピューター、Docker、クラウド)に置いて SQL や BI ツールで使う |
19
20
  | [記録される内容と分析の仕組み](analysis.md) | セッションのデータ、ナレッジの種類、分析の流れとその費用 |
@@ -54,6 +54,12 @@ Codex、Copilot、Bob、Antigravity、OpenCode のセッションも、ログに
54
54
  **Status › Analysis** の IBM Bob タブ。`BOB_API_KEY` も使えますが、それを持つターミナルからだけです。バックグラウンドの
55
55
  分析とダッシュボードはシェルの変数を見ないため、`interlatch install` が保存を提案します。モデルは Bob が選びます。Bob は各分析を自身のタスク一覧に残しますが、Interlatch はそれをセッションとして
56
56
  取り込みません。
57
+ - **OpenCode**(`backend = "opencode"`):`opencode run --standalone --format json` を、Interlatch 専用のエージェントで
58
+ 実行します。このエージェントは Interlatch の指示を持ち、すべての権限を拒否するので、モデルにはツールが提示されません。
59
+ ツール呼び出しのあとの応答は破棄されます。OpenCode に設定したプロバイダー(`opencode auth login`、または Ollama などの
60
+ ローカルモデル)を通じて動きます。OpenCode の無料枠はヘッドレス実行を受け付けません。Interlatch は PATH 上の `opencode`、
61
+ または Mac では OpenCode デスクトップアプリに同梱の CLI を見つけます。OpenCode は各実行をセッションとして保存しますが、
62
+ Interlatch はそのトークン数と費用を読んだあとに削除し、作業フォルダーでの実行は取り込みません。
57
63
 
58
64
  - **モデルプロバイダーの API**(`backend = "anthropic"`、`"bedrock"`、`"openai"`、`"azure"`、`"openrouter"`、
59
65
  `"ollama"`、`"openai-compatible"`):呼び出しごとに素の HTTP リクエストを 1 回送ります。ツールは含まないので、モデルは
@@ -62,11 +68,18 @@ Codex、Copilot、Bob、Antigravity、OpenCode のセッションも、ログに
62
68
  **Status › Analysis** の各エージェントのタブでモデルを設定できます。Claude Code では、セッション用(`analysis.model`)、
63
69
  ナレッジベース用(`synthesis.model`)、取り込んだチャットの選別用(`analysis.screen_model`)を、エイリアス(`sonnet`、
64
70
  `opus`、`haiku`、`fable`)か `claude-opus-5-5` のような完全なモデル ID で指定します。Codex では `analysis.codex_model`
65
- (空なら Codex の既定)。どちらも `analysis.effort` を共有します。
71
+ (空なら Codex の既定)。どちらも `analysis.effort` を共有します。OpenCode では `analysis.opencode_model` を
72
+ `provider/model` の形で指定します。例:`anthropic/claude-sonnet-5-5`、`ollama/qwen3.8`(空なら OpenCode の既定のモデル)。
73
+ 一覧は `opencode models` で見られます。
66
74
 
67
75
  これらの実行中は `INTERLATCH_INTERNAL=1` によって Interlatch 自身のフックが無効になります。**Status › Analysis**、
68
76
  `interlatch config set analysis.backend codex`、または 1 回の実行だけなら `interlatch analyze --backend codex` で
69
77
  切り替えられます。
78
+
79
+ **記録のみ。** `backend = "none"`(`interlatch install --no-analysis`、または **Status › Analysis** の **オフ**)では、
80
+ セッションを記録するだけで分析はしません。モデルは呼ばれず、分析のために何もコンピューターの外へ出ません。セッション、
81
+ ナレッジベース、毎週の再分析、選別、用語集のどれも同じです。セッションはキューで待つので、あとで分析エンジンを選べば
82
+ 分析されます。いくつかだけ 1 回分析するなら `interlatch analyze --backend NAME` を使います。
70
83
  4. JSON の応答は寛容に検証され(修復は 1 回まで)、保存されます。プロジェクトに `min_new_items` 件の新しい項目がたまると
71
84
  ([毎週の再分析](dashboard.md#プロジェクトのグループ)をオンにしたプロジェクトでは、それより少なくても週に 1 回、選んだ曜日に)、
72
85
  そのプロジェクトのナレッジベースが再統合され、古くなった項目、矛盾する項目、重複した項目は *superseded*(置き換え済み)になり、
@@ -187,7 +200,7 @@ interlatch config set analysis.backend openai
187
200
 
188
201
  プロバイダーを使う場合の費用は、API が報告する額(OpenRouter)か、トークン数から Anthropic や OpenAI の定価で見積もった額
189
202
  (Anthropic、Bedrock、OpenAI)です。Azure、Ollama、その他のサーバーはトークン数だけを表示します。それ以外では、
190
- 分析はあなた自身の Claude Code または Codex のログイン、または Bob の API キー(Bob は分析ごとの費用を報告します)を通じて行われます。Claude の場合、表示される費用は API 定価に換算した
203
+ 分析はあなた自身の Claude Code、Codex、OpenCode のログイン、または Bob の API キー(Bob は分析ごとの費用を報告します。OpenCode はそのモデルの価格を報告し、サブスクリプションやローカルモデルでは 0 です)を通じて行われます。Claude の場合、表示される費用は API 定価に換算した
191
204
  金額です。Sonnet ではセッションあたり平均約 $0.38 でした(要約の平均は約 15 万文字)。`max_budget_usd` で 1 回の呼び出しの上限を
192
205
  設定できます。Codex はトークン数を報告しますが価格は報告しないため、Codex による分析には費用が表示されません。Claude や ChatGPT の
193
206
  サブスクリプションでは、請求ではなくプランの使用枠から消費されます。`interlatch analyze --pending --dry-run` で、使う前に未分析分の
@@ -46,6 +46,9 @@
46
46
  | `interlatch hub people` / `hub role <email\|id> <role>` / `hub remove <email\|id>` / `hub shared-token on\|off` | ハブで:全員のロール、見えるプロジェクト、コンピューターの一覧/ロールを変える/人を外す/共有トークンを許すか拒むか([利用者とロール](devices.md#利用者とロール)) |
47
47
  | `interlatch hub add-folder <folder> --project <name>` / `hub remove-folder <folder>` / `hub folders [--list]` | ハブに参加したコンピューターで:フォルダーのセッションをハブのプロジェクトに入れる/間違えて追加したフォルダーを外す/どこに入るかを表示(`--list`:ハブのプロジェクト一覧)([同じプロジェクト、別のフォルダー](devices.md#同じプロジェクト別のフォルダー))。ナレッジを共有しているときは、`remove-folder` でそのフォルダーから共有したものもハブが削除します([やめるとき](devices.md#やめるとき)) |
48
48
  | `interlatch hub leave --project <name>` / `hub rejoin --project <name>` | ナレッジを共有するコンピューターで:ハブのプロジェクトの一つへの共有とチームメイトのナレッジの受け取りをやめる(すでに共有したものは残る)、または再開する([やめるとき](devices.md#やめるとき)) |
49
+ | `interlatch hubs` / `hubs add <name> [<address> --code <code>] [--all-folders]` / `hubs remove <name> [--delete-data]` | Personal 以外にこのコンピューターが送るハブと、それぞれにつないだグループの一覧。追加する(参加もする)、削除する([1 台のコンピューターで複数のハブ](profiles.md)) |
50
+ | `interlatch group list` / `create <name> --folder <folder>…` / `add-folder` / `remove-folder <group> <folder>` / `connect <group> <hub>` / `disconnect <group>` / `where <folder>` / `waiting` / `choose <folder> <hub\|personal>` / `remove <group>` | プロジェクトのグループと、それぞれの送り先のハブ:つなぐと、これまでのセッションもそのハブに移る。つないだグループからプロジェクトを外す、または接続を外すと、あなたの選択を待つ。`--dry-run` は移るものの表示だけ、移るセッションを持つハブは先にそれを取り下げる。`--leave-on-hub` は今取り下げられなくても移す |
51
+ | `interlatch --hub <name> hub … \| push \| config …` | このコンピューターのほかのハブでハブのコマンドを実行する:参加する、セッションを送る、設定を変える。記録と分析は Personal が行います。`interlatch push` は Personal のハブ、次にほかの各ハブへ送ります |
49
52
  | `interlatch push` | ハブに参加したコンピューターで:新しいセッションを今すぐ送る(フックとバックグラウンド同期も送ります) |
50
53
  | `interlatch container` | ハブの Docker イメージが実行するコマンド:`INTERLATCH_*` 変数からハブを設定し、ダッシュボードを提供して 15 分ごとに同期([Docker でハブを動かす](docker.md)) |
51
54
  | `interlatch config [edit]` | `~/.interlatch/config.toml` を表示または編集 |
@@ -25,9 +25,10 @@
25
25
  | キー | 既定値 | |
26
26
  | --- | --- | --- |
27
27
  | `auto` | `true` | アイドルになったセッションを自動で分析する |
28
- | `backend` | `claude` | セッションを分析するもの:あなた自身のログインで `claude`(Claude Code)または `codex`(Codex)、Bob の API キーで `bob`(IBM Bob Shell。`interlatch config set-key bob`)、またはモデルプロバイダーの API:`anthropic`、`bedrock`、`openai`、`azure`、`openrouter`、`ollama`、`openai-compatible`([`[providers.<name>]`](#providers) を参照)。**Status › Analysis** でも変更できます |
28
+ | `backend` | `claude` | セッションを分析するもの:あなた自身のログインで `claude`(Claude Code)、`codex`(Codex)、`opencode`(OpenCode)、Bob の API キーで `bob`(IBM Bob Shell。`interlatch config set-key bob`)、またはモデルプロバイダーの API:`anthropic`、`bedrock`、`openai`、`azure`、`openrouter`、`ollama`、`openai-compatible`([`[providers.<name>]`](#providers) を参照)。または `none`:セッションを記録するだけで分析しません(`interlatch install --no-analysis`)。**Status › Analysis** でも変更できます |
29
29
  | `model` / `effort` | `sonnet` / `medium` | Claude:`claude --model` の任意のエイリアスか完全なモデル ID。`effort` は Codex の推論の強さにも使われます(`max` は `xhigh` になります)。どちらも **Status › Analysis** の Claude Code タブで変更できます |
30
30
  | `codex_model` | `""` | Codex のモデル。例:`gpt-5.5`。空の場合は Codex の既定のモデルを使います |
31
+ | `opencode_model` | `""` | OpenCode のモデル(`provider/model`)。例:`ollama/qwen3.8`。空の場合は OpenCode の既定のモデルを使います |
31
32
  | `screen_model` | `haiku` | 取り込んだチャットを選別するモデル(`interlatch screen`)。各チャットの冒頭だけを、1 回の呼び出しで 60 件ずつ読みます |
32
33
  | `language` | `en` | Interlatch が書く言語:要約、ナレッジ、ナレッジベース、プレイブック、用語集の定義、週次の振り返り、選別の理由、`CLAUDE.md` / `AGENTS.md` に提案する行。`en` または `ja`。変更したあとに分析するものから反映されます。**Status › Analysis** でも変更できます。ダッシュボード自体の言語は、ダッシュボードでブラウザーごとに選びます |
33
34
  | `max_budget_usd` | `3.0` | `claude -p` の呼び出し 1 回あたりの費用上限(API 換算の USD。Codex はトークン数だけを報告します) |
@@ -37,7 +38,7 @@
37
38
  | `backfill` | `true` | インストール前に記録されたセッションも分析する(新しい順) |
38
39
  | `chunk_chars` | `150000` | 1 回の呼び出しに渡す、まとめたトランスクリプトの文字数。これより長いセッションは map-reduce で処理します |
39
40
  | `timeout_seconds` | `900` | 呼び出し 1 回あたりの実時間の上限 |
40
- | `claude_bin` / `codex_bin` / `bob_bin` | `""` | `claude` / `codex` / Bob Shell の `bob` のパス(空の場合は自動で検出) |
41
+ | `claude_bin` / `codex_bin` / `bob_bin` / `opencode_bin` | `""` | `claude` / `codex` / Bob Shell の `bob` / `opencode` のパス(空の場合は自動で検出。OpenCode はデスクトップアプリに同梱の CLI も探します) |
41
42
 
42
43
  ## `[providers.*]`
43
44
 
@@ -0,0 +1,112 @@
1
+ # 1 台のコンピューターで複数のハブ
2
+
3
+ [← Interlatch](../../README.ja.md) · [ドキュメント一覧](README.md)
4
+
5
+ コンピューターが参加できるハブは一つです。自分のプロジェクトと取引先のプロジェクトのように、それぞれにハブがある複数のチームで働くときは、**プロジェクトのグループ**を、それぞれが属するハブにつなぎます。そうすると、各フォルダーのセッションは一つのハブにだけ届き、そこで作業するエージェントにはそのハブのものだけが見えます。
6
+
7
+ - **Personal**(`~/.interlatch`)は、これまでどおり、すべてのエージェントのすべてのセッションを記録・分析します。このコンピューターにあるすべてのものの元のコピーで、自分のハブに送ることもできます。
8
+ - **ほかのハブ**には、ここでの名前(たとえば Acme)を付けます。そのハブにつないだグループのセッションが届きます。読むのは Personal のアーカイブで、コピーは作らず、分析も二度しません。
9
+
10
+ ## ハブを追加してグループをつなぐ
11
+
12
+ 1. ハブの管理者から受け取った招待コードでハブを追加します([チームのハブに参加する](join-a-hub.md))。
13
+
14
+ ```bash
15
+ interlatch hubs add Acme https://hub.acme.example --code XXXX-XXXX-XXXX
16
+ ```
17
+
18
+ 2. そのハブに属するフォルダーのグループを作ります。ダッシュボードの「プロジェクト」ページにあるグループも使えます。
19
+
20
+ ```bash
21
+ interlatch group create "Acme work" --folder ~/work/acme --folder ~/clients/acme-site
22
+ ```
23
+
24
+ 3. グループをハブにつなぎます。
25
+
26
+ ```bash
27
+ interlatch group connect "Acme work" Acme
28
+ ```
29
+
30
+ グループのフォルダーですでに記録されたセッションは Acme に移り、それ以降は Acme のハブに送られます。Personal のハブがすでに持っているものは、先にそのハブが取り下げます([移すとハブから取り下げる](#moving-takes-sessions-back))。`--dry-run` を付けると、何も変えずに、移るものと、そのうちハブが持っている数を表示します。
31
+
32
+ **ダッシュボードでは:** **設定 › デバイス › ハブ**でハブを追加し(名前、アドレス、招待コード)、グループのページの**送り先**で、そのグループのセッションを送るハブを選びます。
33
+
34
+ ほかのコンピューターと同じく、ハブに送られるのは、そのハブのプロジェクトに追加したフォルダーのものだけです(`interlatch --hub Acme hub add-folder ~/work/acme/app --project App`)。`--all-folders` を付けて参加した場合は別です。
35
+
36
+ ## グループで決まる
37
+
38
+ つないだグループに入っているものが、そのハブに送られます。グループのフォルダーとその下のすべて、そして「プロジェクト」ページで手で入れたプロジェクトです。グループを変えると、これまでのセッションも含めてハブがそれに従います。
39
+
40
+ | すること | そこにあるセッション |
41
+ | --- | --- |
42
+ | つないだグループにフォルダーを加える、プロジェクトを入れる | そのハブに移る |
43
+ | つないだグループからプロジェクトを外す | あなたの選択を待つ(下記)。勝手に Personal には戻らない |
44
+ | つないだグループのフォルダーの中に、どのハブにもつながないグループを作る | あなたの選択を待つ |
45
+ | つないだグループのフォルダーの中のグループを、別のハブにつなぐ | そのハブに移る。狭いほうのグループが優先 |
46
+ | グループの接続を外す(`interlatch group disconnect "Acme work"`) | あなたの選択を待つ |
47
+
48
+ <a id="moving-takes-sessions-back"></a>
49
+
50
+ ### 移すとハブから取り下げる
51
+
52
+ セッションが置かれるハブは一度に一つです。変更でセッションがあるハブから離れるとき(別のハブへ、またはあなたの選択待ちへ)、そのハブは、このコンピューターが送ったものを取り下げます。要約とナレッジが、そのハブとチームストアから消えます。これは新しいハブに何かを送る前に行います。あとでそのハブに戻すと、もう一度送られます。
53
+
54
+ ハブに届かないとき、またはこのコンピューターがまだそのハブに送っている最中のときは、何も変えず、理由を表示します(ダッシュボードでも同じ)。あとでやり直すか、そのまま移してください(`--leave-on-hub`、またはダッシュボードの確認で **OK**)。その場合、次にこのコンピューターがそのハブに送るときに取り下げます。このバージョンより古いハブは取り下げができません。ハブを更新するか、そのまま移してください。そのハブのコピーは残ります。
55
+
56
+ ハブの削除(`interlatch hubs remove`)では何も取り下げません。先にそのハブから抜けてください。
57
+
58
+ 一つのフォルダーが属せるハブは一つです。二つのハブのグループを同じフォルダーにつなぐことはできません。
59
+
60
+ ## 選択を待つフォルダー
61
+
62
+ 複数のハブのものになりうるフォルダーや、グループが手放したフォルダーは**選択を待ちます**。Personal は記録・分析を続けますが、あなたが選ぶまで、どのハブにも送られず、どのエージェントにも見えません。
63
+
64
+ ```bash
65
+ interlatch group waiting
66
+ interlatch group choose ~/work/acme/notes Acme # または personal
67
+ interlatch group where ~/work/acme/app # フォルダーがどのハブに行くか、その理由
68
+ ```
69
+
70
+ **設定 › デバイス › ハブ**にも一覧があり、それぞれに**選ぶ**ボタンがあります。**ホーム**の**あなたの対応待ち**にも表示されます。あるフォルダーが選択待ちにしているプロジェクト(つないだグループの中にある、どのハブにもつないでいないグループ)は、そのフォルダーの下にまとめて表示します。
71
+
72
+ ## エージェントに見えるもの
73
+
74
+ Interlatch がエージェントに渡すもの([MCP サーバー](mcp.md)のツールと、セッション開始時のメモ)は、エージェントが動くフォルダーで決まります。
75
+
76
+ - **ハブにつないだグループのフォルダーでは:** そのハブのセッション、ナレッジ、ナレッジベース、チームメイトのナレッジだけ。
77
+ - **それ以外の場所では:** Personal のものだけ。
78
+ - **選択を待つフォルダーでは:** 何もありません。MCP のツールは、そのフォルダーがあなたの選択を待っていると伝えます。
79
+
80
+ すべてのプロジェクトをまとめて作るもの(全体のプレイブック、ほかのハブのプロジェクトにも出てくる用語集の用語、テーマ、週次レビュー)は、ほかのハブがある間はエージェントに見せません。ダッシュボードには引き続きすべて表示されます。
81
+
82
+ すべてのフォルダーでエージェントが読むユーザーレベルの指示ファイル(`~/.claude/CLAUDE.md`、`~/.codex/AGENTS.md`)に Interlatch が提案する行は、Personal のナレッジからだけ作ります。ほかのハブのセッションで得たナレッジは、そのプロジェクト自身のファイルに提案します([提案](suggestions.md))。
83
+
84
+ ## コマンド
85
+
86
+ | 目的 | 実行するコマンド |
87
+ | --- | --- |
88
+ | ハブとそのグループの一覧 | `interlatch hubs` |
89
+ | ハブを追加して参加する | `interlatch hubs add <name> [<address> --code <code>] [--all-folders]` |
90
+ | ハブを削除する | `interlatch hubs remove <name> [--delete-data]`(先に抜けておく:`interlatch --hub <name> hub leave`) |
91
+ | グループと送り先の一覧 | `interlatch group list` |
92
+ | グループを作る、フォルダーを変える | `interlatch group create <name> --folder <folder>…`、`group add-folder` / `remove-folder <group> <folder>` |
93
+ | グループをつなぐ、外す | `interlatch group connect <group> <hub>`、`group disconnect <group>` |
94
+ | ほかのハブのハブコマンドを実行する | `interlatch --hub <name> hub …` / `push` / `config …` |
95
+
96
+ `interlatch push` とバックグラウンドの処理は、Personal のハブ、次にほかの各ハブへ送ります。記録、分析、ダッシュボードは Personal が行います。`--hub` を付けて実行できるのは `hub`、`push`、`config` だけです。
97
+
98
+ ## 複数のハブとの共有
99
+
100
+ - **ナレッジだけ。** どのハブにも、要約とプロジェクトのナレッジだけを送り、トランスクリプトは送りません。トランスクリプトを送るとすべてのハブのセッションが含まれてしまうため、ほかのハブがある間は Personal もトランスクリプトを送りません:`interlatch config set hub.share knowledge`。
101
+ - **各ハブに一度だけ。** このコンピューターがすでに送っているハブへの参加は、何も送る前に断られます。
102
+ - **自分の ID。** ハブごとにトークンとコンピューターの ID が別なので、二つのハブが ID でこのコンピューターを突き合わせることはできません。ただし、どのハブにもコンピューターの名前は表示されます。ハブに見せる名前は `~/.interlatch/profiles/<id>/machine.json` で変えられます。
103
+ - **自分のチームメイト。** ハブから届いたチームメイトのナレッジはそのハブのものとして保存し、エージェントにはそのフォルダーでだけ見せます。一つのハブから抜けても(`interlatch --hub Acme hub leave`)、消えるのはそのハブのものだけです。
104
+ - **Personal のハブ**には Personal のセッションだけが届きます。ハブへのあいさつで伝えるリポジトリやフォルダーにも、ほかのハブのものは含まれません。
105
+
106
+ ## 保存場所
107
+
108
+ `~/.interlatch/profiles.toml` に、ほかのハブ、それぞれにつないだグループ、そこから決まるフォルダー、あなたの選択が入ります。読めるのはあなただけです。このファイルが読めないときは、直すまでどのハブにも何も共有しません。ハブごとに専用のフォルダー `~/.interlatch/profiles/<id>` があり、トークン、コンピューターの ID、共有の状態が入ります。
109
+
110
+ 最初にほかのハブを追加すると、Personal のアーカイブに各セッションの属するハブを記録する `session_owner` テーブルができます。ほかのハブのないアーカイブは変更されません。
111
+
112
+ **0.28.1 から:** `interlatch profile` は `interlatch hubs` と `interlatch group` になり、`--profile` は `--hub` になりました(古い名前も使えます)。`--owns` でプロファイルに与えたフォルダーは、そのハブのものとして残ります。
@@ -0,0 +1,145 @@
1
+ # Several hubs on one computer
2
+
3
+ [← Interlatch](../README.md) · [Docs index](README.md)
4
+
5
+ A computer joins one hub. If you work for more than one team, such as your own projects and a client's, each with
6
+ its own hub, connect your **groups of projects** to the hub each one belongs to. Each folder's sessions then reach one
7
+ hub only, and agents working there see only what belongs to it.
8
+
9
+ - **Personal** (`~/.interlatch`) records and analyzes every session from every agent, as always. It's the master copy
10
+ of everything on this computer, and it may send to a hub of its own.
11
+ - **Another hub** has a name here, such as Acme. It gets the sessions in the groups you connect to it, read from
12
+ Personal's archive: no second copy, and nothing analyzed twice.
13
+
14
+ <a id="connect-a-profile-to-its-hub"></a>
15
+
16
+ ## Add a hub and connect a group
17
+
18
+ 1. Add the hub, with the invite code its admin sent ([Joining your team's hub](join-a-hub.md)):
19
+
20
+ ```bash
21
+ interlatch hubs add Acme https://hub.acme.example --code XXXX-XXXX-XXXX
22
+ ```
23
+
24
+ 2. Make a group of the folders that belong to it, or use one you already have on the dashboard's **Projects** page:
25
+
26
+ ```bash
27
+ interlatch group create "Acme work" --folder ~/work/acme --folder ~/clients/acme-site
28
+ ```
29
+
30
+ 3. Connect the group to the hub:
31
+
32
+ ```bash
33
+ interlatch group connect "Acme work" Acme
34
+ ```
35
+
36
+ The sessions already recorded in the group's folders move to Acme, and go to Acme's hub from then on. Any that
37
+ Personal's hub already has, it takes back first (see [Moving takes sessions back](#moving-takes-sessions-back)).
38
+ `--dry-run` shows what would move, and how many of them a hub has, without changing anything.
39
+
40
+ **On the dashboard:** **Settings › Devices › Hubs** adds a hub (its name, address and invite code), and a group's page
41
+ has **Goes to**, where you pick the hub its sessions go to.
42
+
43
+ As on any computer, a hub gets only the folders added to one of its projects
44
+ (`interlatch --hub Acme hub add-folder ~/work/acme/app --project App`), unless you joined with `--all-folders`.
45
+
46
+ ## Groups decide
47
+
48
+ What a connected group holds goes to its hub: its folders and everything below them, and projects you put in it by
49
+ hand on the **Projects** page. Change the group and its hub follows, sessions so far included:
50
+
51
+ | You | The sessions there |
52
+ | --- | --- |
53
+ | Add a folder to a connected group, or put a project in it | Move to its hub |
54
+ | Take a project out of a connected group | Wait for you (below), never back to Personal on their own |
55
+ | Make a group inside a connected group's folder, connected to no hub | Wait for you |
56
+ | Connect a group to another hub inside a connected group's folder | Go to that hub: the narrower group wins |
57
+ | Disconnect a group (`interlatch group disconnect "Acme work"`) | Wait for you |
58
+
59
+ <a id="moving-takes-sessions-back"></a>
60
+
61
+ ### Moving takes sessions back
62
+
63
+ A session is on one hub at a time. When a change moves sessions away from a hub (to another hub, or to wait for
64
+ you), that hub takes back the ones this computer sent it: their summaries and lessons go, there and in its team
65
+ store. This happens before anything goes to the new hub. A session chosen for that hub again is simply sent again.
66
+
67
+ If the hub can't be reached, or this computer is still sending to it, nothing changes, on the dashboard too, and
68
+ you're told why. Try again later, or move them anyway (`--leave-on-hub`, or **OK** on the dashboard's question): the
69
+ hub takes them back the next time this computer sends to it. A hub older than this version can't take sessions back.
70
+ Update it, or move them anyway and its copies stay there.
71
+
72
+ Removing a hub (`interlatch hubs remove`) takes nothing back: leave it first.
73
+
74
+ A folder can belong to one hub: connecting two hubs' groups to the same folder is refused.
75
+
76
+ ## Waiting folders
77
+
78
+ A folder that could belong to more than one hub, or that a group let go, **waits**. Personal still records and
79
+ analyzes its sessions, but no hub gets them and no agent sees them until you choose:
80
+
81
+ ```bash
82
+ interlatch group waiting
83
+ interlatch group choose ~/work/acme/notes Acme # or: personal
84
+ interlatch group where ~/work/acme/app # who gets a folder, and why
85
+ ```
86
+
87
+ **Settings › Devices › Hubs** lists them too, with a **Choose** for each, and **Home** shows them under **Needs you**. Projects a folder holds waiting (a group
88
+ connected to no hub inside a connected one) are listed once, under that folder.
89
+
90
+ ## What agents see
91
+
92
+ What Interlatch gives an agent depends on the folder it runs in: the [MCP server](mcp.md)'s tools and the notes at
93
+ the start of each session.
94
+
95
+ - **In a folder of a group connected to a hub:** that hub's sessions, lessons, knowledge bases and teammates' lessons
96
+ only.
97
+ - **Anywhere else:** Personal's only.
98
+ - **In a waiting folder:** nothing. The MCP tools say the folder waits for you to choose.
99
+
100
+ What is made from every project at once (the global playbook, glossary terms seen in another hub's projects, themes
101
+ and weekly reviews) isn't shown to agents while you have another hub. The dashboard still shows everything.
102
+
103
+ Lines Interlatch proposes for your user-level instruction files (`~/.claude/CLAUDE.md`, `~/.codex/AGENTS.md`), which
104
+ agents read in every folder, come only from Personal's lessons. A lesson another hub's sessions taught is proposed for
105
+ that project's own files instead ([Suggestions](suggestions.md)).
106
+
107
+ ## Commands
108
+
109
+ | To | Run |
110
+ | --- | --- |
111
+ | List the hubs and their groups | `interlatch hubs` |
112
+ | Add a hub, and join it | `interlatch hubs add <name> [<address> --code <code>] [--all-folders]` |
113
+ | Remove a hub | `interlatch hubs remove <name> [--delete-data]` (leave it first: `interlatch --hub <name> hub leave`) |
114
+ | List your groups and where each goes | `interlatch group list` |
115
+ | Make a group, change its folders | `interlatch group create <name> --folder <folder>…`, `group add-folder` / `remove-folder <group> <folder>` |
116
+ | Connect a group, or disconnect it | `interlatch group connect <group> <hub>`, `group disconnect <group>` |
117
+ | Run a hub command for another hub | `interlatch --hub <name> hub …` / `push` / `config …` |
118
+
119
+ `interlatch push` and the background job send to Personal's hub, then each other hub. Recording, analysis and the
120
+ dashboard are Personal's: with `--hub`, only `hub`, `push` and `config` run.
121
+
122
+ ## Sharing with several hubs
123
+
124
+ - **Knowledge only.** Every hub gets summaries and project lessons, never transcripts. A transcript upload would
125
+ carry every hub's sessions, so while you have another hub, Personal won't send transcripts:
126
+ `interlatch config set hub.share knowledge`.
127
+ - **Each hub once.** Joining a hub that this computer already sends to is refused before anything is sent.
128
+ - **Its own identity.** Each hub gets its own token and computer ID, so two hubs can't match this computer by its ID.
129
+ Each hub still shows the computer's name: change the name a hub sees in `~/.interlatch/profiles/<id>/machine.json`.
130
+ - **Its own teammates.** Teammates' lessons a hub sends are kept for that hub, and agents see them only in its
131
+ folders. Leaving one hub (`interlatch --hub Acme hub leave`) removes only that hub's.
132
+ - **Personal's hub** gets only Personal's sessions. The repositories and folders its hello names leave out what the
133
+ other hubs own.
134
+
135
+ ## Where it's kept
136
+
137
+ `~/.interlatch/profiles.toml` lists the other hubs, the groups connected to each, the folders that follows from, and
138
+ your choices. Only you can read it. If it can't be read, nothing is shared with any hub until it's fixed. Each hub
139
+ also has a folder of its own, `~/.interlatch/profiles/<id>`, with its token, computer ID and sharing state.
140
+
141
+ Personal's archive gets a `session_owner` table, the hub each session belongs to, once the first other hub is added.
142
+ An archive without one is never changed.
143
+
144
+ **From 0.28.1:** `interlatch profile` became `interlatch hubs` and `interlatch group`, and `--profile` is now `--hub`
145
+ (the old name still works). Folders a profile was given with `--owns` stay that hub's.
@@ -75,6 +75,7 @@ nav:
75
75
  - Phone and other computers: devices.md
76
76
  - A hub in Docker: docker.md
77
77
  - Joining your team's hub: join-a-hub.md
78
+ - Several hubs on one computer: profiles.md
78
79
  - A copy in Postgres: postgres.md
79
80
  - Reference:
80
81
  - What gets recorded and how analysis works: analysis.md
@@ -97,6 +98,7 @@ nav:
97
98
  - スマートフォンとほかのコンピューター: ja/devices.md
98
99
  - Docker でハブを動かす: ja/docker.md
99
100
  - チームのハブに参加する: ja/join-a-hub.md
101
+ - 1 台のコンピューターで複数のハブ: ja/profiles.md
100
102
  - Postgres へのコピー: ja/postgres.md
101
103
  - 記録される内容と分析の仕組み: ja/analysis.md
102
104
  - 設定: ja/configuration.md
@@ -10,7 +10,7 @@ from ..core.i18n import tr
10
10
  from ..core.util import local_str, one_line, parse_ts, to_iso, utcnow
11
11
  from ..storage.kv import kv_get
12
12
  from .runners.base import Runner
13
- from .runners.factory import make_runner
13
+ from .runners.factory import OFF, make_runner
14
14
 
15
15
  PAUSE_KEY = "analysis_paused_until"
16
16
 
@@ -91,6 +91,8 @@ def queue_block(conn, cfg: Config, runner: Runner | None = None) -> str | None:
91
91
  paused = kv_get(conn, PAUSE_KEY)
92
92
  if paused and paused > to_iso(utcnow()):
93
93
  return tr("analysis is paused until {when} (usage limit); it resumes by itself", when=local_str(paused, "%m-%d %H:%M"))
94
+ if cfg.analysis.backend == OFF:
95
+ return tr("analysis is off (record only): pick an analyzer in Status › Analysis to analyze sessions")
94
96
  if not cfg.analysis.auto:
95
97
  return tr("automatic analysis is off (analysis.auto); analyze it from its page or with `interlatch analyze`")
96
98
  runner = runner or make_runner(cfg)
@@ -1,5 +1,5 @@
1
- """Run a headless coding agent with structured output: Claude Code (`claude -p`), Codex (`codex exec`) or IBM Bob;
2
- or, through api.py, a model provider's API.
1
+ """Run a headless coding agent with structured output: Claude Code (`claude -p`), Codex (`codex exec`), IBM Bob or
2
+ OpenCode (`opencode run`); or, through api.py, a model provider's API. Or nothing: backend "none" only records.
3
3
 
4
4
  Agent runs use the developer's own install and login of the chosen agent (`analysis.backend`).
5
5
  Each call is isolated: no session is persisted (so analyses never show up as sessions), user hooks,
@@ -63,6 +63,10 @@ LIMIT_MARKERS = (
63
63
  "refresh token",
64
64
  "log in again",
65
65
  )
66
+ # An agent whose tools are all off can still write a tool call into its reply (Bob, OpenCode): saying so up front makes
67
+ # that rare.
68
+ NO_TOOLS = ("You have no tools here: don't call or write one (no list_files, read_file or the like). Everything you "
69
+ "need is in the message; answer it directly.")
66
70
 
67
71
 
68
72
  class Runner: