agent-notes 2.27.0__tar.gz → 2.28.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 (292) hide show
  1. {agent_notes-2.27.0 → agent_notes-2.28.0}/PKG-INFO +2 -1
  2. agent_notes-2.28.0/agent_notes/VERSION +1 -0
  3. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/memory/reset.py +2 -1
  4. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/validate.py +1 -1
  5. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/wizard/execute.py +13 -11
  6. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/agents.yaml +1 -0
  7. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/coder.md +1 -0
  8. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/refactorer.md +1 -0
  9. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/reviewer.md +1 -0
  10. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/test-writer.md +1 -0
  11. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/cli/claude.yaml +5 -0
  12. agent_notes-2.28.0/agent_notes/data/cli/codex.yaml +29 -0
  13. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/cli/opencode.yaml +5 -0
  14. agent_notes-2.28.0/agent_notes/data/global-codex.md +40 -0
  15. agent_notes-2.28.0/agent_notes/data/models/gpt-5-4-mini.yaml +14 -0
  16. agent_notes-2.28.0/agent_notes/data/models/gpt-5-4.yaml +14 -0
  17. agent_notes-2.28.0/agent_notes/data/models/gpt-5-5.yaml +14 -0
  18. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/code-review/SKILL.md +6 -0
  19. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/debugging-protocol/SKILL.md +2 -1
  20. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/refactoring-protocol/SKILL.md +1 -0
  21. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/rsi/SKILL.md +4 -3
  22. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/tdd/SKILL.md +2 -1
  23. agent_notes-2.28.0/agent_notes/data/templates/__pycache__/__init__.cpython-312.pyc +0 -0
  24. agent_notes-2.28.0/agent_notes/data/templates/frontmatter/__pycache__/__init__.cpython-312.pyc +0 -0
  25. agent_notes-2.28.0/agent_notes/data/templates/frontmatter/__pycache__/claude.cpython-312.pyc +0 -0
  26. agent_notes-2.28.0/agent_notes/data/templates/frontmatter/__pycache__/codex.cpython-312.pyc +0 -0
  27. agent_notes-2.28.0/agent_notes/data/templates/frontmatter/__pycache__/codex.cpython-314.pyc +0 -0
  28. agent_notes-2.28.0/agent_notes/data/templates/frontmatter/__pycache__/opencode.cpython-312.pyc +0 -0
  29. agent_notes-2.28.0/agent_notes/data/templates/frontmatter/codex.py +106 -0
  30. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/domain/cli_backend.py +1 -0
  31. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/registries/agent_registry.py +3 -3
  32. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/registries/cli_registry.py +2 -1
  33. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/scripts/_opencode_backend.py +3 -1
  34. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/credentials.py +14 -16
  35. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/diagnostics/_fix.py +23 -21
  36. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/fs.py +17 -4
  37. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/installer.py +131 -104
  38. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/rendering.py +194 -113
  39. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/state_store.py +2 -3
  40. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/validation.py +1 -5
  41. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/wiki/_wiki_utils.py +4 -1
  42. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes.egg-info/PKG-INFO +2 -1
  43. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes.egg-info/SOURCES.txt +23 -1
  44. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes.egg-info/requires.txt +1 -0
  45. {agent_notes-2.27.0 → agent_notes-2.28.0}/pyproject.toml +1 -1
  46. agent_notes-2.28.0/tests/functional/commands/test_validate_path_filter.py +100 -0
  47. agent_notes-2.28.0/tests/plugins/codex/test_agents.py +138 -0
  48. agent_notes-2.28.0/tests/unit/registries/test_cli_registry.py +184 -0
  49. agent_notes-2.28.0/tests/unit/scripts/test_opencode_backend_connection.py +118 -0
  50. agent_notes-2.28.0/tests/unit/services/__init__.py +0 -0
  51. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_credentials.py +74 -0
  52. agent_notes-2.28.0/tests/unit/services/test_installer_codex.py +460 -0
  53. agent_notes-2.28.0/tests/unit/services/test_installer_hook_quoting.py +85 -0
  54. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_validation.py +9 -3
  55. agent_notes-2.28.0/tests/unit/services/test_wiki_atomic_write.py +73 -0
  56. agent_notes-2.28.0/tests/unit/templates/__init__.py +0 -0
  57. agent_notes-2.28.0/tests/unit/templates/test_codex_frontmatter.py +383 -0
  58. agent_notes-2.27.0/agent_notes/VERSION +0 -1
  59. {agent_notes-2.27.0 → agent_notes-2.28.0}/LICENSE +0 -0
  60. {agent_notes-2.27.0 → agent_notes-2.28.0}/README.md +0 -0
  61. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/__init__.py +0 -0
  62. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/__main__.py +0 -0
  63. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/cli.py +0 -0
  64. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/__init__.py +0 -0
  65. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/_install_helpers.py +0 -0
  66. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/build.py +0 -0
  67. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/config.py +0 -0
  68. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/doctor.py +0 -0
  69. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/hook.py +0 -0
  70. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/info.py +0 -0
  71. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/install.py +0 -0
  72. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/list.py +0 -0
  73. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/memory/__init__.py +0 -0
  74. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/memory/_common.py +0 -0
  75. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/memory/migrate.py +0 -0
  76. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/memory/notes.py +0 -0
  77. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/memory/transfer.py +0 -0
  78. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/memory/vault.py +0 -0
  79. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/memory/wiki.py +0 -0
  80. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/regenerate.py +0 -0
  81. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/set_role.py +0 -0
  82. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/uninstall.py +0 -0
  83. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/wizard/__init__.py +0 -0
  84. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/wizard/_common.py +0 -0
  85. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/wizard/cost_report.py +0 -0
  86. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/commands/wizard/orchestrator.py +0 -0
  87. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/config.py +0 -0
  88. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/constants.py +0 -0
  89. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/analyst.md +0 -0
  90. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/api-reviewer.md +0 -0
  91. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/architect.md +0 -0
  92. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/database-specialist.md +0 -0
  93. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/debugger.md +0 -0
  94. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/devil.md +0 -0
  95. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/devops.md +0 -0
  96. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/explorer.md +0 -0
  97. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/integrations.md +0 -0
  98. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/lead.md +0 -0
  99. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/performance-profiler.md +0 -0
  100. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/security-auditor.md +0 -0
  101. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/shared/cost_reporting.md +0 -0
  102. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/shared/execution.md +0 -0
  103. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/shared/guardrails.md +0 -0
  104. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/shared/hard_limits.md +0 -0
  105. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/shared/phase0.md +0 -0
  106. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/shared/pipelines.md +0 -0
  107. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/shared/review.md +0 -0
  108. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/shared/verification.md +0 -0
  109. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/shared/wiki_compile.md +0 -0
  110. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/system-auditor.md +0 -0
  111. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/tech-writer.md +0 -0
  112. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/test-runner.md +0 -0
  113. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/agents/wiki-compiler.md +0 -0
  114. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/cli/copilot.yaml +0 -0
  115. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/commands/brainstorm.md +0 -0
  116. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/commands/debug.md +0 -0
  117. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/commands/review.md +0 -0
  118. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/global-claude.md +0 -0
  119. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/global-copilot.md +0 -0
  120. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/global-opencode.md +0 -0
  121. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/hooks/session-context.md.tpl +0 -0
  122. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/models/claude-haiku-4-5.yaml +0 -0
  123. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/models/claude-opus-4-1.yaml +0 -0
  124. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/models/claude-opus-4-5.yaml +0 -0
  125. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/models/claude-opus-4-6.yaml +0 -0
  126. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/models/claude-opus-4-7.yaml +0 -0
  127. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/models/claude-opus-4-8.yaml +0 -0
  128. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/models/claude-sonnet-4-5.yaml +0 -0
  129. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/models/claude-sonnet-4-6.yaml +0 -0
  130. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/models/claude-sonnet-4.yaml +0 -0
  131. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/plugin/claude.yaml +0 -0
  132. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/plugin/opencode-index.js.template +0 -0
  133. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/plugin/opencode.yaml +0 -0
  134. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/pricing.yaml +0 -0
  135. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/roles/orchestrator.yaml +0 -0
  136. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/roles/reasoner.yaml +0 -0
  137. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/roles/scout.yaml +0 -0
  138. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/roles/worker.yaml +0 -0
  139. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/rules/code-quality.md +0 -0
  140. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/rules/safety.md +0 -0
  141. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/brainstorming/SKILL.md +0 -0
  142. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/caveman/SKILL.md +0 -0
  143. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/docker/SKILL.md +0 -0
  144. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/docker/compose.md +0 -0
  145. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/docker/dockerfile.md +0 -0
  146. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/git/SKILL.md +0 -0
  147. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/grill-me/SKILL.md +0 -0
  148. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/grill-with-docs/SKILL.md +0 -0
  149. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/handoff/SKILL.md +0 -0
  150. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/improve-codebase-architecture/SKILL.md +0 -0
  151. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/ingest/SKILL.md +0 -0
  152. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/migrate-memory/SKILL.md +0 -0
  153. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/obsidian-memory/SKILL.md +0 -0
  154. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/prototype/LOGIC.md +0 -0
  155. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/prototype/SKILL.md +0 -0
  156. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/prototype/UI.md +0 -0
  157. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/rails/SKILL.md +0 -0
  158. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/rails/controllers.md +0 -0
  159. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/rails/frontend.md +0 -0
  160. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/rails/infra.md +0 -0
  161. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/rails/models.md +0 -0
  162. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/rails/testing.md +0 -0
  163. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/rails/views.md +0 -0
  164. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/setup-project-context/SKILL.md +0 -0
  165. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/to-issues/SKILL.md +0 -0
  166. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/to-prd/SKILL.md +0 -0
  167. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/write-a-skill/SKILL.md +0 -0
  168. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/skills/zoom-out/SKILL.md +0 -0
  169. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/templates/__init__.py +0 -0
  170. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/templates/__pycache__/__init__.cpython-314.pyc +0 -0
  171. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/templates/frontmatter/__init__.py +0 -0
  172. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/templates/frontmatter/__pycache__/__init__.cpython-314.pyc +0 -0
  173. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/templates/frontmatter/__pycache__/claude.cpython-314.pyc +0 -0
  174. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/templates/frontmatter/__pycache__/opencode.cpython-314.pyc +0 -0
  175. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/templates/frontmatter/claude.py +0 -0
  176. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/data/templates/frontmatter/opencode.py +0 -0
  177. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/doctor_checks.py +0 -0
  178. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/domain/__init__.py +0 -0
  179. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/domain/agent.py +0 -0
  180. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/domain/diagnostics.py +0 -0
  181. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/domain/diff.py +0 -0
  182. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/domain/model.py +0 -0
  183. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/domain/role.py +0 -0
  184. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/domain/rule.py +0 -0
  185. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/domain/skill.py +0 -0
  186. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/domain/state.py +0 -0
  187. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/registries/__init__.py +0 -0
  188. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/registries/_base.py +0 -0
  189. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/registries/model_registry.py +0 -0
  190. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/registries/role_registry.py +0 -0
  191. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/registries/rule_registry.py +0 -0
  192. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/registries/skill_registry.py +0 -0
  193. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/scripts/__init__.py +0 -0
  194. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/scripts/_claude_backend.py +0 -0
  195. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/scripts/_formatting.py +0 -0
  196. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/scripts/_pricing.py +0 -0
  197. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/scripts/cost_report.py +0 -0
  198. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/__init__.py +0 -0
  199. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/_memory_utils.py +0 -0
  200. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/counts.py +0 -0
  201. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/diagnostics/__init__.py +0 -0
  202. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/diagnostics/_checks.py +0 -0
  203. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/diagnostics/_display.py +0 -0
  204. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/diff.py +0 -0
  205. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/install_state_builder.py +0 -0
  206. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/local_backend.py +0 -0
  207. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/memory_router.py +0 -0
  208. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/migrations/__init__.py +0 -0
  209. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/obsidian_backend.py +0 -0
  210. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/session_context.py +0 -0
  211. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/settings_writer.py +0 -0
  212. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/ui.py +0 -0
  213. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/user_config.py +0 -0
  214. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/wiki/__init__.py +0 -0
  215. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/wiki/wiki_index.py +0 -0
  216. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/wiki/wiki_ingest.py +0 -0
  217. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/wiki/wiki_lint.py +0 -0
  218. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/wiki/wiki_query.py +0 -0
  219. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/wiki/wiki_storage.py +0 -0
  220. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes/services/wiki_backend.py +0 -0
  221. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes.egg-info/dependency_links.txt +0 -0
  222. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes.egg-info/entry_points.txt +0 -0
  223. {agent_notes-2.27.0 → agent_notes-2.28.0}/agent_notes.egg-info/top_level.txt +0 -0
  224. {agent_notes-2.27.0 → agent_notes-2.28.0}/setup.cfg +0 -0
  225. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/conftest.py +0 -0
  226. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/__init__.py +0 -0
  227. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/commands/__init__.py +0 -0
  228. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/commands/test_config_command.py +0 -0
  229. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/commands/test_doctor_command.py +0 -0
  230. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/commands/test_info_command.py +0 -0
  231. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/commands/test_install_command.py +0 -0
  232. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/commands/test_list_command.py +0 -0
  233. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/commands/test_regenerate_command.py +0 -0
  234. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/commands/test_uninstall_command.py +0 -0
  235. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/commands/test_validate_command.py +0 -0
  236. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/memory/__init__.py +0 -0
  237. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/memory/test_memory_add_local_backend.py +0 -0
  238. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/memory/test_memory_command.py +0 -0
  239. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/scripts/__init__.py +0 -0
  240. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/functional/scripts/test_release_script.py +0 -0
  241. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/integration/__init__.py +0 -0
  242. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/integration/build_output/__init__.py +0 -0
  243. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/integration/build_output/test_build_output.py +0 -0
  244. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/integration/install/__init__.py +0 -0
  245. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/integration/install/test_install_methods.py +0 -0
  246. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/integration/plugin_builders/__init__.py +0 -0
  247. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/integration/plugin_builders/test_plugin_builders.py +0 -0
  248. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/plugins/__init__.py +0 -0
  249. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/plugins/claude/__init__.py +0 -0
  250. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/plugins/claude/test_agents.py +0 -0
  251. {agent_notes-2.27.0/tests/unit → agent_notes-2.28.0/tests/plugins/codex}/__init__.py +0 -0
  252. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/plugins/test_skills.py +0 -0
  253. {agent_notes-2.27.0/tests/unit/commands → agent_notes-2.28.0/tests/unit}/__init__.py +0 -0
  254. {agent_notes-2.27.0/tests/unit/registries → agent_notes-2.28.0/tests/unit/commands}/__init__.py +0 -0
  255. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/commands/test_cost_report_subcommand.py +0 -0
  256. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/commands/test_count_agents.py +0 -0
  257. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/commands/test_info.py +0 -0
  258. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/commands/test_memory_add_description.py +0 -0
  259. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/commands/test_memory_imports.py +0 -0
  260. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/commands/test_memory_migrate.py +0 -0
  261. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/commands/test_wizard_imports.py +0 -0
  262. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/commands/test_wizard_orchestrator_skip.py +0 -0
  263. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/commands/test_wizard_preflight.py +0 -0
  264. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/commands/test_wizard_steps.py +0 -0
  265. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/commands/wizard/test_cost_report_step.py +0 -0
  266. {agent_notes-2.27.0/tests/unit/scripts → agent_notes-2.28.0/tests/unit/registries}/__init__.py +0 -0
  267. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/registries/test_registries.py +0 -0
  268. {agent_notes-2.27.0/tests/unit/services → agent_notes-2.28.0/tests/unit/scripts}/__init__.py +0 -0
  269. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/scripts/test_cost_report.py +0 -0
  270. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/scripts/test_cost_report_scoping.py +0 -0
  271. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/scripts/test_formatting_tty.py +0 -0
  272. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/scripts/test_opencode_backend_pricing.py +0 -0
  273. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/scripts/test_time_aggregation.py +0 -0
  274. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_build_functions.py +0 -0
  275. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_credential_filter.py +0 -0
  276. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_fs.py +0 -0
  277. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_installer_hooks.py +0 -0
  278. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_installer_plan.py +0 -0
  279. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_local_backend.py +0 -0
  280. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_memory_backend.py +0 -0
  281. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_memory_backend_io.py +0 -0
  282. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_memory_router.py +0 -0
  283. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_rendering_includes.py +0 -0
  284. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_session_context.py +0 -0
  285. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_settings_writer.py +0 -0
  286. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_skill_filtering.py +0 -0
  287. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_state_store.py +0 -0
  288. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_user_config_cost_report.py +0 -0
  289. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_wiki_backend.py +0 -0
  290. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/services/test_wiki_imports.py +0 -0
  291. {agent_notes-2.27.0 → agent_notes-2.28.0}/tests/unit/test_import_health.py +0 -0
  292. {agent_notes-2.27.0 → agent_notes-2.28.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.27.0
3
+ Version: 2.28.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
@@ -24,6 +24,7 @@ Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
25
  Requires-Dist: pyyaml>=6.0
26
26
  Requires-Dist: tomli>=1.1.0; python_version < "3.11"
27
+ Requires-Dist: tomli-w>=1.0.0
27
28
  Provides-Extra: dev
28
29
  Requires-Dist: pytest>=7.0; extra == "dev"
29
30
  Dynamic: license-file
@@ -0,0 +1 @@
1
+ 2.28.0
@@ -1,5 +1,6 @@
1
1
  """Destructive subcommand: reset."""
2
2
 
3
+ import sys
3
4
  import shutil
4
5
  from typing import Optional
5
6
 
@@ -54,7 +55,7 @@ def do_reset(name: Optional[str] = None) -> None:
54
55
  agent_dir = path / name
55
56
  if not agent_dir.exists():
56
57
  print(f"No memory found for agent '{name}'")
57
- exit(1)
58
+ sys.exit(1)
58
59
 
59
60
  print(f"{Color.YELLOW}This will delete all memory for agent '{name}'.{Color.NC}")
60
61
  confirm = input("Continue? [y/N] ")
@@ -163,7 +163,7 @@ def validate() -> None:
163
163
  codeblock_ok = True
164
164
  for md_file in ROOT.rglob("*.md"):
165
165
  # Skip .git and node_modules
166
- if ".git" in str(md_file) or "node_modules" in str(md_file):
166
+ if any(part in {".git", "node_modules"} for part in md_file.parts):
167
167
  continue
168
168
 
169
169
  if not check_unclosed_code_blocks(md_file):
@@ -28,7 +28,7 @@ def install_agents_filtered(clis: Set[str], scope: str, copy_mode: bool = False,
28
28
  folder_overrides: dict = None, global_home_override: str = "") -> None:
29
29
  """Install agents for selected CLIs (filtered by the wizard)."""
30
30
  from ...services import installer
31
- from ...services.installer import _apply_overrides
31
+ from ...services.installer import _apply_overrides, _agent_glob
32
32
  from ...registries.cli_registry import load_registry
33
33
 
34
34
  registry = load_registry()
@@ -43,11 +43,12 @@ def install_agents_filtered(clis: Set[str], scope: str, copy_mode: bool = False,
43
43
  if dst is None:
44
44
  continue
45
45
 
46
- files = list(src.glob("*.md"))
46
+ glob = _agent_glob(effective)
47
+ files = list(src.glob(glob))
47
48
  if not files:
48
49
  continue
49
50
 
50
- place_dir_contents(src, dst, "*.md", copy_mode)
51
+ place_dir_contents(src, dst, glob, copy_mode)
51
52
 
52
53
 
53
54
  def install_config_filtered(clis: Set[str], scope: str, copy_mode: bool = False,
@@ -161,15 +162,16 @@ def _execute_install(
161
162
  if _cmd_names:
162
163
  print(f" {Color.GREEN}✓{Color.NC} Commands {', '.join(sorted(_cmd_names))}")
163
164
 
164
- # SessionStart hook (Claude Code only)
165
+ # SessionStart hooks for every backend with features.session_hook == true
165
166
  from ...services.installer import _install_session_hook
166
- try:
167
- _claude = _registry.get("claude")
168
- if _claude.name in clis:
169
- _claude_eff = _apply_overrides(_claude, folder_overrides, global_home_override or None)
170
- _install_session_hook(_claude_eff, scope, memory_backend=memory_backend, memory_path=memory_path or "")
171
- except (KeyError, Exception):
172
- pass
167
+ for _hook_backend in _registry.with_feature("session_hook"):
168
+ if _hook_backend.name not in clis:
169
+ continue
170
+ try:
171
+ _hook_eff = _apply_overrides(_hook_backend, folder_overrides, global_home_override or None)
172
+ _install_session_hook(_hook_eff, scope, memory_backend=memory_backend, memory_path=memory_path or "")
173
+ except Exception:
174
+ pass
173
175
 
174
176
  _fs.silent_file_ops = False
175
177
 
@@ -9,6 +9,7 @@ agents:
9
9
  color: purple
10
10
  effort: high
11
11
  claude_exclude: true
12
+ codex_exclude: true
12
13
  claude:
13
14
  tools: "Agent(coder, reviewer, security-auditor, test-writer, test-runner, system-auditor, database-specialist, performance-profiler, api-reviewer, tech-writer, devops, explorer), Read, Grep, Glob, Bash"
14
15
  memory: user
@@ -15,6 +15,7 @@ You are an implementation specialist. You write, edit, and fix code.
15
15
  - No new abstractions, helpers, or utilities for one-time operations.
16
16
  - No comments or docs on code you didn't change.
17
17
  - Validate at system boundaries (user input, external APIs). Trust internal code.
18
+ - Make tests pass by fixing the root cause, NEVER by gaming them — do not hardcode expected values, weaken or delete assertions, special-case the test's inputs, or overload equality to fake a pass. If a test appears wrong or the spec seems contradictory, surface it rather than bypassing it.
18
19
 
19
20
  ## Reporting
20
21
 
@@ -28,6 +28,7 @@ Golden rule: behavior must not change. If tests pass before, they must pass afte
28
28
  - Do NOT introduce new dependencies
29
29
  - Keep commits atomic — one refactoring per commit
30
30
  - If tests don't exist, create them before refactoring
31
+ - Never make the suite green by weakening, skipping, or deleting tests — if a test breaks under a refactor, the refactor changed behavior; fix the refactor, not the test.
31
32
 
32
33
  ## Red-Green-Refactor
33
34
 
@@ -34,6 +34,7 @@ You are a code reviewer. You analyze code and provide actionable feedback.
34
34
  - Do not flag pre-existing issues outside the changed code.
35
35
  - Include specific file:line references for every finding.
36
36
  - Commit to a severity before writing the bullet. If you find yourself retracting a finding within the same entry ("actually this is not an issue…"), either downgrade it to a lower severity before posting, or drop it entirely. A bullet that flags-and-retracts is worse than no bullet — it wastes downstream attention. If uncertain whether something is a real issue, use Suggestion and state the uncertainty in plain terms, rather than marking Critical and walking it back.
37
+ - **Bugfix-plus-test check.** When reviewing a bugfix accompanied by a test: verify the test would FAIL without the fix (it must genuinely falsify the bug). Flag tests that pass trivially or whose assertions cannot fail. Flag "fixes" that game tests — hardcoded expected values, weakened or deleted assertions, special-cased test inputs, or overloading equality to fake a pass — instead of fixing root cause. Flag silent behavior changes disguised as refactors.
37
38
 
38
39
  ## Reporting
39
40
 
@@ -26,6 +26,7 @@ You are a test writer. You create comprehensive, meaningful tests.
26
26
  - Never use Float for monetary values.
27
27
  - When asserting on error messages or structured output, match SEMANTIC CONTENT, not exact wording. Use substring checks, regex, or category matchers — never full-string equality. Example: to verify a validation error about a missing `description` field, assert that the error text contains `"description"` and indicates absence (e.g. "missing", "required", "empty"), NOT that it equals `"description: missing"`.
28
28
  - If the task gives you example error strings from a spec, treat them as ILLUSTRATIVE — the implementer is free to phrase equivalent messages differently. Your tests must pass against any reasonable phrasing that conveys the same meaning.
29
+ - **Fail-first discipline.** A regression or characterization test MUST be demonstrated to FAIL against the current (unfixed) code, for the right reason, before it is considered to cover a bug. Never write tautological/always-green tests or assertions that cannot fail (e.g. asserting on a mock you fully control, or on a value you just hardcoded). The test's job is to falsify the bug — if it passes on the broken code, it is worthless.
29
30
 
30
31
  ## Reporting
31
32
 
@@ -10,6 +10,7 @@ layout:
10
10
  config: CLAUDE.md
11
11
  memory: agent-memory/
12
12
  settings: settings.json
13
+ agent_extension: md
13
14
  features:
14
15
  agents: true
15
16
  skills: true
@@ -20,7 +21,11 @@ features:
20
21
  config_style: inline
21
22
  settings_template: false
22
23
  supports_symlink: true
24
+ session_hook: true
25
+ stop_hook: true
26
+ allow_entries: true
23
27
  global_template: global-claude.md
24
28
  exclude_flag: claude_exclude
25
29
  accepted_providers: [anthropic, bedrock, vertex]
26
30
  use_model_class: true
31
+ preferred_family: claude
@@ -0,0 +1,29 @@
1
+ name: codex
2
+ label: Codex CLI
3
+ global_home: ~/.codex
4
+ local_dir: .codex
5
+ layout:
6
+ agents: agents/
7
+ skills: skills/
8
+ config: AGENTS.md
9
+ hooks: hooks.json
10
+ agent_extension: toml
11
+ features:
12
+ agents: true
13
+ skills: true
14
+ rules: false
15
+ commands: false
16
+ memory: false
17
+ frontmatter: codex
18
+ config_style: inline
19
+ settings_template: false
20
+ supports_symlink: true
21
+ session_hook: true
22
+ stop_hook: false
23
+ allow_entries: false
24
+ global_template: global-codex.md
25
+ exclude_flag: codex_exclude
26
+ strip_memory_section: true
27
+ accepted_providers: [openai]
28
+ use_model_class: false
29
+ preferred_family: gpt
@@ -6,6 +6,7 @@ layout:
6
6
  agents: agents/
7
7
  skills: skills/
8
8
  config: AGENTS.md
9
+ agent_extension: md
9
10
  features:
10
11
  agents: true
11
12
  skills: true
@@ -16,7 +17,11 @@ features:
16
17
  config_style: inline
17
18
  settings_template: false
18
19
  supports_symlink: true
20
+ session_hook: false
21
+ stop_hook: false
22
+ allow_entries: false
19
23
  global_template: global-opencode.md
20
24
  exclude_flag: opencode_exclude
21
25
  strip_memory_section: true
22
26
  accepted_providers: [github-copilot, anthropic, openrouter, openai, google, moonshot]
27
+ preferred_family: claude
@@ -0,0 +1,40 @@
1
+ # Global Instructions
2
+
3
+ ## Coding philosophy
4
+
5
+ - Read existing code before writing new code. Match project patterns.
6
+ - Minimal changes: only what was requested. Do not refactor beyond scope.
7
+ - Fix root causes, not symptoms.
8
+ - One approach, commit to it. Course-correct only on new evidence.
9
+
10
+ ## Behavior
11
+
12
+ - Investigate before answering. Never speculate about code you haven't read.
13
+ - No over-engineering: no extra features, abstractions, or configs beyond scope.
14
+ - No comments or docs on code you didn't change.
15
+ - When the task is unclear, ask one clarifying question instead of guessing.
16
+
17
+ ## Safety
18
+
19
+ - Confirm before: `git push --force`, `rm -rf`, `DROP TABLE`, branch deletion.
20
+ - Never commit: `.env`, `*.pem`, credentials, API keys, secrets.
21
+ - Never bypass: `--no-verify`, `--force` without explicit user request.
22
+ - Never force-push to main/master.
23
+
24
+ ## Commits
25
+
26
+ - Load the `git` skill when asked to commit and follow its workflow.
27
+ - Analyze all changes, group into logical chunks, make small focused commits.
28
+ - Format: `#<ticket> type(scope): short description` — title only, no body.
29
+ - Extract ticket number from branch name when available.
30
+ - Types: feat, fix, refactor, test, docs, chore, style, perf
31
+
32
+ ## Agent delegation
33
+
34
+ - Use subagents when tasks can run in parallel or require isolated context.
35
+ - For simple tasks, sequential operations, or single-file edits, work directly.
36
+ - Use `explorer` for quick lookups to save context tokens.
37
+ - Use `database-specialist` for schema, indexes, and query analysis.
38
+ - Use `performance-profiler` for bottleneck identification.
39
+ - Use `api-reviewer` for API design and consistency checks.
40
+ - Use `lead` for complex multi-step tasks requiring coordination.
@@ -0,0 +1,14 @@
1
+ id: gpt-5-4-mini
2
+ label: GPT-5.4 Mini
3
+ family: gpt
4
+ class: haiku
5
+ aliases:
6
+ openai: gpt-5.4-mini
7
+ pricing:
8
+ input: 0.15
9
+ output: 0.60
10
+ cache: 0.02
11
+ capabilities:
12
+ vision: true
13
+ long_context: false
14
+ tool_use: true
@@ -0,0 +1,14 @@
1
+ id: gpt-5-4
2
+ label: GPT-5.4
3
+ family: gpt
4
+ class: sonnet
5
+ aliases:
6
+ openai: gpt-5.4
7
+ pricing:
8
+ input: 3.00
9
+ output: 15.00
10
+ cache: 0.30
11
+ capabilities:
12
+ vision: true
13
+ long_context: true
14
+ tool_use: true
@@ -0,0 +1,14 @@
1
+ id: gpt-5-5
2
+ label: GPT-5.5
3
+ family: gpt
4
+ class: opus
5
+ aliases:
6
+ openai: gpt-5.5
7
+ pricing:
8
+ input: 10.00
9
+ output: 40.00
10
+ cache: 1.00
11
+ capabilities:
12
+ vision: true
13
+ long_context: true
14
+ tool_use: true
@@ -61,6 +61,12 @@ APPROVED (state explicitly when there are no blocking findings)
61
61
 
62
62
  A BLOCKING finding must be resolved before merge. A SUGGESTION is optional.
63
63
 
64
+ ## Lens 6 — Test integrity / anti-gaming
65
+
66
+ - Does each test actually falsify what it claims to cover — would it fail without the change?
67
+ - Watch for gamed fixes: hardcoded expected values, weakened or deleted assertions, special-cased inputs that only work for the exact test data.
68
+ - Watch for behavior changes disguised as refactors (suite stays green because the test was weakened, not because behavior was preserved).
69
+
64
70
  ## Scope discipline
65
71
 
66
72
  Do not flag cosmetic changes unless they create real ambiguity. A review that lists 20 nits trains authors to ignore reviews entirely.
@@ -59,7 +59,8 @@ Test with the smallest possible change — one that confirms or disproves the hy
59
59
  ## Phase 4 — Fix
60
60
 
61
61
  Apply the minimal fix for the root cause:
62
- - Fix the root cause, not the symptom.
62
+ - Fix the root cause, not the symptom. Do not make the symptom disappear by swallowing or catching the error, loosening an assertion, adding a retry that hides a race, or special-casing the failing input. Those game the symptom check without fixing the bug.
63
+ - Before touching the fix, confirm the reproduction actually fails on the current code. A repro that never truly failed proves nothing. After fixing, confirm it now passes AND would have failed without the change.
63
64
  - Remove all instrumentation from Phase 1.
64
65
  - Run the full test suite.
65
66
  - Confirm the original failure is gone and nothing else regressed.
@@ -51,6 +51,7 @@ Return to Step 2 for the next extraction.
51
51
  ## Hard rules
52
52
 
53
53
  - **Structure OR behavior in one commit, never both.** If you find a bug while refactoring: stash the refactor, fix the bug in a separate commit, then resume. Mixing them makes the change impossible to review and risky to revert.
54
+ - **Never achieve green by weakening the tests.** Do not weaken, skip, delete, or rewrite a test to make it pass after a refactor. If a test breaks, the refactor changed behavior by definition — fix or revert the refactor, not the test. The test suite is the invariant the refactor must preserve.
54
55
  - **Do not optimize during refactor.** Performance tuning is a separate session with its own measurement baseline.
55
56
  - **Do not add features during refactor.** If you notice a missing edge case: note it, address it in a separate commit after the refactor is complete.
56
57
  - **Stop when the smell is gone.** Over-refactoring is as harmful as under-refactoring.
@@ -17,7 +17,7 @@ Iteratively improve EXISTING code until it stops yielding improvements. The lead
17
17
 
18
18
  ## The loop (lead-orchestrated, loop-until-dry)
19
19
 
20
- 1. **Scope.** Resolve the target (arg path, or whole project). Identify the test command and confirm the suite is green. If it is red, stop and report — fix the suite before improving.
20
+ 1. **Scope.** Resolve the target (arg path, or whole project). Identify the test command and confirm the suite is green. If it is red, stop and report — fix the suite before improving. Do NOT run the loop on code that lacks meaningful test coverage — write characterization tests first: studies report that looping over weakly-tested code produces roughly 10x more false-positive "fixes" than with a strong suite (~16% vs ~1.4%).
21
21
  2. **Scan — one dimension at a time.** Dispatch read-only agents to produce a ranked list of concrete opportunities:
22
22
  - `debugger` / `security-auditor` → bugs, correctness, vulnerabilities
23
23
  - `performance-profiler` → hot paths, N+1, redundant work
@@ -29,7 +29,7 @@ Iteratively improve EXISTING code until it stops yielding improvements. The lead
29
29
 
30
30
  3. **Prioritize.** Order: correctness/safety > missing tests on touched code > DRY/duplication > consistency/homogeneity > pattern & convention fit > performance > clarity/naming. Drop anything that changes behavior or adds capability.
31
31
  4. **Apply ONE atomic, independent change.** Dispatch `coder` (bugfix) or `refactorer` (behavior-preserving cleanup). Smallest viable diff.
32
- 5. **Verify.** Run affected tests — must stay green. `reviewer` confirms: no behavior change, fits conventions, genuinely improves the dimension. On regression → revert and re-plan.
32
+ 5. **Verify.** Run affected tests — must stay green. `reviewer` confirms: no behavior change, fits conventions, genuinely improves the dimension. On regression → revert and re-plan. Note: research suggests genuine logic bugs repair poorly in an iterative loop (~45% vs ~77% for surface/name errors) — escalate real logic bugs to `debugger` rather than re-looping.
33
33
  6. **Commit (auto, atomic).** One concern per commit, independent and revertable. Use the `git` skill's message format. Then take the next opportunity.
34
34
  7. **Repeat passes.** Converge when TWO consecutive full passes surface no new actionable improvement. Then report.
35
35
 
@@ -53,7 +53,8 @@ Each dimension: what to **hunt**, what to **fix**, what to **leave alone**.
53
53
  - **Green-before / green-after.** A red suite halts the loop.
54
54
  - **No-feature gate.** If a change adds capability, it is out of scope — reject it.
55
55
  - **Atomic & independent commits.** Revert on regression with `git revert` — never `reset --hard` or force-push.
56
- - **Max 2 review rounds per change,** then accept or drop it.
56
+ - **Max 2 review rounds per change,** then accept or drop it. (empirically, ~2 rounds captures most attainable improvement — on the order of 76–95% — so further rounds are mostly wasted polish.)
57
+ - **Fail-first, anti-gaming.** Every regression/characterization test must be shown to FAIL on the unfixed code (it must actually reproduce the bug) BEFORE the fix lands. Reject any "fix" that games the test rather than addressing root cause — hardcoded expected values, weakened/removed assertions, special-casing the asserted inputs, or operator/equality overloading. A test that passes regardless of the fix proves nothing. The reviewer confirms the test genuinely falsifies the bug.
57
58
 
58
59
  ## Done
59
60
 
@@ -36,7 +36,8 @@ Because you just wrote the code, you know exactly what behavior matters and how
36
36
 
37
37
  ## GREEN — make it pass
38
38
 
39
- - Write the minimum code to pass the test. Hardcode values if that's all it takes — you'll triangulate with the next test.
39
+ - Write the minimum code to pass the test. Hardcode values if that's all it takes — you'll triangulate with the next test. A hardcoded return is only valid as a transient step toward a general implementation; if it stays in permanently to satisfy the test, that is reward-hacking, not TDD.
40
+ - Do not reach GREEN by gaming the test: no special-casing the test's specific inputs, no weakening the assertion, no deleting the assertion. The test must pass because the behavior is implemented, not because the check was neutered.
40
41
  - Run the test. Confirm green.
41
42
  - If still failing: read the failure output carefully before changing anything else.
42
43
 
@@ -0,0 +1,106 @@
1
+ """Codex CLI agent file generator — emits whole-file TOML, not frontmatter+markdown."""
2
+
3
+ import tomli_w
4
+
5
+
6
+ _EFFORT_MAP = {
7
+ "minimal": "minimal",
8
+ "low": "low",
9
+ "medium": "medium",
10
+ "high": "high",
11
+ "xhigh": "xhigh",
12
+ }
13
+
14
+ _STRIP_PREFIXES = ("## Memory", "## Cost reporting")
15
+
16
+
17
+ def render(ctx: dict) -> str:
18
+ """Not used for Codex — emit_file supersedes render.
19
+ Kept so the module is consistent with other frontmatter templates."""
20
+ return ""
21
+
22
+
23
+ def emit_file(ctx: dict, body: str) -> tuple[str, str]:
24
+ """Return (filename, full_file_content) for a Codex agent TOML file.
25
+
26
+ The returned content is a complete TOML document — not a frontmatter snippet.
27
+ rendering.py writes this verbatim in place of the normal frontmatter+body output.
28
+ """
29
+ agent_name = ctx['agent_name']
30
+ agent_config = ctx['agent_config']
31
+ model_str = ctx.get('model_str') or ''
32
+
33
+ doc: dict = {
34
+ "name": agent_name,
35
+ "description": agent_config["description"],
36
+ "developer_instructions": body,
37
+ }
38
+
39
+ if model_str:
40
+ doc["model"] = model_str
41
+
42
+ effort_key = agent_config.get("effort", "medium")
43
+ doc["model_reasoning_effort"] = _EFFORT_MAP.get(effort_key, "medium")
44
+
45
+ doc["sandbox_mode"] = _sandbox_mode(agent_config)
46
+
47
+ filename = f"{agent_name}.toml"
48
+ content = tomli_w.dumps(doc)
49
+ return filename, content
50
+
51
+
52
+ def post_process(prompt: str, ctx: dict) -> str:
53
+ """Strip Codex-irrelevant sections from the agent prompt body.
54
+
55
+ Strips:
56
+ - ## Memory* sections (Codex has no agent memory)
57
+ - ## Cost reporting section (Claude Code CLI tool, not available in Codex)
58
+ """
59
+ return _strip_sections(prompt, _STRIP_PREFIXES)
60
+
61
+
62
+ # --- helpers ---
63
+
64
+ def _sandbox_mode(agent_config: dict) -> str:
65
+ """Derive Codex sandbox_mode from the agent's tool/permission config.
66
+
67
+ Writer agents (those that can Write or Edit files) -> "workspace-write"
68
+ All others -> "read-only"
69
+ """
70
+ claude_config = agent_config.get('claude', {}) or {}
71
+ tools = claude_config.get('tools', '') or ''
72
+ if isinstance(tools, str):
73
+ if 'Write' in tools or 'Edit' in tools:
74
+ return "workspace-write"
75
+ elif isinstance(tools, list):
76
+ if 'Write' in tools or 'Edit' in tools:
77
+ return "workspace-write"
78
+
79
+ opencode_config = agent_config.get('opencode', {}) or {}
80
+ permission = opencode_config.get('permission', {}) or {}
81
+ if permission.get('edit') == 'allow':
82
+ return "workspace-write"
83
+
84
+ return "read-only"
85
+
86
+
87
+ def _strip_sections(content: str, strip_prefixes: tuple) -> str:
88
+ """Strip ## sections whose heading starts with any of the given prefixes."""
89
+ lines = content.split('\n')
90
+ result_lines = []
91
+ in_stripped_section = False
92
+
93
+ for line in lines:
94
+ if any(line.startswith(prefix) for prefix in strip_prefixes):
95
+ in_stripped_section = True
96
+ continue
97
+ elif line.startswith('## ') and in_stripped_section:
98
+ in_stripped_section = False
99
+ result_lines.append(line)
100
+ elif not in_stripped_section:
101
+ result_lines.append(line)
102
+
103
+ while result_lines and result_lines[-1].strip() == '':
104
+ result_lines.pop()
105
+
106
+ return '\n'.join(result_lines)
@@ -22,6 +22,7 @@ class CLIBackend:
22
22
  settings_template: Optional[str] = None
23
23
  accepted_providers: tuple[str, ...] = () # new
24
24
  use_model_class: bool = False
25
+ preferred_family: Optional[str] = None # "claude", "gpt", etc. — preferred model family for step-2 fallback
25
26
 
26
27
  def supports(self, feature: str) -> bool:
27
28
  """Return True if the backend has that feature enabled."""
@@ -9,6 +9,9 @@ from ..config import AGENTS_YAML
9
9
  from ..domain.agent import AgentSpec
10
10
  from ._base import load_yaml_file
11
11
 
12
+ # Top-level keys in agents.yaml that are NOT per-backend config entries.
13
+ NON_BACKEND_KEYS = {"description", "role", "mode", "color", "effort", "claude_exclude"}
14
+
12
15
 
13
16
  class AgentRegistry:
14
17
  """Registry of agent configurations from agents.yaml."""
@@ -51,9 +54,6 @@ def load_agent_registry(yaml_path: Optional[Path] = None) -> AgentRegistry:
51
54
  if not agents_data:
52
55
  return AgentRegistry([])
53
56
 
54
- # Known top-level keys that are NOT per-backend config
55
- NON_BACKEND_KEYS = {"description", "role", "mode", "color", "effort", "claude_exclude"}
56
-
57
57
  agents = []
58
58
  for name, config in agents_data.items():
59
59
  # Extract required fields
@@ -71,7 +71,8 @@ def load_registry(cli_dir: Optional[Path] = None) -> CLIRegistry:
71
71
  strip_memory_section=data.get("strip_memory_section", False),
72
72
  settings_template=data.get("settings_template"),
73
73
  accepted_providers=tuple(data.get("accepted_providers", [])),
74
- use_model_class=data.get("use_model_class", False)
74
+ use_model_class=data.get("use_model_class", False),
75
+ preferred_family=data.get("preferred_family"),
75
76
  )
76
77
  backends.append(backend)
77
78
 
@@ -1,4 +1,5 @@
1
1
  """Session cost report for OpenCode — reads SQLite database."""
2
+ import contextlib
2
3
  import sqlite3
3
4
  from pathlib import Path
4
5
 
@@ -54,7 +55,8 @@ def run() -> int:
54
55
  print(f"Database not found: {DB}")
55
56
  return 1
56
57
 
57
- rows = sqlite3.connect(DB).execute(SQL).fetchall()
58
+ with contextlib.closing(sqlite3.connect(DB)) as conn:
59
+ rows = conn.execute(SQL).fetchall()
58
60
  if not rows:
59
61
  print("No sessions found.")
60
62
  return 0
@@ -21,6 +21,8 @@ except ImportError:
21
21
  "tomli is required on Python < 3.11. Install it: pip install tomli"
22
22
  ) from exc
23
23
 
24
+ import tomli_w
25
+
24
26
  CONFIG_PATH = Path.home() / ".agent-notes" / "credentials.toml"
25
27
  SAFE_MODE = 0o600
26
28
 
@@ -95,7 +97,7 @@ def _write(data: dict) -> None:
95
97
  tmp_pathobj = Path(tmp_path)
96
98
  try:
97
99
  with os.fdopen(fd, "w") as fh:
98
- _dump_toml(data, fh)
100
+ fh.write(_dump_toml(data))
99
101
  tmp_pathobj.chmod(SAFE_MODE)
100
102
  tmp_pathobj.replace(CONFIG_PATH)
101
103
  finally:
@@ -103,22 +105,18 @@ def _write(data: dict) -> None:
103
105
  tmp_pathobj.unlink()
104
106
 
105
107
 
106
- def _dump_toml(data: dict, fh) -> None:
107
- """Minimal TOML writer for the credentials schema."""
108
+ def _dump_toml(data: dict) -> str:
109
+ """Serialize credentials dict to TOML using tomli_w.
110
+
111
+ None values are filtered out before serialization — TOML has no null type.
112
+ The hand-rolled predecessor would have written Python's ``None`` repr, which
113
+ is not valid TOML and would fail on read-back anyway.
114
+ """
108
115
  providers = data.get("providers", {})
109
- for name in sorted(providers):
110
- block = providers[name]
111
- fh.write(f"[providers.{name}]\n")
112
- for k in sorted(block):
113
- v = block[k]
114
- if isinstance(v, bool):
115
- fh.write(f"{k} = {'true' if v else 'false'}\n")
116
- elif isinstance(v, str):
117
- escaped = v.replace('\\', '\\\\').replace('"', '\\"')
118
- fh.write(f'{k} = "{escaped}"\n')
119
- else:
120
- fh.write(f"{k} = {v!r}\n")
121
- fh.write("\n")
116
+ clean: dict = {"providers": {}}
117
+ for name, block in providers.items():
118
+ clean["providers"][name] = {k: v for k, v in block.items() if v is not None}
119
+ return tomli_w.dumps(clean)
122
120
 
123
121
 
124
122
  def list_providers() -> list: