rook-cli 0.2.0__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 (106) hide show
  1. rook_cli-0.2.0/.claude/settings.local.json +66 -0
  2. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/.claude/settings.local.json +66 -0
  3. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/.gitignore +20 -0
  4. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/LICENSE +10 -0
  5. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/README.md +103 -0
  6. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/pyproject.toml +51 -0
  7. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/__init__.py +1 -0
  8. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/__main__.py +48 -0
  9. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/app.py +222 -0
  10. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/branding.py +69 -0
  11. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/domain/__init__.py +0 -0
  12. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/domain/tasks.py +55 -0
  13. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/formatting.py +10 -0
  14. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/paths.py +31 -0
  15. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/persistence/__init__.py +0 -0
  16. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/persistence/archive.py +72 -0
  17. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/persistence/database.py +18 -0
  18. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/persistence/metadata.py +56 -0
  19. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/persistence/migrations.py +111 -0
  20. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/persistence/tasks.py +185 -0
  21. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/services/__init__.py +0 -0
  22. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/services/rollover.py +94 -0
  23. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/services/tasks.py +85 -0
  24. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/services/undo.py +72 -0
  25. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/symbols.py +40 -0
  26. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/widgets/__init__.py +0 -0
  27. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/widgets/archive_screen.py +162 -0
  28. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/widgets/shortcut_footer.py +79 -0
  29. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/widgets/task_line_input.py +44 -0
  30. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/widgets/task_list.py +415 -0
  31. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/src/rook/widgets/task_row.py +155 -0
  32. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/support.py +75 -0
  33. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_app.py +369 -0
  34. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_archive_navigation.py +188 -0
  35. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_archive_queries.py +152 -0
  36. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_formatting.py +11 -0
  37. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_migrations.py +52 -0
  38. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_paths.py +20 -0
  39. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_persistence_failure.py +47 -0
  40. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_rollover.py +257 -0
  41. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_rollover_app.py +104 -0
  42. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_selection.py +40 -0
  43. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_shortcut_footer_selection.py +26 -0
  44. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_smoke.py +5 -0
  45. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_symbols.py +30 -0
  46. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_task_creation_and_editing.py +430 -0
  47. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_task_repository.py +153 -0
  48. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_task_row_rendering.py +57 -0
  49. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_task_service.py +37 -0
  50. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_task_states.py +261 -0
  51. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_undo.py +245 -0
  52. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_undo_manager.py +34 -0
  53. rook_cli-0.2.0/.claude/worktrees/streamed-orbiting-llama/tests/test_widget_markup_safety.py +47 -0
  54. rook_cli-0.2.0/.gitignore +20 -0
  55. rook_cli-0.2.0/DEVELOPMENT_GUIDE.md +15609 -0
  56. rook_cli-0.2.0/LICENSE +10 -0
  57. rook_cli-0.2.0/PKG-INFO +120 -0
  58. rook_cli-0.2.0/README.md +103 -0
  59. rook_cli-0.2.0/pyproject.toml +51 -0
  60. rook_cli-0.2.0/src/rook/__init__.py +1 -0
  61. rook_cli-0.2.0/src/rook/__main__.py +48 -0
  62. rook_cli-0.2.0/src/rook/app.py +222 -0
  63. rook_cli-0.2.0/src/rook/branding.py +69 -0
  64. rook_cli-0.2.0/src/rook/domain/__init__.py +0 -0
  65. rook_cli-0.2.0/src/rook/domain/tasks.py +55 -0
  66. rook_cli-0.2.0/src/rook/formatting.py +10 -0
  67. rook_cli-0.2.0/src/rook/paths.py +31 -0
  68. rook_cli-0.2.0/src/rook/persistence/__init__.py +0 -0
  69. rook_cli-0.2.0/src/rook/persistence/archive.py +72 -0
  70. rook_cli-0.2.0/src/rook/persistence/database.py +18 -0
  71. rook_cli-0.2.0/src/rook/persistence/metadata.py +56 -0
  72. rook_cli-0.2.0/src/rook/persistence/migrations.py +111 -0
  73. rook_cli-0.2.0/src/rook/persistence/tasks.py +185 -0
  74. rook_cli-0.2.0/src/rook/services/__init__.py +0 -0
  75. rook_cli-0.2.0/src/rook/services/rollover.py +94 -0
  76. rook_cli-0.2.0/src/rook/services/tasks.py +85 -0
  77. rook_cli-0.2.0/src/rook/services/undo.py +72 -0
  78. rook_cli-0.2.0/src/rook/symbols.py +40 -0
  79. rook_cli-0.2.0/src/rook/widgets/__init__.py +0 -0
  80. rook_cli-0.2.0/src/rook/widgets/archive_screen.py +162 -0
  81. rook_cli-0.2.0/src/rook/widgets/shortcut_footer.py +79 -0
  82. rook_cli-0.2.0/src/rook/widgets/task_line_input.py +44 -0
  83. rook_cli-0.2.0/src/rook/widgets/task_list.py +415 -0
  84. rook_cli-0.2.0/src/rook/widgets/task_row.py +155 -0
  85. rook_cli-0.2.0/tests/support.py +75 -0
  86. rook_cli-0.2.0/tests/test_app.py +369 -0
  87. rook_cli-0.2.0/tests/test_archive_navigation.py +188 -0
  88. rook_cli-0.2.0/tests/test_archive_queries.py +152 -0
  89. rook_cli-0.2.0/tests/test_formatting.py +11 -0
  90. rook_cli-0.2.0/tests/test_migrations.py +52 -0
  91. rook_cli-0.2.0/tests/test_paths.py +20 -0
  92. rook_cli-0.2.0/tests/test_persistence_failure.py +47 -0
  93. rook_cli-0.2.0/tests/test_rollover.py +257 -0
  94. rook_cli-0.2.0/tests/test_rollover_app.py +104 -0
  95. rook_cli-0.2.0/tests/test_selection.py +40 -0
  96. rook_cli-0.2.0/tests/test_shortcut_footer_selection.py +26 -0
  97. rook_cli-0.2.0/tests/test_smoke.py +5 -0
  98. rook_cli-0.2.0/tests/test_symbols.py +30 -0
  99. rook_cli-0.2.0/tests/test_task_creation_and_editing.py +430 -0
  100. rook_cli-0.2.0/tests/test_task_repository.py +153 -0
  101. rook_cli-0.2.0/tests/test_task_row_rendering.py +57 -0
  102. rook_cli-0.2.0/tests/test_task_service.py +37 -0
  103. rook_cli-0.2.0/tests/test_task_states.py +261 -0
  104. rook_cli-0.2.0/tests/test_undo.py +245 -0
  105. rook_cli-0.2.0/tests/test_undo_manager.py +34 -0
  106. rook_cli-0.2.0/tests/test_widget_markup_safety.py +47 -0
