forked from Rockachopa/Timmy-time-dashboard
This commit is contained in:
@@ -630,7 +630,7 @@ class ThinkingEngine:
|
||||
|
||||
if new_corr:
|
||||
# Count entries (assuming each entry starts with a timestamp or header)
|
||||
line_count = len([l for l in new_corr.splitlines() if l.strip()])
|
||||
line_count = len([line for line in new_corr.splitlines() if line.strip()])
|
||||
parts.append(
|
||||
f"Workspace: {line_count} new correspondence entries (latest from: Hermes)"
|
||||
)
|
||||
@@ -854,10 +854,12 @@ class ThinkingEngine:
|
||||
|
||||
if new_corr or new_inbox:
|
||||
if new_corr:
|
||||
line_count = len([l for l in new_corr.splitlines() if l.strip()])
|
||||
line_count = len([line for line in new_corr.splitlines() if line.strip()])
|
||||
logger.info("Workspace: processed %d new correspondence entries", line_count)
|
||||
if new_inbox:
|
||||
logger.info("Workspace: processed %d new inbox files: %s", len(new_inbox), new_inbox)
|
||||
logger.info(
|
||||
"Workspace: processed %d new inbox files: %s", len(new_inbox), new_inbox
|
||||
)
|
||||
|
||||
# Mark as seen to update the state file
|
||||
workspace_monitor.mark_seen()
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
"""Tests for timmy.workspace — Workspace heartbeat monitoring."""
|
||||
|
||||
import pytest
|
||||
|
||||
from timmy.workspace import WorkspaceMonitor
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -13,10 +10,10 @@ from timmy.workspace import WorkspaceMonitor
|
||||
def _make_monitor(tmp_path, monkeypatch):
|
||||
"""Create a WorkspaceMonitor with tmp_path as the repo_root."""
|
||||
# Mock repo_root to use tmp_path
|
||||
monkeypatch.setattr("timmy.workspace.settings", type("obj", (object,), {
|
||||
"repo_root": str(tmp_path)
|
||||
})())
|
||||
|
||||
monkeypatch.setattr(
|
||||
"timmy.workspace.settings", type("obj", (object,), {"repo_root": str(tmp_path)})()
|
||||
)
|
||||
|
||||
state_path = tmp_path / "workspace_state.json"
|
||||
return WorkspaceMonitor(state_path=state_path)
|
||||
|
||||
@@ -39,9 +36,9 @@ def test_no_updates_when_empty(tmp_path, monkeypatch):
|
||||
"""Fresh monitor with no workspace files should report no updates."""
|
||||
# Don't create workspace dir — monitor should handle gracefully
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
|
||||
|
||||
updates = monitor.get_pending_updates()
|
||||
|
||||
|
||||
assert updates["new_correspondence"] is None
|
||||
assert updates["new_inbox_files"] == []
|
||||
|
||||
@@ -50,12 +47,12 @@ def test_detects_new_correspondence(tmp_path, monkeypatch):
|
||||
"""Writing to correspondence.md should be detected as new entries."""
|
||||
workspace = _setup_workspace(tmp_path)
|
||||
correspondence = workspace / "correspondence.md"
|
||||
|
||||
|
||||
# Pre-populate correspondence file
|
||||
correspondence.write_text("Entry 1\nEntry 2\nEntry 3\n")
|
||||
|
||||
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
|
||||
|
||||
# Should detect all 3 lines as new
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_correspondence"] == "Entry 1\nEntry 2\nEntry 3"
|
||||
@@ -66,12 +63,12 @@ def test_detects_new_inbox_file(tmp_path, monkeypatch):
|
||||
"""Creating a file in inbox/ should be detected as new."""
|
||||
workspace = _setup_workspace(tmp_path)
|
||||
inbox = workspace / "inbox"
|
||||
|
||||
|
||||
# Create a file in inbox
|
||||
(inbox / "message_1.md").write_text("Hello Timmy")
|
||||
|
||||
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
|
||||
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_correspondence"] is None
|
||||
assert updates["new_inbox_files"] == ["message_1.md"]
|
||||
@@ -81,14 +78,14 @@ def test_detects_multiple_inbox_files(tmp_path, monkeypatch):
|
||||
"""Multiple new inbox files should all be detected."""
|
||||
workspace = _setup_workspace(tmp_path)
|
||||
inbox = workspace / "inbox"
|
||||
|
||||
|
||||
# Create multiple files
|
||||
(inbox / "message_2.md").write_text("Hello again")
|
||||
(inbox / "task_1.md").write_text("Do something")
|
||||
(inbox / "note.txt").write_text("A note")
|
||||
|
||||
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
|
||||
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_inbox_files"] == ["message_2.md", "note.txt", "task_1.md"]
|
||||
|
||||
@@ -96,15 +93,15 @@ def test_detects_multiple_inbox_files(tmp_path, monkeypatch):
|
||||
def test_detects_both_correspondence_and_inbox(tmp_path, monkeypatch):
|
||||
"""Monitor should detect both correspondence and inbox updates together."""
|
||||
workspace = _setup_workspace(tmp_path)
|
||||
|
||||
|
||||
correspondence = workspace / "correspondence.md"
|
||||
correspondence.write_text("New journal entry\n")
|
||||
|
||||
|
||||
inbox = workspace / "inbox"
|
||||
(inbox / "urgent.md").write_text("Urgent message")
|
||||
|
||||
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
|
||||
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_correspondence"] == "New journal entry"
|
||||
assert updates["new_inbox_files"] == ["urgent.md"]
|
||||
@@ -118,23 +115,23 @@ def test_detects_both_correspondence_and_inbox(tmp_path, monkeypatch):
|
||||
def test_mark_seen_clears_pending(tmp_path, monkeypatch):
|
||||
"""After mark_seen, get_pending_updates should return empty."""
|
||||
workspace = _setup_workspace(tmp_path)
|
||||
|
||||
|
||||
correspondence = workspace / "correspondence.md"
|
||||
correspondence.write_text("Line 1\nLine 2\n")
|
||||
|
||||
|
||||
inbox = workspace / "inbox"
|
||||
(inbox / "file.md").write_text("Content")
|
||||
|
||||
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
|
||||
|
||||
# First check — should have updates
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_correspondence"] is not None
|
||||
assert len(updates["new_inbox_files"]) == 1
|
||||
|
||||
|
||||
# Mark as seen
|
||||
monitor.mark_seen()
|
||||
|
||||
|
||||
# Second check — should be empty
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_correspondence"] is None
|
||||
@@ -144,16 +141,16 @@ def test_mark_seen_clears_pending(tmp_path, monkeypatch):
|
||||
def test_mark_seen_persists_line_count(tmp_path, monkeypatch):
|
||||
"""mark_seen should remember how many lines we've seen."""
|
||||
workspace = _setup_workspace(tmp_path)
|
||||
|
||||
|
||||
correspondence = workspace / "correspondence.md"
|
||||
correspondence.write_text("Line 1\nLine 2\nLine 3\n")
|
||||
|
||||
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
monitor.mark_seen()
|
||||
|
||||
|
||||
# Add more lines
|
||||
correspondence.write_text("Line 1\nLine 2\nLine 3\nLine 4\nLine 5\n")
|
||||
|
||||
|
||||
# Should only see the new lines
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_correspondence"] == "Line 4\nLine 5"
|
||||
@@ -167,24 +164,24 @@ def test_mark_seen_persists_line_count(tmp_path, monkeypatch):
|
||||
def test_state_persists_across_instances(tmp_path, monkeypatch):
|
||||
"""State should be saved and loaded when creating a new monitor instance."""
|
||||
workspace = _setup_workspace(tmp_path)
|
||||
|
||||
|
||||
correspondence = workspace / "correspondence.md"
|
||||
correspondence.write_text("First entry\n")
|
||||
|
||||
|
||||
inbox = workspace / "inbox"
|
||||
(inbox / "first.md").write_text("First")
|
||||
|
||||
|
||||
# First monitor instance
|
||||
monitor1 = _make_monitor(tmp_path, monkeypatch)
|
||||
monitor1.mark_seen()
|
||||
|
||||
|
||||
# Add new content
|
||||
correspondence.write_text("First entry\nSecond entry\n")
|
||||
(inbox / "second.md").write_text("Second")
|
||||
|
||||
|
||||
# Second monitor instance (should load state from file)
|
||||
monitor2 = _make_monitor(tmp_path, monkeypatch)
|
||||
|
||||
|
||||
updates = monitor2.get_pending_updates()
|
||||
assert updates["new_correspondence"] == "Second entry"
|
||||
assert updates["new_inbox_files"] == ["second.md"]
|
||||
@@ -193,17 +190,17 @@ def test_state_persists_across_instances(tmp_path, monkeypatch):
|
||||
def test_state_survives_missing_files(tmp_path, monkeypatch):
|
||||
"""Monitor should handle missing correspondence file gracefully."""
|
||||
workspace = _setup_workspace(tmp_path)
|
||||
|
||||
|
||||
# Create and mark as seen
|
||||
correspondence = workspace / "correspondence.md"
|
||||
correspondence.write_text("Entry\n")
|
||||
|
||||
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
monitor.mark_seen()
|
||||
|
||||
|
||||
# Delete the file
|
||||
correspondence.unlink()
|
||||
|
||||
|
||||
# Should return None gracefully
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_correspondence"] is None
|
||||
@@ -218,9 +215,9 @@ def test_empty_correspondence_file(tmp_path, monkeypatch):
|
||||
"""Empty correspondence file should return None."""
|
||||
workspace = _setup_workspace(tmp_path)
|
||||
(workspace / "correspondence.md").write_text("")
|
||||
|
||||
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
|
||||
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_correspondence"] is None
|
||||
|
||||
@@ -228,9 +225,9 @@ def test_empty_correspondence_file(tmp_path, monkeypatch):
|
||||
def test_empty_inbox_dir(tmp_path, monkeypatch):
|
||||
"""Empty inbox directory should return empty list."""
|
||||
_setup_workspace(tmp_path)
|
||||
|
||||
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
|
||||
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_inbox_files"] == []
|
||||
|
||||
@@ -240,9 +237,9 @@ def test_missing_inbox_dir(tmp_path, monkeypatch):
|
||||
workspace = tmp_path / "workspace"
|
||||
workspace.mkdir()
|
||||
# No inbox subdir
|
||||
|
||||
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
|
||||
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_inbox_files"] == []
|
||||
|
||||
@@ -251,7 +248,7 @@ def test_missing_workspace_dir(tmp_path, monkeypatch):
|
||||
"""Missing workspace directory should return empty results."""
|
||||
# No workspace dir at all
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
|
||||
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_correspondence"] is None
|
||||
assert updates["new_inbox_files"] == []
|
||||
@@ -260,12 +257,12 @@ def test_missing_workspace_dir(tmp_path, monkeypatch):
|
||||
def test_correspondence_with_blank_lines(tmp_path, monkeypatch):
|
||||
"""Correspondence with blank lines should be handled correctly."""
|
||||
workspace = _setup_workspace(tmp_path)
|
||||
|
||||
|
||||
correspondence = workspace / "correspondence.md"
|
||||
correspondence.write_text("Entry 1\n\nEntry 2\n\n\nEntry 3\n")
|
||||
|
||||
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
|
||||
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_correspondence"] == "Entry 1\n\nEntry 2\n\n\nEntry 3"
|
||||
|
||||
@@ -274,12 +271,12 @@ def test_inbox_ignores_subdirectories(tmp_path, monkeypatch):
|
||||
"""Inbox should only list files, not subdirectories."""
|
||||
workspace = _setup_workspace(tmp_path)
|
||||
inbox = workspace / "inbox"
|
||||
|
||||
|
||||
(inbox / "file.md").write_text("Content")
|
||||
(inbox / "subdir").mkdir()
|
||||
|
||||
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
|
||||
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_inbox_files"] == ["file.md"]
|
||||
|
||||
@@ -288,18 +285,18 @@ def test_deleted_inbox_files_removed_from_state(tmp_path, monkeypatch):
|
||||
"""When inbox files are deleted, they should be removed from seen list."""
|
||||
workspace = _setup_workspace(tmp_path)
|
||||
inbox = workspace / "inbox"
|
||||
|
||||
|
||||
# Create and see a file
|
||||
(inbox / "temp.md").write_text("Temp")
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
monitor.mark_seen()
|
||||
|
||||
|
||||
# Delete the file
|
||||
(inbox / "temp.md").unlink()
|
||||
|
||||
|
||||
# mark_seen should update seen list to remove deleted files
|
||||
monitor.mark_seen()
|
||||
|
||||
|
||||
# State should now have empty seen list
|
||||
assert monitor._state["seen_inbox_files"] == []
|
||||
|
||||
@@ -307,17 +304,17 @@ def test_deleted_inbox_files_removed_from_state(tmp_path, monkeypatch):
|
||||
def test_correspondence_append_only(tmp_path, monkeypatch):
|
||||
"""Correspondence is append-only; modifying existing content doesn't re-notify."""
|
||||
workspace = _setup_workspace(tmp_path)
|
||||
|
||||
|
||||
correspondence = workspace / "correspondence.md"
|
||||
correspondence.write_text("Line 1\nLine 2\n")
|
||||
|
||||
|
||||
monitor = _make_monitor(tmp_path, monkeypatch)
|
||||
monitor.mark_seen()
|
||||
|
||||
|
||||
# Modify the file (truncate and rewrite) — this resets line count
|
||||
# but correspondence.md should be append-only in practice
|
||||
correspondence.write_text("Modified Line 1\nModified Line 2\nLine 3\n")
|
||||
|
||||
|
||||
# Line 3 is the only truly new line (we've now seen 2, file has 3)
|
||||
updates = monitor.get_pending_updates()
|
||||
assert updates["new_correspondence"] == "Line 3"
|
||||
|
||||
Reference in New Issue
Block a user