agent-notes 2.13.0__tar.gz → 2.14.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 (228) hide show
  1. {agent_notes-2.13.0 → agent_notes-2.14.0}/PKG-INFO +1 -1
  2. agent_notes-2.14.0/agent_notes/VERSION +1 -0
  3. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/memory_backend.py +23 -6
  4. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes.egg-info/PKG-INFO +1 -1
  5. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/services/test_memory_backend_io.py +209 -5
  6. agent_notes-2.13.0/agent_notes/VERSION +0 -1
  7. {agent_notes-2.13.0 → agent_notes-2.14.0}/LICENSE +0 -0
  8. {agent_notes-2.13.0 → agent_notes-2.14.0}/README.md +0 -0
  9. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/__init__.py +0 -0
  10. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/__main__.py +0 -0
  11. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/cli.py +0 -0
  12. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/__init__.py +0 -0
  13. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/_install_helpers.py +0 -0
  14. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/build.py +0 -0
  15. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/config.py +0 -0
  16. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/doctor.py +0 -0
  17. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/info.py +0 -0
  18. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/install.py +0 -0
  19. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/list.py +0 -0
  20. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/memory.py +0 -0
  21. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/regenerate.py +0 -0
  22. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/set_role.py +0 -0
  23. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/uninstall.py +0 -0
  24. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/update.py +0 -0
  25. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/validate.py +0 -0
  26. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/commands/wizard.py +0 -0
  27. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/config.py +0 -0
  28. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/agents.yaml +0 -0
  29. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/analyst.md +0 -0
  30. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/api-reviewer.md +0 -0
  31. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/architect.md +0 -0
  32. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/coder.md +0 -0
  33. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/database-specialist.md +0 -0
  34. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/debugger.md +0 -0
  35. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/devil.md +0 -0
  36. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/devops.md +0 -0
  37. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/explorer.md +0 -0
  38. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/integrations.md +0 -0
  39. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/lead.md +0 -0
  40. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/performance-profiler.md +0 -0
  41. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/refactorer.md +0 -0
  42. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/reviewer.md +0 -0
  43. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/security-auditor.md +0 -0
  44. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/shared/cost_reporting.md +0 -0
  45. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/shared/phase0.md +0 -0
  46. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/system-auditor.md +0 -0
  47. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/tech-writer.md +0 -0
  48. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/test-runner.md +0 -0
  49. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/agents/test-writer.md +0 -0
  50. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/cli/claude.yaml +0 -0
  51. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/cli/copilot.yaml +0 -0
  52. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/cli/opencode.yaml +0 -0
  53. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/commands/brainstorm.md +0 -0
  54. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/commands/debug.md +0 -0
  55. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/commands/review.md +0 -0
  56. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/global-claude.md +0 -0
  57. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/global-copilot.md +0 -0
  58. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/global-opencode.md +0 -0
  59. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/hooks/session-context.md.tpl +0 -0
  60. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-haiku-4-5.yaml +0 -0
  61. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-opus-4-1.yaml +0 -0
  62. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-opus-4-5.yaml +0 -0
  63. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-opus-4-6.yaml +0 -0
  64. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-opus-4-7.yaml +0 -0
  65. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-sonnet-4-5.yaml +0 -0
  66. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-sonnet-4-6.yaml +0 -0
  67. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-sonnet-4.yaml +0 -0
  68. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/plugin/claude.yaml +0 -0
  69. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/plugin/opencode-index.js.template +0 -0
  70. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/plugin/opencode.yaml +0 -0
  71. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/pricing.yaml +0 -0
  72. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/roles/orchestrator.yaml +0 -0
  73. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/roles/reasoner.yaml +0 -0
  74. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/roles/scout.yaml +0 -0
  75. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/roles/worker.yaml +0 -0
  76. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/rules/code-quality.md +0 -0
  77. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/rules/safety.md +0 -0
  78. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/brainstorming/SKILL.md +0 -0
  79. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/caveman/SKILL.md +0 -0
  80. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/code-review/SKILL.md +0 -0
  81. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/debugging-protocol/SKILL.md +0 -0
  82. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/docker-compose/SKILL.md +0 -0
  83. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/docker-compose-advanced/SKILL.md +0 -0
  84. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/docker-dockerfile/SKILL.md +0 -0
  85. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/docker-dockerfile-languages/SKILL.md +0 -0
  86. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/git/SKILL.md +0 -0
  87. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/grill-me/SKILL.md +0 -0
  88. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/grill-with-docs/SKILL.md +0 -0
  89. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/improve-codebase-architecture/SKILL.md +0 -0
  90. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/obsidian-memory/SKILL.md +0 -0
  91. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-active-storage/SKILL.md +0 -0
  92. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-broadcasting/SKILL.md +0 -0
  93. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-concerns/SKILL.md +0 -0
  94. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-controllers/SKILL.md +0 -0
  95. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-controllers-advanced/SKILL.md +0 -0
  96. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-helpers/SKILL.md +0 -0
  97. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-initializers/SKILL.md +0 -0
  98. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-javascript/SKILL.md +0 -0
  99. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-jobs/SKILL.md +0 -0
  100. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-kamal/SKILL.md +0 -0
  101. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-lib/SKILL.md +0 -0
  102. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-mailers/SKILL.md +0 -0
  103. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-migrations/SKILL.md +0 -0
  104. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-models/SKILL.md +0 -0
  105. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-models-advanced/SKILL.md +0 -0
  106. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-routes/SKILL.md +0 -0
  107. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-style/SKILL.md +0 -0
  108. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-testing-controllers/SKILL.md +0 -0
  109. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-testing-models/SKILL.md +0 -0
  110. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-testing-system/SKILL.md +0 -0
  111. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-validations/SKILL.md +0 -0
  112. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-view-components/SKILL.md +0 -0
  113. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-view-components-advanced/SKILL.md +0 -0
  114. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-views/SKILL.md +0 -0
  115. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-views-advanced/SKILL.md +0 -0
  116. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/refactoring-protocol/SKILL.md +0 -0
  117. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/setup-project-context/SKILL.md +0 -0
  118. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/tdd/SKILL.md +0 -0
  119. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/skills/zoom-out/SKILL.md +0 -0
  120. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/templates/__init__.py +0 -0
  121. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/templates/__pycache__/__init__.cpython-314.pyc +0 -0
  122. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/templates/frontmatter/__init__.py +0 -0
  123. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/templates/frontmatter/__pycache__/__init__.cpython-314.pyc +0 -0
  124. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/templates/frontmatter/__pycache__/claude.cpython-314.pyc +0 -0
  125. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/templates/frontmatter/__pycache__/opencode.cpython-314.pyc +0 -0
  126. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/templates/frontmatter/claude.py +0 -0
  127. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/data/templates/frontmatter/opencode.py +0 -0
  128. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/doctor_checks.py +0 -0
  129. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/domain/__init__.py +0 -0
  130. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/domain/agent.py +0 -0
  131. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/domain/cli_backend.py +0 -0
  132. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/domain/diagnostics.py +0 -0
  133. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/domain/diff.py +0 -0
  134. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/domain/model.py +0 -0
  135. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/domain/role.py +0 -0
  136. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/domain/rule.py +0 -0
  137. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/domain/skill.py +0 -0
  138. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/domain/state.py +0 -0
  139. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/install_state.py +0 -0
  140. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/registries/__init__.py +0 -0
  141. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/registries/_base.py +0 -0
  142. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/registries/agent_registry.py +0 -0
  143. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/registries/cli_registry.py +0 -0
  144. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/registries/model_registry.py +0 -0
  145. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/registries/role_registry.py +0 -0
  146. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/registries/rule_registry.py +0 -0
  147. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/registries/skill_registry.py +0 -0
  148. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/scripts/__init__.py +0 -0
  149. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/scripts/_claude_backend.py +0 -0
  150. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/scripts/_formatting.py +0 -0
  151. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/scripts/_opencode_backend.py +0 -0
  152. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/scripts/_pricing.py +0 -0
  153. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/scripts/cost_report.py +0 -0
  154. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/__init__.py +0 -0
  155. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/credentials.py +0 -0
  156. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/diagnostics/__init__.py +0 -0
  157. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/diagnostics/_checks.py +0 -0
  158. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/diagnostics/_display.py +0 -0
  159. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/diagnostics/_fix.py +0 -0
  160. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/diff.py +0 -0
  161. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/fs.py +0 -0
  162. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/install_state_builder.py +0 -0
  163. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/installer.py +0 -0
  164. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/rendering.py +0 -0
  165. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/session_context.py +0 -0
  166. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/settings_writer.py +0 -0
  167. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/state_store.py +0 -0
  168. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/ui.py +0 -0
  169. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/user_config.py +0 -0
  170. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/services/validation.py +0 -0
  171. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes/state.py +0 -0
  172. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes.egg-info/SOURCES.txt +0 -0
  173. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes.egg-info/dependency_links.txt +0 -0
  174. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes.egg-info/entry_points.txt +0 -0
  175. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes.egg-info/requires.txt +0 -0
  176. {agent_notes-2.13.0 → agent_notes-2.14.0}/agent_notes.egg-info/top_level.txt +0 -0
  177. {agent_notes-2.13.0 → agent_notes-2.14.0}/pyproject.toml +0 -0
  178. {agent_notes-2.13.0 → agent_notes-2.14.0}/setup.cfg +0 -0
  179. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/conftest.py +0 -0
  180. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/__init__.py +0 -0
  181. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/commands/__init__.py +0 -0
  182. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/commands/test_config_command.py +0 -0
  183. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/commands/test_doctor_command.py +0 -0
  184. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/commands/test_info_command.py +0 -0
  185. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/commands/test_install_command.py +0 -0
  186. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/commands/test_list_command.py +0 -0
  187. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/commands/test_regenerate_command.py +0 -0
  188. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/commands/test_uninstall_command.py +0 -0
  189. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/commands/test_update_command.py +0 -0
  190. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/commands/test_validate_command.py +0 -0
  191. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/memory/__init__.py +0 -0
  192. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/memory/test_memory_command.py +0 -0
  193. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/scripts/__init__.py +0 -0
  194. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/functional/scripts/test_release_script.py +0 -0
  195. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/integration/__init__.py +0 -0
  196. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/integration/build_output/__init__.py +0 -0
  197. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/integration/build_output/test_build_output.py +0 -0
  198. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/integration/install/__init__.py +0 -0
  199. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/integration/install/test_install_methods.py +0 -0
  200. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/integration/plugin_builders/__init__.py +0 -0
  201. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/integration/plugin_builders/test_plugin_builders.py +0 -0
  202. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/plugins/__init__.py +0 -0
  203. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/plugins/claude/__init__.py +0 -0
  204. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/plugins/claude/test_agents.py +0 -0
  205. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/plugins/test_skills.py +0 -0
  206. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/__init__.py +0 -0
  207. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/commands/__init__.py +0 -0
  208. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/commands/test_cost_report_subcommand.py +0 -0
  209. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/commands/test_count_agents.py +0 -0
  210. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/commands/test_memory_migrate.py +0 -0
  211. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/commands/test_wizard_orchestrator_skip.py +0 -0
  212. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/commands/test_wizard_preflight.py +0 -0
  213. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/registries/__init__.py +0 -0
  214. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/registries/test_registries.py +0 -0
  215. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/scripts/__init__.py +0 -0
  216. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/scripts/test_cost_report.py +0 -0
  217. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/scripts/test_cost_report_scoping.py +0 -0
  218. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/scripts/test_formatting_tty.py +0 -0
  219. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/scripts/test_time_aggregation.py +0 -0
  220. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/services/__init__.py +0 -0
  221. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/services/test_build_functions.py +0 -0
  222. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/services/test_credentials.py +0 -0
  223. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/services/test_fs.py +0 -0
  224. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/services/test_installer_plan.py +0 -0
  225. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/services/test_memory_backend.py +0 -0
  226. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/services/test_rendering_includes.py +0 -0
  227. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/services/test_settings_writer.py +0 -0
  228. {agent_notes-2.13.0 → agent_notes-2.14.0}/tests/unit/test_memory_dir_for_backend.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-notes