@@ -0,0 +1,66 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "PowerShell(\\(Get-Content \"C:\\\\Users\\\\janchawla\\\\rook\\\\DEVELOPMENT_GUIDE.md\" | Measure-Object -Line\\).Lines)",
5
+ "PowerShell(\\(Get-Content \"C:\\\\Users\\\\janchawla\\\\rook\\\\DEVELOPMENT_GUIDE.md\"\\).Count)",
6
+ "PowerShell(py *)",
7
+ "PowerShell(Get-Command *)",
8
+ "PowerShell(python3 --version; python3 -c \"import sys; print\\(sys.executable\\)\")",
9
+ "PowerShell(git config *)",
10
+ "PowerShell(python3 -m venv .venv; Write-Host \"exit code: $LASTEXITCODE\")",
11
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pip install --upgrade pip 2>&1 | Select-Object -Last 5; .\\\\.venv\\\\Scripts\\\\python.exe -m pip install -e \".[dev]\" 2>&1 | Select-Object -Last 40)",
12
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q)",
13
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; Write-Host \"ruff check exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; Write-Host \"ruff format exit: $LASTEXITCODE\")",
14
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
15
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m build 2>&1 | Select-Object -Last 20)",
16
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m rook; Write-Host \"---\"; .\\\\.venv\\\\Scripts\\\\rook.exe; Write-Host \"---\"; Get-ChildItem dist)",
17
+ "PowerShell(git add *)",
18
+ "PowerShell(git commit *)",
19
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pip install -e \".[dev]\" 2>&1 | Select-Object -Last 30)",
20
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 80)",
21
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 60)",
22
+ "PowerShell(Remove-Item *)",
23
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; Write-Host \"ruff check exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; Write-Host \"ruff format exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
24
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q; Write-Host \"pytest exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
25
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 150)",
26
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .)",
27
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; Write-Host \"check exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check . 2>&1)",
28
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff format .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .)",
29
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_widget_markup_safety.py -q 2>&1 | Select-Object -Last 60)",
30
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 200)",
31
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 100)",
32
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; Write-Host \"check exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .)",
33
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff format .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
34
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_task_creation_and_editing.py -q 2>&1 | Select-Object -Last 250)",
35
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_task_creation_and_editing.py -q 2>&1 | Select-Object -Last 150)",
36
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; Write-Host \"check exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
37
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 250)",
38
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m mypy src; Write-Host \"mypy exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 60)",
39
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_paths.py -q 2>&1 | Select-Object -Last 60)",
40
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 60; Write-Host \"---\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
41
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_app.py -q -k \"bold or scrollbar\" 2>&1 | Select-Object -Last 100)",
42
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_app.py -q -k \"bold or scrollbar\" 2>&1 | Select-Object -Last 60)",
43
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 30; Write-Host \"---\"; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
44
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 40; Write-Host \"---\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
45
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_task_creation_and_editing.py -q -k cursor 2>&1 | Select-Object -Last 60)",
46
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 40)",
47
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_task_states.py -q 2>&1 | Select-Object -Last 60)",
48
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_task_states.py -q 2>&1 | Select-Object -Last 200)",
49
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .)",
50
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m mypy src; Write-Host \"mypy exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 40)",
51
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m mypy src; Write-Host \"mypy exit: $LASTEXITCODE\")",
52
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_undo.py tests/test_undo_manager.py tests/test_task_repository.py -q 2>&1 | Select-Object -Last 250)",
53
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 30)",
54
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_rollover.py -q 2>&1 | Select-Object -Last 250)",
55
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check --fix .)",
56
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; Write-Host \"check exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
57
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_rollover_app.py -q 2>&1 | Select-Object -Last 250)",
58
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_rollover_app.py -q 2>&1 | Select-Object -Last 150)",
59
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m mypy src; Write-Host \"---\"; .\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 30)",
60
+ "PowerShell(jq *)",
61
+ "PowerShell(claude *)",
62
+ "PowerShell(Get-Content *)",
63
+ "Artifact"
64
+ ]
65
+ }
66
+ }
@@ -0,0 +1,66 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "PowerShell(\\(Get-Content \"C:\\\\Users\\\\janchawla\\\\rook\\\\DEVELOPMENT_GUIDE.md\" | Measure-Object -Line\\).Lines)",
5
+ "PowerShell(\\(Get-Content \"C:\\\\Users\\\\janchawla\\\\rook\\\\DEVELOPMENT_GUIDE.md\"\\).Count)",
6
+ "PowerShell(py *)",
7
+ "PowerShell(Get-Command *)",
8
+ "PowerShell(python3 --version; python3 -c \"import sys; print\\(sys.executable\\)\")",
9
+ "PowerShell(git config *)",
10
+ "PowerShell(python3 -m venv .venv; Write-Host \"exit code: $LASTEXITCODE\")",
11
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pip install --upgrade pip 2>&1 | Select-Object -Last 5; .\\\\.venv\\\\Scripts\\\\python.exe -m pip install -e \".[dev]\" 2>&1 | Select-Object -Last 40)",
12
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q)",
13
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; Write-Host \"ruff check exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; Write-Host \"ruff format exit: $LASTEXITCODE\")",
14
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
15
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m build 2>&1 | Select-Object -Last 20)",
16
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m rook; Write-Host \"---\"; .\\\\.venv\\\\Scripts\\\\rook.exe; Write-Host \"---\"; Get-ChildItem dist)",
17
+ "PowerShell(git add *)",
18
+ "PowerShell(git commit *)",
19
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pip install -e \".[dev]\" 2>&1 | Select-Object -Last 30)",
20
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 80)",
21
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 60)",
22
+ "PowerShell(Remove-Item *)",
23
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; Write-Host \"ruff check exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; Write-Host \"ruff format exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
24
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q; Write-Host \"pytest exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
25
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 150)",
26
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .)",
27
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; Write-Host \"check exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check . 2>&1)",
28
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff format .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .)",
29
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_widget_markup_safety.py -q 2>&1 | Select-Object -Last 60)",
30
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 200)",
31
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 100)",
32
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; Write-Host \"check exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .)",
33
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff format .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
34
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_task_creation_and_editing.py -q 2>&1 | Select-Object -Last 250)",
35
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_task_creation_and_editing.py -q 2>&1 | Select-Object -Last 150)",
36
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; Write-Host \"check exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
37
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 250)",
38
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m mypy src; Write-Host \"mypy exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 60)",
39
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_paths.py -q 2>&1 | Select-Object -Last 60)",
40
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 60; Write-Host \"---\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
41
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_app.py -q -k \"bold or scrollbar\" 2>&1 | Select-Object -Last 100)",
42
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_app.py -q -k \"bold or scrollbar\" 2>&1 | Select-Object -Last 60)",
43
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 30; Write-Host \"---\"; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
44
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 40; Write-Host \"---\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
45
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_task_creation_and_editing.py -q -k cursor 2>&1 | Select-Object -Last 60)",
46
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 40)",
47
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_task_states.py -q 2>&1 | Select-Object -Last 60)",
48
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_task_states.py -q 2>&1 | Select-Object -Last 200)",
49
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .)",
50
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m mypy src; Write-Host \"mypy exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 40)",
51
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m mypy src; Write-Host \"mypy exit: $LASTEXITCODE\")",
52
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_undo.py tests/test_undo_manager.py tests/test_task_repository.py -q 2>&1 | Select-Object -Last 250)",
53
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 30)",
54
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_rollover.py -q 2>&1 | Select-Object -Last 250)",
55
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check --fix .)",
56
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m ruff check .; Write-Host \"check exit: $LASTEXITCODE\"; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format .; .\\\\.venv\\\\Scripts\\\\python.exe -m ruff format --check .; .\\\\.venv\\\\Scripts\\\\python.exe -m mypy src)",
57
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_rollover_app.py -q 2>&1 | Select-Object -Last 250)",
58
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m pytest tests/test_rollover_app.py -q 2>&1 | Select-Object -Last 150)",
59
+ "PowerShell(.\\\\.venv\\\\Scripts\\\\python.exe -m mypy src; Write-Host \"---\"; .\\\\.venv\\\\Scripts\\\\python.exe -m pytest -q 2>&1 | Select-Object -Last 30)",
60
+ "PowerShell(jq *)",
61
+ "PowerShell(claude *)",
62
+ "PowerShell(Get-Content *)",
63
+ "Artifact"
64
+ ]
65
+ }
66
+ }
@@ -0,0 +1,20 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.py[cod]
4
+ .pytest_cache/
5
+ .mypy_cache/
6
+ .ruff_cache/
7
+ .coverage
8
+ htmlcov/
9
+ dist/
10
+ build/
11
+ *.egg-info/
12
+ *.db
13
+ *.db-journal
14
+ *.db-wal
15
+ *.db-shm
16
+ *.sqlite
17
+ *.sqlite3
18
+ .env
19
+ .DS_Store
20
+ Thumbs.db
@@ -0,0 +1,10 @@
1
+ Copyright (c) 2026 Janvi Chawla. All Rights Reserved.
2
+
3
+ This software and its source code are proprietary and confidential.
4
+ No part of this software may be copied, modified, merged, distributed,
5
+ sublicensed, or used to create derivative works without explicit written
6
+ permission from the copyright owner.
7
+
8
+ You may install and use this software for personal, non-commercial purposes.
9
+ You may not redistribute it, repackage it, or incorporate it into another
10
+ product or service without permission.
@@ -0,0 +1,103 @@
1
+ # Rook ♖
2
+
3
+ A local, keyboard-first terminal journal for working through one day at a time.
4
+
5
+ ```text
6
+ rook ♖ Today — Friday, July 24, 2026
7
+ ⋆⁺₊ (。'▽'。)♡ ₊⁺⋆ "Showing up is the whole trick."
8
+
9
+ ❯ • Finish the presentation
10
+ • Reply to Alex
11
+ > Read Chapter 3
12
+ × Submit the expense report
13
+
14
+ [n] new [e/Ent] edit [x] complete [>] migrate [d] delete [u] undo [a] archive [q] quit
15
+ ```
16
+
17
+ Rook is inspired by the simplicity of a paper bullet journal:
18
+
19
+ - one active list: **Today**
20
+ - direct, in-place editing
21
+ - local SQLite storage
22
+ - read-only history
23
+ - no accounts, cloud sync, reminders, priorities, or telemetry
24
+
25
+ ## Installation
26
+
27
+ Requires Python 3.10 or newer. Install with [uv](https://docs.astral.sh/uv/):
28
+
29
+ ```powershell
30
+ uv tool install rook-cli
31
+ ```
32
+
33
+ Then launch:
34
+
35
+ ```powershell
36
+ rook
37
+ ```
38
+
39
+ To upgrade later:
40
+
41
+ ```powershell
42
+ uv tool upgrade rook-cli
43
+ ```
44
+
45
+ ## Keyboard reference
46
+
47
+ | Key | Action |
48
+ |-----|--------|
49
+ | `n` | New task |
50
+ | `e` or `Ent` | Edit selected task |
51
+ | `x` | Toggle complete |
52
+ | `>` | Toggle migrated |
53
+ | `d` | Soft-delete / permanently remove (press twice) |
54
+ | `u` | Undo last action |
55
+ | `a` | Open weekly archive |
56
+ | `↑` / `↓` | Move selection |
57
+ | `Esc` | Cancel edit |
58
+ | `q` | Quit |
59
+
60
+ ## Data and privacy
61
+
62
+ Tasks are stored in a local SQLite database. Nothing leaves your machine.
63
+
64
+ | Platform | Location |
65
+ |----------|----------|
66
+ | Windows | `%LOCALAPPDATA%\Rook\data.sqlite3` |
67
+ | macOS | `~/Library/Application Support/Rook/data.sqlite3` |
68
+ | Linux | `~/.local/share/rook/data.sqlite3` |
69
+
70
+ To print the exact path on your system:
71
+
72
+ ```powershell
73
+ rook --data-path
74
+ ```
75
+
76
+ Uninstalling Rook does not delete the database.
77
+
78
+ ## FAQ
79
+
80
+ **How do I change the archive week layout from Sun–Sat to Mon–Sun?**
81
+
82
+ There is no in-app setting yet. Update the value directly in the SQLite database.
83
+ Find the exact path with `rook --data-path`, or use the default:
84
+
85
+ ```powershell
86
+ sqlite3 "$env:LOCALAPPDATA\Rook\data.sqlite3"
87
+ ```
88
+
89
+ ```sql
90
+ INSERT OR REPLACE INTO app_meta (key, value) VALUES ('week_start_day', 'monday');
91
+ ```
92
+
93
+ To switch back to Sunday-start:
94
+
95
+ ```sql
96
+ INSERT OR REPLACE INTO app_meta (key, value) VALUES ('week_start_day', 'sunday');
97
+ ```
98
+
99
+ ## License
100
+
101
+ Copyright (c) 2026 Janvi Chawla. All Rights Reserved.
102
+
103
+ Personal use permitted. No redistribution or derivative works without permission.
@@ -0,0 +1,51 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "rook-cli"
7
+ dynamic = ["version"]
8
+ description = "A local, keyboard-first terminal daily journal."
9
+ readme = "README.md"
10
+ license = "LicenseRef-Proprietary"
11
+ requires-python = ">=3.10"
12
+ authors = [
13
+ { name = "Janvi Chawla" },
14
+ ]
15
+ dependencies = [
16
+ "textual>=0.60",
17
+ ]
18
+
19
+ [project.optional-dependencies]
20
+ dev = [
21
+ "pytest>=8.0",
22
+ "ruff>=0.6",
23
+ "mypy>=1.10",
24
+ "build>=1.2",
25
+ ]
26
+
27
+ [project.urls]
28
+ Repository = "https://github.com/JanviChawla/rook"
29
+
30
+ [project.scripts]
31
+ rook = "rook.__main__:main"
32
+
33
+ [tool.hatch.version]
34
+ path = "src/rook/__init__.py"
35
+
36
+ [tool.hatch.build.targets.wheel]
37
+ packages = ["src/rook"]
38
+
39
+ [tool.ruff]
40
+ line-length = 100
41
+ target-version = "py310"
42
+
43
+ [tool.ruff.lint]
44
+ select = ["E", "F", "I", "UP", "B"]
45
+
46
+ [tool.mypy]
47
+ python_version = "3.10"
48
+ strict = true
49
+
50
+ [tool.pytest.ini_options]
51
+ testpaths = ["tests"]
@@ -0,0 +1,48 @@
1
+ import sys
2
+
3
+ from rook.app import RookApp
4
+ from rook.paths import default_database_path
5
+ from rook.persistence.database import connect
6
+ from rook.persistence.metadata import MetadataRepository
7
+ from rook.persistence.migrations import UnsupportedSchemaVersionError, migrate
8
+ from rook.persistence.tasks import TaskRepository
9
+ from rook.services.rollover import RolloverService
10
+ from rook.services.tasks import TaskService
11
+
12
+
13
+ def main() -> int:
14
+ if len(sys.argv) > 1 and sys.argv[1] == "--data-path":
15
+ print(default_database_path())
16
+ return 0
17
+
18
+ db_path = default_database_path()
19
+ connection = connect(db_path)
20
+
21
+ try:
22
+ migrate(connection)
23
+ except UnsupportedSchemaVersionError as error:
24
+ connection.close()
25
+ print(error)
26
+ print(f"Database file: {db_path}")
27
+ return 1
28
+
29
+ task_service = TaskService(TaskRepository(connection))
30
+ rollover_service = RolloverService(connection, MetadataRepository(connection))
31
+
32
+ # Section 16.8: rollover runs once at startup, before Today ever renders.
33
+ rollover_service.roll_forward_if_needed()
34
+
35
+ try:
36
+ RookApp(
37
+ task_service=task_service,
38
+ rollover_service=rollover_service,
39
+ connection=connection,
40
+ ).run()
41
+ finally:
42
+ connection.close()
43
+
44
+ return 0
45
+
46
+
47
+ if __name__ == "__main__":
48
+ raise SystemExit(main())
@@ -0,0 +1,222 @@
1
+ import sqlite3
2
+ from collections.abc import Callable
3
+ from datetime import date
4
+
5
+ from textual.app import App, ComposeResult
6
+ from textual.binding import Binding
7
+ from textual.widgets import Static
8
+
9
+ from rook import branding
10
+ from rook.formatting import format_header_date
11
+ from rook.persistence.metadata import MetadataRepository
12
+ from rook.services.rollover import RolloverService
13
+ from rook.services.tasks import TaskService
14
+ from rook.services.undo import UndoManager
15
+ from rook.widgets.archive_screen import ArchiveScreen
16
+ from rook.widgets.shortcut_footer import ShortcutFooter
17
+ from rook.widgets.task_list import TaskListView
18
+
19
+ TodayProvider = Callable[[], date]
20
+
21
+ # Section 21.13 explicitly excludes anything more frequent than needed; a
22
+ # once-a-minute check is enough to notice a live midnight crossing without
23
+ # being a tight polling loop.
24
+ ROLLOVER_CHECK_INTERVAL_SECONDS = 60
25
+
26
+
27
+ class RookApp(App[None]):
28
+ """The Rook terminal shell.
29
+
30
+ Phase 5 replaces the in-memory Task list with SQLite as the source of
31
+ truth, via an injected TaskService. Task state changes, Archive, and
32
+ Routines are still not implemented.
33
+ """
34
+
35
+ CSS = """
36
+ Screen {
37
+ layout: vertical;
38
+ }
39
+
40
+ #header, #mascot-quote, #spacer, #status {
41
+ height: 1;
42
+ }
43
+
44
+ #header {
45
+ text-style: bold;
46
+ }
47
+
48
+ #task-list {
49
+ height: 1fr;
50
+ /* The "ansi-dark" theme doesn't define scrollbar variables (only
51
+ * "ansi-light" happens to), so these fall back to Textual's fixed
52
+ * truecolor defaults - the mismatched, chunky bar reported after
53
+ * scrolling a long list. Set them directly to ANSI colors instead,
54
+ * and use a slimmer single-column bar (Section 11.1 "compact"). */
55
+ scrollbar-size-vertical: 1;
56
+ scrollbar-color: ansi_default;
57
+ scrollbar-color-hover: ansi_default;
58
+ scrollbar-color-active: ansi_default;
59
+ scrollbar-background: ansi_default;
60
+ scrollbar-background-hover: ansi_default;
61
+ scrollbar-background-active: ansi_default;
62
+ scrollbar-corner-color: ansi_default;
63
+ }
64
+
65
+ /* "ansi-dark" hardcodes the text-entry cursor to a solid reverse-video
66
+ * block in ansi_black on ansi_bright_white, which many customized
67
+ * terminal palettes remap to something unrelated to the terminal's
68
+ * actual foreground/background (reported as an unrelated light gray).
69
+ * Reversing the terminal's own default foreground instead keeps the
70
+ * filled-block look but in the user's own theme color. This is Rook's
71
+ * own simulated text cursor, not the terminal's hardware cursor - a
72
+ * full-screen app owning the whole display can't repurpose the
73
+ * terminal's native caret for a styled, multi-character-wide input. */
74
+ TaskLineInput > .input--cursor {
75
+ color: ansi_default;
76
+ text-style: reverse;
77
+ }
78
+
79
+ #footer {
80
+ height: 1;
81
+ dock: bottom;
82
+ }
83
+ """
84
+
85
+ BINDINGS = [
86
+ Binding("q", "quit", "Quit"),
87
+ Binding("up", "cursor_up", "Up", show=False),
88
+ Binding("down", "cursor_down", "Down", show=False),
89
+ Binding("n", "new_task", "New", show=False),
90
+ Binding("e", "edit_task", "Edit", show=False),
91
+ Binding("enter", "edit_task", "Edit", show=False),
92
+ Binding("x", "toggle_completed", "Complete", show=False),
93
+ Binding(">", "toggle_migrated", "Migrate", show=False),
94
+ Binding("d", "delete_or_remove", "Delete", show=False),
95
+ Binding("u", "undo", "Undo", show=False),
96
+ Binding("a", "archive", "Archive", show=False),
97
+ ]
98
+
99
+ def __init__(
100
+ self,
101
+ today_provider: TodayProvider = date.today,
102
+ *,
103
+ task_service: TaskService,
104
+ rollover_service: RolloverService,
105
+ connection: sqlite3.Connection | None = None,
106
+ safe_symbols: bool = False,
107
+ ) -> None:
108
+ super().__init__()
109
+ self._today_provider = today_provider
110
+ self._task_service = task_service
111
+ self._rollover_service = rollover_service
112
+ self._connection = connection
113
+ self._rollover_pending = False
114
+ # Session-scoped: owned here (not per-widget) so a later Routine
115
+ # phase can share the same single undo slot (Section 6.10).
116
+ self._undo_manager = UndoManager()
117
+ self._safe_symbols = safe_symbols
118
+ # Map foreground/background to the terminal's own ANSI defaults
119
+ # instead of Textual's fixed truecolor theme, so the app respects
120
+ # the user's existing terminal background (Section 11.9-11.10).
121
+ self.theme = "ansi-dark"
122
+
123
+ def _mascot_quote_text(self) -> str:
124
+ mascot, quote = branding.pick_for_date(self._today_provider())
125
+ return f'{mascot} "{quote}"'
126
+
127
+ def compose(self) -> ComposeResult:
128
+ mascot_quote_text = self._mascot_quote_text()
129
+ tasks = self._task_service.list_active_tasks()
130
+
131
+ yield Static(self._header_text(), id="header", markup=False)
132
+ yield Static(mascot_quote_text, id="mascot-quote", markup=False)
133
+ yield Static("", id="spacer")
134
+ yield TaskListView(
135
+ tasks,
136
+ task_service=self._task_service,
137
+ undo_manager=self._undo_manager,
138
+ safe_symbols=self._safe_symbols,
139
+ id="task-list",
140
+ )
141
+ yield Static("", id="status", markup=False)
142
+ yield ShortcutFooter(has_tasks=bool(tasks), id="footer")
143
+
144
+ def _header_text(self) -> str:
145
+ today = self._today_provider()
146
+ return f"{branding.DISPLAY_NAME.lower()} {branding.ICON} Today — {format_header_date(today)}"
147
+
148
+ def on_mount(self) -> None:
149
+ self.set_interval(ROLLOVER_CHECK_INTERVAL_SECONDS, self._check_for_new_day)
150
+
151
+ async def _check_for_new_day(self) -> None:
152
+ if self.query_one(TaskListView).is_editing:
153
+ # Section 18.12: defer while the user is actively typing;
154
+ # on_task_list_view_editing_changed runs it once they finish.
155
+ self._rollover_pending = True
156
+ return
157
+ await self._apply_rollover_if_needed()
158
+
159
+ async def _apply_rollover_if_needed(self) -> None:
160
+ try:
161
+ result = self._rollover_service.roll_forward_if_needed()
162
+ except Exception:
163
+ # A transient failure here must not crash a running session -
164
+ # Section 16.24's fatal-error handling is for startup, not a
165
+ # live background reconciliation. The next check retries.
166
+ return
167
+
168
+ if not result.changed:
169
+ return
170
+
171
+ self.query_one("#header", Static).update(self._header_text())
172
+ self.query_one("#mascot-quote", Static).update(self._mascot_quote_text())
173
+ tasks = self._task_service.list_active_tasks()
174
+ await self.query_one(TaskListView).reload(tasks)
175
+ self.query_one(ShortcutFooter).set_has_tasks(bool(tasks))
176
+ # Section 6.10: Day Rollover clears session undo after completing.
177
+ self._undo_manager.clear()
178
+
179
+ def action_cursor_up(self) -> None:
180
+ self.query_one(TaskListView).select_previous()
181
+
182
+ def action_cursor_down(self) -> None:
183
+ self.query_one(TaskListView).select_next()
184
+
185
+ async def action_new_task(self) -> None:
186
+ await self.query_one(TaskListView).begin_create()
187
+
188
+ async def action_edit_task(self) -> None:
189
+ await self.query_one(TaskListView).begin_edit()
190
+
191
+ async def action_toggle_completed(self) -> None:
192
+ await self.query_one(TaskListView).toggle_completed()
193
+
194
+ async def action_toggle_migrated(self) -> None:
195
+ await self.query_one(TaskListView).toggle_migrated()
196
+
197
+ async def action_delete_or_remove(self) -> None:
198
+ await self.query_one(TaskListView).delete_or_remove()
199
+
200
+ async def action_undo(self) -> None:
201
+ await self.query_one(TaskListView).undo()
202
+
203
+ def on_task_list_view_status_message(self, message: TaskListView.StatusMessage) -> None:
204
+ self.query_one("#status", Static).update(message.text)
205
+
206
+ async def on_task_list_view_editing_changed(self, message: TaskListView.EditingChanged) -> None:
207
+ self.query_one(ShortcutFooter).set_editing(message.editing)
208
+ self.query_one("#status", Static).update("")
209
+ if not message.editing and self._rollover_pending:
210
+ self._rollover_pending = False
211
+ await self._apply_rollover_if_needed()
212
+
213
+ def on_task_list_view_tasks_empty_changed(
214
+ self, message: TaskListView.TasksEmptyChanged
215
+ ) -> None:
216
+ self.query_one(ShortcutFooter).set_has_tasks(message.has_tasks)
217
+
218
+ def action_archive(self) -> None:
219
+ if self._connection is None:
220
+ return
221
+ first_weekday = MetadataRepository(self._connection).get_week_start_day()
222
+ self.push_screen(ArchiveScreen(connection=self._connection, first_weekday=first_weekday))