agent-notes 2.11.0__tar.gz → 2.13.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.
- {agent_notes-2.11.0 → agent_notes-2.13.0}/PKG-INFO +2 -3
- agent_notes-2.13.0/agent_notes/VERSION +1 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/__init__.py +7 -7
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/memory.py +150 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/wizard.py +3 -24
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/config.py +1 -9
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/lead.md +5 -21
- agent_notes-2.13.0/agent_notes/data/agents/shared/cost_reporting.md +13 -0
- agent_notes-2.13.0/agent_notes/data/agents/shared/phase0.md +20 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/global-claude.md +5 -21
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/obsidian-memory/SKILL.md +38 -25
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/scripts/_claude_backend.py +1 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/diagnostics/_display.py +2 -2
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/memory_backend.py +141 -80
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes.egg-info/PKG-INFO +2 -3
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes.egg-info/SOURCES.txt +3 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/pyproject.toml +1 -2
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/commands/test_uninstall_command.py +1 -0
- agent_notes-2.13.0/tests/unit/commands/test_memory_migrate.py +378 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/services/test_memory_backend_io.py +172 -95
- agent_notes-2.13.0/tests/unit/test_memory_dir_for_backend.py +67 -0
- agent_notes-2.11.0/agent_notes/VERSION +0 -1
- agent_notes-2.11.0/agent_notes/data/agents/shared/cost_reporting.md +0 -7
- {agent_notes-2.11.0 → agent_notes-2.13.0}/LICENSE +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/README.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/__main__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/cli.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/_install_helpers.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/build.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/config.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/doctor.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/info.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/install.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/list.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/regenerate.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/set_role.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/uninstall.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/update.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/commands/validate.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/agents.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/analyst.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/api-reviewer.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/architect.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/coder.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/database-specialist.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/debugger.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/devil.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/devops.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/explorer.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/integrations.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/performance-profiler.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/refactorer.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/reviewer.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/security-auditor.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/system-auditor.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/tech-writer.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/test-runner.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/agents/test-writer.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/cli/claude.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/cli/copilot.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/cli/opencode.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/commands/brainstorm.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/commands/debug.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/commands/review.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/global-copilot.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/global-opencode.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/hooks/session-context.md.tpl +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/models/claude-haiku-4-5.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/models/claude-opus-4-1.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/models/claude-opus-4-5.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/models/claude-opus-4-6.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/models/claude-opus-4-7.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/models/claude-sonnet-4-5.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/models/claude-sonnet-4-6.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/models/claude-sonnet-4.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/plugin/claude.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/plugin/opencode-index.js.template +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/plugin/opencode.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/pricing.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/roles/orchestrator.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/roles/reasoner.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/roles/scout.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/roles/worker.yaml +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/rules/code-quality.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/rules/safety.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/brainstorming/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/caveman/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/code-review/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/debugging-protocol/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/docker-compose/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/docker-compose-advanced/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/docker-dockerfile/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/docker-dockerfile-languages/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/git/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/grill-me/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/grill-with-docs/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/improve-codebase-architecture/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-active-storage/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-broadcasting/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-concerns/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-controllers/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-controllers-advanced/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-helpers/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-initializers/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-javascript/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-jobs/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-kamal/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-lib/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-mailers/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-migrations/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-models/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-models-advanced/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-routes/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-style/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-testing-controllers/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-testing-models/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-testing-system/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-validations/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-view-components/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-view-components-advanced/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-views/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/rails-views-advanced/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/refactoring-protocol/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/setup-project-context/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/tdd/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/skills/zoom-out/SKILL.md +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/templates/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/templates/__pycache__/__init__.cpython-314.pyc +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/templates/frontmatter/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/templates/frontmatter/__pycache__/__init__.cpython-314.pyc +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/templates/frontmatter/__pycache__/claude.cpython-314.pyc +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/templates/frontmatter/__pycache__/opencode.cpython-314.pyc +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/templates/frontmatter/claude.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/data/templates/frontmatter/opencode.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/doctor_checks.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/domain/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/domain/agent.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/domain/cli_backend.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/domain/diagnostics.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/domain/diff.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/domain/model.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/domain/role.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/domain/rule.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/domain/skill.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/domain/state.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/install_state.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/registries/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/registries/_base.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/registries/agent_registry.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/registries/cli_registry.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/registries/model_registry.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/registries/role_registry.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/registries/rule_registry.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/registries/skill_registry.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/scripts/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/scripts/_formatting.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/scripts/_opencode_backend.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/scripts/_pricing.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/scripts/cost_report.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/credentials.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/diagnostics/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/diagnostics/_checks.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/diagnostics/_fix.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/diff.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/fs.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/install_state_builder.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/installer.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/rendering.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/session_context.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/settings_writer.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/state_store.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/ui.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/user_config.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/services/validation.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes/state.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes.egg-info/dependency_links.txt +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes.egg-info/entry_points.txt +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes.egg-info/requires.txt +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/agent_notes.egg-info/top_level.txt +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/setup.cfg +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/conftest.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/commands/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/commands/test_config_command.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/commands/test_doctor_command.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/commands/test_info_command.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/commands/test_install_command.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/commands/test_list_command.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/commands/test_regenerate_command.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/commands/test_update_command.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/commands/test_validate_command.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/memory/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/memory/test_memory_command.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/scripts/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/functional/scripts/test_release_script.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/integration/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/integration/build_output/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/integration/build_output/test_build_output.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/integration/install/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/integration/install/test_install_methods.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/integration/plugin_builders/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/integration/plugin_builders/test_plugin_builders.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/plugins/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/plugins/claude/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/plugins/claude/test_agents.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/plugins/test_skills.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/commands/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/commands/test_cost_report_subcommand.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/commands/test_count_agents.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/commands/test_wizard_orchestrator_skip.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/commands/test_wizard_preflight.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/registries/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/registries/test_registries.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/scripts/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/scripts/test_cost_report.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/scripts/test_cost_report_scoping.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/scripts/test_formatting_tty.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/scripts/test_time_aggregation.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/services/__init__.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/services/test_build_functions.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/services/test_credentials.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/services/test_fs.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/services/test_installer_plan.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/services/test_memory_backend.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.0}/tests/unit/services/test_rendering_includes.py +0 -0
- {agent_notes-2.11.0 → agent_notes-2.13.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.
|
|
3
|
+
Version: 2.13.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
|
|
@@ -13,14 +13,13 @@ Classifier: Development Status :: 4 - Beta
|
|
|
13
13
|
Classifier: Intended Audience :: Developers
|
|
14
14
|
Classifier: Operating System :: OS Independent
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
19
|
Classifier: Topic :: Software Development :: Code Generators
|
|
21
20
|
Classifier: Topic :: Utilities
|
|
22
21
|
Classifier: Environment :: Console
|
|
23
|
-
Requires-Python: >=3.
|
|
22
|
+
Requires-Python: >=3.10
|
|
24
23
|
Description-Content-Type: text/markdown
|
|
25
24
|
License-File: LICENSE
|
|
26
25
|
Requires-Dist: pyyaml>=6.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.13.0
|
|
@@ -6,16 +6,16 @@ Commands MUST NOT import other commands (use services to share logic).
|
|
|
6
6
|
Exception: install/uninstall/info share helpers via _install_helpers.py since
|
|
7
7
|
they are sibling members of one logical command group.
|
|
8
8
|
"""
|
|
9
|
-
from .install import install
|
|
10
|
-
from .uninstall import uninstall
|
|
11
9
|
from .info import show_info
|
|
12
|
-
from .build import build
|
|
13
|
-
from .doctor import doctor
|
|
14
|
-
from .validate import validate
|
|
15
|
-
from .update import update
|
|
16
|
-
from .regenerate import regenerate
|
|
17
10
|
from .set_role import set_role
|
|
18
11
|
from .wizard import interactive_install
|
|
12
|
+
from . import install
|
|
13
|
+
from . import uninstall
|
|
14
|
+
from . import build
|
|
15
|
+
from . import doctor
|
|
16
|
+
from . import validate
|
|
17
|
+
from . import update
|
|
18
|
+
from . import regenerate
|
|
19
19
|
from . import list as list_cmd
|
|
20
20
|
from . import memory as memory_cmd
|
|
21
21
|
|
|
@@ -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
|
-
|
|
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}/
|
|
428
|
+
print(f" {c}/agent-notes")
|
|
446
429
|
_mem_base = candidates[0] if candidates else Path.home() / "Documents" / "Obsidian Vault"
|
|
447
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
**
|
|
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.
|
|
263
|
-
12. Reporting "done"
|
|
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
|
-
|
|
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
|
-
**
|
|
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.
|
|
338
|
-
12. Reporting "done"
|
|
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
|
-
-
|
|
18
|
-
|
|
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
|
-
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
149
|
+
```
|
|
150
|
+
- [[<filename-stem>]] — <type> — <title>
|
|
151
|
+
```
|
|
137
152
|
|
|
138
|
-
|
|
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
|
-
|
|
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**:
|
|
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
|
|
|
@@ -102,7 +102,7 @@ def _check_config(backend, scope: str) -> tuple:
|
|
|
102
102
|
def _check_role_models(state):
|
|
103
103
|
"""Display role→model assignments and check compatibility."""
|
|
104
104
|
from ...model_registry import load_model_registry
|
|
105
|
-
from ...
|
|
105
|
+
from ...registries.cli_registry import load_registry
|
|
106
106
|
from ...role_registry import load_role_registry
|
|
107
107
|
from ...config import Color
|
|
108
108
|
|
|
@@ -218,7 +218,7 @@ def print_summary(scope: str):
|
|
|
218
218
|
print(f"Checking AgentNotes {label} installation:")
|
|
219
219
|
print("")
|
|
220
220
|
|
|
221
|
-
from ...
|
|
221
|
+
from ...registries.cli_registry import load_registry
|
|
222
222
|
registry = load_registry()
|
|
223
223
|
for backend in registry.all():
|
|
224
224
|
if not backend.supports("agents"):
|