agent-notes 2.0.4__py3-none-any.whl
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/VERSION +1 -0
- agent_notes/__init__.py +1 -0
- agent_notes/__main__.py +4 -0
- agent_notes/cli.py +348 -0
- agent_notes/commands/__init__.py +27 -0
- agent_notes/commands/_install_helpers.py +262 -0
- agent_notes/commands/build.py +170 -0
- agent_notes/commands/doctor.py +112 -0
- agent_notes/commands/info.py +95 -0
- agent_notes/commands/install.py +99 -0
- agent_notes/commands/list.py +169 -0
- agent_notes/commands/memory.py +430 -0
- agent_notes/commands/regenerate.py +152 -0
- agent_notes/commands/set_role.py +143 -0
- agent_notes/commands/uninstall.py +26 -0
- agent_notes/commands/update.py +169 -0
- agent_notes/commands/validate.py +199 -0
- agent_notes/commands/wizard.py +720 -0
- agent_notes/config.py +154 -0
- agent_notes/data/agents/agents.yaml +352 -0
- agent_notes/data/agents/analyst.md +45 -0
- agent_notes/data/agents/api-reviewer.md +47 -0
- agent_notes/data/agents/architect.md +46 -0
- agent_notes/data/agents/coder.md +28 -0
- agent_notes/data/agents/database-specialist.md +45 -0
- agent_notes/data/agents/debugger.md +47 -0
- agent_notes/data/agents/devil.md +47 -0
- agent_notes/data/agents/devops.md +38 -0
- agent_notes/data/agents/explorer.md +23 -0
- agent_notes/data/agents/integrations.md +44 -0
- agent_notes/data/agents/lead.md +216 -0
- agent_notes/data/agents/performance-profiler.md +44 -0
- agent_notes/data/agents/refactorer.md +48 -0
- agent_notes/data/agents/reviewer.md +44 -0
- agent_notes/data/agents/security-auditor.md +44 -0
- agent_notes/data/agents/system-auditor.md +38 -0
- agent_notes/data/agents/tech-writer.md +32 -0
- agent_notes/data/agents/test-runner.md +36 -0
- agent_notes/data/agents/test-writer.md +39 -0
- agent_notes/data/cli/claude.yaml +25 -0
- agent_notes/data/cli/copilot.yaml +18 -0
- agent_notes/data/cli/opencode.yaml +22 -0
- agent_notes/data/commands/brainstorm.md +8 -0
- agent_notes/data/commands/debug.md +9 -0
- agent_notes/data/commands/review.md +10 -0
- agent_notes/data/global-claude.md +290 -0
- agent_notes/data/global-copilot.md +27 -0
- agent_notes/data/global-opencode.md +40 -0
- agent_notes/data/hooks/session-context.md.tpl +19 -0
- agent_notes/data/models/claude-haiku-4-5.yaml +15 -0
- agent_notes/data/models/claude-opus-4-1.yaml +16 -0
- agent_notes/data/models/claude-opus-4-5.yaml +16 -0
- agent_notes/data/models/claude-opus-4-6.yaml +16 -0
- agent_notes/data/models/claude-opus-4-7.yaml +15 -0
- agent_notes/data/models/claude-sonnet-4-5.yaml +16 -0
- agent_notes/data/models/claude-sonnet-4-6.yaml +15 -0
- agent_notes/data/models/claude-sonnet-4.yaml +16 -0
- agent_notes/data/pricing.yaml +33 -0
- agent_notes/data/roles/orchestrator.yaml +5 -0
- agent_notes/data/roles/reasoner.yaml +5 -0
- agent_notes/data/roles/scout.yaml +5 -0
- agent_notes/data/roles/worker.yaml +5 -0
- agent_notes/data/rules/code-quality.md +9 -0
- agent_notes/data/rules/safety.md +10 -0
- agent_notes/data/scripts/cost-report +211 -0
- agent_notes/data/skills/brainstorming/SKILL.md +57 -0
- agent_notes/data/skills/code-review/SKILL.md +64 -0
- agent_notes/data/skills/debugging-protocol/SKILL.md +51 -0
- agent_notes/data/skills/docker-compose/SKILL.md +318 -0
- agent_notes/data/skills/docker-compose-advanced/SKILL.md +575 -0
- agent_notes/data/skills/docker-dockerfile/SKILL.md +385 -0
- agent_notes/data/skills/docker-dockerfile-languages/SKILL.md +293 -0
- agent_notes/data/skills/git/SKILL.md +87 -0
- agent_notes/data/skills/rails-active-storage/SKILL.md +321 -0
- agent_notes/data/skills/rails-broadcasting/SKILL.md +374 -0
- agent_notes/data/skills/rails-concerns/SKILL.md +806 -0
- agent_notes/data/skills/rails-controllers/SKILL.md +510 -0
- agent_notes/data/skills/rails-controllers-advanced/SKILL.md +441 -0
- agent_notes/data/skills/rails-helpers/SKILL.md +677 -0
- agent_notes/data/skills/rails-initializers/SKILL.md +79 -0
- agent_notes/data/skills/rails-javascript/SKILL.md +567 -0
- agent_notes/data/skills/rails-jobs/SKILL.md +700 -0
- agent_notes/data/skills/rails-kamal/SKILL.md +483 -0
- agent_notes/data/skills/rails-lib/SKILL.md +101 -0
- agent_notes/data/skills/rails-mailers/SKILL.md +321 -0
- agent_notes/data/skills/rails-migrations/SKILL.md +268 -0
- agent_notes/data/skills/rails-models/SKILL.md +459 -0
- agent_notes/data/skills/rails-models-advanced/SKILL.md +398 -0
- agent_notes/data/skills/rails-routes/SKILL.md +804 -0
- agent_notes/data/skills/rails-style/SKILL.md +538 -0
- agent_notes/data/skills/rails-testing-controllers/SKILL.md +343 -0
- agent_notes/data/skills/rails-testing-models/SKILL.md +296 -0
- agent_notes/data/skills/rails-testing-system/SKILL.md +375 -0
- agent_notes/data/skills/rails-validations/SKILL.md +108 -0
- agent_notes/data/skills/rails-view-components/SKILL.md +511 -0
- agent_notes/data/skills/rails-view-components-advanced/SKILL.md +376 -0
- agent_notes/data/skills/rails-views/SKILL.md +413 -0
- agent_notes/data/skills/rails-views-advanced/SKILL.md +450 -0
- agent_notes/data/skills/refactoring-protocol/SKILL.md +64 -0
- agent_notes/data/skills/tdd/SKILL.md +57 -0
- agent_notes/data/templates/__init__.py +1 -0
- agent_notes/data/templates/__pycache__/__init__.cpython-314.pyc +0 -0
- agent_notes/data/templates/frontmatter/__init__.py +1 -0
- agent_notes/data/templates/frontmatter/__pycache__/__init__.cpython-314.pyc +0 -0
- agent_notes/data/templates/frontmatter/__pycache__/claude.cpython-314.pyc +0 -0
- agent_notes/data/templates/frontmatter/__pycache__/cursor.cpython-314.pyc +0 -0
- agent_notes/data/templates/frontmatter/__pycache__/opencode.cpython-314.pyc +0 -0
- agent_notes/data/templates/frontmatter/claude.py +44 -0
- agent_notes/data/templates/frontmatter/opencode.py +104 -0
- agent_notes/doctor_checks.py +189 -0
- agent_notes/domain/__init__.py +17 -0
- agent_notes/domain/agent.py +34 -0
- agent_notes/domain/cli_backend.py +40 -0
- agent_notes/domain/diagnostics.py +29 -0
- agent_notes/domain/diff.py +44 -0
- agent_notes/domain/model.py +27 -0
- agent_notes/domain/role.py +13 -0
- agent_notes/domain/rule.py +13 -0
- agent_notes/domain/skill.py +15 -0
- agent_notes/domain/state.py +46 -0
- agent_notes/install_state.py +11 -0
- agent_notes/registries/__init__.py +16 -0
- agent_notes/registries/_base.py +46 -0
- agent_notes/registries/agent_registry.py +107 -0
- agent_notes/registries/cli_registry.py +89 -0
- agent_notes/registries/model_registry.py +85 -0
- agent_notes/registries/role_registry.py +64 -0
- agent_notes/registries/rule_registry.py +80 -0
- agent_notes/registries/skill_registry.py +141 -0
- agent_notes/services/__init__.py +8 -0
- agent_notes/services/diagnostics/__init__.py +47 -0
- agent_notes/services/diagnostics/_checks.py +272 -0
- agent_notes/services/diagnostics/_display.py +346 -0
- agent_notes/services/diagnostics/_fix.py +169 -0
- agent_notes/services/diff.py +349 -0
- agent_notes/services/fs.py +195 -0
- agent_notes/services/install_state_builder.py +210 -0
- agent_notes/services/installer.py +293 -0
- agent_notes/services/memory_backend.py +155 -0
- agent_notes/services/rendering.py +329 -0
- agent_notes/services/session_context.py +23 -0
- agent_notes/services/settings_writer.py +79 -0
- agent_notes/services/state_store.py +249 -0
- agent_notes/services/ui.py +419 -0
- agent_notes/services/user_config.py +62 -0
- agent_notes/services/validation.py +67 -0
- agent_notes/state.py +21 -0
- agent_notes-2.0.4.dist-info/METADATA +14 -0
- agent_notes-2.0.4.dist-info/RECORD +162 -0
- agent_notes-2.0.4.dist-info/WHEEL +5 -0
- agent_notes-2.0.4.dist-info/entry_points.txt +2 -0
- agent_notes-2.0.4.dist-info/licenses/LICENSE +21 -0
- agent_notes-2.0.4.dist-info/top_level.txt +2 -0
- tests/conftest.py +20 -0
- tests/functional/__init__.py +0 -0
- tests/functional/test_build_commands.py +88 -0
- tests/functional/test_registries.py +128 -0
- tests/integration/__init__.py +0 -0
- tests/integration/test_build_output.py +129 -0
- tests/plugins/__init__.py +0 -0
- tests/plugins/test_agents.py +93 -0
- tests/plugins/test_skills.py +77 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Load and merge user config for agent role/model overrides and prompt patches."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional
|
|
5
|
+
import yaml
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def config_path() -> Path:
|
|
9
|
+
xdg = Path.home() / ".config" / "agent-notes" / "config.yaml"
|
|
10
|
+
legacy = Path.home() / ".agent-notes.yaml"
|
|
11
|
+
if xdg.exists():
|
|
12
|
+
return xdg
|
|
13
|
+
if legacy.exists():
|
|
14
|
+
return legacy
|
|
15
|
+
return xdg # canonical write location
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def load_user_config(path: Optional[Path] = None) -> dict:
|
|
19
|
+
"""Return user config dict. Empty dict if file missing."""
|
|
20
|
+
p = path or config_path()
|
|
21
|
+
if not p.exists():
|
|
22
|
+
return {}
|
|
23
|
+
try:
|
|
24
|
+
data = yaml.safe_load(p.read_text())
|
|
25
|
+
return data or {}
|
|
26
|
+
except yaml.YAMLError as e:
|
|
27
|
+
raise ValueError(f"Invalid YAML in {p}: {e}") from e
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def resolve_agent_role(agent_name: str, default_role: str, config: dict) -> str:
|
|
31
|
+
"""Return effective role, applying user override if present."""
|
|
32
|
+
return config.get("agent_roles", {}).get(agent_name, default_role)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def resolve_role_model(role: str, backend_name: str, config: dict) -> Optional[str]:
|
|
36
|
+
"""Return user-specified model ID for a role+backend, or None."""
|
|
37
|
+
return config.get("role_models", {}).get(backend_name, {}).get(role)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def get_patch(agent_name: str, config: dict) -> Optional[str]:
|
|
41
|
+
"""Return patch text to append to agent prompt, or None."""
|
|
42
|
+
return config.get("patches", {}).get(agent_name)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def merge_configs(base: dict, override: dict) -> dict:
|
|
46
|
+
"""Merge override on top of base. Nested dicts are merged; patches are concatenated."""
|
|
47
|
+
result = dict(base)
|
|
48
|
+
for key, value in override.items():
|
|
49
|
+
if key == "patches" and key in result:
|
|
50
|
+
# Concatenate patches from both configs
|
|
51
|
+
merged_patches = dict(result[key])
|
|
52
|
+
for agent, patch in value.items():
|
|
53
|
+
if agent in merged_patches:
|
|
54
|
+
merged_patches[agent] = merged_patches[agent].rstrip() + "\n\n" + patch
|
|
55
|
+
else:
|
|
56
|
+
merged_patches[agent] = patch
|
|
57
|
+
result[key] = merged_patches
|
|
58
|
+
elif isinstance(value, dict) and key in result and isinstance(result[key], dict):
|
|
59
|
+
result[key] = {**result[key], **value}
|
|
60
|
+
else:
|
|
61
|
+
result[key] = value
|
|
62
|
+
return result
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""Validation helpers used by commands/validate.py."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def has_field(file_path: Path, field: str) -> bool:
|
|
9
|
+
"""Check if file has frontmatter field."""
|
|
10
|
+
try:
|
|
11
|
+
content = file_path.read_text()
|
|
12
|
+
return f"{field}:" in content
|
|
13
|
+
except (FileNotFoundError, OSError):
|
|
14
|
+
return False
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def get_field(file_path: Path, field: str) -> Optional[str]:
|
|
18
|
+
"""Extract frontmatter field value."""
|
|
19
|
+
try:
|
|
20
|
+
content = file_path.read_text()
|
|
21
|
+
lines = content.split('\n')
|
|
22
|
+
|
|
23
|
+
in_frontmatter = False
|
|
24
|
+
for line in lines:
|
|
25
|
+
if line.strip() == "---":
|
|
26
|
+
if not in_frontmatter:
|
|
27
|
+
in_frontmatter = True
|
|
28
|
+
continue
|
|
29
|
+
else:
|
|
30
|
+
break # End of frontmatter
|
|
31
|
+
|
|
32
|
+
if in_frontmatter and line.startswith(f"{field}:"):
|
|
33
|
+
value = line.split(':', 1)[1].strip()
|
|
34
|
+
# Remove quotes
|
|
35
|
+
value = value.strip('"\'')
|
|
36
|
+
return value
|
|
37
|
+
|
|
38
|
+
return None
|
|
39
|
+
except (FileNotFoundError, OSError):
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def line_count(file_path: Path) -> int:
|
|
44
|
+
"""Count lines in file."""
|
|
45
|
+
try:
|
|
46
|
+
return len(file_path.read_text().split('\n'))
|
|
47
|
+
except (FileNotFoundError, OSError):
|
|
48
|
+
return 0
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def has_frontmatter(file_path: Path) -> bool:
|
|
52
|
+
"""Check if file starts with frontmatter."""
|
|
53
|
+
try:
|
|
54
|
+
content = file_path.read_text()
|
|
55
|
+
return content.startswith("---\n")
|
|
56
|
+
except (FileNotFoundError, OSError):
|
|
57
|
+
return False
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def check_unclosed_code_blocks(file_path: Path) -> bool:
|
|
61
|
+
"""Check for unclosed code blocks."""
|
|
62
|
+
try:
|
|
63
|
+
content = file_path.read_text()
|
|
64
|
+
fence_count = content.count('```')
|
|
65
|
+
return fence_count % 2 == 0 # Even number means all blocks are closed
|
|
66
|
+
except (FileNotFoundError, OSError):
|
|
67
|
+
return True
|
agent_notes/state.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Installation state management."""
|
|
2
|
+
|
|
3
|
+
# Re-export dataclasses from domain
|
|
4
|
+
from .domain.state import State, ScopeState, BackendState, InstalledItem # noqa: F401
|
|
5
|
+
|
|
6
|
+
# Re-export I/O functions from services
|
|
7
|
+
from .services.state_store import (
|
|
8
|
+
state_dir, state_file,
|
|
9
|
+
load_state as load, load_state, # Export both names
|
|
10
|
+
save_state as save, save_state, # Export both names
|
|
11
|
+
clear_state as clear,
|
|
12
|
+
get_scope, set_scope, remove_scope, default_state, sha256_of, now_iso
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
# Backward compatibility aliases
|
|
16
|
+
__all__ = [
|
|
17
|
+
'State', 'ScopeState', 'BackendState', 'InstalledItem',
|
|
18
|
+
'state_dir', 'state_file', 'load', 'save', 'clear',
|
|
19
|
+
'load_state', 'save_state', # Original names too
|
|
20
|
+
'get_scope', 'set_scope', 'remove_scope', 'default_state', 'sha256_of', 'now_iso'
|
|
21
|
+
]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agent-notes
|
|
3
|
+
Version: 2.0.4
|
|
4
|
+
Summary: AI agent configuration manager for Claude Code, OpenCode, and Copilot
|
|
5
|
+
Author: Eugene Naumov
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/rubakas/agent-notes
|
|
8
|
+
Project-URL: Repository, https://github.com/rubakas/agent-notes
|
|
9
|
+
Requires-Python: >=3.9
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: pyyaml>=6.0
|
|
12
|
+
Provides-Extra: dev
|
|
13
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
14
|
+
Dynamic: license-file
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
agent_notes/VERSION,sha256=E39GckECPa36YF2wDmMLJak5TQ_HIycYgSmDuiS5OUU,6
|
|
2
|
+
agent_notes/__init__.py,sha256=nNtT73D8u7W5AqsLodGp6jvsjT-y3kQ74pgToqrZeDw,53
|
|
3
|
+
agent_notes/__main__.py,sha256=EAOa_67LSqh5Jb9obGmEE9Aofyd5yv68mxLMmUGBwgE,88
|
|
4
|
+
agent_notes/cli.py,sha256=tjX1M6XUn-xhemFNdypsy6nOK50UazQA9rvRK7Y2O0U,14504
|
|
5
|
+
agent_notes/config.py,sha256=5wfeXtFy-x6SHwRa9FbfsR6GWWoiS7yihncz6jfCTCk,6414
|
|
6
|
+
agent_notes/doctor_checks.py,sha256=kk5zmpfdpS6A14JqyOuyVzz7_HHbFzRM3zZxCzRcvV8,9020
|
|
7
|
+
agent_notes/install_state.py,sha256=PLY3YePlIiFPaREN7YCeEvfSh8G5Q5beElAc_NRbz_k,486
|
|
8
|
+
agent_notes/state.py,sha256=-LQ045BC0-xBc4ltGzNHJFYwb_C3pvYe_RsIvlfen90,785
|
|
9
|
+
agent_notes/commands/__init__.py,sha256=vM4L4muUwH-VlsKz4CQIPvmIFB6zZdtwefJf9j78vBs,893
|
|
10
|
+
agent_notes/commands/_install_helpers.py,sha256=0ndUq957dzQtUkkfMmNNpVATwJDicKUQfe5xZ-Z5oGo,9625
|
|
11
|
+
agent_notes/commands/build.py,sha256=wAJlXM3n2UkAz84EXQbeGD4rMTZstr3wbV-VqssZzrk,5045
|
|
12
|
+
agent_notes/commands/doctor.py,sha256=4I72UQVQMsn8xKlF2lF6dZezwhGh6zW1oj2i7LNsYz8,3617
|
|
13
|
+
agent_notes/commands/info.py,sha256=mWczDJ6VkagBQkWGBdlFNURnDlxzch-Es911FLXzAvg,3662
|
|
14
|
+
agent_notes/commands/install.py,sha256=3GRqYz6qEIbmyJ8ifxCl_VFJO1ZGkGxVzLoECZrwYFo,3623
|
|
15
|
+
agent_notes/commands/list.py,sha256=7Qe22Cke6ME-u6crbMk0MTquzwUndwFufue8gNM74KU,5816
|
|
16
|
+
agent_notes/commands/memory.py,sha256=omJHHcXEA_whgbl8VgYQdMnFplnQ_DtnOp_6nWqx9pM,13867
|
|
17
|
+
agent_notes/commands/regenerate.py,sha256=jlpBvO3b3B_oZWdBJWOX5-bEpZYCO0RlbAF4qDb76vk,5547
|
|
18
|
+
agent_notes/commands/set_role.py,sha256=OPXKs5071qzO06uapLC8xqYei1M45iQCeS0kkzrPQVg,5389
|
|
19
|
+
agent_notes/commands/uninstall.py,sha256=6f2-ROmsGIFEpfLOyqBhnJQkWLlO0D1tUdnGNeK8nAA,752
|
|
20
|
+
agent_notes/commands/update.py,sha256=C2PwBqkmI80KNMvpuoKcDJSAb2cMYyFyQrI0DyFAvHs,5749
|
|
21
|
+
agent_notes/commands/validate.py,sha256=5YJoO9zez5zQd1y5IAJiiFiLR5D0PO4bBzewK8vdSaw,7104
|
|
22
|
+
agent_notes/commands/wizard.py,sha256=1zHhBdye8e2HjOe2ZFBcEVicJyxcMlbmGqzzORhRXks,30127
|
|
23
|
+
agent_notes/data/global-claude.md,sha256=5mXAvUHe7vnqeDRY2gJ5Ii-weps88GT6GOUbrSGxfBo,15319
|
|
24
|
+
agent_notes/data/global-copilot.md,sha256=a4mLfNZ10im7fHDrQe_bhBQ-5C_IX1lSh9jt2EwfSh8,936
|
|
25
|
+
agent_notes/data/global-opencode.md,sha256=4mAhdI6Hbf3t4YZCGPytGsILI2CSidtVszFr4rd3I8g,1697
|
|
26
|
+
agent_notes/data/pricing.yaml,sha256=_RdzC5tb6J_S_d6EuCzOOyXcxfstO46BBhHMr9Z2pkE,929
|
|
27
|
+
agent_notes/data/agents/agents.yaml,sha256=2fRprOudEgpUEfe5m7kA1V43TIiNgGb5yTosBKTcBHI,11346
|
|
28
|
+
agent_notes/data/agents/analyst.md,sha256=_W3Xw_rHsvWsP8-J722ce1kamkZWFYvNS-gqE5n4YRg,2252
|
|
29
|
+
agent_notes/data/agents/api-reviewer.md,sha256=_ZTKalS6_b1kK7KXqJtv5QRuWxnetamHKzJxbJiyhYs,1784
|
|
30
|
+
agent_notes/data/agents/architect.md,sha256=i_BWeMRwu4cgUAStzqH2vE6BeVMQGzrDMGT8jfg3Fuc,1449
|
|
31
|
+
agent_notes/data/agents/coder.md,sha256=SGi7_rA_9SwDmFYEYXdzSby_BpLlLh0yF8SalSJKbas,1187
|
|
32
|
+
agent_notes/data/agents/database-specialist.md,sha256=od5-eVycRuK1h5Hf2xHWTgwJH1V2Xevq0a8OvB7NkiE,2006
|
|
33
|
+
agent_notes/data/agents/debugger.md,sha256=7nVeAC6tqL9A11fmewDbhQMF50FZ-wCs06-KrHlNFso,1396
|
|
34
|
+
agent_notes/data/agents/devil.md,sha256=g8QkHMhXrk2qB9o6dgcAfYZEroxb1zIrAsEIT5GVzIo,1357
|
|
35
|
+
agent_notes/data/agents/devops.md,sha256=5Zf4iomnARBZfQEItRQwQJ79MVGTFYNLo_aYQelydzE,1513
|
|
36
|
+
agent_notes/data/agents/explorer.md,sha256=MGfuKzMCog_Q1j0a6d7rcjGP5R1h8jgiud40FfyvwkA,948
|
|
37
|
+
agent_notes/data/agents/integrations.md,sha256=3dptJxTG3WP0Q3yPoWtzjKs5Lif282q9CAyFpOp0fvM,1511
|
|
38
|
+
agent_notes/data/agents/lead.md,sha256=89vp1-pSwf3l4q7iWQ8mb286dEy9z-EzM2GGw1jIPiY,9786
|
|
39
|
+
agent_notes/data/agents/performance-profiler.md,sha256=GtohSPwTDUQrLA1sdXpCjVlX4NFRCFnocuW0o0qE1OY,1607
|
|
40
|
+
agent_notes/data/agents/refactorer.md,sha256=HEFEMrozgPZ0_QYmoEag9tHQ15fHk2rTeI0lYFTpsT4,1410
|
|
41
|
+
agent_notes/data/agents/reviewer.md,sha256=pY_Ogj0Rpi4o3FLw20eu3G7FT8nhw0edCSYnl6hQ1TI,1896
|
|
42
|
+
agent_notes/data/agents/security-auditor.md,sha256=BLXPPeoxh7s24SoTKv9IspFwN-WtZxFyCCEUTp9zZIY,2195
|
|
43
|
+
agent_notes/data/agents/system-auditor.md,sha256=otxLGjW7R9iHeKESExtV2sojBtS2MHMTfMVdq3T96mY,1284
|
|
44
|
+
agent_notes/data/agents/tech-writer.md,sha256=QSiCfus2q_gDO3w9WN7UK70MI1KJAwigqSHfhwDB2Ck,1686
|
|
45
|
+
agent_notes/data/agents/test-runner.md,sha256=5J4YXK48OF2aQfImYOabOCuFEHurSE4C44uYjcCtklA,1400
|
|
46
|
+
agent_notes/data/agents/test-writer.md,sha256=ThLLLrJTkCIWraEaPxh-4oKnVFhmFX-pnrYWS40lZEs,2048
|
|
47
|
+
agent_notes/data/cli/claude.yaml,sha256=ubWCU37SlFzpf4rMn7vDDcVvOS4NTwccCV6vYhA4e6g,521
|
|
48
|
+
agent_notes/data/cli/copilot.yaml,sha256=qBMev0yYIf_26mqwStjcf_zWEOPAoRCLf4rcqACD0ww,378
|
|
49
|
+
agent_notes/data/cli/opencode.yaml,sha256=UtKoknnua3c7Yr9QErVSOjee_hhcYM5b35-gPnpzSAA,516
|
|
50
|
+
agent_notes/data/commands/brainstorm.md,sha256=da0St-n9LKvI1IPddB8INI2N4_sIvX7NBWvTg78s3y8,379
|
|
51
|
+
agent_notes/data/commands/debug.md,sha256=pPAUBdaYV2eM6WG3JfkODp2g_yGgjjkU9F9QNu57nMs,461
|
|
52
|
+
agent_notes/data/commands/review.md,sha256=MRHI36lxRn7eVhRvDdWpQyDnpTmWMmgRhYC9DeKvnwY,510
|
|
53
|
+
agent_notes/data/hooks/session-context.md.tpl,sha256=y1rGR3WiIHRomulTT1CPLvitgPVDReRvQKiwjrJIflM,648
|
|
54
|
+
agent_notes/data/models/claude-haiku-4-5.yaml,sha256=zmaIU23bBqIWLlejGu3B2kkrPR6sB6YGJUTVtk-KrXo,277
|
|
55
|
+
agent_notes/data/models/claude-opus-4-1.yaml,sha256=Yi7oGZkRJkYVtFkJk_hTuzZTc0X4lv0VKx59MzZ_D0Q,303
|
|
56
|
+
agent_notes/data/models/claude-opus-4-5.yaml,sha256=Q9dy8nbA7xebCyxOB0TOLX-BtNMz677j-Afe6KOuCbs,302
|
|
57
|
+
agent_notes/data/models/claude-opus-4-6.yaml,sha256=GLrJhva6UKii26NWr1Hj3f5dY0vdA2pojUvlnm1_CGk,300
|
|
58
|
+
agent_notes/data/models/claude-opus-4-7.yaml,sha256=nYRI9AU41u34x-qbbTnxsLe8P5mzLoCypVnGyd6hlPM,272
|
|
59
|
+
agent_notes/data/models/claude-sonnet-4-5.yaml,sha256=GJrwD4O_dm7_2KpKFu5QThxOJ0x3hNflK2L4A-hubS8,312
|
|
60
|
+
agent_notes/data/models/claude-sonnet-4-6.yaml,sha256=N_Y2GJiGHhii9i1eekA2D6XRJOgYBo7zVyPLDCwd7Xg,283
|
|
61
|
+
agent_notes/data/models/claude-sonnet-4.yaml,sha256=bEDxxljgNAFF6B8xT579Oz366gJ_fyLRZfgb6NtAsUs,311
|
|
62
|
+
agent_notes/data/roles/orchestrator.yaml,sha256=0DnJv45m3Yb7wiA6FlLVWYBlzNIzemKxdH5o4c-nGPA,166
|
|
63
|
+
agent_notes/data/roles/reasoner.yaml,sha256=G82eJyuL1ny3ZHbuSrznDofZOMs1otggYTu0AnfoDP0,150
|
|
64
|
+
agent_notes/data/roles/scout.yaml,sha256=lpQn0CJ5cRljuBlLyIMAhXKdJu0Cf-eRWTx_ejF3czE,135
|
|
65
|
+
agent_notes/data/roles/worker.yaml,sha256=r4LxfECkFpV2bdsCCCZXo_edoqChR-xubDJLRUwsXT0,143
|
|
66
|
+
agent_notes/data/rules/code-quality.md,sha256=CX4UIVWCny4gv7pWAX45dfj9L2eabdCc-RhSwhB5ZOU,483
|
|
67
|
+
agent_notes/data/rules/safety.md,sha256=I9HGLlVpP3dcDDS6jXqloXcgW8-IVJMyl8V_tbamkj8,559
|
|
68
|
+
agent_notes/data/scripts/cost-report,sha256=TLO_D1u8SlRXISEWZggLTWhDE9SX58d09yKV5kua3fk,6918
|
|
69
|
+
agent_notes/data/skills/brainstorming/SKILL.md,sha256=d2-zf-zrY6vzDCj5Z1Bv4TG16IM0ZpxUDGKBUrKBb7Y,2282
|
|
70
|
+
agent_notes/data/skills/code-review/SKILL.md,sha256=nvNX2d4yGXe3ZV12TyhQconDVcTwG9cHd8jKADeVIng,2362
|
|
71
|
+
agent_notes/data/skills/debugging-protocol/SKILL.md,sha256=cNY8_69juFgAg8Kxc2bj97zqfFWxJXgVsoJzCMmmQSM,2106
|
|
72
|
+
agent_notes/data/skills/docker-compose/SKILL.md,sha256=FxVR5qvIkJYBTRwEDW3Ag7cy5YzhRycaXCuN1J_ViKc,7886
|
|
73
|
+
agent_notes/data/skills/docker-compose-advanced/SKILL.md,sha256=WfbfcX7wcudPwATAbMn5zjU0DtoI3t2ZP4SXNmB6udM,12587
|
|
74
|
+
agent_notes/data/skills/docker-dockerfile/SKILL.md,sha256=n5GcRZsiwBdMO69d6IxrqJoTAEMqVgGgaPuNNgs0Lmw,10205
|
|
75
|
+
agent_notes/data/skills/docker-dockerfile-languages/SKILL.md,sha256=EqOqq2Pe-ceU8ZDVOyZiYjf4DRLV-KiMtrn9qtTW59M,6515
|
|
76
|
+
agent_notes/data/skills/git/SKILL.md,sha256=OT3b-2TzwmCRYAhYzAFTSqzbh7PnfOiihSH_Z4y1SR8,1944
|
|
77
|
+
agent_notes/data/skills/rails-active-storage/SKILL.md,sha256=SKkp67EVRUGuKq1sqh_orIiUAeQtex2o1WAfL-3m9Lc,6963
|
|
78
|
+
agent_notes/data/skills/rails-broadcasting/SKILL.md,sha256=8JbPrSZ8rDZ658Gz2b534uPXScfkkKspBnOHkifJDok,7667
|
|
79
|
+
agent_notes/data/skills/rails-concerns/SKILL.md,sha256=4yQCdU8Gy0yYPCkUNIF96UUGZEhj4I2_5aL8ZrM673M,16165
|
|
80
|
+
agent_notes/data/skills/rails-controllers/SKILL.md,sha256=xwqcXlntzrnD6VZsVFo06OU91XDFpHCnLp07jXjTieA,11293
|
|
81
|
+
agent_notes/data/skills/rails-controllers-advanced/SKILL.md,sha256=5OXgdhnWyd5rclZn21xb-DnRR3Tr64I-DMxsp6r803E,8728
|
|
82
|
+
agent_notes/data/skills/rails-helpers/SKILL.md,sha256=3TEooNjzujQJOnYhnLtuha1JGbXN3pyl8e2i_QkOcc8,16349
|
|
83
|
+
agent_notes/data/skills/rails-initializers/SKILL.md,sha256=YcwmpTv1lQ9Kuwe__p49bV3Khc3BbM52VeisinYyJFE,1572
|
|
84
|
+
agent_notes/data/skills/rails-javascript/SKILL.md,sha256=EtSVLbo2Ux-dTFIb3JjPk5lwVwpw1t4KwicyCjX5g8s,12173
|
|
85
|
+
agent_notes/data/skills/rails-jobs/SKILL.md,sha256=Fi9ucRWFZ-_HvBKOJxDB4Z9RHxT4UppzyFHtoJxbX3A,13559
|
|
86
|
+
agent_notes/data/skills/rails-kamal/SKILL.md,sha256=HBRspZ1tX6KL5oAj6THdZgjCX-UFN9V11pZvUfZQnuY,7732
|
|
87
|
+
agent_notes/data/skills/rails-lib/SKILL.md,sha256=cAJhQ9Wp48twlfPqscWiWt3m5MO4fbwyOalOKI5Yxg4,1952
|
|
88
|
+
agent_notes/data/skills/rails-mailers/SKILL.md,sha256=aUNJWgIfX4yH5if1pJXYto4vlQvR6oEZtVukoWVg8AA,5922
|
|
89
|
+
agent_notes/data/skills/rails-migrations/SKILL.md,sha256=wbE7QPjknk-nKET-pdIRg33wnPz9PNStOVsbiI0T7eg,4773
|
|
90
|
+
agent_notes/data/skills/rails-models/SKILL.md,sha256=hmejzvAUmzMGl1aDlO8yxQqXdbu2LtD0TJnzCJ3K0gY,11025
|
|
91
|
+
agent_notes/data/skills/rails-models-advanced/SKILL.md,sha256=8MoGewmt29GB3ykzdivfPuLj6qjZWKjztzfxIY0KhFQ,7745
|
|
92
|
+
agent_notes/data/skills/rails-routes/SKILL.md,sha256=udfFxBk-exQlIMXYEnJ2zy4GH5wlUsFX-K0SQ0Z4-e0,15682
|
|
93
|
+
agent_notes/data/skills/rails-style/SKILL.md,sha256=jibISwJ67aTuyBKm-nGt1t8vk_mQL9Frof3sJjDzbx0,10867
|
|
94
|
+
agent_notes/data/skills/rails-testing-controllers/SKILL.md,sha256=Y8dcGFRkwqW00JdsDWrCepca2yQCIU6T5GbZ16Y6Cyc,6640
|
|
95
|
+
agent_notes/data/skills/rails-testing-models/SKILL.md,sha256=Y2RYjeef2p4e5iDrvtfyRSJc03T3Us3aZ776sksu6Vo,6055
|
|
96
|
+
agent_notes/data/skills/rails-testing-system/SKILL.md,sha256=V3dU55_2i4a2oT6Qir7_EqvRYPJ9ExDh2RAuiMdnPEA,7204
|
|
97
|
+
agent_notes/data/skills/rails-validations/SKILL.md,sha256=Wo0MHxidY4gtrYd__BimS_FBsMy5-jj5KPiDhW9PUlo,2063
|
|
98
|
+
agent_notes/data/skills/rails-view-components/SKILL.md,sha256=PT5jdMYE0q9AhdCVHM14coacxDgxJxJw73ISITdig2U,10971
|
|
99
|
+
agent_notes/data/skills/rails-view-components-advanced/SKILL.md,sha256=DxaaP69Jaif7-TxghPc4LzByWAO4ANHgeftbBk5MP9s,8019
|
|
100
|
+
agent_notes/data/skills/rails-views/SKILL.md,sha256=VwBwB3OXUGawiwaqH4PeH67R58fSWB1UxdtTPR6wloE,8583
|
|
101
|
+
agent_notes/data/skills/rails-views-advanced/SKILL.md,sha256=wnRPv_3K0xghfQXsCtjhMuYHisxXhFS5ilBRCqYtBko,9045
|
|
102
|
+
agent_notes/data/skills/refactoring-protocol/SKILL.md,sha256=Wy0jGMk3vYfX0Di6rpmrwrXKHx-yV559viWJg-mLdxw,3065
|
|
103
|
+
agent_notes/data/skills/tdd/SKILL.md,sha256=DsYGXDS1rz-RARqV2NlVmeHngdbcJ8hhHy3dAjYPQ-Q,2106
|
|
104
|
+
agent_notes/data/templates/__init__.py,sha256=NpGBytOwk_ywSOqKt9Ub-SSUNkDYR2uez4UVbOAEwUM,41
|
|
105
|
+
agent_notes/data/templates/__pycache__/__init__.cpython-314.pyc,sha256=3aE_8ZRVK3HmgW1q41V4WDbJ_MLA6ktGBTXyROI5fkI,223
|
|
106
|
+
agent_notes/data/templates/frontmatter/__init__.py,sha256=SlCC0jmmvVxtEE4T8zC3vjPOB3UK6Vjkpy3SjWesD_s,52
|
|
107
|
+
agent_notes/data/templates/frontmatter/claude.py,sha256=8UlcD85cu7kSeEaxSNNtPBX9zGGf6Jkk8og-DRYpQDQ,1448
|
|
108
|
+
agent_notes/data/templates/frontmatter/opencode.py,sha256=mHxmuKcZXki5OOcsOcKgnRD_Ap6ze2IzNUE25NIKoLY,3285
|
|
109
|
+
agent_notes/data/templates/frontmatter/__pycache__/__init__.cpython-314.pyc,sha256=7YF0z6DTZZGVXL4GuYvZZiY7HOO_YvKyvF5_1i6tx6s,246
|
|
110
|
+
agent_notes/data/templates/frontmatter/__pycache__/claude.cpython-314.pyc,sha256=XKpeqMYF7ZLuv_UnzPo5fE0BPjBDPvMWzQrPSTcCrvw,2397
|
|
111
|
+
agent_notes/data/templates/frontmatter/__pycache__/cursor.cpython-314.pyc,sha256=wfizKrb9TbPALC-er2yN-7zt6u6GWJAcRvd6Pvd0nxA,1787
|
|
112
|
+
agent_notes/data/templates/frontmatter/__pycache__/opencode.cpython-314.pyc,sha256=LpJ3yY1UT32D-6KcY6PkKHwAjjyhBDpkmpn5Q5vOB1k,4590
|
|
113
|
+
agent_notes/domain/__init__.py,sha256=Z0JSvaeG6XFKVDSt5mpsXEEMiy7fBExoy1Fbfgr4J_Y,664
|
|
114
|
+
agent_notes/domain/agent.py,sha256=M9uTvcCo0aduiJhhWv0D7OxuXYKm4aXP8QLhAvS0BRg,1435
|
|
115
|
+
agent_notes/domain/cli_backend.py,sha256=0E_msddRNB6JHvWzTn7aeLAyVmrFnnaOgk5Xxufzlg4,1706
|
|
116
|
+
agent_notes/domain/diagnostics.py,sha256=5UKQvXKivbXkbV4XPGx_TsschRt8-LX3QUO50p-FeD4,739
|
|
117
|
+
agent_notes/domain/diff.py,sha256=1RDmH06bqf_nXqwqbMjq6FrSQYb-LgfXs51OsA4mPUw,1774
|
|
118
|
+
agent_notes/domain/model.py,sha256=Mh5c4jad01HB6jk2MLNSIl-rKpY3uMvDM1owizPUn_4,1183
|
|
119
|
+
agent_notes/domain/role.py,sha256=opLIvu_MluR6GGwr-7yQvlHv1isK2FaFOeC8e3vF86o,263
|
|
120
|
+
agent_notes/domain/rule.py,sha256=h_yLYPBESwMfW3An2fOGSMhTrkjMfn7Gkfx433eJzpE,314
|
|
121
|
+
agent_notes/domain/skill.py,sha256=NNjakUWhcTnn95ZeNfFH_4LFtEl43Wcfw5mvEECEhQw,468
|
|
122
|
+
agent_notes/domain/state.py,sha256=0HnfzJWK82NCkok__82CvId-YthyZi0dNav8G47YcQE,1462
|
|
123
|
+
agent_notes/registries/__init__.py,sha256=3ck4jz8YgqaQBSSfKUkcwrM8Me0_6JvL-_RHvm8iCFw,994
|
|
124
|
+
agent_notes/registries/_base.py,sha256=HDVf-fzwQj-JkqrflIYwX0y2_rv7axrWziczayvxEZc,1611
|
|
125
|
+
agent_notes/registries/agent_registry.py,sha256=eU3ipCOd1LyTAKJFXz7ErmMKMIvLK2uL-bTKmBHw8Wo,3891
|
|
126
|
+
agent_notes/registries/cli_registry.py,sha256=EKHYyQYLLhgc8idSqEZ9IwSWthTqfeMzjqV84DLjTCY,3017
|
|
127
|
+
agent_notes/registries/model_registry.py,sha256=n81nc8IbvHUY_EwjzAYiUFLr3K7dftcjIXJFDLfoQOs,2911
|
|
128
|
+
agent_notes/registries/role_registry.py,sha256=KQvlETHkyYaOlTtS5snKVlL35friMc_gloG4YU-kVQ0,2004
|
|
129
|
+
agent_notes/registries/rule_registry.py,sha256=s81gSHu-hOL5tlq_TeUdIvK_if5wefZktTRXqGCygOY,2252
|
|
130
|
+
agent_notes/registries/skill_registry.py,sha256=w6DVRDebb4IO1s1CX4C8pUMYj6w7fo5Ifh1kSSKUqi4,4487
|
|
131
|
+
agent_notes/services/__init__.py,sha256=yRCXbPVjtkWJZrjmLLKcilHPwHDW7vO5JTeRRbrgd_8,547
|
|
132
|
+
agent_notes/services/diff.py,sha256=XYL3p-8OtdSaUn-ApKNYcmatpzt_tk60gQtMUbEKP60,13913
|
|
133
|
+
agent_notes/services/fs.py,sha256=2qWKCI_W5iitSvKnYk96jbgwdYEsCC39d3pvyS-5-Jw,5839
|
|
134
|
+
agent_notes/services/install_state_builder.py,sha256=8MIbrwnlNb7DGoUFfwKa5lq1afTUOi6kEt67SSkdcZE,8583
|
|
135
|
+
agent_notes/services/installer.py,sha256=gfBMOONcdhDY22F2o7i0m1-DzlbmZz51L5mQ7Ibd04A,10629
|
|
136
|
+
agent_notes/services/memory_backend.py,sha256=OAyZrg1YF7PeHoLH3oG2C9_MogzbErvtt7MAdNzIYGs,5351
|
|
137
|
+
agent_notes/services/rendering.py,sha256=9f7mxXVET7Bep-5Erz8YTVWyayxYGuUnMX5o9YdEw0g,14474
|
|
138
|
+
agent_notes/services/session_context.py,sha256=CEx3dVQ3KlELqURQfj627-UB85ejk8W9xdrEj5LXYrE,815
|
|
139
|
+
agent_notes/services/settings_writer.py,sha256=T6_WetwXWBMq367ARhcp9nYwKX9ogm_Oq4u7fZFFRpY,2620
|
|
140
|
+
agent_notes/services/state_store.py,sha256=E0KHyVCES6uyeGte8bN-zmExtIsV8wcWiHtZdqtXPPg,8062
|
|
141
|
+
agent_notes/services/ui.py,sha256=C6SbUCd3LpPgqwMtUJGwc0Vpwn3Qn8eA_DL0l-c4yn8,13430
|
|
142
|
+
agent_notes/services/user_config.py,sha256=9dD14EkpqdZud26RLpzZOHSdrDLp0j_10rfOu8Z3kUo,2317
|
|
143
|
+
agent_notes/services/validation.py,sha256=9Aru7NiCYU2yKnxY6ROY2q_xAU6sqA4Cnz50OBtwdx4,1947
|
|
144
|
+
agent_notes/services/diagnostics/__init__.py,sha256=oELb_SHuWnqVKBT8IxxyUraRCw9cp89czNuYobTdeIc,980
|
|
145
|
+
agent_notes/services/diagnostics/_checks.py,sha256=16T5JjHt0zRXRyfq3JctdzTr38Rqb2IuD3Vll3rxECY,11931
|
|
146
|
+
agent_notes/services/diagnostics/_display.py,sha256=9VYfVXYDat4isYgRJdJ76ytQ4N1PgpAQ2U09PmZ21sg,13640
|
|
147
|
+
agent_notes/services/diagnostics/_fix.py,sha256=byYGhbBxHs6P8VUKtH0-L5QdzrmSDw8sTKyBMG3tNaY,7519
|
|
148
|
+
agent_notes-2.0.4.dist-info/licenses/LICENSE,sha256=-zkfoVV5cCbXHNJK0qnSSSCvw7hqEIOZ-0yARp5XLrE,1064
|
|
149
|
+
tests/conftest.py,sha256=Ewhhi4cQc7iat4vU1xXCc7Eyuwhle9oZbmyJVKKAGPU,535
|
|
150
|
+
tests/functional/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
151
|
+
tests/functional/test_build_commands.py,sha256=SO9tJHS1vY1VYXaQrzHFzE7ddfJXWAsFXydI-vc_k4U,3051
|
|
152
|
+
tests/functional/test_registries.py,sha256=nc1DLBD5THTY2wvXQZoXYRNfipODPBV_vJ74_KMCKOw,3551
|
|
153
|
+
tests/integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
154
|
+
tests/integration/test_build_output.py,sha256=ufl7ak-NGFiv7HCfBxPnaN61CiQVTu3-dM1U30jP8fw,3611
|
|
155
|
+
tests/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
156
|
+
tests/plugins/test_agents.py,sha256=ITPHZWansWgVXph-ZBM3sFndtjVFfjHPf7XWVbHNTcc,3258
|
|
157
|
+
tests/plugins/test_skills.py,sha256=C5D2fWGsYkS26v1hQ0-g_0WpGxSlVieBZw9oHEhfk1U,2774
|
|
158
|
+
agent_notes-2.0.4.dist-info/METADATA,sha256=eqaiGVy84D0pAYmfy28p0oHBozFQPOZbm_vFrPgjM9c,463
|
|
159
|
+
agent_notes-2.0.4.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
160
|
+
agent_notes-2.0.4.dist-info/entry_points.txt,sha256=bIfdJBqQoatEtDipiruWiSyHudtnSr4VxUAMJaRJ878,53
|
|
161
|
+
agent_notes-2.0.4.dist-info/top_level.txt,sha256=owterz4f7Vvxrodr57ouqQZ3ejcA-L91LnNmkgcktbI,18
|
|
162
|
+
agent_notes-2.0.4.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 rubakas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
tests/conftest.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Shared test fixtures."""
|
|
2
|
+
import subprocess
|
|
3
|
+
import pytest
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from agent_notes.config import ROOT, DIST_DIR
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.fixture(scope="session")
|
|
10
|
+
def built_dist():
|
|
11
|
+
"""Run the build once per session; skip all dependents if it fails."""
|
|
12
|
+
result = subprocess.run(
|
|
13
|
+
["python3", "-m", "agent_notes", "build"],
|
|
14
|
+
cwd=ROOT,
|
|
15
|
+
capture_output=True,
|
|
16
|
+
text=True,
|
|
17
|
+
)
|
|
18
|
+
if result.returncode != 0:
|
|
19
|
+
pytest.skip(f"Build failed:\n{result.stdout}\n{result.stderr}")
|
|
20
|
+
return DIST_DIR
|
|
File without changes
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""Tests for individual build command functions in isolation."""
|
|
2
|
+
import importlib
|
|
3
|
+
import json
|
|
4
|
+
import pytest
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from unittest.mock import patch
|
|
7
|
+
|
|
8
|
+
# Must use importlib because agent_notes.commands exports a `build` function
|
|
9
|
+
# at package level, shadowing the submodule when accessed via attribute lookup.
|
|
10
|
+
_build_mod = importlib.import_module("agent_notes.commands.build")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_copy_scripts_replaces_pricing_placeholder(tmp_path):
|
|
14
|
+
"""copy_scripts() should replace {{PRICING}} with JSON from pricing.yaml."""
|
|
15
|
+
scripts_src = tmp_path / "scripts"
|
|
16
|
+
scripts_dst = tmp_path / "dist_scripts"
|
|
17
|
+
scripts_src.mkdir()
|
|
18
|
+
|
|
19
|
+
# Write a script file with the placeholder
|
|
20
|
+
script_file = scripts_src / "cost-report"
|
|
21
|
+
script_file.write_text("#!/usr/bin/env python3\nPRICING = {{PRICING}}\n")
|
|
22
|
+
|
|
23
|
+
import agent_notes.config as config_mod
|
|
24
|
+
|
|
25
|
+
with patch.object(config_mod, "SCRIPTS_DIR", scripts_src), \
|
|
26
|
+
patch.object(config_mod, "DIST_SCRIPTS_DIR", scripts_dst):
|
|
27
|
+
copied = _build_mod.copy_scripts()
|
|
28
|
+
|
|
29
|
+
assert len(copied) == 1
|
|
30
|
+
content = copied[0].read_text()
|
|
31
|
+
assert "{{PRICING}}" not in content
|
|
32
|
+
assert '"providers"' in content
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_copy_scripts_result_is_executable(tmp_path):
|
|
36
|
+
"""copy_scripts() should make output files executable."""
|
|
37
|
+
import stat
|
|
38
|
+
scripts_src = tmp_path / "scripts"
|
|
39
|
+
scripts_dst = tmp_path / "dist_scripts"
|
|
40
|
+
scripts_src.mkdir()
|
|
41
|
+
|
|
42
|
+
(scripts_src / "my-script").write_text("#!/bin/sh\necho hi\n")
|
|
43
|
+
|
|
44
|
+
import agent_notes.config as config_mod
|
|
45
|
+
|
|
46
|
+
with patch.object(config_mod, "SCRIPTS_DIR", scripts_src), \
|
|
47
|
+
patch.object(config_mod, "DIST_SCRIPTS_DIR", scripts_dst):
|
|
48
|
+
copied = _build_mod.copy_scripts()
|
|
49
|
+
|
|
50
|
+
assert len(copied) == 1
|
|
51
|
+
mode = copied[0].stat().st_mode
|
|
52
|
+
assert mode & stat.S_IXUSR
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_copy_skills_copies_all_skill_dirs(tmp_path):
|
|
56
|
+
"""copy_skills() should copy every skill directory to dist/skills/."""
|
|
57
|
+
skills_src = tmp_path / "skills"
|
|
58
|
+
skill_a = skills_src / "alpha"
|
|
59
|
+
skill_b = skills_src / "beta"
|
|
60
|
+
skill_a.mkdir(parents=True)
|
|
61
|
+
skill_b.mkdir(parents=True)
|
|
62
|
+
(skill_a / "SKILL.md").write_text("---\nname: alpha\n---\n")
|
|
63
|
+
(skill_b / "SKILL.md").write_text("---\nname: beta\n---\n")
|
|
64
|
+
|
|
65
|
+
dist_dir = tmp_path / "dist"
|
|
66
|
+
dist_dir.mkdir()
|
|
67
|
+
|
|
68
|
+
import agent_notes.config as config_mod
|
|
69
|
+
|
|
70
|
+
def fake_find_skill_dirs():
|
|
71
|
+
return sorted(d for d in skills_src.iterdir() if d.is_dir() and (d / "SKILL.md").exists())
|
|
72
|
+
|
|
73
|
+
with patch.object(_build_mod, "DIST_DIR", dist_dir), \
|
|
74
|
+
patch.object(config_mod, "find_skill_dirs", fake_find_skill_dirs):
|
|
75
|
+
copied = _build_mod.copy_skills()
|
|
76
|
+
|
|
77
|
+
assert len(copied) == 2
|
|
78
|
+
names = {p.name for p in copied}
|
|
79
|
+
assert "alpha" in names
|
|
80
|
+
assert "beta" in names
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def test_copy_global_files_returns_list_of_paths(tmp_path):
|
|
84
|
+
"""copy_global_files() should return a list of Path objects without error."""
|
|
85
|
+
result = _build_mod.copy_global_files()
|
|
86
|
+
assert isinstance(result, list)
|
|
87
|
+
for item in result:
|
|
88
|
+
assert isinstance(item, Path)
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""Tests that all 4 registries load correctly from their source files."""
|
|
2
|
+
import pytest
|
|
3
|
+
|
|
4
|
+
from agent_notes.registries.model_registry import load_model_registry
|
|
5
|
+
from agent_notes.registries.role_registry import load_role_registry
|
|
6
|
+
from agent_notes.registries.skill_registry import load_skill_registry
|
|
7
|
+
from agent_notes.registries.agent_registry import load_agent_registry
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# --- Model registry ---
|
|
11
|
+
|
|
12
|
+
def test_model_registry_loads():
|
|
13
|
+
registry = load_model_registry()
|
|
14
|
+
assert len(registry.all()) >= 8
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_model_registry_includes_opus():
|
|
18
|
+
registry = load_model_registry()
|
|
19
|
+
ids = registry.ids()
|
|
20
|
+
assert "claude-opus-4-7" in ids
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_model_registry_includes_sonnet():
|
|
24
|
+
registry = load_model_registry()
|
|
25
|
+
ids = registry.ids()
|
|
26
|
+
assert "claude-sonnet-4-6" in ids
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_model_registry_includes_haiku():
|
|
30
|
+
registry = load_model_registry()
|
|
31
|
+
ids = registry.ids()
|
|
32
|
+
assert "claude-haiku-4-5" in ids
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_model_has_required_fields():
|
|
36
|
+
registry = load_model_registry()
|
|
37
|
+
for model in registry.all():
|
|
38
|
+
assert model.id, f"Model missing id"
|
|
39
|
+
assert model.label, f"Model {model.id} missing label"
|
|
40
|
+
assert model.family, f"Model {model.id} missing family"
|
|
41
|
+
assert model.model_class, f"Model {model.id} missing model_class"
|
|
42
|
+
assert model.aliases is not None, f"Model {model.id} missing aliases"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# --- Role registry ---
|
|
46
|
+
|
|
47
|
+
def test_role_registry_loads():
|
|
48
|
+
registry = load_role_registry()
|
|
49
|
+
assert len(registry.all()) >= 3
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_role_registry_has_orchestrator():
|
|
53
|
+
registry = load_role_registry()
|
|
54
|
+
names = registry.names()
|
|
55
|
+
assert "orchestrator" in names
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_role_registry_has_worker():
|
|
59
|
+
registry = load_role_registry()
|
|
60
|
+
names = registry.names()
|
|
61
|
+
assert "worker" in names
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def test_role_registry_has_scout():
|
|
65
|
+
registry = load_role_registry()
|
|
66
|
+
names = registry.names()
|
|
67
|
+
assert "scout" in names
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_role_has_required_fields():
|
|
71
|
+
registry = load_role_registry()
|
|
72
|
+
for role in registry.all():
|
|
73
|
+
assert role.name, f"Role missing name"
|
|
74
|
+
assert role.label, f"Role {role.name} missing label"
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# --- Skill registry ---
|
|
78
|
+
|
|
79
|
+
def test_skill_registry_loads():
|
|
80
|
+
registry = load_skill_registry()
|
|
81
|
+
assert len(registry.all()) >= 30
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_skill_registry_includes_git():
|
|
85
|
+
registry = load_skill_registry()
|
|
86
|
+
assert "git" in registry.names()
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def test_skill_registry_includes_brainstorming():
|
|
90
|
+
registry = load_skill_registry()
|
|
91
|
+
assert "brainstorming" in registry.names()
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def test_skill_has_required_fields():
|
|
95
|
+
registry = load_skill_registry()
|
|
96
|
+
for skill in registry.all():
|
|
97
|
+
assert skill.name, f"Skill missing name"
|
|
98
|
+
assert skill.description, f"Skill {skill.name} missing description"
|
|
99
|
+
assert skill.group, f"Skill {skill.name} missing group"
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
# --- Agent registry ---
|
|
103
|
+
|
|
104
|
+
def test_agent_registry_loads():
|
|
105
|
+
registry = load_agent_registry()
|
|
106
|
+
assert len(registry.all()) >= 15
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def test_agent_registry_includes_coder():
|
|
110
|
+
registry = load_agent_registry()
|
|
111
|
+
assert "coder" in registry.names()
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def test_agent_registry_includes_reviewer():
|
|
115
|
+
registry = load_agent_registry()
|
|
116
|
+
assert "reviewer" in registry.names()
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def test_agent_registry_includes_explorer():
|
|
120
|
+
registry = load_agent_registry()
|
|
121
|
+
assert "explorer" in registry.names()
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def test_agent_has_required_fields():
|
|
125
|
+
registry = load_agent_registry()
|
|
126
|
+
for agent in registry.all():
|
|
127
|
+
assert agent.name, f"Agent missing name (id)"
|
|
128
|
+
assert agent.description, f"Agent {agent.name} missing description"
|
|
File without changes
|