3
- Version: 2.13.0
3
+ Version: 2.14.0
4
4
  Summary: AI agent configuration manager for Claude Code, OpenCode, and Copilot
5
5
  Author-email: Eugene Naumov <min.verkligheten@gmail.com>
6
6
  License-Expression: MIT
@@ -0,0 +1 @@
1
+ 2.14.0
@@ -53,6 +53,12 @@ def _current_session_id() -> Optional[str]:
53
53
  return None
54
54
 
55
55
 
56
+ def _current_project_name() -> str:
57
+ """Return the current working directory's name as the project name."""
58
+ name = Path.cwd().name
59
+ return name or ""
60
+
61
+
56
62
  # ── Obsidian backend ───────────────────────────────────────────────────────────
57
63
 
58
64
  def obsidian_init(vault: Path) -> None:
@@ -107,9 +113,12 @@ def _build_note(
107
113
  agent: str,
108
114
  session_stem: Optional[str],
109
115
  created_at: str,
116
+ project: str = "",
110
117
  ) -> str:
111
118
  """Render the canonical note content (frontmatter + heading + body + Related section)."""
112
119
  lines = ["---", f"created_at: {created_at}", f"type: {note_type}"]
120
+ if project:
121
+ lines.append(f"project: {project}")
113
122
  if session_stem and note_type != "session":
