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.
- {interlatch-0.23.2 → interlatch-0.23.3}/.pre-commit-config.yaml +1 -1
- {interlatch-0.23.2 → interlatch-0.23.3}/CHANGELOG.md +14 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/CONTRIBUTING.md +2 -2
- {interlatch-0.23.2 → interlatch-0.23.3}/PKG-INFO +1 -1
- interlatch-0.23.3/changelog.d/gemini-prices.md +3 -0
- interlatch-0.23.3/changelog.d/home-agents.md +4 -0
- interlatch-0.23.3/changelog.d/python-package.md +3 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/dev.sh +1 -1
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/analysis.md +2 -1
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/dashboard.md +4 -2
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/demo/make_demo.py +2 -2
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/demo/record_demo.py +1 -1
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/development.md +33 -8
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/development.md +30 -6
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/privacy.md +1 -1
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/privacy.md +1 -1
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/sources.md +3 -1
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/README.md +1 -1
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/render.py +2 -2
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/Interlatch.spec +7 -7
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/icon-blueprint-prompt.md +2 -2
- interlatch-0.23.2/packaging/macos/chronicle_app.py → interlatch-0.23.3/packaging/macos/interlatch_app.py +2 -2
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/make_icon.py +1 -1
- {interlatch-0.23.2 → interlatch-0.23.3}/pyproject.toml +3 -3
- interlatch-0.23.3/src/chronicle/__init__.py +8 -0
- interlatch-0.23.3/src/chronicle/__main__.py +3 -0
- interlatch-0.23.3/src/chronicle/windows.py +11 -0
- interlatch-0.23.3/src/interlatch/__main__.py +3 -0
- interlatch-0.23.3/src/interlatch/analysis/__init__.py +2 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/analysis}/digest.py +3 -3
- interlatch-0.23.3/src/interlatch/analysis/language.py +22 -0
- interlatch-0.23.3/src/interlatch/analysis/queue.py +132 -0
- interlatch-0.23.3/src/interlatch/analysis/runners/__init__.py +2 -0
- interlatch-0.23.2/src/chronicle/providers.py → interlatch-0.23.3/src/interlatch/analysis/runners/api.py +15 -134
- interlatch-0.23.3/src/interlatch/analysis/runners/base.py +148 -0
- interlatch-0.23.3/src/interlatch/analysis/runners/bob.py +121 -0
- interlatch-0.23.3/src/interlatch/analysis/runners/claude.py +89 -0
- interlatch-0.23.3/src/interlatch/analysis/runners/codex.py +127 -0
- interlatch-0.23.3/src/interlatch/analysis/runners/factory.py +25 -0
- interlatch-0.23.3/src/interlatch/analysis/runners/process.py +67 -0
- interlatch-0.23.3/src/interlatch/analysis/runners/replies.py +38 -0
- interlatch-0.23.3/src/interlatch/analysis/runners/settings.py +131 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/analysis}/screen.py +7 -5
- interlatch-0.23.2/src/chronicle/analyze.py → interlatch-0.23.3/src/interlatch/analysis/session.py +12 -10
- interlatch-0.23.3/src/interlatch/analysis/worker.py +116 -0
- interlatch-0.23.3/src/interlatch/application/__init__.py +2 -0
- interlatch-0.23.3/src/interlatch/application/records.py +54 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/application}/search.py +5 -5
- interlatch-0.23.3/src/interlatch/application/workflows.py +180 -0
- interlatch-0.23.3/src/interlatch/artifacts/__init__.py +2 -0
- interlatch-0.23.3/src/interlatch/artifacts/files.py +123 -0
- interlatch-0.23.3/src/interlatch/artifacts/queries.py +183 -0
- interlatch-0.23.3/src/interlatch/cli.py +4 -0
- interlatch-0.23.3/src/interlatch/core/__init__.py +2 -0
- interlatch-0.23.2/src/chronicle/artifacts.py → interlatch-0.23.3/src/interlatch/core/artifact_records.py +5 -296
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/core}/config.py +3 -3
- interlatch-0.23.3/src/interlatch/core/diagrams.py +124 -0
- interlatch-0.23.2/src/chronicle/i18n.py → interlatch-0.23.3/src/interlatch/core/i18n/__init__.py +1 -1
- interlatch-0.23.3/src/interlatch/core/machine.py +54 -0
- interlatch-0.23.3/src/interlatch/core/paths.py +86 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/core}/pricing.py +51 -0
- interlatch-0.23.3/src/interlatch/core/process.py +20 -0
- interlatch-0.23.3/src/interlatch/core/sessions.py +238 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/core}/util.py +0 -73
- interlatch-0.23.3/src/interlatch/ingestion/__init__.py +2 -0
- interlatch-0.23.3/src/interlatch/ingestion/analyses.py +75 -0
- interlatch-0.23.3/src/interlatch/ingestion/archive.py +176 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/ingestion}/chat_import.py +17 -37
- interlatch-0.23.3/src/interlatch/ingestion/deletion.py +76 -0
- interlatch-0.23.3/src/interlatch/ingestion/history.py +66 -0
- interlatch-0.23.3/src/interlatch/ingestion/memory.py +150 -0
- interlatch-0.23.3/src/interlatch/ingestion/persistence.py +274 -0
- interlatch-0.23.3/src/interlatch/ingestion/report.py +30 -0
- interlatch-0.23.3/src/interlatch/ingestion/service.py +485 -0
- interlatch-0.23.3/src/interlatch/interfaces/__init__.py +2 -0
- interlatch-0.23.3/src/interlatch/interfaces/cli/__init__.py +2 -0
- interlatch-0.23.3/src/interlatch/interfaces/cli/commands/__init__.py +3 -0
- interlatch-0.23.3/src/interlatch/interfaces/cli/commands/archive.py +311 -0
- interlatch-0.23.3/src/interlatch/interfaces/cli/commands/knowledge.py +599 -0
- interlatch-0.23.3/src/interlatch/interfaces/cli/commands/operations.py +259 -0
- interlatch-0.23.3/src/interlatch/interfaces/cli/commands/recording.py +312 -0
- interlatch-0.23.3/src/interlatch/interfaces/cli/commands/setup.py +679 -0
- interlatch-0.23.3/src/interlatch/interfaces/cli/commands/sharing.py +913 -0
- interlatch-0.23.3/src/interlatch/interfaces/cli/common.py +85 -0
- interlatch-0.23.3/src/interlatch/interfaces/cli/main.py +52 -0
- interlatch-0.23.3/src/interlatch/interfaces/cli/parser.py +45 -0
- interlatch-0.23.3/src/interlatch/interfaces/exports/__init__.py +1 -0
- interlatch-0.23.2/src/chronicle/diagram.py → interlatch-0.23.3/src/interlatch/interfaces/exports/diagrams.py +13 -129
- interlatch-0.23.2/src/chronicle/views.py → interlatch-0.23.3/src/interlatch/interfaces/exports/markdown.py +5 -85
- interlatch-0.23.2/src/chronicle/session_export.py → interlatch-0.23.3/src/interlatch/interfaces/exports/sessions.py +7 -6
- interlatch-0.23.2/src/chronicle/export_md.py → interlatch-0.23.3/src/interlatch/interfaces/exports/vault.py +9 -7
- interlatch-0.23.2/src/chronicle/mcp_server.py → interlatch-0.23.3/src/interlatch/interfaces/mcp.py +19 -17
- interlatch-0.23.3/src/interlatch/knowledge/__init__.py +2 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/cases.py +1 -1
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/friction.py +2 -2
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/glossary.py +11 -9
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/instructions.py +8 -8
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/ladder.py +2 -2
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/learning.py +3 -3
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/reviews.py +7 -5
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/suggest.py +4 -4
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/knowledge}/synthesize.py +6 -4
- interlatch-0.23.3/src/interlatch/projects/__init__.py +2 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/projects}/groups.py +3 -3
- interlatch-0.23.3/src/interlatch/projects/labels.py +17 -0
- interlatch-0.23.3/src/interlatch/projects/routing.py +201 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/projects}/systems.py +2 -2
- interlatch-0.23.3/src/interlatch/runtime/__init__.py +2 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/connectors.py +14 -36
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/container.py +19 -17
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/hooks.py +10 -21
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/install.py +18 -17
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/migrate.py +12 -10
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/notify.py +3 -3
- interlatch-0.23.3/src/interlatch/runtime/platforms/__init__.py +2 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime/platforms}/desktop.py +21 -19
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime/platforms}/menubar.py +15 -14
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime/platforms}/windows.py +8 -8
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/statusline.py +4 -4
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/update.py +7 -7
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/server.py +272 -213
- interlatch-0.23.3/src/interlatch/sharing/__init__.py +20 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/sharing}/access.py +1 -1
- interlatch-0.23.3/src/interlatch/sharing/client.py +400 -0
- interlatch-0.23.3/src/interlatch/sharing/identity.py +91 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/sharing}/leaderboard.py +4 -4
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/sharing}/news.py +2 -2
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/sharing}/people.py +3 -2
- interlatch-0.23.3/src/interlatch/sharing/projects.py +370 -0
- interlatch-0.23.3/src/interlatch/sharing/protocol.py +111 -0
- interlatch-0.23.3/src/interlatch/sharing/pull.py +162 -0
- interlatch-0.23.3/src/interlatch/sharing/push.py +320 -0
- interlatch-0.23.3/src/interlatch/sharing/receiver.py +620 -0
- interlatch-0.23.3/src/interlatch/sources/__init__.py +2 -0
- interlatch-0.23.2/src/chronicle/antigravity_parser.py → interlatch-0.23.3/src/interlatch/sources/antigravity.py +6 -6
- interlatch-0.23.2/src/chronicle/bob_parser.py → interlatch-0.23.3/src/interlatch/sources/bob.py +10 -10
- interlatch-0.23.3/src/interlatch/sources/builder.py +179 -0
- interlatch-0.23.2/src/chronicle/chatgpt_export.py → interlatch-0.23.3/src/interlatch/sources/chatgpt.py +4 -4
- interlatch-0.23.3/src/interlatch/sources/chats.py +33 -0
- interlatch-0.23.3/src/interlatch/sources/claude/__init__.py +1 -0
- interlatch-0.23.2/src/chronicle/claude_export.py → interlatch-0.23.3/src/interlatch/sources/claude/export.py +7 -7
- interlatch-0.23.3/src/interlatch/sources/claude/files.py +71 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/sources/claude}/parser.py +10 -242
- interlatch-0.23.3/src/interlatch/sources/codex/__init__.py +1 -0
- interlatch-0.23.2/src/chronicle/codex_cloud.py → interlatch-0.23.3/src/interlatch/sources/codex/cloud.py +7 -7
- interlatch-0.23.2/src/chronicle/codex_parser.py → interlatch-0.23.3/src/interlatch/sources/codex/parser.py +9 -20
- interlatch-0.23.2/src/chronicle/copilot_parser.py → interlatch-0.23.3/src/interlatch/sources/copilot.py +9 -174
- interlatch-0.23.3/src/interlatch/sources/discovery.py +39 -0
- interlatch-0.23.3/src/interlatch/sources/prompts.py +23 -0
- interlatch-0.23.3/src/interlatch/storage/__init__.py +2 -0
- interlatch-0.23.3/src/interlatch/storage/fts.py +21 -0
- interlatch-0.23.3/src/interlatch/storage/kv.py +17 -0
- interlatch-0.23.3/src/interlatch/storage/migrations.py +66 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/storage}/mirror.py +8 -7
- interlatch-0.23.2/src/chronicle/db.py → interlatch-0.23.3/src/interlatch/storage/schema.py +1 -112
- interlatch-0.23.3/src/interlatch/storage/sqlite.py +33 -0
- interlatch-0.23.2/src/chronicle/team_store.py → interlatch-0.23.3/src/interlatch/storage/team.py +4 -4
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/app.css +17 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/app.js +89 -8
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/ja.js +6 -0
- interlatch-0.23.3/src/interlatch/windows.py +10 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/conftest.py +5 -5
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/friction_fixture.py +5 -5
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/parsers/antigravity.json +4 -4
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_analysis.py +31 -25
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_antigravity.py +7 -7
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_artifacts.py +21 -20
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_bob_analysis.py +11 -9
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_boot_web.py +1 -1
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_case_files.py +5 -4
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_cases.py +6 -6
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_chat_import.py +9 -7
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_cli_pins.py +4 -4
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_codex.py +6 -6
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_codex_analysis.py +9 -6
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_codex_cloud.py +6 -6
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_container.py +13 -10
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_copilot_bob.py +11 -11
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_dedicated_hub.py +1 -1
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_dedupe.py +3 -3
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_desktop.py +11 -11
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_diagram.py +5 -4
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_ee_boundary.py +3 -3
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_friction.py +1 -1
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_glossary.py +9 -9
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_group_sharing.py +25 -20
- interlatch-0.23.3/tests/test_home_agents.py +59 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_hub.py +105 -94
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_hub_accept.py +7 -5
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_hub_news.py +17 -13
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_hub_projects.py +44 -36
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_hub_projects_listed.py +7 -7
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_hub_purge.py +24 -18
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_hub_sharing_race.py +25 -19
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_i18n_web.py +1 -1
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_ingest.py +9 -7
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_instructions.py +9 -9
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_integration.py +21 -21
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_ladder.py +7 -6
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_language.py +36 -29
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_leaderboard.py +8 -7
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_learning_glance.py +3 -3
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_learning_interests.py +7 -5
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_learning_web.py +1 -1
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_leave_project.py +41 -33
- interlatch-0.23.3/tests/test_legacy_package.py +39 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_map_goldens.py +3 -2
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_menubar.py +41 -35
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_migrate.py +21 -20
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_mirror.py +8 -8
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_notify.py +11 -11
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_parser.py +19 -2
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_parser_goldens.py +7 -6
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_people.py +2 -2
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_people_hub.py +59 -54
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_people_web.py +12 -9
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_project_groups.py +4 -3
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_providers.py +11 -9
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_queue.py +9 -9
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_regressions.py +10 -9
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_release.py +3 -3
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_route_matrix.py +11 -8
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_screen.py +5 -5
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_security.py +52 -45
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_setup.py +26 -26
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_statusline.py +6 -6
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_suggest.py +5 -4
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_suggest_cli.py +9 -9
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_systems.py +3 -3
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_team.py +31 -25
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_team_home.py +6 -5
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_update.py +8 -7
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/test_windows.py +29 -24
- interlatch-0.23.2/changelog.d/agent-icons.md +0 -3
- interlatch-0.23.2/changelog.d/devices-admin-only.md +0 -3
- interlatch-0.23.2/changelog.d/windows-polish.md +0 -5
- interlatch-0.23.2/src/chronicle/__main__.py +0 -3
- interlatch-0.23.2/src/chronicle/cli.py +0 -3058
- interlatch-0.23.2/src/chronicle/hub.py +0 -2308
- interlatch-0.23.2/src/chronicle/ingest.py +0 -1190
- interlatch-0.23.2/src/chronicle/llm.py +0 -577
- interlatch-0.23.2/src/chronicle/worker.py +0 -390
- {interlatch-0.23.2 → interlatch-0.23.3}/.github/dependabot.yml +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/.github/workflows/changelog.yml +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/.github/workflows/ci.yml +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/.github/workflows/docs.yml +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/.github/workflows/release.yml +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/.gitignore +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/.python-version +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/LICENSE +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/README.ja.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/README.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/ROADMAP.ja.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/ROADMAP.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/SECURITY.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/changelog.d/README.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docker/.dockerignore +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docker/.env.example +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docker/Caddyfile +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docker/Dockerfile +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docker/compose.yaml +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docker/wheels/.gitignore +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/README.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/_site/hooks.py +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/cli.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/configuration.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/design/ja/learning.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/design/learning.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/devices.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/diagrams/analysis.excalidraw.svg +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/diagrams/architecture.excalidraw.svg +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/docker.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/images/demo.gif +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/images/home.png +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/images/map.png +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/images/palette.png +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/images/session.png +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/install.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/README.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/analysis.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/cli.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/configuration.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/dashboard.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/devices.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/docker.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/install.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/join-a-hub.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/mcp.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/moving-from-chronicle.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/postgres.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/sources.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/suggestions.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/troubleshooting.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/ja/vscode.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/join-a-hub.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/mcp.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/moving-from-chronicle.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/postgres.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/suggestions.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/troubleshooting.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/docs/vscode.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/leaderboard/.firebaserc +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/leaderboard/.gitignore +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/leaderboard/README.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/leaderboard/firebase.json +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/leaderboard/firestore.indexes.json +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/leaderboard/firestore.rules +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/mkdocs.yml +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/art.json +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/filing.html +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/loops.json +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/loops.py +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/members.js +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/render.html +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/scenes-more.js +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/icons3d/scenes.html +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/Chronicle.icns +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/build.sh +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/entitlements.plist +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/icon-3d.webp +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/icon-blueprint.webp +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/macos/icon.png +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/packaging/release.py +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/__init__.py +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/core}/agents.py +0 -0
- /interlatch-0.23.2/src/chronicle/i18n_ja.py → /interlatch-0.23.3/src/interlatch/core/i18n/ja.py +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/core}/redact.py +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch/runtime}/tailnet.py +0 -0
- /interlatch-0.23.2/src/chronicle/pg.py → /interlatch-0.23.3/src/interlatch/storage/postgres.py +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/AGENT-ICONS.txt +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/PLEX-OFL.txt +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/agent-antigravity.svg +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/agent-bob.svg +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/agent-chatgpt.svg +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/agent-claude-ai.svg +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/agent-claude.svg +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/agent-codex.svg +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/agent-copilot.svg +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-book.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-camera.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-chip.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-clock.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-cloud.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-coins.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-container.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-dashboard.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-dex.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-document.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-flag.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-folder.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-gateway.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-gears.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-glitch.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-globe.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-laptop.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-log.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-lumi.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-magnifier.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-pip.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-plug.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-rack.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/art-tink.webp +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/boot.js +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/favicon.png +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/i18n.js +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/icon-180.png +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/icon-192.png +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/icon-512.png +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/icon.png +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/index.html +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/learning.js +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/manifest.webmanifest +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/panel.css +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/panel.html +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/panel.js +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/plex-mono-400.woff2 +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/plex-mono-500.woff2 +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/plex-mono-600.woff2 +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/plex-sans-400.woff2 +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/plex-sans-500.woff2 +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/plex-sans-600.woff2 +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/plex-sans-700.woff2 +0 -0
- {interlatch-0.23.2/src/chronicle → interlatch-0.23.3/src/interlatch}/web/rough.js +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/antigravity_fixture.py +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/codex_fixture.py +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/copilot_fixture.py +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/golden.py +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/cli.json +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/diagram.json +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/parsers/bob.json +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/parsers/claude_code.json +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/parsers/codex.json +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/parsers/copilot.json +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/goldens/systems.json +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/tests/windows_smoke.py +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/uv.lock +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/vscode-extension/.vscodeignore +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/vscode-extension/LICENSE +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/vscode-extension/README.md +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/vscode-extension/extension.js +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/vscode-extension/media/icon.png +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/vscode-extension/media/interlatch.svg +0 -0
- {interlatch-0.23.2 → interlatch-0.23.3}/vscode-extension/package.json +0 -0
|
@@ -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
|
|
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
|
|
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.
|
|
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**.
|
|
@@ -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
|
|
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;
|
|
75
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
`
|
|
123
|
-
|
|
124
|
-
|
|
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 (`
|
|
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
|
|
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
|
-
`
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
|
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/
|
|
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/
|
|
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
|
|
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/
|
|
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/
|
|
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" / "
|
|
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
|
|
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 / "
|
|
19
|
+
[str(HERE / "interlatch_app.py")],
|
|
20
20
|
pathex=[str(ROOT / "src")],
|
|
21
|
-
# the package metadata carries the version (
|
|
22
|
-
datas=[(str(ROOT / "src" / "
|
|
23
|
-
#
|
|
24
|
-
hiddenimports=collect_submodules("
|
|
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
|
|
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/
|
|
14
|
-
- `src/
|
|
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
|
|
13
|
+
from interlatch.cli import main
|
|
14
14
|
|
|
15
15
|
return main(args)
|
|
16
|
-
from
|
|
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" / "
|
|
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 = "
|
|
34
|
-
chronicle = "
|
|
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,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:]))
|
|
@@ -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
|