auto-context-cli 1.0.3__tar.gz → 1.0.5__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.
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/PKG-INFO +2 -2
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/README.md +1 -1
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/pyproject.toml +1 -1
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/__init__.py +1 -1
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/commands/init_cmd.py +11 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/commands/scan_cmd.py +9 -3
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/main.py +1 -1
- auto_context_cli-1.0.5/src/auto_context/scanner.py +421 -0
- auto_context_cli-1.0.5/src/auto_context/templates/AGENTS.template.md +47 -0
- auto_context_cli-1.0.5/src/auto_context/templates/GEMINI.template.md +47 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/context.template.md +1 -2
- auto_context_cli-1.0.5/src/auto_context/templates/maintain_context.template.md +48 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/rules/hub-satellite-architecture.md +1 -0
- auto_context_cli-1.0.3/src/auto_context/scanner.py +0 -297
- auto_context_cli-1.0.3/src/auto_context/templates/AGENTS.template.md +0 -53
- auto_context_cli-1.0.3/src/auto_context/templates/GEMINI.template.md +0 -53
- auto_context_cli-1.0.3/src/auto_context/templates/maintain_context.template.md +0 -37
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/.gitignore +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/LICENSE +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/commands/__init__.py +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/commands/import_cmd.py +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/commands/mcp.py +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/commands/memory.py +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/commands/share.py +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/commands/update_cmd.py +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/config.py +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/security.py +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/context.local.template.md +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/mcp_config.template.json +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/profile.template.md +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/rule.template.md +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/rules/code-standards.md +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/rules/readme-docs-sync.md +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/rules/security-boundaries.md +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/skill.template.md +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/skills/browser-testing/SKILL.md +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/skills/docker-ops/SKILL.md +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/skills/git-workflow/SKILL.md +0 -0
- {auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/skills/server-diagnostics/SKILL.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: auto-context-cli
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.5
|
|
4
4
|
Summary: Autonomous context & instruction manager for AI coding assistants
|
|
5
5
|
Author: Arghya Biswas
|
|
6
6
|
License: MIT
|
|
@@ -20,7 +20,7 @@ Description-Content-Type: text/markdown
|
|
|
20
20
|
|
|
21
21
|
[](https://pypi.org/project/auto-context-cli/)
|
|
22
22
|
[](https://pypi.org/project/auto-context-cli/)
|
|
23
|
-
[](https://github.com/Cyber-arghya/auto-context/releases/tag/v1.0.
|
|
23
|
+
[](https://github.com/Cyber-arghya/auto-context/releases/tag/v1.0.5)
|
|
24
24
|
[](https://opensource.org/licenses/MIT)
|
|
25
25
|
[](#-quick-one-line-install)
|
|
26
26
|
[](#-supported-ai-assistants)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
[](https://pypi.org/project/auto-context-cli/)
|
|
8
8
|
[](https://pypi.org/project/auto-context-cli/)
|
|
9
|
-
[](https://github.com/Cyber-arghya/auto-context/releases/tag/v1.0.
|
|
9
|
+
[](https://github.com/Cyber-arghya/auto-context/releases/tag/v1.0.5)
|
|
10
10
|
[](https://opensource.org/licenses/MIT)
|
|
11
11
|
[](#-quick-one-line-install)
|
|
12
12
|
[](#-supported-ai-assistants)
|
|
@@ -102,6 +102,17 @@ def detect_stack(project_dir: Path) -> tuple[str, str]:
|
|
|
102
102
|
|
|
103
103
|
return stack, "Standard"
|
|
104
104
|
|
|
105
|
+
# Fallback: check immediate child directories if current folder has no manifest
|
|
106
|
+
try:
|
|
107
|
+
for child in project_dir.iterdir():
|
|
108
|
+
if child.is_dir() and not child.name.startswith((".", "node_modules", "venv", "__pycache__")):
|
|
109
|
+
for filename, stack, kind in config.STACK_INDICATORS:
|
|
110
|
+
if (child / filename).exists():
|
|
111
|
+
sub_stack, sub_fw = detect_stack(child)
|
|
112
|
+
return f"{sub_stack} (in {child.name}/)", sub_fw
|
|
113
|
+
except Exception:
|
|
114
|
+
pass
|
|
115
|
+
|
|
105
116
|
return "General / Multi-stack", "Not detected"
|
|
106
117
|
|
|
107
118
|
|
|
@@ -59,15 +59,20 @@ def scan(
|
|
|
59
59
|
for svc, port, src in ports:
|
|
60
60
|
ports_table += f"| **{svc}** | `{port}` | {src} |\n"
|
|
61
61
|
else:
|
|
62
|
-
|
|
62
|
+
is_web = any(w in (stack + framework).lower() for w in ("next", "react", "vue", "express", "fastapi", "flask", "django", "node", "web", "nest", "svelte"))
|
|
63
|
+
if is_web:
|
|
64
|
+
ports_table += "| **App Port** | `3000` (Default) | Inferred web port |\n"
|
|
65
|
+
else:
|
|
66
|
+
ports_table += "| **Network Ports** | `None` | CLI / Library (No local server ports detected) |\n"
|
|
63
67
|
|
|
64
|
-
# Build runbook table
|
|
68
|
+
# Build runbook table (Strictly verified executable commands, zero hallucinated fallbacks)
|
|
65
69
|
runbook_table = "| Task | Executable Command |\n| :--- | :--- |\n"
|
|
66
70
|
if commands:
|
|
67
71
|
for action, cmd in commands:
|
|
68
72
|
runbook_table += f"| {action} | `{cmd}` |\n"
|
|
69
73
|
else:
|
|
70
|
-
runbook_table += "|
|
|
74
|
+
runbook_table += "| Project Runbook | No startup scripts declared in manifests |\n"
|
|
75
|
+
runbook_table += "| Rescan Codebase | `init-context scan` |\n"
|
|
71
76
|
|
|
72
77
|
# Build satellites index section
|
|
73
78
|
satellites_index = ""
|
|
@@ -131,3 +136,4 @@ def scan(
|
|
|
131
136
|
f"• Hub size (context.md): [bold green]< 60 lines (Token Optimized)[/]",
|
|
132
137
|
border_style="green",
|
|
133
138
|
))
|
|
139
|
+
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
"""
|
|
2
|
+
scanner.py — Stack-Adaptive Codebase Introspection & Brownfield Discovery Engine.
|
|
3
|
+
|
|
4
|
+
Discovers ports, routes, database schemas, services, and runbooks using lightweight
|
|
5
|
+
filesystem convention heuristics (0 LLM tokens, 100% crash-proof, idempotency-guaranteed).
|
|
6
|
+
"""
|
|
7
|
+
import hashlib
|
|
8
|
+
import json
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
import re
|
|
11
|
+
from typing import Optional
|
|
12
|
+
try:
|
|
13
|
+
import tomllib
|
|
14
|
+
except ImportError:
|
|
15
|
+
try:
|
|
16
|
+
import tomli as tomllib # type: ignore
|
|
17
|
+
except ImportError:
|
|
18
|
+
tomllib = None
|
|
19
|
+
|
|
20
|
+
from rich.console import Console
|
|
21
|
+
|
|
22
|
+
console = Console()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# ── Idempotency & Hash Helpers ────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
def get_content_hash(text: str) -> str:
|
|
28
|
+
"""Compute SHA-256 hash of text content."""
|
|
29
|
+
return hashlib.sha256(text.encode("utf-8")).hexdigest()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def write_idempotent(path: Path, content: str, label: str = "File") -> bool:
|
|
33
|
+
"""
|
|
34
|
+
Write content to path only if content has changed (Content-Hash Guard).
|
|
35
|
+
Returns True if a write occurred, False if content was already identical.
|
|
36
|
+
"""
|
|
37
|
+
if path.exists():
|
|
38
|
+
try:
|
|
39
|
+
existing = path.read_text(encoding="utf-8")
|
|
40
|
+
if get_content_hash(existing) == get_content_hash(content):
|
|
41
|
+
console.print(f" [dim]— Up to date:[/] {path.name}")
|
|
42
|
+
return False
|
|
43
|
+
except Exception:
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
47
|
+
path.write_text(content, encoding="utf-8")
|
|
48
|
+
console.print(f" [green][✓] Synchronized:[/] {path.name}")
|
|
49
|
+
return True
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _get_project_search_roots(project_dir: Path) -> list[Path]:
|
|
53
|
+
"""
|
|
54
|
+
Returns [project_dir] plus any immediate child directories containing manifests.
|
|
55
|
+
Guards against scanning dependencies or virtual environments.
|
|
56
|
+
"""
|
|
57
|
+
roots = [project_dir]
|
|
58
|
+
ignore_names = {
|
|
59
|
+
"node_modules", ".git", ".venv", "venv", "__pycache__",
|
|
60
|
+
".agents", ".gemini", "dist", "build", "site-packages", ".idea", ".vscode"
|
|
61
|
+
}
|
|
62
|
+
manifest_names = {
|
|
63
|
+
"package.json", "pyproject.toml", "Makefile", "manage.py",
|
|
64
|
+
"Cargo.toml", "go.mod", "docker-compose.yml", "compose.yaml", "requirements.txt"
|
|
65
|
+
}
|
|
66
|
+
try:
|
|
67
|
+
for child in project_dir.iterdir():
|
|
68
|
+
if child.is_dir() and child.name not in ignore_names and not child.name.startswith("."):
|
|
69
|
+
if any((child / m).exists() for m in manifest_names):
|
|
70
|
+
roots.append(child)
|
|
71
|
+
except Exception:
|
|
72
|
+
pass
|
|
73
|
+
return roots
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# ── Port & Service Extractor ──────────────────────────────────────────────────
|
|
77
|
+
|
|
78
|
+
def discover_ports_and_services(project_dir: Path) -> list[tuple[str, str, str]]:
|
|
79
|
+
"""
|
|
80
|
+
Extract network ports and service bindings from configs without leaking secrets.
|
|
81
|
+
Returns list of (Service, Port, SourceFile).
|
|
82
|
+
"""
|
|
83
|
+
results: list[tuple[str, str, str]] = []
|
|
84
|
+
seen_ports: set[str] = set()
|
|
85
|
+
|
|
86
|
+
for d in _get_project_search_roots(project_dir):
|
|
87
|
+
# 1. Check docker-compose.yml / compose.yaml
|
|
88
|
+
for compose_name in ("docker-compose.yml", "docker-compose.yaml", "compose.yml", "compose.yaml"):
|
|
89
|
+
compose_file = d / compose_name
|
|
90
|
+
if compose_file.exists():
|
|
91
|
+
try:
|
|
92
|
+
text = compose_file.read_text(encoding="utf-8", errors="ignore")
|
|
93
|
+
matches = re.findall(r'["\']?(\d{2,5}):(\d{2,5})["\']?', text)
|
|
94
|
+
for host_port, container_port in matches:
|
|
95
|
+
if host_port not in seen_ports and int(host_port) > 80:
|
|
96
|
+
seen_ports.add(host_port)
|
|
97
|
+
src_label = compose_name if d == project_dir else f"{d.name}/{compose_name}"
|
|
98
|
+
results.append(("Container Port", host_port, src_label))
|
|
99
|
+
except Exception:
|
|
100
|
+
pass
|
|
101
|
+
|
|
102
|
+
# 2. Check .env.example / .env
|
|
103
|
+
for env_name in (".env.example", ".env", ".env.local"):
|
|
104
|
+
env_file = d / env_name
|
|
105
|
+
if env_file.exists():
|
|
106
|
+
try:
|
|
107
|
+
for line in env_file.read_text(encoding="utf-8", errors="ignore").splitlines():
|
|
108
|
+
line = line.strip()
|
|
109
|
+
if line.startswith("#") or "=" not in line:
|
|
110
|
+
continue
|
|
111
|
+
key, val = line.split("=", 1)
|
|
112
|
+
key = key.strip()
|
|
113
|
+
val = val.strip().strip('"').strip("'")
|
|
114
|
+
if "PORT" in key.upper() and val.isdigit() and val not in seen_ports:
|
|
115
|
+
seen_ports.add(val)
|
|
116
|
+
src_label = env_name if d == project_dir else f"{d.name}/{env_name}"
|
|
117
|
+
results.append((key, val, src_label))
|
|
118
|
+
except Exception:
|
|
119
|
+
pass
|
|
120
|
+
|
|
121
|
+
# 3. Check Dockerfile
|
|
122
|
+
dockerfile = d / "Dockerfile"
|
|
123
|
+
if dockerfile.exists():
|
|
124
|
+
try:
|
|
125
|
+
for line in dockerfile.read_text(encoding="utf-8", errors="ignore").splitlines():
|
|
126
|
+
if line.strip().upper().startswith("EXPOSE "):
|
|
127
|
+
port = line.strip().split()[1]
|
|
128
|
+
if port.isdigit() and port not in seen_ports:
|
|
129
|
+
seen_ports.add(port)
|
|
130
|
+
src_label = "Dockerfile" if d == project_dir else f"{d.name}/Dockerfile"
|
|
131
|
+
results.append(("Exposed Port", port, src_label))
|
|
132
|
+
except Exception:
|
|
133
|
+
pass
|
|
134
|
+
|
|
135
|
+
return results
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# ── Runbook Command Extractor ─────────────────────────────────────────────────
|
|
139
|
+
|
|
140
|
+
def discover_runbook_commands(project_dir: Path) -> list[tuple[str, str]]:
|
|
141
|
+
"""
|
|
142
|
+
Extract executable development, build, and test commands from project manifests.
|
|
143
|
+
Guarantees 100% executable commands without hallucinated placeholders.
|
|
144
|
+
Returns list of (Action, Command).
|
|
145
|
+
"""
|
|
146
|
+
commands: list[tuple[str, str]] = []
|
|
147
|
+
seen_commands: set[str] = set()
|
|
148
|
+
|
|
149
|
+
for d in _get_project_search_roots(project_dir):
|
|
150
|
+
dir_label = "" if d == project_dir else f" ({d.name})"
|
|
151
|
+
|
|
152
|
+
# 1. package.json scripts
|
|
153
|
+
pkg_file = d / "package.json"
|
|
154
|
+
if pkg_file.exists():
|
|
155
|
+
try:
|
|
156
|
+
data = json.loads(pkg_file.read_text(encoding="utf-8", errors="ignore"))
|
|
157
|
+
scripts = data.get("scripts", {})
|
|
158
|
+
runner = "pnpm" if (d / "pnpm-lock.yaml").exists() else (
|
|
159
|
+
"yarn" if (d / "yarn.lock").exists() else (
|
|
160
|
+
"bun" if (d / "bun.lockb").exists() else "npm"
|
|
161
|
+
)
|
|
162
|
+
)
|
|
163
|
+
for key in ("dev", "start", "build", "test", "lint"):
|
|
164
|
+
if key in scripts:
|
|
165
|
+
if d == project_dir:
|
|
166
|
+
cmd = f"{runner} run {key}" if runner != "yarn" else f"yarn {key}"
|
|
167
|
+
else:
|
|
168
|
+
cmd = f"{runner} --prefix {d.name} run {key}" if runner == "npm" else f"{runner} --cwd {d.name} run {key}"
|
|
169
|
+
if cmd not in seen_commands:
|
|
170
|
+
seen_commands.add(cmd)
|
|
171
|
+
commands.append((f"Run {key}{dir_label}", cmd))
|
|
172
|
+
except Exception:
|
|
173
|
+
pass
|
|
174
|
+
|
|
175
|
+
# 2. pyproject.toml (scripts & test runner)
|
|
176
|
+
pyproj = d / "pyproject.toml"
|
|
177
|
+
if pyproj.exists():
|
|
178
|
+
try:
|
|
179
|
+
raw_text = pyproj.read_text(encoding="utf-8", errors="ignore")
|
|
180
|
+
data = tomllib.loads(raw_text) if tomllib else {}
|
|
181
|
+
scripts = data.get("project", {}).get("scripts", {})
|
|
182
|
+
for script_name in scripts:
|
|
183
|
+
cmd = f"uv run {script_name}" if d == project_dir else f"uv run --directory {d.name} {script_name}"
|
|
184
|
+
if cmd not in seen_commands:
|
|
185
|
+
seen_commands.add(cmd)
|
|
186
|
+
commands.append((f"Run CLI ({script_name}){dir_label}", cmd))
|
|
187
|
+
|
|
188
|
+
if "pytest" in raw_text or (d / "tests").is_dir() or (d / "test").is_dir():
|
|
189
|
+
cmd = "uv run pytest" if d == project_dir else f"uv run --directory {d.name} pytest"
|
|
190
|
+
if cmd not in seen_commands:
|
|
191
|
+
seen_commands.add(cmd)
|
|
192
|
+
commands.append((f"Run Tests{dir_label}", cmd))
|
|
193
|
+
except Exception:
|
|
194
|
+
pass
|
|
195
|
+
|
|
196
|
+
# 3. Python indicators (manage.py, main.py, app.py, server.py)
|
|
197
|
+
if (d / "manage.py").exists():
|
|
198
|
+
target = "manage.py" if d == project_dir else f"{d.name}/manage.py"
|
|
199
|
+
cmd_run = f"python {target} runserver"
|
|
200
|
+
cmd_mig = f"python {target} migrate"
|
|
201
|
+
if cmd_run not in seen_commands:
|
|
202
|
+
seen_commands.add(cmd_run)
|
|
203
|
+
commands.append((f"Django Runserver{dir_label}", cmd_run))
|
|
204
|
+
if cmd_mig not in seen_commands:
|
|
205
|
+
seen_commands.add(cmd_mig)
|
|
206
|
+
commands.append((f"Django Migrate{dir_label}", cmd_mig))
|
|
207
|
+
else:
|
|
208
|
+
for main_candidate in ("main.py", "app.py", "server.py", "wsgi.py"):
|
|
209
|
+
if (d / main_candidate).exists():
|
|
210
|
+
target = main_candidate if d == project_dir else f"{d.name}/{main_candidate}"
|
|
211
|
+
cmd = f"python {target}"
|
|
212
|
+
if cmd not in seen_commands:
|
|
213
|
+
seen_commands.add(cmd)
|
|
214
|
+
commands.append((f"Start Server{dir_label}", cmd))
|
|
215
|
+
break
|
|
216
|
+
|
|
217
|
+
# 4. Makefile targets
|
|
218
|
+
makefile = d / "Makefile"
|
|
219
|
+
if makefile.exists():
|
|
220
|
+
try:
|
|
221
|
+
targets = re.findall(r"^([a-zA-Z0-9_-]+):", makefile.read_text(encoding="utf-8", errors="ignore"), re.M)
|
|
222
|
+
preferred = [t for t in targets if not t.startswith(".") and t in ("dev", "start", "build", "test", "lint", "all", "run")]
|
|
223
|
+
if not preferred:
|
|
224
|
+
preferred = [t for t in targets if not t.startswith(".")][:3]
|
|
225
|
+
for t in preferred[:3]:
|
|
226
|
+
cmd = f"make {t}" if d == project_dir else f"make -C {d.name} {t}"
|
|
227
|
+
if cmd not in seen_commands:
|
|
228
|
+
seen_commands.add(cmd)
|
|
229
|
+
commands.append((f"Make {t}{dir_label}", cmd))
|
|
230
|
+
except Exception:
|
|
231
|
+
pass
|
|
232
|
+
|
|
233
|
+
# 5. Rust Cargo
|
|
234
|
+
cargo = d / "Cargo.toml"
|
|
235
|
+
if cargo.exists():
|
|
236
|
+
cmd_run = "cargo run" if d == project_dir else f"cargo run --manifest-path {d.name}/Cargo.toml"
|
|
237
|
+
cmd_test = "cargo test" if d == project_dir else f"cargo test --manifest-path {d.name}/Cargo.toml"
|
|
238
|
+
if cmd_run not in seen_commands:
|
|
239
|
+
seen_commands.add(cmd_run)
|
|
240
|
+
commands.append((f"Cargo Run{dir_label}", cmd_run))
|
|
241
|
+
if cmd_test not in seen_commands:
|
|
242
|
+
seen_commands.add(cmd_test)
|
|
243
|
+
commands.append((f"Cargo Test{dir_label}", cmd_test))
|
|
244
|
+
|
|
245
|
+
# 6. Go mod
|
|
246
|
+
go_mod = d / "go.mod"
|
|
247
|
+
if go_mod.exists():
|
|
248
|
+
cmd_run = "go run ." if d == project_dir else f"cd {d.name} && go run ."
|
|
249
|
+
cmd_test = "go test ./..." if d == project_dir else f"cd {d.name} && go test ./..."
|
|
250
|
+
if cmd_run not in seen_commands:
|
|
251
|
+
seen_commands.add(cmd_run)
|
|
252
|
+
commands.append((f"Go Run{dir_label}", cmd_run))
|
|
253
|
+
if cmd_test not in seen_commands:
|
|
254
|
+
seen_commands.add(cmd_test)
|
|
255
|
+
commands.append((f"Go Test{dir_label}", cmd_test))
|
|
256
|
+
|
|
257
|
+
# 7. Docker Compose
|
|
258
|
+
if (d / "docker-compose.yml").exists() or (d / "compose.yaml").exists():
|
|
259
|
+
cmd = "docker compose up -d" if d == project_dir else f"docker compose -f {d.name}/docker-compose.yml up -d"
|
|
260
|
+
if cmd not in seen_commands:
|
|
261
|
+
seen_commands.add(cmd)
|
|
262
|
+
commands.append((f"Start Docker Services{dir_label}", cmd))
|
|
263
|
+
|
|
264
|
+
return commands[:6]
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
# ── Routes & Endpoints Extractor ──────────────────────────────────────────────
|
|
268
|
+
|
|
269
|
+
def discover_routes(project_dir: Path) -> list[str]:
|
|
270
|
+
"""
|
|
271
|
+
Extract API and UI routes using Next.js, Express, FastAPI, and Django conventions.
|
|
272
|
+
Returns clean list of detected route paths.
|
|
273
|
+
"""
|
|
274
|
+
routes: list[str] = []
|
|
275
|
+
|
|
276
|
+
try:
|
|
277
|
+
# 1. Next.js App Router (app/ or src/app/)
|
|
278
|
+
app_dirs = [d for d in (project_dir / "app", project_dir / "src" / "app") if d.is_dir()]
|
|
279
|
+
for app_dir in app_dirs:
|
|
280
|
+
for file_path in app_dir.rglob("*"):
|
|
281
|
+
if file_path.is_file() and file_path.name in ("route.ts", "route.js", "page.tsx", "page.jsx"):
|
|
282
|
+
rel = file_path.parent.relative_to(app_dir).as_posix()
|
|
283
|
+
route_path = "/" if rel == "." else f"/{rel}"
|
|
284
|
+
kind = "API" if file_path.name.startswith("route") else "Page"
|
|
285
|
+
routes.append(f"[{kind}] {route_path} -> {file_path.relative_to(project_dir).as_posix()}")
|
|
286
|
+
|
|
287
|
+
# 2. Next.js Pages Router (pages/ or src/pages/)
|
|
288
|
+
page_dirs = [d for d in (project_dir / "pages", project_dir / "src" / "pages") if d.is_dir()]
|
|
289
|
+
for page_dir in page_dirs:
|
|
290
|
+
for file_path in page_dir.rglob("*.tsx"):
|
|
291
|
+
if not file_path.name.startswith("_"):
|
|
292
|
+
rel = file_path.relative_to(page_dir).with_suffix("").as_posix()
|
|
293
|
+
route_path = "/" if rel == "index" else f"/{rel.replace('/index', '')}"
|
|
294
|
+
kind = "API" if "api" in rel else "Page"
|
|
295
|
+
routes.append(f"[{kind}] {route_path} -> {file_path.relative_to(project_dir).as_posix()}")
|
|
296
|
+
|
|
297
|
+
# 3. Modular Route, Controller & CLI Command Folders (Deep Convention Search)
|
|
298
|
+
target_dirs = ("routes", "controllers", "routers", "endpoints", "commands", "handlers", "views", "api")
|
|
299
|
+
ignore_parts = {"node_modules", ".git", ".venv", "venv", "__pycache__", ".agents", ".gemini", "dist", "build", "site-packages"}
|
|
300
|
+
|
|
301
|
+
for folder in project_dir.rglob("*"):
|
|
302
|
+
if folder.is_dir() and folder.name in target_dirs:
|
|
303
|
+
if any(ignored in folder.parts for ignored in ignore_parts):
|
|
304
|
+
continue
|
|
305
|
+
|
|
306
|
+
label = "Command" if folder.name in ("commands", "cli") else "Route"
|
|
307
|
+
for ext in ("*.ts", "*.tsx", "*.js", "*.jsx", "*.py", "*.go", "*.rs"):
|
|
308
|
+
for f in folder.glob(ext):
|
|
309
|
+
if not f.name.startswith(("_", ".")):
|
|
310
|
+
rel_file = f.relative_to(project_dir).as_posix()
|
|
311
|
+
routes.append(f"[{label}] {f.stem} -> {rel_file}")
|
|
312
|
+
|
|
313
|
+
except Exception:
|
|
314
|
+
pass
|
|
315
|
+
|
|
316
|
+
return routes[:35] # Cap to prevent unbounded lists
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
# ── Database Models Extractor ─────────────────────────────────────────────────
|
|
320
|
+
|
|
321
|
+
def discover_database_models(project_dir: Path) -> list[str]:
|
|
322
|
+
"""
|
|
323
|
+
Extract data models from Prisma, Django, SQLAlchemy, Drizzle schemas.
|
|
324
|
+
Returns list of discovered model names and schema files.
|
|
325
|
+
"""
|
|
326
|
+
models: list[str] = []
|
|
327
|
+
|
|
328
|
+
try:
|
|
329
|
+
# 1. Prisma schema
|
|
330
|
+
for prisma_path in (project_dir / "prisma" / "schema.prisma", project_dir / "schema.prisma"):
|
|
331
|
+
if prisma_path.exists():
|
|
332
|
+
text = prisma_path.read_text(encoding="utf-8", errors="ignore")
|
|
333
|
+
found = re.findall(r"\bmodel\s+([A-Za-z0-9_]+)\s*\{", text)
|
|
334
|
+
for m in found:
|
|
335
|
+
models.append(f"[Prisma] {m} ({prisma_path.relative_to(project_dir).as_posix()})")
|
|
336
|
+
|
|
337
|
+
# 2. Django / SQLAlchemy models.py
|
|
338
|
+
for models_file in project_dir.rglob("models.py"):
|
|
339
|
+
if "venv" not in models_file.parts and ".git" not in models_file.parts:
|
|
340
|
+
text = models_file.read_text(encoding="utf-8", errors="ignore")
|
|
341
|
+
found = re.findall(r"\bclass\s+([A-Za-z0-9_]+)\s*\(", text)
|
|
342
|
+
for m in found:
|
|
343
|
+
if m not in ("Meta",):
|
|
344
|
+
models.append(f"[Model] {m} ({models_file.relative_to(project_dir).as_posix()})")
|
|
345
|
+
|
|
346
|
+
# 3. Drizzle schema
|
|
347
|
+
for drizzle_file in project_dir.rglob("schema.ts"):
|
|
348
|
+
if "node_modules" not in drizzle_file.parts:
|
|
349
|
+
text = drizzle_file.read_text(encoding="utf-8", errors="ignore")
|
|
350
|
+
found = re.findall(r"export\s+const\s+([A-Za-z0-9_]+)\s+=\s+(?:pgTable|mysqlTable|sqliteTable)", text)
|
|
351
|
+
for m in found:
|
|
352
|
+
models.append(f"[Drizzle] {m} ({drizzle_file.relative_to(project_dir).as_posix()})")
|
|
353
|
+
|
|
354
|
+
except Exception:
|
|
355
|
+
pass
|
|
356
|
+
|
|
357
|
+
return models[:30]
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
# ── Satellites Generator (.agents/context/) ───────────────────────────────────
|
|
361
|
+
|
|
362
|
+
def generate_satellites(project_dir: Path, force: bool = False) -> dict[str, Path]:
|
|
363
|
+
"""
|
|
364
|
+
Generate stack-adaptive satellite files in .agents/context/ on-demand.
|
|
365
|
+
Enforces strict idempotency and zero token bloat in the main hub.
|
|
366
|
+
"""
|
|
367
|
+
satellites_dir = project_dir / ".agents" / "context"
|
|
368
|
+
satellites_dir.mkdir(parents=True, exist_ok=True)
|
|
369
|
+
generated: dict[str, Path] = {}
|
|
370
|
+
|
|
371
|
+
routes = discover_routes(project_dir)
|
|
372
|
+
models = discover_database_models(project_dir)
|
|
373
|
+
|
|
374
|
+
# 1. routes.md (if web routes detected)
|
|
375
|
+
if routes:
|
|
376
|
+
routes_path = satellites_dir / "routes.md"
|
|
377
|
+
routes_content = (
|
|
378
|
+
"# System Route & Endpoint Map\n\n"
|
|
379
|
+
"> Discovered automatically via convention scanner. Used by AI agents for precision navigation.\n\n"
|
|
380
|
+
"| Kind | Route Path | Implementation File |\n"
|
|
381
|
+
"| :--- | :--- | :--- |\n"
|
|
382
|
+
)
|
|
383
|
+
for r in routes:
|
|
384
|
+
parts = r.split(" -> ")
|
|
385
|
+
kind_path = parts[0]
|
|
386
|
+
impl = parts[1] if len(parts) > 1 else ""
|
|
387
|
+
routes_content += f"| {kind_path} | `{impl}` |\n"
|
|
388
|
+
|
|
389
|
+
write_idempotent(routes_path, routes_content, "Routes Satellite")
|
|
390
|
+
generated["routes"] = routes_path
|
|
391
|
+
|
|
392
|
+
# 2. schema.md (if database models detected)
|
|
393
|
+
if models:
|
|
394
|
+
schema_path = satellites_dir / "schema.md"
|
|
395
|
+
schema_content = (
|
|
396
|
+
"# Database Schema & Entity Models\n\n"
|
|
397
|
+
"> Discovered data models and ORM schema definitions. Used by AI agents for database context.\n\n"
|
|
398
|
+
"| Model / Entity | Definition File |\n"
|
|
399
|
+
"| :--- | :--- |\n"
|
|
400
|
+
)
|
|
401
|
+
for m in models:
|
|
402
|
+
schema_content += f"| {m} |\n"
|
|
403
|
+
|
|
404
|
+
write_idempotent(schema_path, schema_content, "Schema Satellite")
|
|
405
|
+
generated["schema"] = schema_path
|
|
406
|
+
|
|
407
|
+
# 3. gotchas.md (Critical Traps & Anti-Patterns — Replaces useless bug diaries)
|
|
408
|
+
gotchas_path = satellites_dir / "gotchas.md"
|
|
409
|
+
if not gotchas_path.exists() or force:
|
|
410
|
+
gotchas_content = (
|
|
411
|
+
"# Critical Gotchas, Anti-Patterns & Architecture Invariants\n\n"
|
|
412
|
+
"> Institutional knowledge and non-obvious traps that cannot be guessed from reading code.\n\n"
|
|
413
|
+
"## ⚠️ Active Constraints & Traps\n\n"
|
|
414
|
+
"1. **Port Invariants:** Inspect discovered ports before binding local services.\n"
|
|
415
|
+
"2. **Secret Isolation:** Production secrets belong in `.env`; dummy dev accounts belong in `context.local.md`.\n"
|
|
416
|
+
"3. **State Boundaries:** Verify migrations before initiating build or release cycles.\n"
|
|
417
|
+
)
|
|
418
|
+
write_idempotent(gotchas_path, gotchas_content, "Gotchas Satellite")
|
|
419
|
+
generated["gotchas"] = gotchas_path
|
|
420
|
+
|
|
421
|
+
return generated
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Standing Agent Rules for {{PROJECT_NAME}}
|
|
2
|
+
|
|
3
|
+
## Critical Mandate: Autonomous Context Synchronization & Precision Architecture
|
|
4
|
+
As an AI coding assistant working in this repository (`{{PROJECT_DIR}}`), you are **strictly mandated** to maintain the Hub & Satellite context architecture, navigate codebases with laser precision, and autonomously crystallize new rules and skills. The user must **never** need to remind or instruct you.
|
|
5
|
+
|
|
6
|
+
### 1. Precision Context Navigation Protocol
|
|
7
|
+
Whenever exploring code or resolving tasks during an active session, follow the precision formula:
|
|
8
|
+
$$\text{Precision Context} = \text{Route Map (Macro)} + \text{Grep/Symbol (Micro)} + \text{Targeted Range Read}$$
|
|
9
|
+
- **Never bulk-read entire directories or loop through 50+ source files.**
|
|
10
|
+
- First inspect `.agents/context/routes.md` or Section 2 of `context.md` for high-level file locations.
|
|
11
|
+
- Use `grep` or symbol search to pinpoint exact files and line numbers.
|
|
12
|
+
- Read only the specific target line range (e.g. `#L30-L70`) rather than loading entire large files.
|
|
13
|
+
|
|
14
|
+
### 2. Mandatory Post-Action Protocol & Satellite Sync (Phase 3)
|
|
15
|
+
Before concluding any turn or session, the agent MUST inspect and update context:
|
|
16
|
+
- **Routes & Pages:** If any API endpoint or UI view is created, modified, or removed, immediately update `.agents/context/routes.md` (or run `init-context scan`).
|
|
17
|
+
- **Database Models:** If any schema, migration, or entity is changed, immediately update `.agents/context/schema.md`.
|
|
18
|
+
- **Architecture Gotchas:** If a non-obvious trap, port collision, or bug invariant is discovered, immediately record it in `.agents/context/gotchas.md`.
|
|
19
|
+
- **Core Hub:** Keep `context.md` compact (< 400 tokens / 60 lines) as an executive routing hub.
|
|
20
|
+
|
|
21
|
+
### 3. Domain Consolidation & Anti-Fragmentation (Single Responsibility)
|
|
22
|
+
When codifying new guidelines or workflows, DO NOT create fragmented micro-files if a domain file already exists:
|
|
23
|
+
- **Docker & Containerization:** Update/append to `.agents/skills/docker-ops/SKILL.md`.
|
|
24
|
+
- **Git & Release Workflows:** Update/append to `.agents/skills/git-workflow/SKILL.md`.
|
|
25
|
+
- **Coding Standards & Patterns:** Update/append to `.agents/rules/code-standards.md`.
|
|
26
|
+
- **Security Boundaries:** Update/append to `.agents/rules/security-boundaries.md`.
|
|
27
|
+
- Only create a new rule or skill file (`init-context -r` / `-s`) if it represents a distinctly new, independent domain.
|
|
28
|
+
|
|
29
|
+
### 4. Context Distillation over Blind Deletion
|
|
30
|
+
Never blindly delete or truncate context:
|
|
31
|
+
- When problem logs or debugging notes grow beyond 50 lines, distill and synthesize the technical root causes into high-density invariants inside `.agents/context/gotchas.md`.
|
|
32
|
+
- Preserve 100% of the architectural wisdom with 90% fewer tokens.
|
|
33
|
+
|
|
34
|
+
### 5. Local Sandbox Test Credentials (`context.local.md`)
|
|
35
|
+
- **Chat Continuity:** When starting a new session or switching chats, always read `context.local.md` to identify local dev ports, seed users, and mock passwords (`admin@test.local`) before running browser automation or curl tests.
|
|
36
|
+
- **Strict Boundary:** Real production secrets, payment keys, and cloud tokens belong strictly in `.env`.
|
|
37
|
+
- Ensure `context.local.md` is protected with `.gitignore` and `chmod 600`.
|
|
38
|
+
|
|
39
|
+
### 6. Autonomous Learning & Tool Access
|
|
40
|
+
- **Zero Token Waste:** DO NOT burn tokens manually searching directories to check for duplicates. Directly run `init-context -r <name> [-g]` — the CLI has instant built-in duplicate detection and collision guards.
|
|
41
|
+
- **Mandatory Global Scope:** When the user mentions "for future", "always", or defines a reusable standard, **MANDATORY: Always pass `--global` (`-g`)** and immediately follow with `init-context memory push`.
|
|
42
|
+
- Available CLI commands:
|
|
43
|
+
- `init-context scan`: Refresh stack-adaptive satellites (`routes.md`, `schema.md`, `gotchas.md`).
|
|
44
|
+
- `init-context -r <name> [-g]`: Create rule.
|
|
45
|
+
- `init-context -s <name> [-g]`: Create skill.
|
|
46
|
+
- `init-context update`: Safely sync public rules and upstream capabilities (non-breaking).
|
|
47
|
+
- `init-context memory push`: Push updates to central memory.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Standing Agent Rules for {{PROJECT_NAME}}
|
|
2
|
+
|
|
3
|
+
## Critical Mandate: Autonomous Context Synchronization & Precision Architecture
|
|
4
|
+
As an AI coding assistant working in this repository (`{{PROJECT_DIR}}`), you are **strictly mandated** to maintain the Hub & Satellite context architecture, navigate codebases with laser precision, and autonomously crystallize new rules and skills. The user must **never** need to remind or instruct you.
|
|
5
|
+
|
|
6
|
+
### 1. Precision Context Navigation Protocol
|
|
7
|
+
Whenever exploring code or resolving tasks during an active session, follow the precision formula:
|
|
8
|
+
$$\text{Precision Context} = \text{Route Map (Macro)} + \text{Grep/Symbol (Micro)} + \text{Targeted Range Read}$$
|
|
9
|
+
- **Never bulk-read entire directories or loop through 50+ source files.**
|
|
10
|
+
- First inspect `.agents/context/routes.md` or Section 2 of `context.md` for high-level file locations.
|
|
11
|
+
- Use `grep` or symbol search to pinpoint exact files and line numbers.
|
|
12
|
+
- Read only the specific target line range (e.g. `#L30-L70`) rather than loading entire large files.
|
|
13
|
+
|
|
14
|
+
### 2. Mandatory Post-Action Protocol & Satellite Sync (Phase 3)
|
|
15
|
+
Before concluding any turn or session, the agent MUST inspect and update context:
|
|
16
|
+
- **Routes & Pages:** If any API endpoint or UI view is created, modified, or removed, immediately update `.agents/context/routes.md` (or run `init-context scan`).
|
|
17
|
+
- **Database Models:** If any schema, migration, or entity is changed, immediately update `.agents/context/schema.md`.
|
|
18
|
+
- **Architecture Gotchas:** If a non-obvious trap, port collision, or bug invariant is discovered, immediately record it in `.agents/context/gotchas.md`.
|
|
19
|
+
- **Core Hub:** Keep `context.md` compact (< 400 tokens / 60 lines) as an executive routing hub.
|
|
20
|
+
|
|
21
|
+
### 3. Domain Consolidation & Anti-Fragmentation (Single Responsibility)
|
|
22
|
+
When codifying new guidelines or workflows, DO NOT create fragmented micro-files if a domain file already exists:
|
|
23
|
+
- **Docker & Containerization:** Update/append to `.agents/skills/docker-ops/SKILL.md`.
|
|
24
|
+
- **Git & Release Workflows:** Update/append to `.agents/skills/git-workflow/SKILL.md`.
|
|
25
|
+
- **Coding Standards & Patterns:** Update/append to `.agents/rules/code-standards.md`.
|
|
26
|
+
- **Security Boundaries:** Update/append to `.agents/rules/security-boundaries.md`.
|
|
27
|
+
- Only create a new rule or skill file (`init-context -r` / `-s`) if it represents a distinctly new, independent domain.
|
|
28
|
+
|
|
29
|
+
### 4. Context Distillation over Blind Deletion
|
|
30
|
+
Never blindly delete or truncate context:
|
|
31
|
+
- When problem logs or debugging notes grow beyond 50 lines, distill and synthesize the technical root causes into high-density invariants inside `.agents/context/gotchas.md`.
|
|
32
|
+
- Preserve 100% of the architectural wisdom with 90% fewer tokens.
|
|
33
|
+
|
|
34
|
+
### 5. Local Sandbox Test Credentials (`context.local.md`)
|
|
35
|
+
- **Chat Continuity:** When starting a new session or switching chats, always read `context.local.md` to identify local dev ports, seed users, and mock passwords (`admin@test.local`) before running browser automation or curl tests.
|
|
36
|
+
- **Strict Boundary:** Real production secrets, payment keys, and cloud tokens belong strictly in `.env`.
|
|
37
|
+
- Ensure `context.local.md` is protected with `.gitignore` and `chmod 600`.
|
|
38
|
+
|
|
39
|
+
### 6. Autonomous Learning & Tool Access
|
|
40
|
+
- **Zero Token Waste:** DO NOT burn tokens manually searching directories to check for duplicates. Directly run `init-context -r <name> [-g]` — the CLI has instant built-in duplicate detection and collision guards.
|
|
41
|
+
- **Mandatory Global Scope:** When the user mentions "for future", "always", or defines a reusable standard, **MANDATORY: Always pass `--global` (`-g`)** and immediately follow with `init-context memory push`.
|
|
42
|
+
- Available CLI commands:
|
|
43
|
+
- `init-context scan`: Refresh stack-adaptive satellites (`routes.md`, `schema.md`, `gotchas.md`).
|
|
44
|
+
- `init-context -r <name> [-g]`: Create rule.
|
|
45
|
+
- `init-context -s <name> [-g]`: Create skill.
|
|
46
|
+
- `init-context update`: Safely sync public rules and upstream capabilities (non-breaking).
|
|
47
|
+
- `init-context memory push`: Push updates to central memory.
|
{auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/context.template.md
RENAMED
|
@@ -28,8 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
| Action | Command |
|
|
30
30
|
| :--- | :--- |
|
|
31
|
-
| **
|
|
32
|
-
| **Codebase Rescan** | `init-context scan` |
|
|
31
|
+
| **Rescan & Sync Runbook** | `init-context scan` |
|
|
33
32
|
<!-- AUTO-CONTEXT:DISCOVERY:END -->
|
|
34
33
|
|
|
35
34
|
---
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: maintain_context
|
|
3
|
+
description: Mandates autonomous, continuous synchronization of context.md and proactive rule/skill learning on any repository or server configuration change without requiring user prompting.
|
|
4
|
+
trigger: always_on
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Autonomous Context Maintenance & Self-Evolution Rule
|
|
8
|
+
|
|
9
|
+
## 1. Precision Context Navigation Protocol
|
|
10
|
+
Whenever exploring code or resolving tasks during an active session, follow the precision formula:
|
|
11
|
+
$$\text{Precision Context} = \text{Route Map (Macro)} + \text{Grep/Symbol (Micro)} + \text{Targeted Range Read}$$
|
|
12
|
+
- **Never bulk-read entire directories or loop through 50+ source files.**
|
|
13
|
+
- First inspect `.agents/context/routes.md` or Section 2 of `context.md` for high-level file locations.
|
|
14
|
+
- Use `grep` or symbol search to pinpoint exact files and line numbers.
|
|
15
|
+
- Read only the specific target line range (e.g. `#L30-L70`) rather than loading entire large files.
|
|
16
|
+
|
|
17
|
+
## 2. Mandatory Post-Action Protocol & Satellite Sync (Phase 3)
|
|
18
|
+
Before concluding any turn or session, the agent MUST inspect and update context:
|
|
19
|
+
- **Routes & Pages:** If any API endpoint or UI view is created, modified, or removed, immediately update `.agents/context/routes.md` (or run `init-context scan`).
|
|
20
|
+
- **Database Models:** If any schema, migration, or entity is changed, immediately update `.agents/context/schema.md`.
|
|
21
|
+
- **Architecture Gotchas:** If a non-obvious trap, port collision, or bug invariant is discovered, immediately record it in `.agents/context/gotchas.md`.
|
|
22
|
+
- **Core Hub:** Keep `context.md` compact (< 400 tokens / 60 lines) as an executive routing hub.
|
|
23
|
+
|
|
24
|
+
## 3. Domain Consolidation & Anti-Fragmentation (Single Responsibility)
|
|
25
|
+
When codifying new guidelines or workflows, DO NOT create fragmented micro-files if a domain file already exists:
|
|
26
|
+
- **Docker & Containerization:** Update/append to `.agents/skills/docker-ops/SKILL.md`.
|
|
27
|
+
- **Git & Release Workflows:** Update/append to `.agents/skills/git-workflow/SKILL.md`.
|
|
28
|
+
- **Coding Standards & Patterns:** Update/append to `.agents/rules/code-standards.md`.
|
|
29
|
+
- **Security Boundaries:** Update/append to `.agents/rules/security-boundaries.md`.
|
|
30
|
+
- Only create a new rule or skill file (`init-context -r` / `-s`) if it represents a distinctly new, independent domain.
|
|
31
|
+
|
|
32
|
+
## 4. Context Distillation over Blind Deletion
|
|
33
|
+
Never blindly delete or truncate context:
|
|
34
|
+
- When problem logs or debugging notes grow beyond 50 lines, distill and synthesize the technical root causes into high-density invariants inside `.agents/context/gotchas.md`.
|
|
35
|
+
- Preserve 100% of the architectural wisdom with 90% fewer tokens.
|
|
36
|
+
|
|
37
|
+
## 5. Local Sandbox Test Credentials (`context.local.md`)
|
|
38
|
+
- **Chat Continuity:** When starting a new session or switching chats, always read `context.local.md` to identify local dev ports, seed users, and mock passwords (`admin@test.local`) before running browser automation or curl tests.
|
|
39
|
+
- **Strict Boundary:** Real production secrets, payment keys, and cloud tokens belong strictly in `.env`.
|
|
40
|
+
- Ensure `context.local.md` is protected with `.gitignore` and `chmod 600`.
|
|
41
|
+
|
|
42
|
+
## 6. Autonomous Learning & Tooling
|
|
43
|
+
- **Zero Token Waste:** DO NOT burn tokens manually searching directories to check for duplicates. Directly run `init-context -r <name> [-g]` — the CLI has instant built-in duplicate detection and collision guards.
|
|
44
|
+
- **Mandatory Global Scope:** When the user mentions "for future", "always", or defines a reusable standard, **MANDATORY: Always pass `--global` (`-g`)** and immediately follow with `init-context memory push`.
|
|
45
|
+
- The agent has full access to run `init-context`:
|
|
46
|
+
- `init-context scan`: Refresh stack-adaptive satellites (`routes.md`, `schema.md`, `gotchas.md`).
|
|
47
|
+
- `init-context update`: Safely sync public rules and upstream capabilities (non-breaking).
|
|
48
|
+
- `init-context memory push`: Push updates to central memory.
|
|
@@ -31,3 +31,4 @@ Prevent monolithic context file bloat, eliminate token waste, ensure 100% idempo
|
|
|
31
31
|
4. **KISS & DRY Heuristics:**
|
|
32
32
|
- Prefer language-agnostic filesystem convention heuristics (directories, manifests) over heavy language AST parsers that crash on in-flight syntax errors.
|
|
33
33
|
- All scanners must degrade gracefully with zero unhandled exceptions.
|
|
34
|
+
|
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
scanner.py — Stack-Adaptive Codebase Introspection & Brownfield Discovery Engine.
|
|
3
|
-
|
|
4
|
-
Discovers ports, routes, database schemas, services, and runbooks using lightweight
|
|
5
|
-
filesystem convention heuristics (0 LLM tokens, 100% crash-proof, idempotency-guaranteed).
|
|
6
|
-
"""
|
|
7
|
-
import hashlib
|
|
8
|
-
import json
|
|
9
|
-
from pathlib import Path
|
|
10
|
-
import re
|
|
11
|
-
from typing import Optional
|
|
12
|
-
|
|
13
|
-
from rich.console import Console
|
|
14
|
-
|
|
15
|
-
console = Console()
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
# ── Idempotency & Hash Helpers ────────────────────────────────────────────────
|
|
19
|
-
|
|
20
|
-
def get_content_hash(text: str) -> str:
|
|
21
|
-
"""Compute SHA-256 hash of text content."""
|
|
22
|
-
return hashlib.sha256(text.encode("utf-8")).hexdigest()
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def write_idempotent(path: Path, content: str, label: str = "File") -> bool:
|
|
26
|
-
"""
|
|
27
|
-
Write content to path only if content has changed (Content-Hash Guard).
|
|
28
|
-
Returns True if a write occurred, False if content was already identical.
|
|
29
|
-
"""
|
|
30
|
-
if path.exists():
|
|
31
|
-
try:
|
|
32
|
-
existing = path.read_text(encoding="utf-8")
|
|
33
|
-
if get_content_hash(existing) == get_content_hash(content):
|
|
34
|
-
console.print(f" [dim]— Up to date:[/] {path.name}")
|
|
35
|
-
return False
|
|
36
|
-
except Exception:
|
|
37
|
-
pass
|
|
38
|
-
|
|
39
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
|
40
|
-
path.write_text(content, encoding="utf-8")
|
|
41
|
-
console.print(f" [green][✓] Synchronized:[/] {path.name}")
|
|
42
|
-
return True
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
# ── Port & Service Extractor ──────────────────────────────────────────────────
|
|
46
|
-
|
|
47
|
-
def discover_ports_and_services(project_dir: Path) -> list[tuple[str, str, str]]:
|
|
48
|
-
"""
|
|
49
|
-
Extract network ports and service bindings from configs without leaking secrets.
|
|
50
|
-
Returns list of (Service, Port, SourceFile).
|
|
51
|
-
"""
|
|
52
|
-
results: list[tuple[str, str, str]] = []
|
|
53
|
-
seen_ports: set[str] = set()
|
|
54
|
-
|
|
55
|
-
# 1. Check docker-compose.yml / compose.yaml
|
|
56
|
-
for compose_name in ("docker-compose.yml", "docker-compose.yaml", "compose.yml", "compose.yaml"):
|
|
57
|
-
compose_file = project_dir / compose_name
|
|
58
|
-
if compose_file.exists():
|
|
59
|
-
try:
|
|
60
|
-
text = compose_file.read_text(encoding="utf-8", errors="ignore")
|
|
61
|
-
matches = re.findall(r'["\']?(\d{2,5}):(\d{2,5})["\']?', text)
|
|
62
|
-
for host_port, container_port in matches:
|
|
63
|
-
if host_port not in seen_ports and int(host_port) > 80:
|
|
64
|
-
seen_ports.add(host_port)
|
|
65
|
-
results.append(("Container Port", host_port, compose_name))
|
|
66
|
-
except Exception:
|
|
67
|
-
pass
|
|
68
|
-
|
|
69
|
-
# 2. Check .env.example / .env
|
|
70
|
-
for env_name in (".env.example", ".env", ".env.local"):
|
|
71
|
-
env_file = project_dir / env_name
|
|
72
|
-
if env_file.exists():
|
|
73
|
-
try:
|
|
74
|
-
for line in env_file.read_text(encoding="utf-8", errors="ignore").splitlines():
|
|
75
|
-
line = line.strip()
|
|
76
|
-
if line.startswith("#") or "=" not in line:
|
|
77
|
-
continue
|
|
78
|
-
key, val = line.split("=", 1)
|
|
79
|
-
key = key.strip()
|
|
80
|
-
val = val.strip().strip('"').strip("'")
|
|
81
|
-
if "PORT" in key.upper() and val.isdigit() and val not in seen_ports:
|
|
82
|
-
seen_ports.add(val)
|
|
83
|
-
results.append((key, val, env_name))
|
|
84
|
-
except Exception:
|
|
85
|
-
pass
|
|
86
|
-
|
|
87
|
-
# 3. Check Dockerfile
|
|
88
|
-
dockerfile = project_dir / "Dockerfile"
|
|
89
|
-
if dockerfile.exists():
|
|
90
|
-
try:
|
|
91
|
-
for line in dockerfile.read_text(encoding="utf-8", errors="ignore").splitlines():
|
|
92
|
-
if line.strip().upper().startswith("EXPOSE "):
|
|
93
|
-
port = line.strip().split()[1]
|
|
94
|
-
if port.isdigit() and port not in seen_ports:
|
|
95
|
-
seen_ports.add(port)
|
|
96
|
-
results.append(("Exposed Port", port, "Dockerfile"))
|
|
97
|
-
except Exception:
|
|
98
|
-
pass
|
|
99
|
-
|
|
100
|
-
return results
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
# ── Runbook Command Extractor ─────────────────────────────────────────────────
|
|
104
|
-
|
|
105
|
-
def discover_runbook_commands(project_dir: Path) -> list[tuple[str, str]]:
|
|
106
|
-
"""
|
|
107
|
-
Extract executable development, build, and test commands from project manifests.
|
|
108
|
-
Returns list of (Action, Command).
|
|
109
|
-
"""
|
|
110
|
-
commands: list[tuple[str, str]] = []
|
|
111
|
-
|
|
112
|
-
# 1. package.json scripts
|
|
113
|
-
pkg_file = project_dir / "package.json"
|
|
114
|
-
if pkg_file.exists():
|
|
115
|
-
try:
|
|
116
|
-
data = json.loads(pkg_file.read_text(encoding="utf-8", errors="ignore"))
|
|
117
|
-
scripts = data.get("scripts", {})
|
|
118
|
-
for key in ("dev", "start", "build", "test", "lint"):
|
|
119
|
-
if key in scripts:
|
|
120
|
-
commands.append((f"Run {key}", f"npm run {key}"))
|
|
121
|
-
except Exception:
|
|
122
|
-
pass
|
|
123
|
-
|
|
124
|
-
# 2. Makefile
|
|
125
|
-
makefile = project_dir / "Makefile"
|
|
126
|
-
if makefile.exists():
|
|
127
|
-
try:
|
|
128
|
-
targets = re.findall(r"^([a-zA-Z0-9_-]+):", makefile.read_text(encoding="utf-8", errors="ignore"), re.M)
|
|
129
|
-
for t in targets[:4]:
|
|
130
|
-
if not t.startswith("."):
|
|
131
|
-
commands.append((f"Make {t}", f"make {t}"))
|
|
132
|
-
except Exception:
|
|
133
|
-
pass
|
|
134
|
-
|
|
135
|
-
# 3. Python indicators
|
|
136
|
-
if (project_dir / "manage.py").exists():
|
|
137
|
-
commands.append(("Django Runserver", "python manage.py runserver"))
|
|
138
|
-
commands.append(("Django Migrate", "python manage.py migrate"))
|
|
139
|
-
elif (project_dir / "pyproject.toml").exists() or (project_dir / "requirements.txt").exists():
|
|
140
|
-
for main_candidate in ("main.py", "app.py", "server.py", "wsgi.py"):
|
|
141
|
-
if (project_dir / main_candidate).exists():
|
|
142
|
-
commands.append(("Start Python Server", f"python {main_candidate}"))
|
|
143
|
-
break
|
|
144
|
-
|
|
145
|
-
# 4. Docker Compose
|
|
146
|
-
if (project_dir / "docker-compose.yml").exists() or (project_dir / "compose.yaml").exists():
|
|
147
|
-
commands.append(("Start Docker Services", "docker compose up -d"))
|
|
148
|
-
|
|
149
|
-
return commands
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
# ── Routes & Endpoints Extractor ──────────────────────────────────────────────
|
|
153
|
-
|
|
154
|
-
def discover_routes(project_dir: Path) -> list[str]:
|
|
155
|
-
"""
|
|
156
|
-
Extract API and UI routes using Next.js, Express, FastAPI, and Django conventions.
|
|
157
|
-
Returns clean list of detected route paths.
|
|
158
|
-
"""
|
|
159
|
-
routes: list[str] = []
|
|
160
|
-
|
|
161
|
-
try:
|
|
162
|
-
# 1. Next.js App Router (app/ or src/app/)
|
|
163
|
-
app_dirs = [d for d in (project_dir / "app", project_dir / "src" / "app") if d.is_dir()]
|
|
164
|
-
for app_dir in app_dirs:
|
|
165
|
-
for file_path in app_dir.rglob("*"):
|
|
166
|
-
if file_path.is_file() and file_path.name in ("route.ts", "route.js", "page.tsx", "page.jsx"):
|
|
167
|
-
rel = file_path.parent.relative_to(app_dir).as_posix()
|
|
168
|
-
route_path = "/" if rel == "." else f"/{rel}"
|
|
169
|
-
kind = "API" if file_path.name.startswith("route") else "Page"
|
|
170
|
-
routes.append(f"[{kind}] {route_path} -> {file_path.relative_to(project_dir).as_posix()}")
|
|
171
|
-
|
|
172
|
-
# 2. Next.js Pages Router (pages/ or src/pages/)
|
|
173
|
-
page_dirs = [d for d in (project_dir / "pages", project_dir / "src" / "pages") if d.is_dir()]
|
|
174
|
-
for page_dir in page_dirs:
|
|
175
|
-
for file_path in page_dir.rglob("*.tsx"):
|
|
176
|
-
if not file_path.name.startswith("_"):
|
|
177
|
-
rel = file_path.relative_to(page_dir).with_suffix("").as_posix()
|
|
178
|
-
route_path = "/" if rel == "index" else f"/{rel.replace('/index', '')}"
|
|
179
|
-
kind = "API" if "api" in rel else "Page"
|
|
180
|
-
routes.append(f"[{kind}] {route_path} -> {file_path.relative_to(project_dir).as_posix()}")
|
|
181
|
-
|
|
182
|
-
# 3. Express / FastAPI / Django Route folders
|
|
183
|
-
for folder_name in ("routes", "controllers", "routers", "endpoints"):
|
|
184
|
-
for candidate in (project_dir / folder_name, project_dir / "src" / folder_name):
|
|
185
|
-
if candidate.is_dir():
|
|
186
|
-
for f in candidate.glob("*.py") if candidate.glob("*.py") else candidate.glob("*.ts"):
|
|
187
|
-
routes.append(f"[Module] {f.stem} -> {f.relative_to(project_dir).as_posix()}")
|
|
188
|
-
|
|
189
|
-
except Exception:
|
|
190
|
-
pass
|
|
191
|
-
|
|
192
|
-
return routes[:35] # Cap to prevent unbounded lists
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
# ── Database Models Extractor ─────────────────────────────────────────────────
|
|
196
|
-
|
|
197
|
-
def discover_database_models(project_dir: Path) -> list[str]:
|
|
198
|
-
"""
|
|
199
|
-
Extract data models from Prisma, Django, SQLAlchemy, Drizzle schemas.
|
|
200
|
-
Returns list of discovered model names and schema files.
|
|
201
|
-
"""
|
|
202
|
-
models: list[str] = []
|
|
203
|
-
|
|
204
|
-
try:
|
|
205
|
-
# 1. Prisma schema
|
|
206
|
-
for prisma_path in (project_dir / "prisma" / "schema.prisma", project_dir / "schema.prisma"):
|
|
207
|
-
if prisma_path.exists():
|
|
208
|
-
text = prisma_path.read_text(encoding="utf-8", errors="ignore")
|
|
209
|
-
found = re.findall(r"\bmodel\s+([A-Za-z0-9_]+)\s*\{", text)
|
|
210
|
-
for m in found:
|
|
211
|
-
models.append(f"[Prisma] {m} ({prisma_path.relative_to(project_dir).as_posix()})")
|
|
212
|
-
|
|
213
|
-
# 2. Django / SQLAlchemy models.py
|
|
214
|
-
for models_file in project_dir.rglob("models.py"):
|
|
215
|
-
if "venv" not in models_file.parts and ".git" not in models_file.parts:
|
|
216
|
-
text = models_file.read_text(encoding="utf-8", errors="ignore")
|
|
217
|
-
found = re.findall(r"\bclass\s+([A-Za-z0-9_]+)\s*\(", text)
|
|
218
|
-
for m in found:
|
|
219
|
-
if m not in ("Meta",):
|
|
220
|
-
models.append(f"[Model] {m} ({models_file.relative_to(project_dir).as_posix()})")
|
|
221
|
-
|
|
222
|
-
# 3. Drizzle schema
|
|
223
|
-
for drizzle_file in project_dir.rglob("schema.ts"):
|
|
224
|
-
if "node_modules" not in drizzle_file.parts:
|
|
225
|
-
text = drizzle_file.read_text(encoding="utf-8", errors="ignore")
|
|
226
|
-
found = re.findall(r"export\s+const\s+([A-Za-z0-9_]+)\s+=\s+(?:pgTable|mysqlTable|sqliteTable)", text)
|
|
227
|
-
for m in found:
|
|
228
|
-
models.append(f"[Drizzle] {m} ({drizzle_file.relative_to(project_dir).as_posix()})")
|
|
229
|
-
|
|
230
|
-
except Exception:
|
|
231
|
-
pass
|
|
232
|
-
|
|
233
|
-
return models[:30]
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
# ── Satellites Generator (.agents/context/) ───────────────────────────────────
|
|
237
|
-
|
|
238
|
-
def generate_satellites(project_dir: Path, force: bool = False) -> dict[str, Path]:
|
|
239
|
-
"""
|
|
240
|
-
Generate stack-adaptive satellite files in .agents/context/ on-demand.
|
|
241
|
-
Enforces strict idempotency and zero token bloat in the main hub.
|
|
242
|
-
"""
|
|
243
|
-
satellites_dir = project_dir / ".agents" / "context"
|
|
244
|
-
satellites_dir.mkdir(parents=True, exist_ok=True)
|
|
245
|
-
generated: dict[str, Path] = {}
|
|
246
|
-
|
|
247
|
-
routes = discover_routes(project_dir)
|
|
248
|
-
models = discover_database_models(project_dir)
|
|
249
|
-
|
|
250
|
-
# 1. routes.md (if web routes detected)
|
|
251
|
-
if routes:
|
|
252
|
-
routes_path = satellites_dir / "routes.md"
|
|
253
|
-
routes_content = (
|
|
254
|
-
"# System Route & Endpoint Map\n\n"
|
|
255
|
-
"> Discovered automatically via convention scanner. Used by AI agents for precision navigation.\n\n"
|
|
256
|
-
"| Kind | Route Path | Implementation File |\n"
|
|
257
|
-
"| :--- | :--- | :--- |\n"
|
|
258
|
-
)
|
|
259
|
-
for r in routes:
|
|
260
|
-
parts = r.split(" -> ")
|
|
261
|
-
kind_path = parts[0]
|
|
262
|
-
impl = parts[1] if len(parts) > 1 else ""
|
|
263
|
-
routes_content += f"| {kind_path} | `{impl}` |\n"
|
|
264
|
-
|
|
265
|
-
write_idempotent(routes_path, routes_content, "Routes Satellite")
|
|
266
|
-
generated["routes"] = routes_path
|
|
267
|
-
|
|
268
|
-
# 2. schema.md (if database models detected)
|
|
269
|
-
if models:
|
|
270
|
-
schema_path = satellites_dir / "schema.md"
|
|
271
|
-
schema_content = (
|
|
272
|
-
"# Database Schema & Entity Models\n\n"
|
|
273
|
-
"> Discovered data models and ORM schema definitions. Used by AI agents for database context.\n\n"
|
|
274
|
-
"| Model / Entity | Definition File |\n"
|
|
275
|
-
"| :--- | :--- |\n"
|
|
276
|
-
)
|
|
277
|
-
for m in models:
|
|
278
|
-
schema_content += f"| {m} |\n"
|
|
279
|
-
|
|
280
|
-
write_idempotent(schema_path, schema_content, "Schema Satellite")
|
|
281
|
-
generated["schema"] = schema_path
|
|
282
|
-
|
|
283
|
-
# 3. gotchas.md (Critical Traps & Anti-Patterns — Replaces useless bug diaries)
|
|
284
|
-
gotchas_path = satellites_dir / "gotchas.md"
|
|
285
|
-
if not gotchas_path.exists() or force:
|
|
286
|
-
gotchas_content = (
|
|
287
|
-
"# Critical Gotchas, Anti-Patterns & Architecture Invariants\n\n"
|
|
288
|
-
"> Institutional knowledge and non-obvious traps that cannot be guessed from reading code.\n\n"
|
|
289
|
-
"## ⚠️ Active Constraints & Traps\n\n"
|
|
290
|
-
"1. **Port Invariants:** Inspect discovered ports before binding local services.\n"
|
|
291
|
-
"2. **Secret Isolation:** Production secrets belong in `.env`; dummy dev accounts belong in `context.local.md`.\n"
|
|
292
|
-
"3. **State Boundaries:** Verify migrations before initiating build or release cycles.\n"
|
|
293
|
-
)
|
|
294
|
-
write_idempotent(gotchas_path, gotchas_content, "Gotchas Satellite")
|
|
295
|
-
generated["gotchas"] = gotchas_path
|
|
296
|
-
|
|
297
|
-
return generated
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# Standing Agent Rules for {{PROJECT_NAME}}
|
|
2
|
-
|
|
3
|
-
## Critical Mandate: Autonomous `context.md` Synchronization & Self-Evolution
|
|
4
|
-
As an AI coding assistant working in this repository (`{{PROJECT_DIR}}`), you are **strictly mandated** to keep `{{PROJECT_DIR}}/context.md` continuously up to date and autonomously learn, persist, and crystallize new rules and skills. The user must **never** need to remind or instruct you.
|
|
5
|
-
|
|
6
|
-
### 1. Mandatory Post-Action Protocol
|
|
7
|
-
Whenever ANY of the following events occur in any session or conversation turn:
|
|
8
|
-
- A configuration file or script is created, edited, moved, or deleted.
|
|
9
|
-
- A problem, bug, or error is encountered and diagnosed.
|
|
10
|
-
- Credentials, tokens, user accounts, or security keys are generated or updated.
|
|
11
|
-
- Architectural decisions or operational steps are modified.
|
|
12
|
-
|
|
13
|
-
**You MUST immediately update `{{PROJECT_DIR}}/context.md` before finalizing your response.**
|
|
14
|
-
|
|
15
|
-
### 2. Autonomous Learning & Self-Evolution Protocol
|
|
16
|
-
Whenever you learn a new pattern, receive a correction, observe a coding preference, or resolve a complex repeatable problem:
|
|
17
|
-
1. **Identify the Type:**
|
|
18
|
-
- **Rule:** If it is a constraint, coding standard, safety boundary, or architectural preference -> Create a Rule (`init-context -r <name>`).
|
|
19
|
-
- **Skill:** If it is a multi-step procedure, deployment workflow, diagnosis runbook, or CLI sequence -> Create a Skill (`init-context -s <name>`).
|
|
20
|
-
2. **Zero Token Waste:**
|
|
21
|
-
- **DO NOT burn tokens manually searching directories or reading files to check for existing rules.** Directly run `init-context -r <name> [-g]` — the CLI has instant built-in duplicate detection and collision guards.
|
|
22
|
-
3. **Mandatory Global Scope:**
|
|
23
|
-
- When the user mentions "for future", "always", or defines a reusable standard, **MANDATORY: Always pass `--global` (`-g`)** and immediately follow with `init-context memory push`.
|
|
24
|
-
- **Project-Specific:** Only omit `-g` if strictly confined to this specific project repository.
|
|
25
|
-
4. **Execution:**
|
|
26
|
-
- Use the `init-context` CLI tool to scaffold the file.
|
|
27
|
-
- Populate it with clear objectives, constraints, or step-by-step instructions.
|
|
28
|
-
- Inform the user of the new rule or skill codified.
|
|
29
|
-
|
|
30
|
-
### 3. Tool Access: `init-context`
|
|
31
|
-
You have native access to run `init-context` via terminal commands:
|
|
32
|
-
- `init-context`: Scaffolds or repairs project context.
|
|
33
|
-
- `init-context -r <rule-name> [-g]`: Creates a new rule with frontmatter.
|
|
34
|
-
- `init-context -s <skill-name> [-g]`: Creates a new skill with frontmatter.
|
|
35
|
-
- `init-context update`: Safely syncs public rules and upstream capabilities (non-breaking).
|
|
36
|
-
- `init-context memory push`: Synchronizes central brain memory to private Git repository.
|
|
37
|
-
|
|
38
|
-
### 4. Required Content & Structure in `context.md`
|
|
39
|
-
1. **Master Credentials & Configuration Vault (Section 1):** Keep all ports, IPs, secrets, tokens, and endpoints synchronized.
|
|
40
|
-
2. **Chronological Problem Log & Technical Solutions (Section 2):** Document symptom, root cause, exact commands/code used, and update Mermaid diagram.
|
|
41
|
-
3. **Architecture & Component Layout (Section 3):** Keep stack overview and directory maps accurate.
|
|
42
|
-
4. **Operations Runbook (Section 4):** Ensure 1-step reproduction instructions remain functional.
|
|
43
|
-
|
|
44
|
-
### 5. Local Sandbox Credentials & Dummy Test Fixtures (`context.local.md`)
|
|
45
|
-
- **Inspection Mandate:** When testing local dev servers, performing browser automation (Playwright/Puppeteer), or authenticating API endpoints, ALWAYS read `context.local.md` first before prompting the user for credentials.
|
|
46
|
-
- **Strict Mock Boundary:** ONLY store dummy test credentials, mock accounts (`admin@test.local`), seed users, and local dev ports in `context.local.md`.
|
|
47
|
-
- **Zero Real Secrets:** Real production secrets, payment keys, or personal tokens MUST NEVER be stored in `context.local.md` or `context.md`; reference them via `.env` or system environment variables.
|
|
48
|
-
- **Git Protection:** Ensure `context.local.md` remains strictly ignored by Git (`.gitignore`) and protected with `chmod 600`.
|
|
49
|
-
|
|
50
|
-
### 6. Two-Tier Progressive Disclosure Protocol (Token Optimization)
|
|
51
|
-
- **Initial Boot Budget:** NEVER read full `SKILL.md` files into the initial context. Use Section 5 of `context.md` for lightweight routing (< 800 tokens).
|
|
52
|
-
- **Dynamic On-Demand Loading:** Only when a user prompt matches a skill's triggers (e.g. "docker", "rebase", "diagnostics", "browser"), dynamically inspect the file using `read_file`.
|
|
53
|
-
- **Zero Session Bloat:** Once the task concludes, do not keep the full skill body in persistent memory.
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# Standing Agent Rules for {{PROJECT_NAME}}
|
|
2
|
-
|
|
3
|
-
## Critical Mandate: Autonomous `context.md` Synchronization & Self-Evolution
|
|
4
|
-
As an AI coding assistant working in this repository (`{{PROJECT_DIR}}`), you are **strictly mandated** to keep `{{PROJECT_DIR}}/context.md` continuously up to date and autonomously learn, persist, and crystallize new rules and skills. The user must **never** need to remind or instruct you.
|
|
5
|
-
|
|
6
|
-
### 1. Mandatory Post-Action Protocol
|
|
7
|
-
Whenever ANY of the following events occur in any session or conversation turn:
|
|
8
|
-
- A configuration file or script is created, edited, moved, or deleted.
|
|
9
|
-
- A problem, bug, or error is encountered and diagnosed.
|
|
10
|
-
- Credentials, tokens, user accounts, or security keys are generated or updated.
|
|
11
|
-
- Architectural decisions or operational steps are modified.
|
|
12
|
-
|
|
13
|
-
**You MUST immediately update `{{PROJECT_DIR}}/context.md` before finalizing your response.**
|
|
14
|
-
|
|
15
|
-
### 2. Autonomous Learning & Self-Evolution Protocol
|
|
16
|
-
Whenever you learn a new pattern, receive a correction, observe a coding preference, or resolve a complex repeatable problem:
|
|
17
|
-
1. **Identify the Type:**
|
|
18
|
-
- **Rule:** If it is a constraint, coding standard, safety boundary, or architectural preference -> Create a Rule (`init-context -r <name>`).
|
|
19
|
-
- **Skill:** If it is a multi-step procedure, deployment workflow, diagnosis runbook, or CLI sequence -> Create a Skill (`init-context -s <name>`).
|
|
20
|
-
2. **Zero Token Waste:**
|
|
21
|
-
- **DO NOT burn tokens manually searching directories or reading files to check for existing rules.** Directly run `init-context -r <name> [-g]` — the CLI has instant built-in duplicate detection and collision guards.
|
|
22
|
-
3. **Mandatory Global Scope:**
|
|
23
|
-
- When the user mentions "for future", "always", or defines a reusable standard, **MANDATORY: Always pass `--global` (`-g`)** and immediately follow with `init-context memory push`.
|
|
24
|
-
- **Project-Specific:** Only omit `-g` if strictly confined to this specific project repository.
|
|
25
|
-
4. **Execution:**
|
|
26
|
-
- Use the `init-context` CLI tool to scaffold the file.
|
|
27
|
-
- Populate it with clear objectives, constraints, or step-by-step instructions.
|
|
28
|
-
- Inform the user of the new rule or skill codified.
|
|
29
|
-
|
|
30
|
-
### 3. Tool Access: `init-context`
|
|
31
|
-
You have native access to run `init-context` via terminal commands:
|
|
32
|
-
- `init-context`: Scaffolds or repairs project context.
|
|
33
|
-
- `init-context -r <rule-name> [-g]`: Creates a new rule with frontmatter.
|
|
34
|
-
- `init-context -s <skill-name> [-g]`: Creates a new skill with frontmatter.
|
|
35
|
-
- `init-context update`: Safely syncs public rules and upstream capabilities (non-breaking).
|
|
36
|
-
- `init-context memory push`: Synchronizes central brain memory to private Git repository.
|
|
37
|
-
|
|
38
|
-
### 4. Required Content & Structure in `context.md`
|
|
39
|
-
1. **Master Credentials & Configuration Vault (Section 1):** Keep all ports, IPs, secrets, tokens, and endpoints synchronized.
|
|
40
|
-
2. **Chronological Problem Log & Technical Solutions (Section 2):** Document symptom, root cause, exact commands/code used, and update Mermaid diagram.
|
|
41
|
-
3. **Architecture & Component Layout (Section 3):** Keep stack overview and directory maps accurate.
|
|
42
|
-
4. **Operations Runbook (Section 4):** Ensure 1-step reproduction instructions remain functional.
|
|
43
|
-
|
|
44
|
-
### 5. Local Sandbox Credentials & Dummy Test Fixtures (`context.local.md`)
|
|
45
|
-
- **Inspection Mandate:** When testing local dev servers, performing browser automation (Playwright/Puppeteer), or authenticating API endpoints, ALWAYS read `context.local.md` first before prompting the user for credentials.
|
|
46
|
-
- **Strict Mock Boundary:** ONLY store dummy test credentials, mock accounts (`admin@test.local`), seed users, and local dev ports in `context.local.md`.
|
|
47
|
-
- **Zero Real Secrets:** Real production secrets, payment keys, or personal tokens MUST NEVER be stored in `context.local.md` or `context.md`; reference them via `.env` or system environment variables.
|
|
48
|
-
- **Git Protection:** Ensure `context.local.md` remains strictly ignored by Git (`.gitignore`) and protected with `chmod 600`.
|
|
49
|
-
|
|
50
|
-
### 6. Two-Tier Progressive Disclosure Protocol (Token Optimization)
|
|
51
|
-
- **Initial Boot Budget:** NEVER read full `SKILL.md` files into the initial context. Use Section 5 of `context.md` for lightweight routing (< 800 tokens).
|
|
52
|
-
- **Dynamic On-Demand Loading:** Only when a user prompt matches a skill's triggers (e.g. "docker", "rebase", "diagnostics", "browser"), dynamically inspect the file using `read_file`.
|
|
53
|
-
- **Zero Session Bloat:** Once the task concludes, do not keep the full skill body in persistent memory.
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: maintain_context
|
|
3
|
-
description: Mandates autonomous, continuous synchronization of context.md and proactive rule/skill learning on any repository or server configuration change without requiring user prompting.
|
|
4
|
-
trigger: always_on
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Autonomous Context Maintenance & Self-Evolution Rule
|
|
8
|
-
|
|
9
|
-
1. **Mandatory Synchronization**: Every agent working in this workspace MUST inspect and update `context.md` before finishing their turn whenever any of the following occur:
|
|
10
|
-
- Script or configuration edits (environment variables, docker-compose, configs, network parameters).
|
|
11
|
-
- Problem diagnosis, debugging steps, and technical solutions.
|
|
12
|
-
- User credentials, tokens, secrets, or permissions changes.
|
|
13
|
-
- Architectural decisions or operational runbooks.
|
|
14
|
-
|
|
15
|
-
2. **Autonomous Learning & Skill Crystallization**:
|
|
16
|
-
- **Zero Token Waste:** DO NOT burn tokens manually searching directories or reading files to check for existing rules. Directly run `init-context -r <name> [-g]` — the CLI has instant built-in duplicate detection and collision guards.
|
|
17
|
-
- **Mandatory Global Scope:** When the user mentions "for future", "always", or defines a reusable standard, **MANDATORY: Always pass `--global` (`-g`)** and immediately follow with `init-context memory push`.
|
|
18
|
-
- Populates the file with clear instructions and notifies the user.
|
|
19
|
-
|
|
20
|
-
3. **CLI Tool Availability**:
|
|
21
|
-
- The agent has full access to run `init-context` directly via terminal:
|
|
22
|
-
- `init-context`: Initialize/repair context.
|
|
23
|
-
- `init-context -r <name> [-g]`: Create rule.
|
|
24
|
-
- `init-context -s <name> [-g]`: Create skill.
|
|
25
|
-
- `init-context update`: Safely sync public rules and upstream capabilities (non-breaking).
|
|
26
|
-
- `init-context memory push`: Push updates to central memory.
|
|
27
|
-
|
|
28
|
-
4. **No User Reminder Needed**: The user must never need to ask the agent to update `context.md` or learn rules. This is a strict automated post-condition for all actions.
|
|
29
|
-
|
|
30
|
-
5. **Local Sandbox Test Credentials (`context.local.md`)**:
|
|
31
|
-
- For local dev logins, automated browser testing, and mock fixtures, inspect and update `context.local.md`.
|
|
32
|
-
- Never store real production secrets or payment tokens in markdown files. Real secrets belong in `.env`.
|
|
33
|
-
- Ensure `context.local.md` is strictly git-ignored and protected with `chmod 600`.
|
|
34
|
-
|
|
35
|
-
6. **Two-Tier Progressive Disclosure**:
|
|
36
|
-
- Never load full `SKILL.md` bodies into the initial context. Use Section 5 of `context.md` for routing.
|
|
37
|
-
- Dynamically load specific skills via `read_file` only when a user prompt matches their triggers.
|
|
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
|
{auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/profile.template.md
RENAMED
|
File without changes
|
{auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/rule.template.md
RENAMED
|
File without changes
|
{auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/rules/code-standards.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{auto_context_cli-1.0.3 → auto_context_cli-1.0.5}/src/auto_context/templates/skill.template.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|