devhive 0.1.37__tar.gz → 0.1.40__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.
- {devhive-0.1.37/devhive.egg-info → devhive-0.1.40}/PKG-INFO +1 -1
- {devhive-0.1.37 → devhive-0.1.40/devhive.egg-info}/PKG-INFO +1 -1
- {devhive-0.1.37 → devhive-0.1.40}/devhive.egg-info/SOURCES.txt +2 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/main.py +95 -14
- devhive-0.1.40/devhive_cli/memory.py +358 -0
- devhive-0.1.40/devhive_cli/skills/devhive_analyzer/SKILL.md +151 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_architect/SKILL.md +9 -1
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_auditor/SKILL.md +9 -1
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_backender/SKILL.md +9 -1
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_explorer/SKILL.md +8 -1
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_frontender/SKILL.md +9 -1
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_orchestrator/SKILL.md +22 -18
- devhive-0.1.40/devhive_cli/skills/devhive_reflection/SKILL.md +91 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_taskplanner/SKILL.md +8 -1
- {devhive-0.1.37 → devhive-0.1.40}/setup.py +1 -1
- devhive-0.1.37/devhive_cli/skills/devhive_reflection/SKILL.md +0 -37
- {devhive-0.1.37 → devhive-0.1.40}/LICENSE +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/MANIFEST.in +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/README.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive.egg-info/dependency_links.txt +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive.egg-info/entry_points.txt +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive.egg-info/requires.txt +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive.egg-info/top_level.txt +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/__init__.py +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/agents/devhive.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/architecture-patterns/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/architecture-patterns/resources/implementation-playbook.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/backend-arthitect/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/backend-security-coder/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/docker-expert/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/frontend-design/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/frontend-developer/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/theme-showcase.pdf +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/arctic-frost.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/botanical-garden.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/desert-rose.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/forest-canopy.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/golden-hour.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/midnight-galaxy.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/modern-minimalist.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/ocean-depths.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/sunset-boulevard.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/tech-innovation.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_dba/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_designer/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_devops/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_perf/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_prd/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_proposal/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_qa/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_releaser/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_sast/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_techwriter/SKILL.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/skills/devhive_workflow.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/templates/AGENTS.backend.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/templates/AGENTS.frontend.md +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/devhive_cli/templates_backend.py +0 -0
- {devhive-0.1.37 → devhive-0.1.40}/setup.cfg +0 -0
|
@@ -10,6 +10,7 @@ devhive.egg-info/requires.txt
|
|
|
10
10
|
devhive.egg-info/top_level.txt
|
|
11
11
|
devhive_cli/__init__.py
|
|
12
12
|
devhive_cli/main.py
|
|
13
|
+
devhive_cli/memory.py
|
|
13
14
|
devhive_cli/templates_backend.py
|
|
14
15
|
devhive_cli/agents/devhive.md
|
|
15
16
|
devhive_cli/community_skills/architecture-patterns/SKILL.md
|
|
@@ -32,6 +33,7 @@ devhive_cli/community_skills/theme-factory/themes/ocean-depths.md
|
|
|
32
33
|
devhive_cli/community_skills/theme-factory/themes/sunset-boulevard.md
|
|
33
34
|
devhive_cli/community_skills/theme-factory/themes/tech-innovation.md
|
|
34
35
|
devhive_cli/skills/devhive_workflow.md
|
|
36
|
+
devhive_cli/skills/devhive_analyzer/SKILL.md
|
|
35
37
|
devhive_cli/skills/devhive_architect/SKILL.md
|
|
36
38
|
devhive_cli/skills/devhive_auditor/SKILL.md
|
|
37
39
|
devhive_cli/skills/devhive_backender/SKILL.md
|
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import shutil
|
|
3
|
+
import subprocess
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import click
|
|
6
|
+
from devhive_cli.templates_backend import generate_backend_agents_md
|
|
7
|
+
from devhive_cli.memory import MemoryCLI, get_memory_cli, ensure_memory_dir
|
|
8
|
+
|
|
9
|
+
# Paths configuration
|
|
10
|
+
CLI_DIR = Path(__file__).resolve().parent
|
|
11
|
+
LOCAL_SKILLS_DIR = CLI_DIR / "skills"
|
|
12
|
+
COMMUNITY_SKILLS_DIR = CLI_DIR / "community_skills"
|
|
13
|
+
TEMPLATES_DIR = CLI_DIR / "templates"
|
|
14
|
+
LOCAL_AGENTS_DIR = CLI_DIR / "agents"
|
|
15
|
+
TARGET_DIR = Path.home() / ".config" / "opencode" / "skills"
|
|
16
|
+
TARGET_AGENTS_DIR = Path.home() / ".config" / "opencode" / "agents"
|
|
3
17
|
|
|
4
18
|
ZERO_TOUCH_POLICY = """# 🛑 SYSTEM DIRECTIVE: ZERO-TOUCH POLICY (DevHive Enforcement)
|
|
5
19
|
**CRITICAL INSTRUCTION FOR ALL AI AGENTS:**
|
|
@@ -47,20 +61,6 @@ def handle_existing_agents_md(dest_path: Path) -> bool:
|
|
|
47
61
|
click.secho("Aborted.", fg="yellow")
|
|
48
62
|
return False
|
|
49
63
|
|
|
50
|
-
import subprocess
|
|
51
|
-
from pathlib import Path
|
|
52
|
-
import click
|
|
53
|
-
from devhive_cli.templates_backend import generate_backend_agents_md
|
|
54
|
-
|
|
55
|
-
# Paths configuration
|
|
56
|
-
CLI_DIR = Path(__file__).resolve().parent
|
|
57
|
-
LOCAL_SKILLS_DIR = CLI_DIR / "skills"
|
|
58
|
-
COMMUNITY_SKILLS_DIR = CLI_DIR / "community_skills"
|
|
59
|
-
TEMPLATES_DIR = CLI_DIR / "templates"
|
|
60
|
-
LOCAL_AGENTS_DIR = CLI_DIR / "agents"
|
|
61
|
-
TARGET_DIR = Path.home() / ".config" / "opencode" / "skills"
|
|
62
|
-
TARGET_AGENTS_DIR = Path.home() / ".config" / "opencode" / "agents"
|
|
63
|
-
|
|
64
64
|
@click.group()
|
|
65
65
|
def cli():
|
|
66
66
|
"""DevHive CLI for managing AI agent skills."""
|
|
@@ -191,5 +191,86 @@ def init_backend():
|
|
|
191
191
|
|
|
192
192
|
click.secho("✅ Successfully created AGENTS.md with Hexagonal Architecture guidelines!", fg="green", bold=True)
|
|
193
193
|
|
|
194
|
+
|
|
195
|
+
@cli.group()
|
|
196
|
+
def memory():
|
|
197
|
+
"""Manage DevHive persistent memory."""
|
|
198
|
+
pass
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
@memory.command()
|
|
202
|
+
def list():
|
|
203
|
+
"""List all memory entries."""
|
|
204
|
+
cli_instance = get_memory_cli()
|
|
205
|
+
cli_instance.list_entries()
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@memory.command()
|
|
209
|
+
def show():
|
|
210
|
+
"""Show all entries of a specific memory type."""
|
|
211
|
+
click.echo("Available types: semantic, episodic, anti_patterns")
|
|
212
|
+
entry_type = click.prompt("Memory type", type=click.Choice(['semantic', 'episodic', 'anti_patterns']))
|
|
213
|
+
cli_instance = get_memory_cli()
|
|
214
|
+
cli_instance.list_entries(entry_type)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
@memory.command()
|
|
218
|
+
@click.argument("query")
|
|
219
|
+
@click.option("--type", "entry_type", default=None, help="Filter by type (semantic, episodic, anti_patterns)")
|
|
220
|
+
def search(query, entry_type):
|
|
221
|
+
"""Search memory entries by query."""
|
|
222
|
+
cli_instance = get_memory_cli()
|
|
223
|
+
cli_instance.search_entries(query, entry_type)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
@memory.command()
|
|
227
|
+
@click.argument("entry_id")
|
|
228
|
+
def info(entry_id):
|
|
229
|
+
"""Show detailed info for a memory entry."""
|
|
230
|
+
cli_instance = get_memory_cli()
|
|
231
|
+
cli_instance.show_entry(entry_id)
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
@memory.command()
|
|
235
|
+
@click.argument("entry_id")
|
|
236
|
+
def delete(entry_id):
|
|
237
|
+
"""Delete a memory entry by ID."""
|
|
238
|
+
cli_instance = get_memory_cli()
|
|
239
|
+
if click.confirm(f"Delete entry '{entry_id}'?"):
|
|
240
|
+
cli_instance.delete_entry(entry_id)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
@memory.command()
|
|
244
|
+
def stats():
|
|
245
|
+
"""Show memory statistics."""
|
|
246
|
+
cli_instance = get_memory_cli()
|
|
247
|
+
cli_instance.show_stats()
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
@memory.command()
|
|
251
|
+
@click.option("--type", "entry_type", default=None, help="Export specific type")
|
|
252
|
+
@click.option("--output", "-o", "output_file", default=None, help="Output file path")
|
|
253
|
+
def export(entry_type, output_file):
|
|
254
|
+
"""Export memory entries to JSON."""
|
|
255
|
+
cli_instance = get_memory_cli()
|
|
256
|
+
cli_instance.export_memory(entry_type, output_file)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
@memory.command()
|
|
260
|
+
@click.argument("input_file")
|
|
261
|
+
def import_mem(input_file):
|
|
262
|
+
"""Import memory entries from JSON file."""
|
|
263
|
+
cli_instance = get_memory_cli()
|
|
264
|
+
cli_instance.import_memory(input_file)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
@memory.command()
|
|
268
|
+
@click.option("--threshold", default=0.5, help="Score threshold for garbage collection")
|
|
269
|
+
def gc(threshold):
|
|
270
|
+
"""Garbage collect memory entries below threshold."""
|
|
271
|
+
cli_instance = get_memory_cli()
|
|
272
|
+
cli_instance.garbage_collect(float(threshold))
|
|
273
|
+
|
|
274
|
+
|
|
194
275
|
if __name__ == "__main__":
|
|
195
276
|
cli()
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
import uuid
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from typing import Optional, List, Dict, Any
|
|
8
|
+
|
|
9
|
+
MEMORY_DIR = ".devhive/memory"
|
|
10
|
+
INDEX_FILE = f"{MEMORY_DIR}/index.json"
|
|
11
|
+
SEMANTIC_FILE = f"{MEMORY_DIR}/semantic.md"
|
|
12
|
+
EPISODIC_FILE = f"{MEMORY_DIR}/episodic.md"
|
|
13
|
+
ANTIPATTERNS_FILE = f"{MEMORY_DIR}/anti_patterns.md"
|
|
14
|
+
|
|
15
|
+
MEMORY_TYPES = ["semantic", "episodic", "anti_patterns"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class MemoryEntry:
|
|
19
|
+
def __init__(self, entry_id: str, entry_type: str, summary: str, tags: List[str],
|
|
20
|
+
source: str, score: float, project: str, created_at: str, line_ref: str = ""):
|
|
21
|
+
self.id = entry_id
|
|
22
|
+
self.type = entry_type
|
|
23
|
+
self.summary = summary
|
|
24
|
+
self.tags = tags
|
|
25
|
+
self.source = source
|
|
26
|
+
self.score = score
|
|
27
|
+
self.project = project
|
|
28
|
+
self.created_at = created_at
|
|
29
|
+
self.line_ref = line_ref
|
|
30
|
+
|
|
31
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
32
|
+
return {
|
|
33
|
+
"id": self.id,
|
|
34
|
+
"type": self.type,
|
|
35
|
+
"summary": self.summary,
|
|
36
|
+
"tags": self.tags,
|
|
37
|
+
"source": self.source,
|
|
38
|
+
"score": self.score,
|
|
39
|
+
"project": self.project,
|
|
40
|
+
"created_at": self.created_at,
|
|
41
|
+
"line_ref": self.line_ref
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@classmethod
|
|
45
|
+
def from_dict(cls, data: Dict[str, Any]) -> "MemoryEntry":
|
|
46
|
+
return cls(
|
|
47
|
+
entry_id=data["id"],
|
|
48
|
+
entry_type=data["type"],
|
|
49
|
+
summary=data["summary"],
|
|
50
|
+
tags=data.get("tags", []),
|
|
51
|
+
source=data.get("source", "unknown"),
|
|
52
|
+
score=data.get("score", 0.5),
|
|
53
|
+
project=data.get("project", ""),
|
|
54
|
+
created_at=data.get("created_at", ""),
|
|
55
|
+
line_ref=data.get("line_ref", "")
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class MemoryIndex:
|
|
60
|
+
def __init__(self, memory_dir: str = MEMORY_DIR):
|
|
61
|
+
self.memory_dir = Path(memory_dir)
|
|
62
|
+
self.index_path = self.memory_dir / "index.json"
|
|
63
|
+
self.entries: List[MemoryEntry] = []
|
|
64
|
+
self._load_index()
|
|
65
|
+
|
|
66
|
+
def _load_index(self):
|
|
67
|
+
if self.index_path.exists():
|
|
68
|
+
with open(self.index_path, "r", encoding="utf-8") as f:
|
|
69
|
+
data = json.load(f)
|
|
70
|
+
self.entries = [MemoryEntry.from_dict(e) for e in data.get("entries", [])]
|
|
71
|
+
else:
|
|
72
|
+
self.entries = []
|
|
73
|
+
|
|
74
|
+
def _save_index(self):
|
|
75
|
+
self.memory_dir.mkdir(parents=True, exist_ok=True)
|
|
76
|
+
data = {
|
|
77
|
+
"version": "1.0",
|
|
78
|
+
"last_updated": datetime.now().isoformat(),
|
|
79
|
+
"entries": [e.to_dict() for e in self.entries]
|
|
80
|
+
}
|
|
81
|
+
with open(self.index_path, "w", encoding="utf-8") as f:
|
|
82
|
+
json.dump(data, f, indent=2, ensure_ascii=False)
|
|
83
|
+
|
|
84
|
+
def _generate_id(self, entry_type: str) -> str:
|
|
85
|
+
prefix = entry_type[:3]
|
|
86
|
+
existing = [e.id for e in self.entries if e.id.startswith(prefix)]
|
|
87
|
+
counter = len(existing) + 1
|
|
88
|
+
return f"{prefix}-{counter:03d}"
|
|
89
|
+
|
|
90
|
+
def _get_file_path(self, entry_type: str) -> Path:
|
|
91
|
+
type_to_file = {
|
|
92
|
+
"semantic": self.memory_dir / "semantic.md",
|
|
93
|
+
"episodic": self.memory_dir / "episodic.md",
|
|
94
|
+
"anti_patterns": self.memory_dir / "anti_patterns.md"
|
|
95
|
+
}
|
|
96
|
+
return type_to_file.get(entry_type, self.memory_dir / "semantic.md")
|
|
97
|
+
|
|
98
|
+
def add_entry(self, entry_type: str, summary: str, tags: List[str] = None,
|
|
99
|
+
source: str = "reflection", score: float = 0.7, project: str = "") -> MemoryEntry:
|
|
100
|
+
if entry_type not in MEMORY_TYPES:
|
|
101
|
+
raise ValueError(f"Invalid type. Must be one of: {MEMORY_TYPES}")
|
|
102
|
+
|
|
103
|
+
entry_id = self._generate_id(entry_type)
|
|
104
|
+
created_at = datetime.now().strftime("%Y-%m-%d")
|
|
105
|
+
|
|
106
|
+
entry = MemoryEntry(
|
|
107
|
+
entry_id=entry_id,
|
|
108
|
+
entry_type=entry_type,
|
|
109
|
+
summary=summary,
|
|
110
|
+
tags=tags or [],
|
|
111
|
+
source=source,
|
|
112
|
+
score=score,
|
|
113
|
+
project=project,
|
|
114
|
+
created_at=created_at,
|
|
115
|
+
line_ref=""
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
self.entries.append(entry)
|
|
119
|
+
self._save_index()
|
|
120
|
+
|
|
121
|
+
file_path = self._get_file_path(entry_type)
|
|
122
|
+
self.memory_dir.mkdir(parents=True, exist_ok=True)
|
|
123
|
+
|
|
124
|
+
with open(file_path, "a", encoding="utf-8") as f:
|
|
125
|
+
f.write(f"\n<!-- id: {entry_id} -->\n")
|
|
126
|
+
f.write(f"- **{entry.type.capitalize()}**: {summary}\n")
|
|
127
|
+
|
|
128
|
+
for i, e in enumerate(self.entries):
|
|
129
|
+
if e.id == entry_id:
|
|
130
|
+
e.line_ref = f"{entry_type}.md:new"
|
|
131
|
+
break
|
|
132
|
+
|
|
133
|
+
self._save_index()
|
|
134
|
+
return entry
|
|
135
|
+
|
|
136
|
+
def get_by_type(self, entry_type: str) -> List[MemoryEntry]:
|
|
137
|
+
return [e for e in self.entries if e.type == entry_type]
|
|
138
|
+
|
|
139
|
+
def get_by_id(self, entry_id: str) -> Optional[MemoryEntry]:
|
|
140
|
+
for e in self.entries:
|
|
141
|
+
if e.id == entry_id:
|
|
142
|
+
return e
|
|
143
|
+
return None
|
|
144
|
+
|
|
145
|
+
def search(self, query: str, entry_type: str = None) -> List[MemoryEntry]:
|
|
146
|
+
query_lower = query.lower()
|
|
147
|
+
results = []
|
|
148
|
+
|
|
149
|
+
for e in self.entries:
|
|
150
|
+
if entry_type and e.type != entry_type:
|
|
151
|
+
continue
|
|
152
|
+
|
|
153
|
+
if (query_lower in e.summary.lower() or
|
|
154
|
+
query_lower in " ".join(e.tags).lower() or
|
|
155
|
+
query_lower in e.source.lower()):
|
|
156
|
+
results.append(e)
|
|
157
|
+
|
|
158
|
+
return results
|
|
159
|
+
|
|
160
|
+
def update_entry(self, entry_id: str, summary: str = None, tags: List[str] = None,
|
|
161
|
+
score: float = None) -> Optional[MemoryEntry]:
|
|
162
|
+
for e in self.entries:
|
|
163
|
+
if e.id == entry_id:
|
|
164
|
+
if summary is not None:
|
|
165
|
+
e.summary = summary
|
|
166
|
+
if tags is not None:
|
|
167
|
+
e.tags = tags
|
|
168
|
+
if score is not None:
|
|
169
|
+
e.score = score
|
|
170
|
+
|
|
171
|
+
self._save_index()
|
|
172
|
+
|
|
173
|
+
file_path = self._get_file_path(e.type)
|
|
174
|
+
if file_path.exists():
|
|
175
|
+
content = file_path.read_text(encoding="utf-8")
|
|
176
|
+
old_line = f"<!-- id: {entry_id} -->"
|
|
177
|
+
new_line = f"<!-- id: {entry_id} -->"
|
|
178
|
+
if old_line in content:
|
|
179
|
+
content = content.replace(old_line, new_line)
|
|
180
|
+
|
|
181
|
+
lines = content.split("\n")
|
|
182
|
+
for i, line in enumerate(lines):
|
|
183
|
+
if old_line in line:
|
|
184
|
+
pass
|
|
185
|
+
|
|
186
|
+
with open(file_path, "w", encoding="utf-8") as f:
|
|
187
|
+
f.write(content)
|
|
188
|
+
|
|
189
|
+
return e
|
|
190
|
+
return None
|
|
191
|
+
|
|
192
|
+
def delete_entry(self, entry_id: str) -> bool:
|
|
193
|
+
for i, e in enumerate(self.entries):
|
|
194
|
+
if e.id == entry_id:
|
|
195
|
+
del self.entries[i]
|
|
196
|
+
self._save_index()
|
|
197
|
+
return True
|
|
198
|
+
return False
|
|
199
|
+
|
|
200
|
+
def garbage_collect(self, threshold: float = 0.5) -> List[str]:
|
|
201
|
+
deleted_ids = []
|
|
202
|
+
for e in self.entries[:]:
|
|
203
|
+
if e.score < threshold:
|
|
204
|
+
deleted_ids.append(e.id)
|
|
205
|
+
self.entries.remove(e)
|
|
206
|
+
self._save_index()
|
|
207
|
+
return deleted_ids
|
|
208
|
+
|
|
209
|
+
def export_to_json(self, entry_type: str = None) -> str:
|
|
210
|
+
entries = self.entries
|
|
211
|
+
if entry_type:
|
|
212
|
+
entries = [e for e in entries if e.type == entry_type]
|
|
213
|
+
|
|
214
|
+
data = {
|
|
215
|
+
"version": "1.0",
|
|
216
|
+
"exported_at": datetime.now().isoformat(),
|
|
217
|
+
"count": len(entries),
|
|
218
|
+
"entries": [e.to_dict() for e in entries]
|
|
219
|
+
}
|
|
220
|
+
return json.dumps(data, indent=2, ensure_ascii=False)
|
|
221
|
+
|
|
222
|
+
def import_from_json(self, json_str: str) -> int:
|
|
223
|
+
data = json.loads(json_str)
|
|
224
|
+
imported = 0
|
|
225
|
+
|
|
226
|
+
for e_data in data.get("entries", []):
|
|
227
|
+
existing = self.get_by_id(e_data["id"])
|
|
228
|
+
if not existing:
|
|
229
|
+
entry = MemoryEntry.from_dict(e_data)
|
|
230
|
+
self.entries.append(entry)
|
|
231
|
+
imported += 1
|
|
232
|
+
|
|
233
|
+
self._save_index()
|
|
234
|
+
return imported
|
|
235
|
+
|
|
236
|
+
def get_stats(self) -> Dict[str, Any]:
|
|
237
|
+
by_type = {t: [] for t in MEMORY_TYPES}
|
|
238
|
+
for e in self.entries:
|
|
239
|
+
if e.type in by_type:
|
|
240
|
+
by_type[e.type].append(e)
|
|
241
|
+
|
|
242
|
+
return {
|
|
243
|
+
"total": len(self.entries),
|
|
244
|
+
"by_type": {t: len(by_type[t]) for t in MEMORY_TYPES},
|
|
245
|
+
"avg_score": sum(e.score for e in self.entries) / len(self.entries) if self.entries else 0,
|
|
246
|
+
"tags": list(set(tag for e in self.entries for tag in e.tags)),
|
|
247
|
+
"sources": list(set(e.source for e in self.entries))
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
class MemoryCLI:
|
|
252
|
+
def __init__(self, memory_dir: str = MEMORY_DIR):
|
|
253
|
+
self.index = MemoryIndex(memory_dir)
|
|
254
|
+
|
|
255
|
+
def list_entries(self, entry_type: str = None):
|
|
256
|
+
if entry_type:
|
|
257
|
+
entries = self.index.get_by_type(entry_type)
|
|
258
|
+
else:
|
|
259
|
+
entries = self.index.entries
|
|
260
|
+
|
|
261
|
+
if not entries:
|
|
262
|
+
print("No memories found.")
|
|
263
|
+
return
|
|
264
|
+
|
|
265
|
+
print(f"\n{'ID':<12} {'TYPE':<12} {'SCORE':<6} {'SUMMARY':<50} {'TAGS'}")
|
|
266
|
+
print("-" * 120)
|
|
267
|
+
for e in entries:
|
|
268
|
+
tags_str = ", ".join(e.tags[:3]) if e.tags else "-"
|
|
269
|
+
summary = e.summary[:47] + "..." if len(e.summary) > 50 else e.summary
|
|
270
|
+
print(f"{e.id:<12} {e.type:<12} {e.score:.2f} {summary:<50} [{tags_str}]")
|
|
271
|
+
|
|
272
|
+
def show_entry(self, entry_id: str):
|
|
273
|
+
entry = self.index.get_by_id(entry_id)
|
|
274
|
+
if not entry:
|
|
275
|
+
print(f"Entry '{entry_id}' not found.")
|
|
276
|
+
return
|
|
277
|
+
|
|
278
|
+
print(f"\n{'='*60}")
|
|
279
|
+
print(f"ID: {entry.id}")
|
|
280
|
+
print(f"Type: {entry.type}")
|
|
281
|
+
print(f"Score: {entry.score}")
|
|
282
|
+
print(f"Tags: {', '.join(entry.tags) if entry.tags else 'None'}")
|
|
283
|
+
print(f"Source: {entry.source}")
|
|
284
|
+
print(f"Project: {entry.project}")
|
|
285
|
+
print(f"Created: {entry.created_at}")
|
|
286
|
+
print(f"{'='*60}")
|
|
287
|
+
print(f"\nSummary:\n{entry.summary}")
|
|
288
|
+
|
|
289
|
+
def search_entries(self, query: str, entry_type: str = None):
|
|
290
|
+
results = self.index.search(query, entry_type)
|
|
291
|
+
if not results:
|
|
292
|
+
print(f"No results found for: '{query}'")
|
|
293
|
+
return
|
|
294
|
+
|
|
295
|
+
print(f"\nFound {len(results)} result(s) for: '{query}'")
|
|
296
|
+
print(f"{'ID':<12} {'TYPE':<12} {'SCORE':<6} {'SUMMARY'}")
|
|
297
|
+
print("-" * 100)
|
|
298
|
+
for e in results:
|
|
299
|
+
summary = e.summary[:60] + "..." if len(e.summary) > 60 else e.summary
|
|
300
|
+
print(f"{e.id:<12} {e.type:<12} {e.score:.2f} {summary}")
|
|
301
|
+
|
|
302
|
+
def edit_entry(self, entry_id: str, summary: str = None, tags: str = None, score: float = None):
|
|
303
|
+
tag_list = [t.strip() for t in tags.split(",")] if tags else None
|
|
304
|
+
entry = self.index.update_entry(entry_id, summary, tag_list, score)
|
|
305
|
+
if entry:
|
|
306
|
+
print(f"Updated entry: {entry_id}")
|
|
307
|
+
else:
|
|
308
|
+
print(f"Entry '{entry_id}' not found.")
|
|
309
|
+
|
|
310
|
+
def delete_entry(self, entry_id: str):
|
|
311
|
+
if self.index.delete_entry(entry_id):
|
|
312
|
+
print(f"Deleted entry: {entry_id}")
|
|
313
|
+
else:
|
|
314
|
+
print(f"Entry '{entry_id}' not found.")
|
|
315
|
+
|
|
316
|
+
def export_memory(self, entry_type: str = None, output_file: str = None):
|
|
317
|
+
json_data = self.index.export_to_json(entry_type)
|
|
318
|
+
if output_file:
|
|
319
|
+
with open(output_file, "w", encoding="utf-8") as f:
|
|
320
|
+
f.write(json_data)
|
|
321
|
+
print(f"Exported to: {output_file}")
|
|
322
|
+
else:
|
|
323
|
+
print(json_data)
|
|
324
|
+
|
|
325
|
+
def import_memory(self, input_file: str):
|
|
326
|
+
with open(input_file, "r", encoding="utf-8") as f:
|
|
327
|
+
json_data = f.read()
|
|
328
|
+
count = self.index.import_from_json(json_data)
|
|
329
|
+
print(f"Imported {count} entries.")
|
|
330
|
+
|
|
331
|
+
def show_stats(self):
|
|
332
|
+
stats = self.index.get_stats()
|
|
333
|
+
print("\n" + "=" * 40)
|
|
334
|
+
print("MEMORY STATISTICS")
|
|
335
|
+
print("=" * 40)
|
|
336
|
+
print(f"Total Entries: {stats['total']}")
|
|
337
|
+
print(f" - Semantic: {stats['by_type'].get('semantic', 0)}")
|
|
338
|
+
print(f" - Episodic: {stats['by_type'].get('episodic', 0)}")
|
|
339
|
+
print(f" - Anti-patterns: {stats['by_type'].get('anti_patterns', 0)}")
|
|
340
|
+
print(f"Average Score: {stats['avg_score']:.2f}")
|
|
341
|
+
print(f"Unique Tags: {len(stats['tags'])}")
|
|
342
|
+
print(f"Sources: {', '.join(stats['sources'][:5]) if stats['sources'] else 'None'}")
|
|
343
|
+
print("=" * 40)
|
|
344
|
+
|
|
345
|
+
def garbage_collect(self, threshold: float = 0.5):
|
|
346
|
+
deleted = self.index.garbage_collect(threshold)
|
|
347
|
+
if deleted:
|
|
348
|
+
print(f"Deleted {len(deleted)} entries: {', '.join(deleted)}")
|
|
349
|
+
else:
|
|
350
|
+
print(f"No entries below threshold {threshold}")
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def get_memory_cli() -> MemoryCLI:
|
|
354
|
+
return MemoryCLI()
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
def ensure_memory_dir():
|
|
358
|
+
Path(MEMORY_DIR).mkdir(parents=True, exist_ok=True)
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: devhive-analyzer
|
|
3
|
+
description: Pre-orchestrator skill that analyzes project structure, detects tech stack, and proposes memory entries from AGENTS.md and codebase.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# DevHive Analyzer Skill
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
You are the DevHive Analyzer - a pre-orchestrator skill that runs before the SDD pipeline begins. Your job is to analyze the existing project structure, extract knowledge from AGENTS.md and codebase, and propose memory entries for user approval.
|
|
10
|
+
|
|
11
|
+
## Trigger
|
|
12
|
+
This skill runs as **Phase 0** when:
|
|
13
|
+
- No `.devhive/specs/` directory exists (first time DevHive is used on this project)
|
|
14
|
+
- No `.devhive/memory/index.json` exists (no prior memory)
|
|
15
|
+
- OR when the user explicitly invokes `@devhive analyze-project`
|
|
16
|
+
|
|
17
|
+
## Input Context
|
|
18
|
+
You will receive the current working directory and any user context. You should analyze:
|
|
19
|
+
- AGENTS.md (if exists) - contains project rules and conventions
|
|
20
|
+
- GUIDELINES.md (if exists) - contains documented stack
|
|
21
|
+
- Project structure and code files
|
|
22
|
+
|
|
23
|
+
## Playbook (What to Do)
|
|
24
|
+
|
|
25
|
+
### Step 1: Detect Project State
|
|
26
|
+
Check if this is a project that DevHive has analyzed before:
|
|
27
|
+
1. Check if `.devhive/memory/index.json` exists
|
|
28
|
+
2. If it exists and has entries, skip analysis (memory already exists)
|
|
29
|
+
3. If no memory exists, proceed with analysis
|
|
30
|
+
|
|
31
|
+
### Step 2: Analyze Key Files
|
|
32
|
+
Use `glob` and `read` tools to find and analyze:
|
|
33
|
+
|
|
34
|
+
**Priority 1 - Documentation:**
|
|
35
|
+
- `AGENTS.md` - Extract rules, conventions, stack definitions
|
|
36
|
+
- `GUIDELINES.md` - Extract documented stack and architecture
|
|
37
|
+
|
|
38
|
+
**Priority 2 - Package Managers:**
|
|
39
|
+
- `package.json` - Node.js ecosystem (React, Next.js, NestJS, etc.)
|
|
40
|
+
- `requirements.txt`, `setup.py`, `pyproject.toml` - Python ecosystem
|
|
41
|
+
- `go.mod` - Go ecosystem
|
|
42
|
+
- `Cargo.toml` - Rust ecosystem
|
|
43
|
+
|
|
44
|
+
**Priority 3 - Infrastructure:**
|
|
45
|
+
- `Dockerfile`, `docker-compose*.yml` - Containerization
|
|
46
|
+
- `terraform/*.tf`, `cdk.json`, `serverless.yml` - IaC tools
|
|
47
|
+
- `.github/workflows/*.yml` - CI/CD
|
|
48
|
+
|
|
49
|
+
**Priority 4 - Architecture Patterns:**
|
|
50
|
+
- Scan directory structure for patterns:
|
|
51
|
+
- `src/`, `lib/` - Library structure
|
|
52
|
+
- `features/`, `domain/`, `application/` - Hexagonal/Clean
|
|
53
|
+
- `controllers/`, `services/`, `models/` - MVC
|
|
54
|
+
- `pages/`, `components/` - Frontend structure
|
|
55
|
+
|
|
56
|
+
### Step 3: Detect Code Patterns
|
|
57
|
+
Use `grep` to detect frameworks from imports:
|
|
58
|
+
- `from fastapi import` → FastAPI (Python)
|
|
59
|
+
- `from flask import` → Flask (Python)
|
|
60
|
+
- `from django` → Django (Python)
|
|
61
|
+
- `"use client"`, `"use server"` → Next.js
|
|
62
|
+
- `useState`, `useEffect` → React hooks
|
|
63
|
+
- `createSlice` → Redux Toolkit
|
|
64
|
+
- `@Component()` → Angular
|
|
65
|
+
- `interface Props` + `React.FC` → React TypeScript
|
|
66
|
+
|
|
67
|
+
### Step 4: Generate Memory Proposals
|
|
68
|
+
Create proposed memory entries organized by type:
|
|
69
|
+
|
|
70
|
+
**From AGENTS.md → Semantic Memories:**
|
|
71
|
+
Extract explicit rules like:
|
|
72
|
+
- "Use Hexagonal Architecture" → semantic with tags ["architecture", "hexagonal"]
|
|
73
|
+
- "API responses follow {success, data, error}" → semantic with tags ["api", "convention"]
|
|
74
|
+
- "Use shadcn/ui components" → semantic with tags ["frontend", "shadcn", "ui"]
|
|
75
|
+
|
|
76
|
+
**From Code Detection → Semantic Memories:**
|
|
77
|
+
- Stack detection (FastAPI, Next.js, etc.)
|
|
78
|
+
- Architecture patterns (feature-based, hexagonal, etc.)
|
|
79
|
+
- Database/ORM patterns
|
|
80
|
+
|
|
81
|
+
**From Code Detection → Anti-patterns:**
|
|
82
|
+
- No `jest.config.js` or `pytest.ini` → "Project lacks automated tests"
|
|
83
|
+
- No TypeScript config → "Project uses JavaScript without type safety"
|
|
84
|
+
|
|
85
|
+
### Step 5: Present to User
|
|
86
|
+
Output a clear summary:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
🔍 DevHive Analyzer: First-time project detected
|
|
90
|
+
|
|
91
|
+
Sources Found:
|
|
92
|
+
✓ AGENTS.md (N conventions extracted)
|
|
93
|
+
✓ package.json (dependencies found)
|
|
94
|
+
✓ Directory structure analyzed
|
|
95
|
+
|
|
96
|
+
Tech Stack Detected:
|
|
97
|
+
- Frontend: [framework]
|
|
98
|
+
- Backend: [framework]
|
|
99
|
+
- Database: [db/orm]
|
|
100
|
+
- IaC: [tool]
|
|
101
|
+
|
|
102
|
+
Proposed Memory Entries (N):
|
|
103
|
+
[1] sem-001: [summary] [tags]
|
|
104
|
+
[2] sem-002: [summary] [tags]
|
|
105
|
+
...
|
|
106
|
+
|
|
107
|
+
[Y] Approve all | [n] Skip all | [e] Edit
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Step 6: Handle User Response
|
|
111
|
+
- **Approve (Y)**: Write all proposed memories to `.devhive/memory/`
|
|
112
|
+
- **Skip (n)**: Skip memory creation, continue to orchestrator
|
|
113
|
+
- **Edit (e)**: Allow user to modify/add/delete proposals before saving
|
|
114
|
+
|
|
115
|
+
### Step 7: Write Memories and Continue
|
|
116
|
+
After approval:
|
|
117
|
+
1. Create `.devhive/memory/` directory
|
|
118
|
+
2. Create `index.json` with proper structure
|
|
119
|
+
3. Write memories to `semantic.md`, `episodic.md`, `anti_patterns.md` with ID comments
|
|
120
|
+
4. Optionally create/enhance `GUIDELINES.md` with detected stack
|
|
121
|
+
5. Return control to orchestrator
|
|
122
|
+
|
|
123
|
+
## Output
|
|
124
|
+
- `.devhive/memory/index.json` - Memory index with all entries
|
|
125
|
+
- `.devhive/memory/semantic.md` - Semantic memories
|
|
126
|
+
- `.devhive/memory/anti_patterns.md` - Anti-pattern memories (if any)
|
|
127
|
+
- Optionally updated `GUIDELINES.md`
|
|
128
|
+
- Control passed to `devhive-orchestrator`
|
|
129
|
+
|
|
130
|
+
## Memory Entry Format
|
|
131
|
+
Each proposed entry should have:
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"id": "sem-001",
|
|
135
|
+
"type": "semantic",
|
|
136
|
+
"summary": "Clear description of the memory",
|
|
137
|
+
"tags": ["relevant", "tags"],
|
|
138
|
+
"source": "analyzer",
|
|
139
|
+
"score": 0.8,
|
|
140
|
+
"project": "",
|
|
141
|
+
"created_at": "YYYY-MM-DD",
|
|
142
|
+
"line_ref": ""
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Important Rules
|
|
147
|
+
1. **Don't auto-create memories** - Always present proposals to user first
|
|
148
|
+
2. **Prioritize AGENTS.md** - It contains explicit rules, higher confidence
|
|
149
|
+
3. **Use high thresholds** - Only propose high-confidence detections (score >= 0.7)
|
|
150
|
+
4. **Be concise** - Focus on actionable, project-specific memories
|
|
151
|
+
5. **Deduplicate** - Don't propose memories that already exist (check index.json if present)
|
|
@@ -9,7 +9,15 @@ description: Designs the technical architecture, components, data models, and in
|
|
|
9
9
|
When the orchestrator assigns you the architecture phase after the proposal is complete.
|
|
10
10
|
|
|
11
11
|
## Input Context
|
|
12
|
-
Read `.devhive/specs/01-exploration.md` and `.devhive/specs/02-proposal.md`. You MUST also check for and read `.devhive/memory/
|
|
12
|
+
Read `.devhive/specs/01-exploration.md` and `.devhive/specs/02-proposal.md`. You MUST also check for and read `.devhive/memory/index.json` and `.devhive/memory/semantic.md`, `.devhive/memory/anti_patterns.md` to ensure your design does not violate historical architectural decisions or repeat past mistakes.
|
|
13
|
+
|
|
14
|
+
## Memory Access
|
|
15
|
+
To search memory efficiently:
|
|
16
|
+
1. First read `.devhive/memory/index.json` to see all memory entries
|
|
17
|
+
2. Filter by tags relevant to your task (e.g., "architecture", "backend", "database", "security")
|
|
18
|
+
3. Read only the specific memory files you need (don't load everything)
|
|
19
|
+
4. Prioritize memories with score >= 0.7 for critical decisions
|
|
20
|
+
5. Check for "architecture" and "convention" tagged memories to ensure design consistency
|
|
13
21
|
|
|
14
22
|
## Playbook (What to Do)
|
|
15
23
|
0. **Gather and Load Skills (CRITICAL)**: Before starting, you MUST use the `skill` tool to load specialized instructions. Check `GUIDELINES.md` for global skills, check `04-tasks.md` for task-specific skills, and ALWAYS load your hardcoded skills: `architecture-patterns`, `backend-architect`. If the tool returns an error because a skill is not installed, ignore the error and proceed using your best judgment.
|
|
@@ -9,7 +9,15 @@ description: Verifies project consistency, architecture adherence, and security.
|
|
|
9
9
|
When the orchestrator assigns you the audit phase as the final check.
|
|
10
10
|
|
|
11
11
|
## Input Context
|
|
12
|
-
Read all specs from `.devhive/specs/` and review the final codebase state. You MUST also read `.devhive/memory/
|
|
12
|
+
Read all specs from `.devhive/specs/` and review the final codebase state. You MUST also check for and read `.devhive/memory/index.json` and `.devhive/memory/semantic.md`, `.devhive/memory/anti_patterns.md` (if they exist) to ensure the code does not violate persistent project rules or use known anti-patterns.
|
|
13
|
+
|
|
14
|
+
## Memory Access
|
|
15
|
+
To search memory efficiently:
|
|
16
|
+
1. First read `.devhive/memory/index.json` to see all memory entries
|
|
17
|
+
2. Filter by tags relevant to your task (e.g., "security", "architecture", "anti-pattern", "quality")
|
|
18
|
+
3. Read only the specific memory files you need (don't load everything)
|
|
19
|
+
4. Prioritize memories with score >= 0.7 for critical decisions
|
|
20
|
+
5. Check for "security" and "anti-pattern" tagged memories to ensure no violations
|
|
13
21
|
|
|
14
22
|
## Playbook (What to Do)
|
|
15
23
|
0. **Gather and Load Skills (CRITICAL)**: Before starting, you MUST use the `skill` tool to load specialized instructions. Check `GUIDELINES.md` for global skills, check `04-tasks.md` for task-specific skills. If the tool returns an error because a skill is not installed, ignore the error and proceed using your best judgment.
|
|
@@ -9,7 +9,15 @@ description: Implements the backend logic (APIs, databases, server setup) based
|
|
|
9
9
|
When the orchestrator assigns you the backend development phase.
|
|
10
10
|
|
|
11
11
|
## Input Context
|
|
12
|
-
Read `.devhive/specs/04-tasks.md`, `.devhive/specs/03-architecture.md`, and the project's `GUIDELINES.md` if it exists. You MUST also read `.devhive/memory/episodic.md` (if it exists) to avoid repeating past backend errors.
|
|
12
|
+
Read `.devhive/specs/04-tasks.md`, `.devhive/specs/03-architecture.md`, and the project's `GUIDELINES.md` if it exists. You MUST also check for and read `.devhive/memory/index.json` and `.devhive/memory/episodic.md` (if it exists) to avoid repeating past backend errors.
|
|
13
|
+
|
|
14
|
+
## Memory Access
|
|
15
|
+
To search memory efficiently:
|
|
16
|
+
1. First read `.devhive/memory/index.json` to see all memory entries
|
|
17
|
+
2. Filter by tags relevant to your task (e.g., "backend", "bug", "fix", "api")
|
|
18
|
+
3. Read only the specific memory files you need (don't load everything)
|
|
19
|
+
4. Prioritize memories with score >= 0.7 for critical decisions
|
|
20
|
+
5. Check for "backend" and "bug" tagged episodic memories to avoid repeating past mistakes
|
|
13
21
|
|
|
14
22
|
## Playbook (What to Do)
|
|
15
23
|
0. **Gather and Load Skills (CRITICAL)**: Before starting, you MUST use the `skill` tool to load specialized instructions. Check `GUIDELINES.md` for global skills, check `04-tasks.md` for task-specific skills, and ALWAYS load your hardcoded skills: `backend-security-coder`, `architecture-patterns`. If the tool returns an error because a skill is not installed, ignore the error and proceed using your best judgment.
|
|
@@ -9,7 +9,14 @@ description: Analyzes requirements, constraints, and dependencies for a new feat
|
|
|
9
9
|
When the orchestrator assigns you the exploration phase for a feature request.
|
|
10
10
|
|
|
11
11
|
## Input Context
|
|
12
|
-
You will read `.devhive/specs/00-prd.md` and `docs/PRODUCT_REQUIREMENTS.md` (if they exist) to understand the product requirements. You MUST also check for and read `.devhive/memory/
|
|
12
|
+
You will read `.devhive/specs/00-prd.md` and `docs/PRODUCT_REQUIREMENTS.md` (if they exist) to understand the product requirements. You MUST also check for and read `.devhive/memory/index.json` and `.devhive/memory/semantic.md`, `.devhive/memory/anti_patterns.md` to ensure your exploration respects historical persistent memory constraints. You may also receive the user's initial request.
|
|
13
|
+
|
|
14
|
+
## Memory Access
|
|
15
|
+
To search memory efficiently:
|
|
16
|
+
1. First read `.devhive/memory/index.json` to see all memory entries
|
|
17
|
+
2. Filter by tags relevant to your task (e.g., "architecture", "backend", "security")
|
|
18
|
+
3. Read only the specific memory files you need (don't load everything)
|
|
19
|
+
4. Prioritize memories with score >= 0.7 for critical decisions
|
|
13
20
|
|
|
14
21
|
## Playbook (What to Do)
|
|
15
22
|
0. **Gather and Load Skills (CRITICAL)**: Before starting, you MUST use the `skill` tool to load specialized instructions. If the tool returns an error because a skill is not installed, ignore the error and proceed using your best judgment.
|
|
@@ -9,7 +9,15 @@ description: Implements the user interface, client-side state, and UI/UX logic.
|
|
|
9
9
|
When the orchestrator assigns you the frontend development phase after backend is complete.
|
|
10
10
|
|
|
11
11
|
## Input Context
|
|
12
|
-
Read `.devhive/specs/04-tasks.md`, `.devhive/specs/03-architecture.md`, and the project's `GUIDELINES.md` if it exists. You MUST also read `.devhive/memory/episodic.md` (if it exists) to avoid repeating past front-end errors.
|
|
12
|
+
Read `.devhive/specs/04-tasks.md`, `.devhive/specs/03-architecture.md`, and the project's `GUIDELINES.md` if it exists. You MUST also check for and read `.devhive/memory/index.json` and `.devhive/memory/episodic.md` (if it exists) to avoid repeating past front-end errors.
|
|
13
|
+
|
|
14
|
+
## Memory Access
|
|
15
|
+
To search memory efficiently:
|
|
16
|
+
1. First read `.devhive/memory/index.json` to see all memory entries
|
|
17
|
+
2. Filter by tags relevant to your task (e.g., "frontend", "bug", "fix", "ui", "react")
|
|
18
|
+
3. Read only the specific memory files you need (don't load everything)
|
|
19
|
+
4. Prioritize memories with score >= 0.7 for critical decisions
|
|
20
|
+
5. Check for "frontend" and "bug" tagged episodic memories to avoid repeating past mistakes
|
|
13
21
|
|
|
14
22
|
## Playbook (What to Do)
|
|
15
23
|
0. **Gather and Load Skills (CRITICAL)**: Before starting, you MUST use the `skill` tool to load specialized instructions. Check `GUIDELINES.md` for global skills, check `04-tasks.md` for task-specific skills, and ALWAYS load your hardcoded skills: `frontend-design`, `frontend-developer`, `theme-factory`. If the project uses shadcn/ui, you MUST load the `shadcn` skill. If the tool returns an error because a skill is not installed, ignore the error and proceed using your best judgment.
|
|
@@ -10,29 +10,32 @@ This skill is the CEO/Orchestrator for the DevHive Skill-Driven Development (SDD
|
|
|
10
10
|
|
|
11
11
|
## The Pipeline
|
|
12
12
|
The typical SDD pipeline consists of the following phases and their corresponding output files:
|
|
13
|
-
0. `devhive-
|
|
14
|
-
1. `devhive-
|
|
15
|
-
2. `devhive-
|
|
16
|
-
3. `devhive-
|
|
17
|
-
4. `devhive-
|
|
18
|
-
5. `devhive-
|
|
19
|
-
6. `devhive-
|
|
20
|
-
7. `devhive-
|
|
21
|
-
8. `devhive-
|
|
22
|
-
9. `devhive-
|
|
23
|
-
10. `devhive-
|
|
24
|
-
11. `devhive-
|
|
25
|
-
12. `devhive-
|
|
26
|
-
13. `devhive-
|
|
27
|
-
14. `devhive-
|
|
28
|
-
15. `devhive-
|
|
29
|
-
16. `devhive-
|
|
13
|
+
0. `devhive-analyzer` -> (optional) analyzes existing project, proposes memory entries for approval
|
|
14
|
+
1. `devhive-prd` -> `00-prd.md` (and updates `docs/PRODUCT_REQUIREMENTS.md`)
|
|
15
|
+
2. `devhive-explorer` -> `01-exploration.md`
|
|
16
|
+
3. `devhive-proposal` -> `02-proposal.md`
|
|
17
|
+
4. `devhive-architect` -> `03-architecture.md`
|
|
18
|
+
5. `devhive-taskplanner` -> `04-tasks.md`
|
|
19
|
+
6. `devhive-designer` -> configures design systems under `## Design Tasks` in `04-tasks.md`
|
|
20
|
+
7. `devhive-devops` -> implements infrastructure under `## Infrastructure Tasks` in `04-tasks.md`
|
|
21
|
+
8. `devhive-dba` -> creates migrations/schemas under `## Data Tasks` in `04-tasks.md`
|
|
22
|
+
9. `devhive-backender` -> writes backend logic under `## Backend Tasks` in `04-tasks.md`
|
|
23
|
+
10. `devhive-frontender` -> writes frontend logic under `## Frontend Tasks` in `04-tasks.md`
|
|
24
|
+
11. `devhive-perf` -> writes load testing scripts under `## Performance Tasks` in `04-tasks.md`
|
|
25
|
+
12. `devhive-techwriter` -> writes documentation under `## Documentation Tasks` in `04-tasks.md`
|
|
26
|
+
13. `devhive-releaser` -> manages semantic versioning under `## Release Tasks` in `04-tasks.md`
|
|
27
|
+
14. `devhive-sast` -> performs security scan and writes `05-sast-report.md`
|
|
28
|
+
15. `devhive-qa` -> writes tests and `06-qa-plan.md`
|
|
29
|
+
16. `devhive-auditor` -> `07-audit.md`
|
|
30
|
+
17. `devhive-reflection` -> generates persistent memory in `.devhive/memory/` and writes `08-reflection.md`
|
|
30
31
|
|
|
31
32
|
## Playbook (Execution Loop)
|
|
32
33
|
|
|
33
34
|
**Strict Sequential Enforcement (CRITICAL):** NEVER skip a phase. Even if the user provides a highly detailed plan, architecture, or task list in their initial prompt, treat it ONLY as *input context*. You MUST still invoke the planning skills (`devhive-prd`, `devhive-explorer`, `devhive-proposal`, `devhive-architect`, `devhive-taskplanner`) sequentially. Instruct those sub-agents to ingest and adapt the user's plan into the official `.devhive/specs/` markdown files.
|
|
34
35
|
|
|
35
|
-
1. **Check State**: Look at the files in `.devhive/specs/`. Determine what the next missing phase is.
|
|
36
|
+
1. **Check State**: Look at the files in `.devhive/specs/`. Determine what the next missing phase is.
|
|
37
|
+
- **Phase 0 (Analyzer)**: If no `.devhive/memory/index.json` exists OR if `.devhive/memory/` is empty, this is a FIRST-TIME project for DevHive. Invoke `devhive-analyzer` FIRST to analyze the project and propose memory entries. Only proceed to Phase 1 after analyzer completes.
|
|
38
|
+
- If memory already exists (`.devhive/memory/index.json` has entries), SKIP the analyzer and go directly to Phase 1.
|
|
36
39
|
2. **Determine Sub-Skill**: Based on the missing phase, decide which skill to invoke.
|
|
37
40
|
- If `00-prd.md` does not exist -> Invoke `devhive-prd`.
|
|
38
41
|
- If `00-prd.md` exists but `01-exploration.md` does not -> Invoke `devhive-explorer`.
|
|
@@ -54,6 +57,7 @@ The typical SDD pipeline consists of the following phases and their correspondin
|
|
|
54
57
|
- If `07-audit.md` exists but `08-reflection.md` does not -> Invoke `devhive-reflection`.
|
|
55
58
|
3. **Launch Task**: Use the `Task` tool (with `subagent_type="general"`) to launch the sub-agent.
|
|
56
59
|
- **Prompt**: Instruct the sub-agent to strictly follow its corresponding DevHive skill. Instruct the sub-agent to read `.devhive/memory/` files (if they exist) for contextual constraints. If invoking `devhive-reflection`, you MUST pass a summary of the current chat history (human corrections and feedback) as input. Pass the user's initial request or context if needed.
|
|
60
|
+
- **Special Case - Analyzer**: When invoking `devhive-analyzer`, pass the current project directory context and indicate if an `AGENTS.md` or `GUIDELINES.md` file exists. Instruct the analyzer to prioritize extracting memories from these files if they exist.
|
|
57
61
|
4. **Evaluate the Result**:
|
|
58
62
|
- Verify that the sub-agent successfully created the required `.devhive/specs/XX-name.md` file (or checked off tasks in `04-tasks.md`).
|
|
59
63
|
- **Pause (Default Behavior)**: Stop and ask the user for approval. Show them the path of the newly created spec and ask if they want to proceed.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: devhive-reflection
|
|
3
|
+
description: Analyzes execution results and human corrections to generate persistent learning memories.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill: devhive-reflection
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
You are the Reflection Agent and Memory Manager for DevHive. Your job is to extract reusable knowledge (Semantic, Episodic, and Anti-pattern memories) from the current execution cycle and persist it, ensuring DevHive learns from mistakes and human feedback.
|
|
10
|
+
|
|
11
|
+
## Memory System Architecture
|
|
12
|
+
DevHive uses a file-based memory system with indexed entries:
|
|
13
|
+
- **Location**: `.devhive/memory/`
|
|
14
|
+
- **Index**: `.devhive/memory/index.json` - contains metadata for all entries
|
|
15
|
+
- **Files**: `semantic.md`, `episodic.md`, `anti_patterns.md` - contain the actual memories
|
|
16
|
+
- **ID Format**: `sem-001`, `epi-001`, `ant-001` (prefix + counter)
|
|
17
|
+
|
|
18
|
+
## Inputs
|
|
19
|
+
You will receive a summary of the chat history (human corrections) from the orchestrator. You MUST also use the `Read` tool to examine:
|
|
20
|
+
- `.devhive/specs/04-tasks.md`
|
|
21
|
+
- `.devhive/specs/05-sast-report.md`
|
|
22
|
+
- `.devhive/specs/07-audit.md`
|
|
23
|
+
- `.devhive/memory/index.json` (if exists)
|
|
24
|
+
- `.devhive/memory/semantic.md` (if exists)
|
|
25
|
+
- `.devhive/memory/episodic.md` (if exists)
|
|
26
|
+
- `.devhive/memory/anti_patterns.md` (if exists)
|
|
27
|
+
|
|
28
|
+
## Playbook (What to Do)
|
|
29
|
+
|
|
30
|
+
### 1. Analyze Execution & Feedback
|
|
31
|
+
- Identify repeated mistakes, successful fixes, bad practices, architectural decisions, and human corrections from the chat history and audit reports.
|
|
32
|
+
|
|
33
|
+
### 2. Memory Scoring
|
|
34
|
+
- Evaluate each potential memory using this logic: `score = recurrence * 0.4 + severity * 0.3 + humanCorrection * 0.3` (Scale 0.0 to 1.0)
|
|
35
|
+
- ONLY keep memories with a score >= 0.6.
|
|
36
|
+
|
|
37
|
+
### 3. Categorize Memories
|
|
38
|
+
- **Semantic (`semantic.md`)**: Architecture rules, conventions, stack rules. Tags: `["architecture", "convention", "stack"]`
|
|
39
|
+
- **Episodic (`episodic.md`)**: Specific bugs and fixes (Issue + Fix). Tags: `["bug", "fix", "specific"]`
|
|
40
|
+
- **Anti-pattern (`anti_patterns.md`)**: What NOT to do, failed strategies. Tags: `["anti-pattern", "warning", "avoid"]`
|
|
41
|
+
|
|
42
|
+
### 4. Deduplication (CRITICAL)
|
|
43
|
+
- Read existing memory files BEFORE writing.
|
|
44
|
+
- Check if a similar memory already exists by comparing summaries and tags.
|
|
45
|
+
- If duplicate found with same essence, skip (don't add again).
|
|
46
|
+
|
|
47
|
+
### 5. Write with ID References (CRITICAL)
|
|
48
|
+
- Create `.devhive/memory/` directory if it doesn't exist using the `Bash` tool.
|
|
49
|
+
- Create `.devhive/memory/index.json` with this structure:
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"version": "1.0",
|
|
53
|
+
"last_updated": "2026-06-05",
|
|
54
|
+
"entries": []
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
- For each new memory, assign a unique ID (sem-001, epi-001, ant-001, etc.)
|
|
58
|
+
- Write memories to their respective files with ID comments:
|
|
59
|
+
```markdown
|
|
60
|
+
<!-- id: sem-001 -->
|
|
61
|
+
- **Semantic**: Use Hexagonal Architecture for backend
|
|
62
|
+
```
|
|
63
|
+
- Update the index.json with the new entry metadata.
|
|
64
|
+
|
|
65
|
+
### 6. Tag Extraction
|
|
66
|
+
For each memory, extract relevant tags from:
|
|
67
|
+
- Technology mentions (fastapi, react, docker)
|
|
68
|
+
- Domain (backend, frontend, infra)
|
|
69
|
+
- Pattern type (architecture, bug, warning)
|
|
70
|
+
- Source (human-feedback, audit, sast)
|
|
71
|
+
|
|
72
|
+
### 7. Acknowledge Completion
|
|
73
|
+
- Write a brief summary of the extracted lessons to `.devhive/specs/08-reflection.md`.
|
|
74
|
+
- Include the new memory IDs in the summary so the user can reference them.
|
|
75
|
+
- This signals to the Orchestrator that memory persistence is complete.
|
|
76
|
+
|
|
77
|
+
## Memory Entry Format
|
|
78
|
+
Each memory in index.json must have:
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"id": "sem-001",
|
|
82
|
+
"type": "semantic",
|
|
83
|
+
"summary": "Use Hexagonal Architecture for backend",
|
|
84
|
+
"tags": ["architecture", "hexagonal", "backend"],
|
|
85
|
+
"source": "human-feedback",
|
|
86
|
+
"score": 0.85,
|
|
87
|
+
"project": "current-project-name",
|
|
88
|
+
"created_at": "2026-06-05",
|
|
89
|
+
"line_ref": "semantic.md:15"
|
|
90
|
+
}
|
|
91
|
+
```
|
|
@@ -9,7 +9,14 @@ description: Breaks down the architecture into actionable infrastructure, backen
|
|
|
9
9
|
When the orchestrator assigns you the task planning phase after the architecture is designed.
|
|
10
10
|
|
|
11
11
|
## Input Context
|
|
12
|
-
Read `.devhive/specs/03-architecture.md` and `.devhive/specs/02-proposal.md`. You MUST also check for and read `.devhive/memory/semantic.md` to integrate any historical rules into your task definitions.
|
|
12
|
+
Read `.devhive/specs/03-architecture.md` and `.devhive/specs/02-proposal.md`. You MUST also check for and read `.devhive/memory/index.json` and `.devhive/memory/semantic.md` to integrate any historical rules into your task definitions.
|
|
13
|
+
|
|
14
|
+
## Memory Access
|
|
15
|
+
To search memory efficiently:
|
|
16
|
+
1. First read `.devhive/memory/index.json` to see all memory entries
|
|
17
|
+
2. Filter by tags relevant to your task (e.g., "architecture", "backend", "frontend", "devops")
|
|
18
|
+
3. Read only the specific memory files you need (don't load everything)
|
|
19
|
+
4. Prioritize memories with score >= 0.7 for critical decisions
|
|
13
20
|
|
|
14
21
|
## Playbook (What to Do)
|
|
15
22
|
0. **Gather and Load Skills (CRITICAL)**: Before starting, you MUST use the `skill` tool to load specialized instructions. Check `GUIDELINES.md` for global skills, check `04-tasks.md` for task-specific skills. If the tool returns an error because a skill is not installed, ignore the error and proceed using your best judgment.
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: devhive-reflection
|
|
3
|
-
description: Analyzes execution results and human corrections to generate persistent learning memories.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Skill: devhive-reflection
|
|
7
|
-
|
|
8
|
-
## Overview
|
|
9
|
-
You are the Reflection Agent and Memory Manager for DevHive. Your job is to extract reusable knowledge (Semantic, Episodic, and Anti-pattern memories) from the current execution cycle and persist it, ensuring DevHive learns from mistakes and human feedback.
|
|
10
|
-
|
|
11
|
-
## Inputs
|
|
12
|
-
You will receive a summary of the chat history (human corrections) from the orchestrator. You MUST also use the `Read` tool to examine:
|
|
13
|
-
- `.devhive/specs/04-tasks.md`
|
|
14
|
-
- `.devhive/specs/05-sast-report.md`
|
|
15
|
-
- `.devhive/specs/07-audit.md`
|
|
16
|
-
|
|
17
|
-
## Playbook (What to Do)
|
|
18
|
-
1. **Analyze Execution & Feedback**:
|
|
19
|
-
- Identify repeated mistakes, successful fixes, bad practices, architectural decisions, and human corrections from the chat history and audit reports.
|
|
20
|
-
|
|
21
|
-
2. **Memory Scoring**:
|
|
22
|
-
- Evaluate each potential memory using this logic: `score = recurrence * 0.4 + severity * 0.3 + humanCorrection * 0.3` (Scale 0.0 to 1.0)
|
|
23
|
-
- ONLY keep memories with a score >= 0.6.
|
|
24
|
-
|
|
25
|
-
3. **Categorize Memories**:
|
|
26
|
-
- **Semantic (`semantic.md`)**: Architecture rules, conventions, stack rules.
|
|
27
|
-
- **Episodic (`episodic.md`)**: Specific bugs and fixes (Issue + Fix).
|
|
28
|
-
- **Anti-pattern (`anti_patterns.md`)**: What NOT to do, failed strategies, destructive errors.
|
|
29
|
-
|
|
30
|
-
4. **Deduplication & Writing (CRITICAL)**:
|
|
31
|
-
- You are the ONLY agent authorized to write to `.devhive/memory/`.
|
|
32
|
-
- Create the directory `.devhive/memory/` if it doesn't exist using the `Bash` tool.
|
|
33
|
-
- Read existing memory files in `.devhive/memory/` before writing to deduplicate new learnings against existing ones.
|
|
34
|
-
- Use the `Write` or `Edit` tools to append or update these files. Use concise Markdown bullet points to save tokens.
|
|
35
|
-
|
|
36
|
-
5. **Acknowledge Completion**:
|
|
37
|
-
- Write a brief summary of the extracted lessons to `.devhive/specs/08-reflection.md`. This signals to the Orchestrator that memory persistence is complete.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/architecture-patterns/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/backend-security-coder/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/theme-showcase.pdf
RENAMED
|
File without changes
|
{devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/arctic-frost.md
RENAMED
|
File without changes
|
|
File without changes
|
{devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/desert-rose.md
RENAMED
|
File without changes
|
{devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/forest-canopy.md
RENAMED
|
File without changes
|
{devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/golden-hour.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devhive-0.1.37 → devhive-0.1.40}/devhive_cli/community_skills/theme-factory/themes/ocean-depths.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|