agent-notes 2.12.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 (230) hide show
  1. {agent_notes-2.12.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.12.0 → agent_notes-2.14.0}/agent_notes/commands/memory.py +150 -0
  4. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/commands/wizard.py +3 -24
  5. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/config.py +1 -9
  6. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/lead.md +5 -21
  7. agent_notes-2.14.0/agent_notes/data/agents/shared/cost_reporting.md +13 -0
  8. agent_notes-2.14.0/agent_notes/data/agents/shared/phase0.md +20 -0
  9. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/global-claude.md +5 -21
  10. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/obsidian-memory/SKILL.md +38 -25
  11. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/memory_backend.py +159 -81
  12. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes.egg-info/PKG-INFO +1 -1
  13. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes.egg-info/SOURCES.txt +3 -0
  14. agent_notes-2.14.0/tests/unit/commands/test_memory_migrate.py +378 -0
  15. agent_notes-2.14.0/tests/unit/services/test_memory_backend_io.py +686 -0
  16. agent_notes-2.14.0/tests/unit/test_memory_dir_for_backend.py +67 -0
  17. agent_notes-2.12.0/agent_notes/VERSION +0 -1
  18. agent_notes-2.12.0/agent_notes/data/agents/shared/cost_reporting.md +0 -7
  19. agent_notes-2.12.0/tests/unit/services/test_memory_backend_io.py +0 -405
  20. {agent_notes-2.12.0 → agent_notes-2.14.0}/LICENSE +0 -0
  21. {agent_notes-2.12.0 → agent_notes-2.14.0}/README.md +0 -0
  22. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/__init__.py +0 -0
  23. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/__main__.py +0 -0
  24. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/cli.py +0 -0
  25. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/commands/__init__.py +0 -0
  26. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/commands/_install_helpers.py +0 -0
  27. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/commands/build.py +0 -0
  28. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/commands/config.py +0 -0
  29. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/commands/doctor.py +0 -0
  30. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/commands/info.py +0 -0
  31. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/commands/install.py +0 -0
  32. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/commands/list.py +0 -0
  33. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/commands/regenerate.py +0 -0
  34. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/commands/set_role.py +0 -0
  35. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/commands/uninstall.py +0 -0
  36. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/commands/update.py +0 -0
  37. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/commands/validate.py +0 -0
  38. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/agents.yaml +0 -0
  39. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/analyst.md +0 -0
  40. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/api-reviewer.md +0 -0
  41. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/architect.md +0 -0
  42. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/coder.md +0 -0
  43. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/database-specialist.md +0 -0
  44. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/debugger.md +0 -0
  45. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/devil.md +0 -0
  46. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/devops.md +0 -0
  47. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/explorer.md +0 -0
  48. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/integrations.md +0 -0
  49. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/performance-profiler.md +0 -0
  50. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/refactorer.md +0 -0
  51. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/reviewer.md +0 -0
  52. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/security-auditor.md +0 -0
  53. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/system-auditor.md +0 -0
  54. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/tech-writer.md +0 -0
  55. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/test-runner.md +0 -0
  56. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/agents/test-writer.md +0 -0
  57. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/cli/claude.yaml +0 -0
  58. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/cli/copilot.yaml +0 -0
  59. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/cli/opencode.yaml +0 -0
  60. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/commands/brainstorm.md +0 -0
  61. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/commands/debug.md +0 -0
  62. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/commands/review.md +0 -0
  63. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/global-copilot.md +0 -0
  64. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/global-opencode.md +0 -0
  65. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/hooks/session-context.md.tpl +0 -0
  66. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-haiku-4-5.yaml +0 -0
  67. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-opus-4-1.yaml +0 -0
  68. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-opus-4-5.yaml +0 -0
  69. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-opus-4-6.yaml +0 -0
  70. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-opus-4-7.yaml +0 -0
  71. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-sonnet-4-5.yaml +0 -0
  72. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-sonnet-4-6.yaml +0 -0
  73. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/models/claude-sonnet-4.yaml +0 -0
  74. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/plugin/claude.yaml +0 -0
  75. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/plugin/opencode-index.js.template +0 -0
  76. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/plugin/opencode.yaml +0 -0
  77. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/pricing.yaml +0 -0
  78. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/roles/orchestrator.yaml +0 -0
  79. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/roles/reasoner.yaml +0 -0
  80. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/roles/scout.yaml +0 -0
  81. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/roles/worker.yaml +0 -0
  82. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/rules/code-quality.md +0 -0
  83. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/rules/safety.md +0 -0
  84. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/brainstorming/SKILL.md +0 -0
  85. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/caveman/SKILL.md +0 -0
  86. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/code-review/SKILL.md +0 -0
  87. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/debugging-protocol/SKILL.md +0 -0
  88. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/docker-compose/SKILL.md +0 -0
  89. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/docker-compose-advanced/SKILL.md +0 -0
  90. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/docker-dockerfile/SKILL.md +0 -0
  91. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/docker-dockerfile-languages/SKILL.md +0 -0
  92. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/git/SKILL.md +0 -0
  93. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/grill-me/SKILL.md +0 -0
  94. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/grill-with-docs/SKILL.md +0 -0
  95. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/improve-codebase-architecture/SKILL.md +0 -0
  96. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-active-storage/SKILL.md +0 -0
  97. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-broadcasting/SKILL.md +0 -0
  98. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-concerns/SKILL.md +0 -0
  99. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-controllers/SKILL.md +0 -0
  100. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-controllers-advanced/SKILL.md +0 -0
  101. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-helpers/SKILL.md +0 -0
  102. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-initializers/SKILL.md +0 -0
  103. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-javascript/SKILL.md +0 -0
  104. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-jobs/SKILL.md +0 -0
  105. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-kamal/SKILL.md +0 -0
  106. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-lib/SKILL.md +0 -0
  107. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-mailers/SKILL.md +0 -0
  108. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-migrations/SKILL.md +0 -0
  109. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-models/SKILL.md +0 -0
  110. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-models-advanced/SKILL.md +0 -0
  111. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-routes/SKILL.md +0 -0
  112. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-style/SKILL.md +0 -0
  113. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-testing-controllers/SKILL.md +0 -0
  114. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-testing-models/SKILL.md +0 -0
  115. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-testing-system/SKILL.md +0 -0
  116. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-validations/SKILL.md +0 -0
  117. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-view-components/SKILL.md +0 -0
  118. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-view-components-advanced/SKILL.md +0 -0
  119. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-views/SKILL.md +0 -0
  120. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/rails-views-advanced/SKILL.md +0 -0
  121. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/refactoring-protocol/SKILL.md +0 -0
  122. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/setup-project-context/SKILL.md +0 -0
  123. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/tdd/SKILL.md +0 -0
  124. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/skills/zoom-out/SKILL.md +0 -0
  125. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/templates/__init__.py +0 -0
  126. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/templates/__pycache__/__init__.cpython-314.pyc +0 -0
  127. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/templates/frontmatter/__init__.py +0 -0
  128. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/templates/frontmatter/__pycache__/__init__.cpython-314.pyc +0 -0
  129. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/templates/frontmatter/__pycache__/claude.cpython-314.pyc +0 -0
  130. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/templates/frontmatter/__pycache__/opencode.cpython-314.pyc +0 -0
  131. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/templates/frontmatter/claude.py +0 -0
  132. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/data/templates/frontmatter/opencode.py +0 -0
  133. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/doctor_checks.py +0 -0
  134. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/domain/__init__.py +0 -0
  135. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/domain/agent.py +0 -0
  136. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/domain/cli_backend.py +0 -0
  137. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/domain/diagnostics.py +0 -0
  138. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/domain/diff.py +0 -0
  139. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/domain/model.py +0 -0
  140. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/domain/role.py +0 -0
  141. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/domain/rule.py +0 -0
  142. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/domain/skill.py +0 -0
  143. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/domain/state.py +0 -0
  144. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/install_state.py +0 -0
  145. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/registries/__init__.py +0 -0
  146. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/registries/_base.py +0 -0
  147. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/registries/agent_registry.py +0 -0
  148. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/registries/cli_registry.py +0 -0
  149. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/registries/model_registry.py +0 -0
  150. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/registries/role_registry.py +0 -0
  151. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/registries/rule_registry.py +0 -0
  152. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/registries/skill_registry.py +0 -0
  153. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/scripts/__init__.py +0 -0
  154. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/scripts/_claude_backend.py +0 -0
  155. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/scripts/_formatting.py +0 -0
  156. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/scripts/_opencode_backend.py +0 -0
  157. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/scripts/_pricing.py +0 -0
  158. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/scripts/cost_report.py +0 -0
  159. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/__init__.py +0 -0
  160. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/credentials.py +0 -0
  161. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/diagnostics/__init__.py +0 -0
  162. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/diagnostics/_checks.py +0 -0
  163. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/diagnostics/_display.py +0 -0
  164. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/diagnostics/_fix.py +0 -0
  165. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/diff.py +0 -0
  166. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/fs.py +0 -0
  167. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/install_state_builder.py +0 -0
  168. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/installer.py +0 -0
  169. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/rendering.py +0 -0
  170. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/session_context.py +0 -0
  171. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/settings_writer.py +0 -0
  172. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/state_store.py +0 -0
  173. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/ui.py +0 -0
  174. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/user_config.py +0 -0
  175. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/services/validation.py +0 -0
  176. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes/state.py +0 -0
  177. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes.egg-info/dependency_links.txt +0 -0
  178. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes.egg-info/entry_points.txt +0 -0
  179. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes.egg-info/requires.txt +0 -0
  180. {agent_notes-2.12.0 → agent_notes-2.14.0}/agent_notes.egg-info/top_level.txt +0 -0
  181. {agent_notes-2.12.0 → agent_notes-2.14.0}/pyproject.toml +0 -0
  182. {agent_notes-2.12.0 → agent_notes-2.14.0}/setup.cfg +0 -0
  183. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/conftest.py +0 -0
  184. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/__init__.py +0 -0
  185. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/commands/__init__.py +0 -0
  186. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/commands/test_config_command.py +0 -0
  187. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/commands/test_doctor_command.py +0 -0
  188. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/commands/test_info_command.py +0 -0
  189. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/commands/test_install_command.py +0 -0
  190. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/commands/test_list_command.py +0 -0
  191. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/commands/test_regenerate_command.py +0 -0
  192. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/commands/test_uninstall_command.py +0 -0
  193. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/commands/test_update_command.py +0 -0
  194. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/commands/test_validate_command.py +0 -0
  195. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/memory/__init__.py +0 -0
  196. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/memory/test_memory_command.py +0 -0
  197. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/scripts/__init__.py +0 -0
  198. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/functional/scripts/test_release_script.py +0 -0
  199. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/integration/__init__.py +0 -0
  200. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/integration/build_output/__init__.py +0 -0
  201. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/integration/build_output/test_build_output.py +0 -0
  202. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/integration/install/__init__.py +0 -0
  203. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/integration/install/test_install_methods.py +0 -0
  204. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/integration/plugin_builders/__init__.py +0 -0
  205. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/integration/plugin_builders/test_plugin_builders.py +0 -0
  206. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/plugins/__init__.py +0 -0
  207. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/plugins/claude/__init__.py +0 -0
  208. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/plugins/claude/test_agents.py +0 -0
  209. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/plugins/test_skills.py +0 -0
  210. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/__init__.py +0 -0
  211. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/commands/__init__.py +0 -0
  212. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/commands/test_cost_report_subcommand.py +0 -0
  213. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/commands/test_count_agents.py +0 -0
  214. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/commands/test_wizard_orchestrator_skip.py +0 -0
  215. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/commands/test_wizard_preflight.py +0 -0
  216. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/registries/__init__.py +0 -0
  217. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/registries/test_registries.py +0 -0
  218. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/scripts/__init__.py +0 -0
  219. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/scripts/test_cost_report.py +0 -0
  220. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/scripts/test_cost_report_scoping.py +0 -0
  221. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/scripts/test_formatting_tty.py +0 -0
  222. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/scripts/test_time_aggregation.py +0 -0
  223. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/services/__init__.py +0 -0
  224. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/services/test_build_functions.py +0 -0
  225. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/services/test_credentials.py +0 -0
  226. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/services/test_fs.py +0 -0
  227. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/services/test_installer_plan.py +0 -0
  228. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/services/test_memory_backend.py +0 -0
  229. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/services/test_rendering_includes.py +0 -0
  230. {agent_notes-2.12.0 → agent_notes-2.14.0}/tests/unit/services/test_settings_writer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-notes