114
123
  lines.append(f"session: {session_stem}")
115
124
  if agent:
@@ -178,6 +187,9 @@ def obsidian_write_note(
178
187
  else:
179
188
  session_id = None
180
189
 
190
+ if not project:
191
+ project = _current_project_name()
192
+
181
193
  today = _today()
182
194
 
183
195
  if note_type == "session" and session_id:
@@ -185,7 +197,7 @@ def obsidian_write_note(
185
197
  # But first check if an existing file already has this session_id (any date prefix)
186
198
  existing = _find_session_note(vault, session_id)
187
199
  if existing is not None:
188
- # Append to existing session note
200
+ # Append to existing session note — preserve existing frontmatter (including project)
189
201
  text = existing.read_text()
190
202
  fm, existing_body = _parse_frontmatter(text)
191
203
  if "created_at" not in fm:
@@ -193,6 +205,9 @@ def obsidian_write_note(
193
205
  if re.fullmatch(r"\d{4}-\d{2}-\d{2}", created_at):
194
206
  created_at = f"{created_at}T00:00:00Z"
195
207
  new_fm_lines = ["---", f"created_at: {created_at}", f"type: {note_type}"]
208
+ existing_project = fm.get("project", "")
209
+ if existing_project:
210
+ new_fm_lines.append(f"project: {existing_project}")
196
211
  if agent:
197
212
  new_fm_lines.append(f"agent: {agent}")
198
213
  new_fm_lines.append("---")
@@ -206,7 +221,7 @@ def obsidian_write_note(
206
221
  path = folder / filename
207
222
  path.write_text(_build_note(
208
223
  title=title, body=body, note_type=note_type,
209
- agent=agent, session_stem=None, created_at=created_at,
224
+ agent=agent, session_stem=None, created_at=created_at, project=project,
210
225
  ))
211
226
  elif note_type == "session":
212
227
  # No session_id available — fall back to timestamp+slug
@@ -215,7 +230,7 @@ def obsidian_write_note(
215
230
  path = folder / filename
216
231
  path.write_text(_build_note(
217
232
  title=title, body=body, note_type=note_type,
218
- agent=agent, session_stem=None, created_at=created_at,
233
+ agent=agent, session_stem=None, created_at=created_at, project=project,
219
234
  ))
220
235
  else:
221
236
  # Non-session note
@@ -232,7 +247,7 @@ def obsidian_write_note(
232
247
  path = folder / filename
233
248
  path.write_text(_build_note(
234
249
  title=title, body=body, note_type=note_type,
235
- agent=agent, session_stem=session_stem, created_at=created_at,
250
+ agent=agent, session_stem=session_stem, created_at=created_at, project=project,
236
251
  ))
237
252
 
238
253
  # Auto-link to session note
@@ -265,7 +280,8 @@ def _parse_note_metadata(path: Path) -> dict:
265
280
  (l.lstrip("# ").strip() for l in full_text.splitlines() if l.startswith("# ")),
266
281
  path.stem,
267
282
  )
268
- return {"created_at": created_at, "type": note_type, "title": title}
283
+ project = fm.get("project", "")
284
+ return {"created_at": created_at, "type": note_type, "title": title, "project": project}
269
285
 
270
286
 
271
287
  def obsidian_regenerate_index(vault: Path) -> None:
@@ -299,7 +315,8 @@ def obsidian_regenerate_index(vault: Path) -> None:
299
315
  display_dt = f"{dt_str[:10]} {dt_str[11:16]}"
300
316
  else:
301
317
  display_dt = dt_str[:16] if len(dt_str) >= 16 else dt_str
302
- lines.append(f"- {display_dt} [[{stem}]] — {meta['type']}")
318
+ project = meta.get("project", "")
319
+ lines.append(f"- [[{stem}|{display_dt}]] - {project}({meta['type']})")
303
320
 
304
321
  (vault / "Index.md").write_text("\n".join(lines) + "\n")
305
322
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-notes
3
- Version: 2.13.0
3
+ Version: 2.14.0
4
4
  Summary: AI agent configuration manager for Claude Code, OpenCode, and Copilot
5
5
  Author-email: Eugene Naumov <min.verkligheten@gmail.com>
6
6
  License-Expression: MIT
@@ -175,7 +175,8 @@ class TestObsidianRegenerateIndex:
175
175
  obsidian_regenerate_index(tmp_path)
176
176
 
177
177
  index_content = (tmp_path / "Index.md").read_text()
178
- assert "[[2026-04-28_test-pattern]]" in index_content
178
+ # New format: [[stem|display_dt]] stem appears inside the piped wikilink
179
+ assert "[[2026-04-28_test-pattern|" in index_content
179
180
 
180
181
  def test_index_lists_notes_from_all_categories(self, tmp_path):
181
182
  for cat, title in [("Patterns", "Pattern Note"), ("Sessions", "Session Note")]:
@@ -219,6 +220,7 @@ class TestObsidianRegenerateIndex:
219
220
  assert "## By category" not in index_content
220
221
 
221
222
  def test_index_is_sorted_newest_first(self, tmp_path):
223
+ import re
222
224
  patterns = tmp_path / "Patterns"
223
225
  patterns.mkdir()
224
226
  for i in range(5):
@@ -229,7 +231,9 @@ class TestObsidianRegenerateIndex:
229
231
  obsidian_regenerate_index(tmp_path)
230
232
  content = (tmp_path / "Index.md").read_text()
231
233
  lines = [l for l in content.splitlines() if l.startswith("- ")]
232
- dts = [l.split(" ")[1] for l in lines]
234
+ # New format: - [[stem|YYYY-MM-DD HH:MM]] - project(type)
235
+ # Extract the display datetime from inside the pipe: [[stem|<dt>]]
236
+ dts = [re.search(r"\|([^\]]+)\]\]", l).group(1) for l in lines]
233
237
  assert dts == sorted(dts, reverse=True)
234
238
 
235
239
  def test_index_falls_back_to_legacy_date_field(self, tmp_path):
@@ -454,6 +458,7 @@ class TestIndexFormat:
454
458
  return path
455
459
 
456
460
  def test_index_is_chronological_newest_first(self, tmp_path):
461
+ import re
457
462
  patterns = tmp_path / "Patterns"
458
463
  for i in range(5):
459
464
  self._make_note(patterns, f"2026-04-29_note-{i}", "pattern",
@@ -461,8 +466,9 @@ class TestIndexFormat:
461
466
  obsidian_regenerate_index(tmp_path)
462
467
  content = (tmp_path / "Index.md").read_text()
463
468
  lines = [l for l in content.splitlines() if l.startswith("- ")]
464
- # Extract the datetime portion (first word after "- ")
465
- dts = [l.split(" ")[1] for l in lines]
469
+ # New format: - [[stem|YYYY-MM-DD HH:MM]] - project(type)
470
+ # Extract the display datetime from inside the pipe: [[stem|<dt>]]
471
+ dts = [re.search(r"\|([^\]]+)\]\]", l).group(1) for l in lines]
466
472
  assert dts == sorted(dts, reverse=True)
467
473
 
468
474
  def test_index_line_format(self, tmp_path):
@@ -471,7 +477,9 @@ class TestIndexFormat:
471
477
  "2026-04-29T10:00:00Z", "Test pattern title")
472
478
  obsidian_regenerate_index(tmp_path)
473
479
  content = (tmp_path / "Index.md").read_text()
474
- assert "- 2026-04-29 10:00 [[2026-04-29_test-pat]] pattern" in content
480
+ # New format: - [[stem|display_dt]] - project(type)
481
+ # Note has no project field so it renders as empty: (pattern)
482
+ assert "- [[2026-04-29_test-pat|2026-04-29 10:00]] - (pattern)" in content
475
483
 
476
484
  def test_index_has_no_by_category_section(self, tmp_path):
477
485
  patterns = tmp_path / "Patterns"
@@ -480,3 +488,199 @@ class TestIndexFormat:
480
488
  content = (tmp_path / "Index.md").read_text()
481
489
  assert "## By category" not in content
482
490
  assert "## Recent activity" not in content
491
+
492
+
493
+ # ── Project field in frontmatter and index ────────────────────────────────────
494
+
495
+ class TestProjectField:
496
+ """Tests for the `project` frontmatter field introduced in the obsidian redesign."""
497
+
498
+ def _parse_yaml_frontmatter(self, text: str) -> dict:
499
+ """Extract key/value pairs from the YAML frontmatter block."""
500
+ if not text.startswith("---"):
501
+ return {}
502
+ end = text.find("\n---", 3)
503
+ if end == -1:
504
+ return {}
505
+ fm_block = text[3:end].strip()
506
+ result = {}
507
+ for line in fm_block.splitlines():
508
+ if ":" in line:
509
+ k, _, v = line.partition(":")
510
+ result[k.strip()] = v.strip()
511
+ return result
512
+
513
+ def test_obsidian_write_note_auto_fills_project_from_cwd(self, tmp_path, monkeypatch):
514
+ """project="" triggers auto-fill from Path.cwd().name."""
515
+ import agent_notes.services.memory_backend as mb
516
+ monkeypatch.setattr(mb.Path, "cwd", classmethod(lambda cls: Path("/fake/my-repo")))
517
+
518
+ path = obsidian_write_note(
519
+ tmp_path, title="Auto project", body="body", note_type="pattern", project=""
520
+ )
521
+ fm = self._parse_yaml_frontmatter(path.read_text())
522
+ assert fm.get("project") == "my-repo"
523
+
524
+ def test_obsidian_write_note_explicit_project_overrides_cwd(self, tmp_path, monkeypatch):
525
+ """An explicit project value is used verbatim, ignoring cwd."""
526
+ import agent_notes.services.memory_backend as mb
527
+ monkeypatch.setattr(mb.Path, "cwd", classmethod(lambda cls: Path("/fake/some-other-dir")))
528
+
529
+ path = obsidian_write_note(
530
+ tmp_path, title="Explicit project", body="body", note_type="pattern",
531
+ project="my-project"
532
+ )
533
+ fm = self._parse_yaml_frontmatter(path.read_text())
534
+ assert fm.get("project") == "my-project"
535
+
536
+ def test_obsidian_write_note_omits_project_when_empty(self, tmp_path, monkeypatch):
537
+ """When _current_project_name() returns "" the project key is absent from frontmatter."""
538
+ import agent_notes.services.memory_backend as mb
539
+ monkeypatch.setattr(mb, "_current_project_name", lambda: "")
540
+
541
+ path = obsidian_write_note(
542
+ tmp_path, title="No project", body="body", note_type="pattern", project=""
543
+ )
544
+ fm = self._parse_yaml_frontmatter(path.read_text())
545
+ assert "project" not in fm
546
+ # Also verify the raw text has no project: line
547
+ assert "project:" not in path.read_text()
548
+
549
+ def test_obsidian_index_line_format_with_project(self, tmp_path):
550
+ """Index line renders - [[stem|dt]] - <project>(type) when project is present."""
551
+ patterns = tmp_path / "Patterns"
552
+ patterns.mkdir(parents=True, exist_ok=True)
553
+ stem = "2026-04-29_indexed-note"
554
+ (patterns / f"{stem}.md").write_text(
555
+ "---\ncreated_at: 2026-04-29T10:00:00Z\ntype: pattern\nproject: agent-notes\n---\n\n# Indexed Note\n\nbody\n"
556
+ )
557
+ obsidian_regenerate_index(tmp_path)
558
+ content = (tmp_path / "Index.md").read_text()
559
+ assert f"- [[{stem}|2026-04-29 10:00]] - agent-notes(pattern)" in content
560
+
561
+ def test_obsidian_index_line_format_legacy_no_project(self, tmp_path):
562
+ """Legacy notes without a project field render with empty project: - [[stem|dt]] - (type)."""
563
+ patterns = tmp_path / "Patterns"
564
+ patterns.mkdir(parents=True, exist_ok=True)
565
+ stem = "2026-04-29_legacy-note"
566
+ # No project field in frontmatter — simulates a pre-feature note
567
+ (patterns / f"{stem}.md").write_text(
568
+ "---\ncreated_at: 2026-04-29T09:00:00Z\ntype: pattern\n---\n\n# Legacy Note\n\nbody\n"
569
+ )
570
+ obsidian_regenerate_index(tmp_path)
571
+ content = (tmp_path / "Index.md").read_text()
572
+ assert f"- [[{stem}|2026-04-29 09:00]] - (pattern)" in content
573
+
574
+ def test_obsidian_session_update_preserves_project(self, tmp_path, monkeypatch):
575
+ """Appending an ## Update block to a session note must not overwrite the original project."""
576
+ cwd = tmp_path / "proj"
577
+ cwd.mkdir()
578
+ slug = str(cwd).replace("/", "-")
579
+ proj_dir = tmp_path / "home" / ".claude" / "projects" / slug
580
+ proj_dir.mkdir(parents=True)
581
+ (proj_dir / "sess-proj.jsonl").write_text("{}")
582
+ monkeypatch.setenv("CLAUDECODE", "1")
583
+ monkeypatch.chdir(cwd)
584
+ monkeypatch.setattr(Path, "home", classmethod(lambda cls: tmp_path / "home"))
585
+
586
+ import agent_notes.services.memory_backend as mb
587
+
588
+ # Write initial session note with project=alpha
589
+ monkeypatch.setattr(mb, "_current_project_name", lambda: "alpha")
590
+ vault = tmp_path / "vault"
591
+ first = obsidian_write_note(vault, title="S", body="first body", note_type="session")
592
+ fm_after_first = self._parse_yaml_frontmatter(first.read_text())
593
+ assert fm_after_first.get("project") == "alpha"
594
+
595
+ # Append update with a different project name (beta) — original frontmatter must survive
596
+ monkeypatch.setattr(mb, "_current_project_name", lambda: "beta")
597
+ second = obsidian_write_note(vault, title="S", body="second body", note_type="session")
598
+
599
+ assert first == second # same file, update appended
600
+ content = second.read_text()
601
+ fm_after_update = self._parse_yaml_frontmatter(content)
602
+ assert fm_after_update.get("project") == "alpha", (
603
+ f"project field was overwritten; got {fm_after_update.get('project')!r}"
604
+ )
605
+ assert "second body" in content # update content is present
606
+
607
+ def test_obsidian_session_update_does_not_stamp_project_onto_legacy_note(
608
+ self, tmp_path, monkeypatch
609
+ ):
610
+ """Appending to a legacy session note (no project key) must not stamp the caller's project.
611
+
612
+ Covers two branches:
613
+ - direct-append branch: existing note already has `created_at` in frontmatter
614
+ - legacy-migration branch: existing note has `date` instead of `created_at` (the buggy path)
615
+ """
616
+ import agent_notes.services.memory_backend as mb
617
+
618
+ # ------------------------------------------------------------------
619
+ # Branch 1: direct-append (created_at present, no project key)
620
+ # ------------------------------------------------------------------
621
+ cwd = tmp_path / "proj-a"
622
+ cwd.mkdir()
623
+ slug = str(cwd).replace("/", "-")
624
+ proj_dir = tmp_path / "home" / ".claude" / "projects" / slug
625
+ proj_dir.mkdir(parents=True)
626
+ (proj_dir / "direct-sess.jsonl").write_text("{}")
627
+ monkeypatch.setenv("CLAUDECODE", "1")
628
+ monkeypatch.chdir(cwd)
629
+ monkeypatch.setattr(Path, "home", classmethod(lambda cls: tmp_path / "home"))
630
+ monkeypatch.setattr(mb, "_current_project_name", lambda: "some-other-project")
631
+
632
+ vault_a = tmp_path / "vault-a"
633
+ sessions_a = vault_a / "Sessions"
634
+ sessions_a.mkdir(parents=True)
635
+ legacy_a = sessions_a / "direct-sess.md"
636
+ # Pre-feature note: has created_at but NO project key
637
+ legacy_a.write_text(
638
+ "---\ncreated_at: 2026-01-01T00:00:00Z\ntype: session\n---\n\n# Old\n\noriginal body\n"
639
+ )
640
+
641
+ obsidian_write_note(vault_a, title="Old", body="appended body", note_type="session")
642
+
643
+ content_a = legacy_a.read_text()
644
+ fm_a = self._parse_yaml_frontmatter(content_a)
645
+ assert "project" not in fm_a, (
646
+ f"direct-append branch: project stamped onto legacy note; got {fm_a.get('project')!r}"
647
+ )
648
+ assert "project:" not in content_a.split("---")[1], (
649
+ "direct-append branch: 'project:' key found in frontmatter block"
650
+ )
651
+ assert "appended body" in content_a
652
+
653
+ # ------------------------------------------------------------------
654
+ # Branch 2: legacy-migration (date present, no created_at, no project key)
655
+ # This is the branch where the bug originally manifested.
656
+ # ------------------------------------------------------------------
657
+ cwd2 = tmp_path / "proj-b"
658
+ cwd2.mkdir()
659
+ slug2 = str(cwd2).replace("/", "-")
660
+ proj_dir2 = tmp_path / "home" / ".claude" / "projects" / slug2
661
+ proj_dir2.mkdir(parents=True)
662
+ (proj_dir2 / "legacy-sess.jsonl").write_text("{}")
663
+ monkeypatch.chdir(cwd2)
664
+
665
+ vault_b = tmp_path / "vault-b"
666
+ sessions_b = vault_b / "Sessions"
667
+ sessions_b.mkdir(parents=True)
668
+ legacy_b = sessions_b / "legacy-sess.md"
669
+ # Pre-feature note: only `date` (no created_at, no project)
670
+ legacy_b.write_text(
671
+ "---\ndate: 2026-01-01\ntype: session\n---\n\n# Legacy\n\noriginal body\n"
672
+ )
673
+
674
+ obsidian_write_note(vault_b, title="Legacy", body="appended body", note_type="session")
675
+
676
+ content_b = legacy_b.read_text()
677
+ fm_b = self._parse_yaml_frontmatter(content_b)
678
+ assert "project" not in fm_b, (
679
+ f"legacy-migration branch: project stamped onto legacy note; got {fm_b.get('project')!r}"
680
+ )
681
+ # The frontmatter block is the text between the first and second ---
682
+ fm_block_b = content_b.split("---")[1]
683
+ assert "project:" not in fm_block_b, (
684
+ "legacy-migration branch: 'project:' key found in frontmatter block"
685
+ )
686
+ assert "appended body" in content_b
@@ -1 +0,0 @@
1
- 2.13.0
File without changes
File without changes