3
- Version: 2.12.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
@@ -361,6 +361,152 @@ def format_size(size_bytes: int) -> str:
361
361
  return f"{original_size:.1f}P"
362
362
 
363
363
 
364
+ def do_migrate() -> None:
365
+ """Migrate vault from per-project layout to flat shared layout with new filenames."""
366
+ import re
367
+ import shutil
368
+ from datetime import datetime, timezone
369
+
370
+ backend, vault = _load_memory_config()
371
+ if backend != "obsidian":
372
+ print("migrate is only available for the obsidian backend.")
373
+ return
374
+ if vault is None:
375
+ print("Memory path not configured.")
376
+ return
377
+
378
+ from ..services.memory_backend import (
379
+ OBSIDIAN_CATEGORIES, obsidian_regenerate_index, _parse_frontmatter,
380
+ )
381
+
382
+ _NEW_FILE_RE = re.compile(r"^\d{4}-\d{2}-\d{2}_")
383
+ _LEGACY_TS_RE = re.compile(r"^(\d{4})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(.+)$")
384
+ _BARE_UUID_RE = re.compile(
385
+ r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", re.IGNORECASE
386
+ )
387
+
388
+ moved = 0
389
+ renamed = 0
390
+ skipped = 0
391
+ errors: list[str] = []
392
+
393
+ def _date_from_frontmatter(path: Path) -> Optional[str]:
394
+ try:
395
+ text = path.read_text()
396
+ fm, _ = _parse_frontmatter(text)
397
+ ca = fm.get("created_at", "")
398
+ if re.fullmatch(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z", ca):
399
+ return ca[:10]
400
+ except OSError:
401
+ pass
402
+ return None
403
+
404
+ def _date_from_mtime(path: Path) -> str:
405
+ ts = path.stat().st_mtime
406
+ return datetime.fromtimestamp(ts, tz=timezone.utc).strftime("%Y-%m-%d")
407
+
408
+ def _safe_rename(src: Path, dst: Path) -> bool:
409
+ if dst.exists():
410
+ return False
411
+ src.rename(dst)
412
+ return True
413
+
414
+ def _new_stem(old_stem: str, folder: Path, path: Path) -> Optional[str]:
415
+ """Return new stem under new naming scheme, or None if already correct."""
416
+ if _NEW_FILE_RE.match(old_stem):
417
+ return None # already in new format
418
+
419
+ # Legacy timestamp: YYYY-MM-DD-HH-MM-SS-<slug>
420
+ m = _LEGACY_TS_RE.match(old_stem)
421
+ if m:
422
+ date_part = f"{m.group(1)}-{m.group(2)}-{m.group(3)}"
423
+ slug_part = m.group(7)
424
+ base = f"{date_part}_{slug_part}"
425
+ candidate = f"{base}.md"
426
+ if not (folder / candidate).exists():
427
+ return base
428
+ # collision: append HHMMSS from the original timestamp
429
+ hhmmss = f"{m.group(4)}{m.group(5)}{m.group(6)}"
430
+ return f"{base}_{hhmmss}"
431
+
432
+ # Bare session UUID: <uuid>.md → <date>_<uuid>.md
433
+ if _BARE_UUID_RE.match(old_stem):
434
+ date_part = _date_from_frontmatter(path) or _date_from_mtime(path)
435
+ base = f"{date_part}_{old_stem}"
436
+ candidate = f"{base}.md"
437
+ if not (folder / candidate).exists():
438
+ return base
439
+ hhmmss = datetime.fromtimestamp(path.stat().st_mtime, tz=timezone.utc).strftime("%H%M%S")
440
+ return f"{base}_{hhmmss}"
441
+
442
+ # Unrecognized pattern — skip
443
+ return None
444
+
445
+ # Step 1: move files from per-project subfolders into the shared root
446
+ for item in list(vault.iterdir()):
447
+ if not item.is_dir():
448
+ continue
449
+ if item.name in OBSIDIAN_CATEGORIES or item.name == "Index.md":
450
+ continue
451
+ # item is a per-project subfolder
452
+ for cat in OBSIDIAN_CATEGORIES:
453
+ src_cat = item / cat
454
+ if not src_cat.exists():
455
+ continue
456
+ dst_cat = vault / cat
457
+ dst_cat.mkdir(exist_ok=True)
458
+ for note in src_cat.glob("*.md"):
459
+ dst = dst_cat / note.name
460
+ if dst.exists():
461
+ errors.append(f"collision: {note} -> {dst}")
462
+ continue
463
+ try:
464
+ shutil.move(str(note), str(dst))
465
+ moved += 1
466
+ except OSError as exc:
467
+ errors.append(f"move failed: {note}: {exc}")
468
+ # Remove now-empty category subdir so parent rmdir can succeed
469
+ try:
470
+ src_cat.rmdir()
471
+ except OSError:
472
+ pass
473
+ # Remove subfolder only if empty (preserves any uncategorized files the user may have there)
474
+ try:
475
+ item.rmdir()
476
+ except OSError:
477
+ errors.append(f"per-project subfolder not removed (non-empty): {item}")
478
+
479
+ # Step 2: rename files in each category to the new naming scheme
480
+ for cat in OBSIDIAN_CATEGORIES:
481
+ cat_dir = vault / cat
482
+ if not cat_dir.exists():
483
+ continue
484
+ for note in list(cat_dir.glob("*.md")):
485
+ new_stem = _new_stem(note.stem, cat_dir, note)
486
+ if new_stem is None:
487
+ skipped += 1
488
+ continue
489
+ dst = cat_dir / f"{new_stem}.md"
490
+ try:
491
+ if not _safe_rename(note, dst):
492
+ errors.append(f"rename collision: {note.name} -> {dst.name}")
493
+ skipped += 1
494
+ else:
495
+ renamed += 1
496
+ except OSError as exc:
497
+ errors.append(f"rename failed: {note}: {exc}")
498
+ skipped += 1
499
+
500
+ # Step 3: regenerate index
501
+ obsidian_regenerate_index(vault)
502
+
503
+ print(f"{moved} moved, {renamed} renamed, {skipped} skipped", end="")
504
+ if errors:
505
+ print(f", errors: {'; '.join(errors)}")
506
+ else:
507
+ print()
508
+
509
+
364
510
  def show_help() -> None:
365
511
  """Show memory command help."""
366
512
  help_text = """Usage: agent-notes memory [command] [args]
@@ -373,6 +519,7 @@ Commands:
373
519
  vault Show current backend and memory path
374
520
  index Regenerate Index.md for the current backend
375
521
  add <title> <body> Add a note (obsidian backend)
522
+ migrate Migrate old per-project layout to new shared flat layout
376
523
  size Total disk usage
377
524
  show <name> Show memory contents for one agent/category
378
525
  reset Clear ALL memories (requires confirmation)
@@ -384,6 +531,7 @@ Examples:
384
531
  agent-notes memory List all memories
385
532
  agent-notes memory vault Show backend configuration
386
533
  agent-notes memory index Regenerate Index.md
534
+ agent-notes memory migrate Migrate to new flat layout
387
535
  agent-notes memory show coder View coder agent's memory
388
536
  agent-notes memory reset reviewer Clear reviewer's memory
389
537
  agent-notes memory export Back up before cleanup"""
@@ -424,6 +572,8 @@ def memory(action: str = "list", name: Optional[str] = None, extra: Optional[lis
424
572
  do_export()
425
573
  elif action == "import":
426
574
  do_import()
575
+ elif action == "migrate":
576
+ do_migrate()
427
577
  else:
428
578
  print(f"Unknown command: {action}")
429
579
  show_help()
@@ -382,21 +382,6 @@ def _render_install_summary(clis: Set[str], scope: str, copy_mode: bool, selecte
382
382
  print("")
383
383
 
384
384
 
385
- def _detect_project_name() -> str:
386
- """Return git repo name, or cwd name as fallback."""
387
- import subprocess
388
- try:
389
- result = subprocess.run(
390
- ["git", "rev-parse", "--show-toplevel"],
391
- capture_output=True, text=True, timeout=3,
392
- )
393
- if result.returncode == 0:
394
- return Path(result.stdout.strip()).name
395
- except (OSError, subprocess.TimeoutExpired):
396
- pass
397
- return Path.cwd().name
398
-
399
-
400
385
  def _detect_obsidian_vaults() -> List[Path]:
401
386
  """Scan common locations for Obsidian vaults (dirs containing .obsidian/)."""
402
387
  candidates = []
@@ -436,19 +421,13 @@ def _select_memory(step: int, total: int, version: str = '') -> tuple:
436
421
  path = ""
437
422
 
438
423
  if backend == "obsidian":
439
- project_name = _detect_project_name()
440
424
  candidates = _detect_obsidian_vaults()
441
425
  if candidates:
442
- _hint_suffix = f"agent-notes/{project_name}" if project_name != "agent-notes" else "agent-notes"
443
- print(f" {Color.DIM}Detected vaults (notes go into {_hint_suffix}/ inside):{Color.NC}")
426
+ print(f" {Color.DIM}Detected vaults (notes go into agent-notes/ inside):{Color.NC}")
444
427
  for c in candidates[:3]:
445
- print(f" {c}/{_hint_suffix}")
428
+ print(f" {c}/agent-notes")
446
429
  _mem_base = candidates[0] if candidates else Path.home() / "Documents" / "Obsidian Vault"
447
- _mem_full = _mem_base / "agent-notes" / project_name
448
- # Avoid agent-notes/agent-notes when project name matches parent folder
449
- if _mem_full.parent.name == _mem_full.name:
450
- _mem_full = _mem_full.parent
451
- default_path = str(_mem_full)
430
+ default_path = str(_mem_base / "agent-notes")
452
431
  raw = _safe_input(f" Memory folder path [{default_path}]: ", default_path)
453
432
  path = raw.strip() or default_path
454
433
 
@@ -45,15 +45,7 @@ def memory_dir_for_backend(backend: str, custom_path: str = "") -> Optional[Path
45
45
  if custom_path:
46
46
  return Path(custom_path).expanduser()
47
47
  if backend == "obsidian":
48
- import subprocess
49
- project = "global"
50
- try:
51
- r = subprocess.run(["git", "rev-parse", "--show-toplevel"], capture_output=True, text=True, timeout=3)
52
- if r.returncode == 0:
53
- project = Path(r.stdout.strip()).name
54
- except (OSError, subprocess.TimeoutExpired):
55
- pass
56
- return Path.home() / "Documents" / "Obsidian Vault" / "agent-notes" / project
48
+ return Path.home() / "Documents" / "Obsidian Vault" / "agent-notes"
57
49
  return MEMORY_DIR # local default: ~/.claude/agent-memory
58
50
 
59
51
  def get_version() -> str:
@@ -1,23 +1,6 @@
1
1
  You are a team lead that plans and coordinates work across specialized agents.
2
2
 
3
- ## Phase 0 — Plan & Approval Gate (MANDATORY)
4
-
5
- Before touching any tool that writes, edits, runs, installs, or otherwise has side effects, you MUST produce and get approval for a plan.
6
-
7
- 1. Restate the user's request in your own words. State the assumed acceptance criteria.
8
- 2. Decompose into discrete, independently verifiable subtasks. Identify dependencies.
9
- 3. If context is thin (you don't know what files are involved, what conventions apply, what tests exist), dispatch `analyst` first. Do not guess.
10
- 4. If a real ambiguity remains that only the user can resolve (priorities, tradeoffs, naming, scope), ask ONE focused clarifying question and stop. Do not invent answers.
11
- 5. Write the full plan to the user. Include:
12
- - Acceptance criteria (what "done" looks like)
13
- - Subtasks with assigned agents
14
- - Files that will be touched (paths)
15
- - How you'll verify each subtask
16
- - Risks and explicit out-of-scope items
17
- 6. Wait for explicit user approval. A "go", "yes", "ok", or "approved" counts. Silence does NOT count.
18
- 7. Only after approval, proceed to Phase 1 execution.
19
-
20
- Trivial requests are exempt: factual questions, conversational replies, single-line corrections explicitly requested.
3
+ <!-- include: phase0 -->
21
4
 
22
5
  ## HARD LIMITS
23
6
 
@@ -64,7 +47,7 @@ The session memory note is the durable cross-session record of work done. It MUS
64
47
  `agent-notes memory add "<title>" "<body>" decision|pattern|mistake|context <agent>`
65
48
  These land in `Decisions/`, `Patterns/`, etc. — independent of the session note.
66
49
 
67
- **Linking rule**: when an active session writes a non-session note (Decision / Pattern / Mistake / Context), the session note gets a wikilink to it in the same operation. See `obsidian-memory` SKILL "Linking rule" section. Obsidian backend only — no-op on local.
50
+ **Auto-linking**: when a non-session note (Decision / Pattern / Mistake / Context) is written while a session is active, the CLI automatically appends a wikilink to that session note's `## Linked notes` section. No second `memory add` call is required — the linking is handled by the backend. Obsidian backend only — no-op on local.
68
51
 
69
52
  **Plan-mirror rule**: after every ExitPlanMode, mirror the plan content as a Decision note in Obsidian. See `obsidian-memory` SKILL "Plan-mirror rule" section. Obsidian backend only — no-op on local.
70
53
 
@@ -259,8 +242,9 @@ Each phase must leave the system in a verified-good state before the next begins
259
242
  8. Breaking tasks into steps so small they have no independent value → group into meaningful chunks.
260
243
  9. Writing a plan that only restates the user's words → a plan must include discovery findings, dependency order, and flagged risks.
261
244
  10. Skipping the cost report at the end of a response → always include it.
262
- 11. Reporting "done" before tests pass and plan items match → forbidden by Done Gate.
263
- 12. Reporting "done" / "complete" / "shipped" without an `agent-notes memory add ... session lead` call covering this work → forbidden by the Done Gate.
245
+ 11. Fabricating a cost-report table or placeholder rows when `agent-notes cost-report` did not run successfully → forbidden. Print "Cost report skipped: <reason>" on a single line instead.
246
+ 12. Reporting "done" before tests pass and plan items match → forbidden by Done Gate.
247
+ 13. Reporting "done" / "complete" / "shipped" without an `agent-notes memory add ... session lead` call covering this work → forbidden by the Done Gate.
264
248
 
265
249
  ## Done Gate (HARD RULE)
266
250
 
@@ -0,0 +1,13 @@
1
+ ## Cost reporting
2
+
3
+ At the END of every response, run `agent-notes cost-report` and include the output as a markdown table prefixed with:
4
+
5
+ **Session cost** (cumulative for the entire conversation):
6
+
7
+ Render every column the `agent-notes cost-report` CLI emits — `agent(model)`, `in/out/cache`, `time`, `actual`, `vs Claude Opus 4.7` — in that order. Do not split, drop, or rename columns. Preserve the data verbatim.
8
+
9
+ **On failure or skip — never fabricate.** If `agent-notes cost-report` returns non-zero, errors, or you skip running it, do NOT render a placeholder table or invent rows like `(cost report unavailable — agent-notes cost-report not run)`. Instead, print one plain line under the heading:
10
+
11
+ `Cost report skipped: <one-line reason>`
12
+
13
+ If the command ran but produced an error message, print the error verbatim under the heading instead of a table. Fabricating a table when the CLI did not run is a violation.
@@ -0,0 +1,20 @@
1
+ ## Phase 0 — Plan & Approval Gate (MANDATORY)
2
+
3
+ Before touching any tool that writes, edits, runs, installs, or otherwise has side effects, you MUST produce and get approval for a plan.
4
+
5
+ 1. Restate the user's request in your own words. State the assumed acceptance criteria.
6
+ 2. Decompose into discrete, independently verifiable subtasks. Identify dependencies.
7
+ 3. If context is thin (you don't know what files are involved, what conventions apply, what tests exist), dispatch `analyst` first. Do not guess.
8
+ 4. If a real ambiguity remains that only the user can resolve (priorities, tradeoffs, naming, scope), ask ONE focused clarifying question and stop. Do not invent answers.
9
+ 5. Write the full plan to the user. Include:
10
+ - Acceptance criteria (what "done" looks like)
11
+ - Subtasks with assigned agents
12
+ - Files that will be touched (paths)
13
+ - How you'll verify each subtask
14
+ - Risks and explicit out-of-scope items
15
+ 6. Wait for explicit user approval. A "go", "yes", "ok", or "approved" counts. Silence does NOT count.
16
+ 7. Only after approval, proceed to Phase 1 execution.
17
+
18
+ **Trivial-request exemption — narrow.** No plan needed only when the response is read-only — no Bash beyond `git status` / `git log` / `git diff` / `gh pr view` / `gh api`, no Edit / Write, no agent dispatch that writes files. Specifically: factual questions, conversational replies, recall-from-memory, and explicit one-shot reads the user limited in scope ("what's in file X?", "what does this function do?").
19
+
20
+ Any task with words like "fix", "implement", "add", "refactor", "update", "build", "investigate" (which implies a follow-up fix), or that will dispatch `coder` / `test-writer` / `devops` / `refactorer` / `integrations` requires a written plan and explicit user approval before any side-effecting tool is touched, regardless of prompt brevity. A short prompt is not a trivial prompt.
@@ -4,24 +4,7 @@ You are the primary assistant. You operate as the lead orchestrator on every req
4
4
 
5
5
  You are a team lead that plans and coordinates work across specialized agents.
6
6
 
7
- ## Phase 0 — Plan & Approval Gate (MANDATORY)
8
-
9
- Before touching any tool that writes, edits, runs, installs, or otherwise has side effects, you MUST produce and get approval for a plan.
10
-
11
- 1. Restate the user's request in your own words. State the assumed acceptance criteria.
12
- 2. Decompose into discrete, independently verifiable subtasks. Identify dependencies.
13
- 3. If context is thin (you don't know what files are involved, what conventions apply, what tests exist), dispatch `analyst` first. Do not guess.
14
- 4. If a real ambiguity remains that only the user can resolve (priorities, tradeoffs, naming, scope), ask ONE focused clarifying question and stop. Do not invent answers.
15
- 5. Write the full plan to the user. Include:
16
- - Acceptance criteria (what "done" looks like)
17
- - Subtasks with assigned agents
18
- - Files that will be touched (paths)
19
- - How you'll verify each subtask
20
- - Risks and explicit out-of-scope items
21
- 6. Wait for explicit user approval. A "go", "yes", "ok", or "approved" counts. Silence does NOT count.
22
- 7. Only after approval, proceed to Phase 1 execution.
23
-
24
- Trivial requests are exempt: factual questions, conversational replies, single-line corrections explicitly requested.
7
+ <!-- include: phase0 -->
25
8
 
26
9
  ## HARD LIMITS
27
10
 
@@ -68,7 +51,7 @@ The session memory note is the durable cross-session record of work done. It MUS
68
51
  `agent-notes memory add "<title>" "<body>" decision|pattern|mistake|context <agent>`
69
52
  These land in `Decisions/`, `Patterns/`, etc. — independent of the session note.
70
53
 
71
- **Linking rule**: when an active session writes a non-session note (Decision / Pattern / Mistake / Context), the session note gets a wikilink to it in the same operation. See `obsidian-memory` SKILL "Linking rule" section. Obsidian backend only — no-op on local.
54
+ **Auto-linking**: when a non-session note (Decision / Pattern / Mistake / Context) is written while a session is active, the CLI automatically appends a wikilink to that session note's `## Linked notes` section. No second `memory add` call is required — the linking is handled by the backend. Obsidian backend only — no-op on local.
72
55
 
73
56
  **Plan-mirror rule**: after every ExitPlanMode, mirror the plan content as a Decision note in Obsidian. See `obsidian-memory` SKILL "Plan-mirror rule" section. Obsidian backend only — no-op on local.
74
57
 
@@ -334,8 +317,9 @@ Each phase must leave the system in a verified-good state before the next begins
334
317
  8. Breaking tasks into steps so small they have no independent value → group into meaningful chunks.
335
318
  9. Writing a plan that only restates the user's words → a plan must include discovery findings, dependency order, and flagged risks.
336
319
  10. Skipping the cost report at the end of a response → always include it.
337
- 11. Reporting "done" before tests pass and plan items match → forbidden by Done Gate.
338
- 12. Reporting "done" / "complete" / "shipped" without an `agent-notes memory add ... session lead` call covering this work → forbidden by the Done Gate.
320
+ 11. Fabricating a cost-report table or placeholder rows when `agent-notes cost-report` did not run successfully → forbidden. Print "Cost report skipped: <reason>" on a single line instead.
321
+ 12. Reporting "done" before tests pass and plan items match → forbidden by Done Gate.
322
+ 13. Reporting "done" / "complete" / "shipped" without an `agent-notes memory add ... session lead` call covering this work → forbidden by the Done Gate.
339
323
 
340
324
  ## Done Gate (HARD RULE)
341
325
 
@@ -14,28 +14,41 @@ This skill is the **single source of truth** for memory record format. The CLI i
14
14
 
15
15
  ### Filename rule
16
16
 
17
- - **Session notes** (`type=session`): filename is `<session-id>.md`
18
- - Claude Code: stem of the active JSONL at `~/.claude/projects/<cwd-slug>/<session-id>.jsonl`
17
+ All notes use `YYYY-MM-DD_<slug>.md`. The folder encodes the type no type segment in the filename.
18
+
19
+ - **Session notes** (`type=session`): `YYYY-MM-DD_<session-id>.md`
20
+ - Claude Code session ID: stem of the active JSONL at `~/.claude/projects/<cwd-slug>/<session-id>.jsonl`
19
21
  - OpenCode: the session row's `id`
20
- - **All other types**: filename is `<UTC-YYYY-MM-DD-HH-MM-SS>-<slug>.md`
22
+ - If no session ID can be detected, falls back to `YYYY-MM-DD_<slug>.md` (slug of the title)
23
+ - **All other types**: `YYYY-MM-DD_<slug>.md` where slug is the slugified title
24
+
25
+ **Collision rule**: if the target filename already exists, `_HHMMSS` is appended before `.md` (e.g. `2026-04-30_fix-foo_142231.md`).
21
26
 
22
- A session note is **per-session**, not per-message. Re-running `memory add` with `type=session` for the same session appends an `## Update <UTC ISO>` block to the existing file rather than creating a new one. If no session ID can be detected (e.g. invoked outside a CLI session), the note falls back to the timestamp+slug filename rule.
27
+ A session note is **per-session**, not per-message. Re-running `memory add` with `type=session` for the same session appends an `## Update <UTC ISO>` block to the existing file rather than creating a new one.
23
28
 
24
29
  ### Frontmatter rule
25
30
 
26
- Every record has this frontmatter, in this order. No `date:` field — only `created_at:`.
31
+ Every record uses the same template. No `date:` field — only `created_at:`.
27
32
 
28
33
  ```yaml
29
34
  ---
30
35
  created_at: 2026-04-28T19:30:35Z # ISO 8601, UTC, "Z" suffix — REQUIRED
31
36
  type: pattern # pattern|decision|mistake|context|session — REQUIRED
32
- session_id: <id> # REQUIRED when detectable (Claude Code / OpenCode session); omitted otherwise
37
+ session: 2026-04-28_<session-id> # wikilink target (no brackets); absent on session notes themselves
33
38
  agent: lead # optional
34
- project: <name> # optional
35
- tags: [a, b] # optional
36
39
  ---
37
40
  ```
38
41
 
42
+ After the frontmatter, every note body is followed by:
43
+
44
+ ```markdown
45
+ ## Related
46
+
47
+ (empty initially; Obsidian links can be added manually)
48
+ ```
49
+
50
+ Session notes additionally grow a `## Linked notes` section that the CLI populates automatically when non-session notes are written during the same session.
51
+
39
52
  ### Time rule
40
53
 
41
54
  All timestamps everywhere are **UTC**. Local time is never written. The CLI uses `datetime.now(timezone.utc)`.
@@ -93,14 +106,17 @@ agent-notes memory vault # confirm backend and path
93
106
 
94
107
  The vault is structured as:
95
108
  ```
96
- vault/
97
- ├── Patterns/ — reusable solutions
98
- ├── Decisions/ — architectural choices
99
- ├── Mistakes/ — errors to avoid
100
- ├── Context/ — project background
101
- └── Sessions/ — one file per session, named <session-id>.md
109
+ vault/agent-notes/
110
+ ├── Patterns/ — reusable solutions YYYY-MM-DD_<slug>.md
111
+ ├── Decisions/ — architectural choices YYYY-MM-DD_<slug>.md
112
+ ├── Mistakes/ — errors to avoid YYYY-MM-DD_<slug>.md
113
+ ├── Context/ — project background YYYY-MM-DD_<slug>.md
114
+ ├── Sessions/ — one file per session YYYY-MM-DD_<session-id>.md
115
+ └── Index.md — chronological list, newest first
102
116
  ```
103
117
 
118
+ The root `agent-notes/` is shared across all projects — there is no per-project subfolder.
119
+
104
120
  ## Regenerate the index
105
121
 
106
122
  After any manual edits in Obsidian:
@@ -126,22 +142,19 @@ The session note is updated on every meaningful state change. Specifically:
126
142
 
127
143
  Skipping any of these makes the session note stale and breaks cross-session reconstruction. The Done Gate in `global-claude.md` enforces this for the lead; team agents follow the read-before-work side via the next section.
128
144
 
129
- ## Linking rule
130
-
131
- Whenever a session is active and a non-session note is written (Decision / Pattern / Mistake / Context), the session note must be appended with a wikilink to it within the same logical operation:
145
+ ## Auto-linking rule
132
146
 
133
- 1. Write the new Decision / Pattern / Mistake / Context note via `agent-notes memory add ... <type> lead`. Capture the returned path.
134
- 2. Append a single line to the session note via a second `agent-notes memory add "<session-title>" "Linked: [[<filename-stem>]] — <type> — <one-line-why>" session lead`.
147
+ Whenever a session is active (Claude Code session ID detectable) and a non-session note is written, the CLI **automatically** appends a wikilink line to the session note's `## Linked notes` section:
135
148
 
136
- The cadence rule already mandates one append per phase outcome; this rule layers wikilinks onto that append. Result: the session note becomes the navigable hub for everything written during the session.
149
+ ```
150
+ - [[<filename-stem>]] — <type> — <title>
151
+ ```
137
152
 
138
- **General notes (project-truths, not tied to one session) do NOT get linked.** Examples:
139
- - A Pattern about Rails enum prefix: applies forever, lives in `Patterns/`, NOT referenced from any session note.
140
- - A Decision about choosing PostgreSQL: applies forever, lives in `Decisions/`, NOT referenced from a session note.
153
+ This is done in the same `agent-notes memory add` call no second call is needed. The operation is idempotent: if the link already exists, it is not duplicated.
141
154
 
142
- **Judgment call**: if the note explains "what we did today and why" link it from the session note. If the note explains "how the project works in general" → don't link it.
155
+ The session note becomes the navigable hub for everything written during the session without any extra work from the agent.
143
156
 
144
- **Backend conditional**: this rule only applies when the configured memory backend is Obsidian. On the local backend (no vault, no wikilinks), skip the linking step the cadence rule alone is enough.
157
+ **Backend conditional**: auto-linking only applies when the configured memory backend is Obsidian. On the local backend, there are no wikilinks and this step is a no-op.
145
158
 
146
159
  ## Plan-mirror rule (Obsidian backend only)
147
160