eljay-ai 1.1.0
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.
- package/AGENTS.md +57 -0
- package/README.md +479 -0
- package/agent/__init__.py +10 -0
- package/agent/agent.py +269 -0
- package/agent/agents/__init__.py +34 -0
- package/agent/agents/registry.py +212 -0
- package/agent/builtin_tools.py +591 -0
- package/agent/chat.py +354 -0
- package/agent/config.py +67 -0
- package/agent/context.py +63 -0
- package/agent/edits.py +167 -0
- package/agent/gitaware.py +126 -0
- package/agent/hardware.py +331 -0
- package/agent/knowledge.py +133 -0
- package/agent/memory.py +98 -0
- package/agent/ollama_client.py +133 -0
- package/agent/permissions.py +93 -0
- package/agent/providers/__init__.py +51 -0
- package/agent/providers/base.py +78 -0
- package/agent/providers/image.py +110 -0
- package/agent/providers/ollama.py +111 -0
- package/agent/providers/video.py +96 -0
- package/agent/providers/web.py +155 -0
- package/agent/router.py +200 -0
- package/agent/rules.py +52 -0
- package/agent/runner.py +168 -0
- package/agent/skills.py +161 -0
- package/agent/tools.py +102 -0
- package/agent/verification.py +80 -0
- package/agent/workspace.py +487 -0
- package/bin/eljay +5 -0
- package/bin/eljay.cmd +4 -0
- package/bin/myagent +4 -0
- package/bin/myagent.cmd +4 -0
- package/eljay-ai-1.1.0.tgz +0 -0
- package/eljay.js +56 -0
- package/eljay.py +150 -0
- package/install.ps1 +28 -0
- package/knowledge/reference/diffusers.md +32 -0
- package/knowledge/reference/video-providers.md +21 -0
- package/knowledge/setup/comfyui.md +35 -0
- package/knowledge/setup/image-providers.md +16 -0
- package/knowledge/test-category/test-entry.md +5 -0
- package/myagent.py +30 -0
- package/package.json +40 -0
- package/skills/coding/code-review.md +3 -0
- package/skills/coding/fix-attempt-protocol.md +9 -0
- package/skills/debugging/root-cause-analysis.md +9 -0
- package/skills/general/communication.md +7 -0
- package/skills/laravel/authentication.md +15 -0
- package/skills/mysql/performance.md +9 -0
- package/skills/php/standards.md +8 -0
- package/skills/react/component-best-practices.md +8 -0
- package/skills/research/source-tracking.md +7 -0
- package/skills/security/input-validation.md +9 -0
- package/skills/testing/pytest-best-practices.md +7 -0
- package/tests/run_all.py +34 -0
- package/tests/test_agent_core.py +385 -0
- package/tests/test_capabilities.py +169 -0
- package/tests/test_edits.py +117 -0
- package/tests/test_eljay.py +209 -0
- package/tests/test_runner.py +114 -0
- package/tests/test_universal.py +458 -0
- package/tests/test_workspace.py +221 -0
package/eljay.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""ElJay AI — local AI coding agent entry point.
|
|
2
|
+
|
|
3
|
+
Usage:
|
|
4
|
+
python eljay.py start an interactive chat session
|
|
5
|
+
python eljay.py "your prompt" send a single prompt and exit
|
|
6
|
+
|
|
7
|
+
`myagent.py` is kept as a compatibility alias that delegates here.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import sys
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from agent import __version__, config
|
|
14
|
+
from agent.agent import AgentCore
|
|
15
|
+
from agent.builtin_tools import register_builtin_tools
|
|
16
|
+
from agent.chat import BANNER, ask_permission, ensure_utf8, run_chat, run_once
|
|
17
|
+
from agent.gitaware import branch, changed_files, is_git_repo
|
|
18
|
+
from agent.hardware import detect_hardware, summarize_hardware
|
|
19
|
+
from agent.knowledge import KnowledgeBase
|
|
20
|
+
from agent.memory import Memory
|
|
21
|
+
from agent.ollama_client import OllamaClient, OllamaError
|
|
22
|
+
from agent.permissions import PermissionPolicy
|
|
23
|
+
from agent.router import AgentRouter
|
|
24
|
+
from agent.rules import build_system_prompt, load_rules
|
|
25
|
+
from agent.skills import Skills
|
|
26
|
+
from agent.tools import ToolRegistry
|
|
27
|
+
from agent.workspace import Workspace, find_project_root
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def resolve_model(client: OllamaClient) -> str:
|
|
31
|
+
"""Pick the model to use, verifying it is actually installed."""
|
|
32
|
+
try:
|
|
33
|
+
available = client.list_models()
|
|
34
|
+
except OllamaError as exc:
|
|
35
|
+
print(f"[error] {exc}")
|
|
36
|
+
raise SystemExit(1)
|
|
37
|
+
|
|
38
|
+
if not available:
|
|
39
|
+
print(
|
|
40
|
+
"[error] No Ollama models are installed.\n"
|
|
41
|
+
" Install one, for example: ollama pull qwen2.5-coder:3b"
|
|
42
|
+
)
|
|
43
|
+
raise SystemExit(1)
|
|
44
|
+
|
|
45
|
+
if config.DEFAULT_MODEL in available:
|
|
46
|
+
return config.DEFAULT_MODEL
|
|
47
|
+
|
|
48
|
+
# Requested model is missing — tell the user rather than silently swapping.
|
|
49
|
+
print(
|
|
50
|
+
f"[warn] Model '{config.DEFAULT_MODEL}' is not installed.\n"
|
|
51
|
+
f" Available: {', '.join(available)}\n"
|
|
52
|
+
f" Using '{available[0]}' for now. "
|
|
53
|
+
f"(set AGENT_MODEL to choose a different default)"
|
|
54
|
+
)
|
|
55
|
+
return available[0]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def build_registry(workspace: Workspace, memory: Memory) -> ToolRegistry:
|
|
59
|
+
registry = ToolRegistry()
|
|
60
|
+
register_builtin_tools(registry, workspace, memory)
|
|
61
|
+
return registry
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def main() -> int:
|
|
65
|
+
# Fix console encoding before printing anything (Windows defaults to cp1252).
|
|
66
|
+
ensure_utf8()
|
|
67
|
+
|
|
68
|
+
args = sys.argv[1:]
|
|
69
|
+
if args and args[0] in ("--version", "-V"):
|
|
70
|
+
print(f"ElJay AI {__version__}")
|
|
71
|
+
return 0
|
|
72
|
+
if args and args[0] in ("--help", "-h"):
|
|
73
|
+
print("usage: eljay [\"prompt\"] | eljay --version")
|
|
74
|
+
print("Run with no arguments for an interactive session.")
|
|
75
|
+
return 0
|
|
76
|
+
|
|
77
|
+
client = OllamaClient(config.OLLAMA_HOST, timeout=config.REQUEST_TIMEOUT)
|
|
78
|
+
model = resolve_model(client)
|
|
79
|
+
|
|
80
|
+
# The project the agent works in, detected from the current directory.
|
|
81
|
+
workspace = Workspace(find_project_root(Path.cwd()))
|
|
82
|
+
memory = Memory(workspace)
|
|
83
|
+
registry = build_registry(workspace, memory)
|
|
84
|
+
|
|
85
|
+
# Project rules (AGENTS.md) are binding: inject them into the system prompt.
|
|
86
|
+
rules_text, rules_source = load_rules(workspace)
|
|
87
|
+
system_prompt = build_system_prompt(config.SYSTEM_PROMPT, rules_text, rules_source)
|
|
88
|
+
notes = memory.load_notes()
|
|
89
|
+
if notes:
|
|
90
|
+
system_prompt += "\n\nREMEMBERED NOTES:\n" + "\n".join(f"- {n}" for n in notes)
|
|
91
|
+
policy = PermissionPolicy(
|
|
92
|
+
ask=ask_permission,
|
|
93
|
+
auto_approve=config.AUTO_APPROVE,
|
|
94
|
+
on_event=lambda msg: print(f" {msg}"),
|
|
95
|
+
)
|
|
96
|
+
core = AgentCore(
|
|
97
|
+
client=client,
|
|
98
|
+
model=model,
|
|
99
|
+
registry=registry,
|
|
100
|
+
system_prompt=system_prompt,
|
|
101
|
+
max_steps=config.MAX_STEPS,
|
|
102
|
+
max_context_chars=config.MAX_CONTEXT_CHARS,
|
|
103
|
+
on_event=lambda msg: print(f" {msg}"),
|
|
104
|
+
policy=policy,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# Build the knowledge base and skills system.
|
|
108
|
+
# Global knowledge lives alongside the installed package.
|
|
109
|
+
global_root = str(Path(__file__).resolve().parent)
|
|
110
|
+
knowledge = KnowledgeBase(project_root=workspace.root, global_root=global_root)
|
|
111
|
+
skills = Skills(root=workspace.root)
|
|
112
|
+
# Build the agent router that dispatches to specialized agents.
|
|
113
|
+
router = AgentRouter(core, skills, knowledge, workspace)
|
|
114
|
+
# Detect local hardware for image/video capability assessment.
|
|
115
|
+
hw = detect_hardware()
|
|
116
|
+
hw_summary = summarize_hardware(hw)
|
|
117
|
+
|
|
118
|
+
print(BANNER)
|
|
119
|
+
print(f"Project: {workspace.name} ({workspace.root})")
|
|
120
|
+
stack = workspace.detect_stack()
|
|
121
|
+
if stack:
|
|
122
|
+
print(f"Detected: {', '.join(stack)}")
|
|
123
|
+
if rules_source:
|
|
124
|
+
print(f"Rules : {rules_source} loaded")
|
|
125
|
+
if is_git_repo(workspace):
|
|
126
|
+
current = branch(workspace) or "?"
|
|
127
|
+
print(f"Git : {current} ({len(changed_files(workspace))} changed file(s))")
|
|
128
|
+
print(f"Ollama : {config.OLLAMA_HOST}")
|
|
129
|
+
print(f"Model : {model}")
|
|
130
|
+
print(f"Tools : {len(registry)} available (/tools to list)")
|
|
131
|
+
print(f"Agents : {len(router)} registered (/agents to list)")
|
|
132
|
+
print(f"Skills : {len(skills.all_skills())} loaded (/skills to list)")
|
|
133
|
+
print(f"Knowledge: {len(knowledge.entries())} entries (/knowledge to search)")
|
|
134
|
+
print(f"Hardware: {hw_summary}")
|
|
135
|
+
if not hw.vram_available_gb or hw.vram_available_gb < 4:
|
|
136
|
+
print("Note: Local image/video generation requires >= 4 GB available VRAM or external provider.")
|
|
137
|
+
if config.AUTO_APPROVE:
|
|
138
|
+
print("WARNING: auto-approve is ON — file writes will NOT be confirmed.")
|
|
139
|
+
print("Type /help for commands, /exit to quit.")
|
|
140
|
+
|
|
141
|
+
if len(sys.argv) > 1:
|
|
142
|
+
prompt = " ".join(sys.argv[1:])
|
|
143
|
+
return run_once(core, prompt)
|
|
144
|
+
|
|
145
|
+
run_chat(core, registry, workspace, memory, router=router, skills=skills, knowledge=knowledge, hardware=hw)
|
|
146
|
+
return 0
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
if __name__ == "__main__":
|
|
150
|
+
raise SystemExit(main())
|
package/install.ps1
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Adds this project's bin folder to your USER PATH so you can run `eljay`.
|
|
2
|
+
# Run it yourself from PowerShell: .\install.ps1
|
|
3
|
+
# It only changes your user environment; it does not touch system settings.
|
|
4
|
+
|
|
5
|
+
$bin = Join-Path $PSScriptRoot 'bin'
|
|
6
|
+
|
|
7
|
+
if (-not (Test-Path $bin)) {
|
|
8
|
+
Write-Host "bin folder not found: $bin" -ForegroundColor Red
|
|
9
|
+
exit 1
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
$current = [Environment]::GetEnvironmentVariable('Path', 'User')
|
|
13
|
+
if ($null -eq $current) { $current = '' }
|
|
14
|
+
|
|
15
|
+
if (($current -split ';') -contains $bin) {
|
|
16
|
+
Write-Host "Already on your user PATH: $bin" -ForegroundColor Yellow
|
|
17
|
+
} else {
|
|
18
|
+
$newPath = if ($current.Trim() -eq '') { $bin } else { "$current;$bin" }
|
|
19
|
+
[Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
|
|
20
|
+
Write-Host "Added to your user PATH: $bin" -ForegroundColor Green
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Write-Host ""
|
|
24
|
+
Write-Host "Restart your terminal, then run the agent from any project folder:"
|
|
25
|
+
Write-Host " cd C:\Projects\your-project"
|
|
26
|
+
Write-Host " eljay"
|
|
27
|
+
Write-Host ""
|
|
28
|
+
Write-Host "The old command `myagent` also still works as an alias."
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Diffusers (Hugging Face)
|
|
2
|
+
|
|
3
|
+
Diffusers is the Hugging Face library for diffusion models (Stable Diffusion, etc.).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```powershell
|
|
8
|
+
pip install diffusers[torch] transformers accelerate
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Key Models
|
|
12
|
+
|
|
13
|
+
- `stabilityai/sdxl` — SDXL (requires 8+ GB VRAM)
|
|
14
|
+
- `runwayml/stable-diffusion-v1-5` — SD 1.5 (requires 4+ GB VRAM)
|
|
15
|
+
- `stabilityai/stable-diffusion-2-1` — SD 2.1
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from diffusers import StableDiffusionPipeline
|
|
21
|
+
pipe = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5")
|
|
22
|
+
image = pipe("a futuristic Filipino city, cyberpunk style").images[0]
|
|
23
|
+
image.save("output.png")
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Notes
|
|
27
|
+
|
|
28
|
+
- CPU-only generation is possible with `torch_dtype=torch.float32` but very slow.
|
|
29
|
+
- Use `pipe.enable_attention_slicing()` to reduce VRAM.
|
|
30
|
+
- Models download on first use (~2-7 GB each).
|
|
31
|
+
|
|
32
|
+
Source: https://github.com/huggingface/diffusers
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Video Generation Providers — Status Matrix
|
|
2
|
+
|
|
3
|
+
Video generation is extremely resource-intensive (VRAM + compute).
|
|
4
|
+
|
|
5
|
+
| Provider | Type | Free? | VRAM | Notes |
|
|
6
|
+
|---|---|---|---|---|
|
|
7
|
+
| ComfyUI + AnimateDiff | Local | Free | 6+ GB | Best local option |
|
|
8
|
+
| diffusers + AnimateDiff | Local | Free | 6+ GB | Requires AnimateDiff |
|
|
9
|
+
| --- | --- | --- | --- | --- |
|
|
10
|
+
| RunwayML | API | Paid | — | High quality |
|
|
11
|
+
| Pika Labs | API | Free tier | — | Limited generations/day |
|
|
12
|
+
| Stable Video Diffusion | Local | Free | 10+ GB | Very slow on CPU |
|
|
13
|
+
|
|
14
|
+
## Hardware Requirements
|
|
15
|
+
|
|
16
|
+
- **Minimum for local**: 6 GB VRAM (SD 1.5), 8 GB VRAM (SDXL)
|
|
17
|
+
- **Recommended**: 12+ GB VRAM for smooth generation
|
|
18
|
+
- **CPU-only**: technically possible but 100–1000x slower; not practical
|
|
19
|
+
|
|
20
|
+
If this machine has no discrete GPU with 6+ GB VRAM, video generation is not
|
|
21
|
+
practical locally. Cloud API services are the alternative for this task.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# ComfyUI Setup
|
|
2
|
+
|
|
3
|
+
ComfyUI is a free, open-source, node-based UI for Stable Diffusion. It runs locally
|
|
4
|
+
and supports both GPU and CPU generation.
|
|
5
|
+
|
|
6
|
+
## Installation (Windows)
|
|
7
|
+
|
|
8
|
+
```powershell
|
|
9
|
+
git clone https://github.com/comfyanonymous/ComfyUI.git
|
|
10
|
+
cd ComfyUI
|
|
11
|
+
pip install -r requirements.txt
|
|
12
|
+
python main.py
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Configuration
|
|
16
|
+
|
|
17
|
+
- Set `COMFYUI_DIR` environment variable to your ComfyUI folder.
|
|
18
|
+
- ElJay AI will auto-detect ComfyUI at `%USERPROFILE%\ComfyUI`.
|
|
19
|
+
- The UI runs at http://127.0.0.1:8188.
|
|
20
|
+
|
|
21
|
+
## Usage with ElJay
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
eljay> generate_image prompt="a lone cowboy in a ruined Western town"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
ComfyUI will queue the generation. Check the UI for results.
|
|
28
|
+
|
|
29
|
+
## Notes
|
|
30
|
+
|
|
31
|
+
- CPU generation is possible but 10–50x slower than GPU.
|
|
32
|
+
- VRAM requirements: 4+ GB for SD 1.5, 8+ GB for SDXL.
|
|
33
|
+
- Models download to `ComfyUI/models/checkpoints/`.
|
|
34
|
+
|
|
35
|
+
Source: https://github.com/comfyanonymous/ComfyUI
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Image Generation Providers — Status Matrix
|
|
2
|
+
|
|
3
|
+
| Provider | Type | Cost | API Key? | Notes |
|
|
4
|
+
|---|---|---|---|---|
|
|
5
|
+
| ComfyUI | Local | Free | No | Best quality; Windows-friendly; CPU works |
|
|
6
|
+
| diffusers + torch | Local | Free | No | Flexible; CPU possible but slow |
|
|
7
|
+
| Ollama vision | Local | Free | No | Can edit images, not generate from text |
|
|
8
|
+
| --- | --- | --- | --- | --- |
|
|
9
|
+
| Hugging Face Inference | API | Free tier | Yes (HF token) | Limited; rate-limited |
|
|
10
|
+
| Stability AI | API | Paid | Yes | Reliable; ~$0.002/image |
|
|
11
|
+
| Replicate | API | Paid | Yes | Many models; pay per use |
|
|
12
|
+
|
|
13
|
+
## Recommendation
|
|
14
|
+
|
|
15
|
+
For local-only setups without a GPU, ComfyUI on CPU is the most practical option.
|
|
16
|
+
No free public API can generate images reliably without rate-limiting or API keys.
|
package/myagent.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Compatibility alias for ElJay AI.
|
|
2
|
+
|
|
3
|
+
This file is kept for backwards compatibility. It simply delegates to
|
|
4
|
+
``eljay.py`` so existing workflows (`python myagent.py`, the `myagent`
|
|
5
|
+
launcher) continue to work while the canonical entry point is ``eljay``.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
python myagent.py -> same as `python eljay.py`
|
|
9
|
+
python myagent.py "your prompt" -> same as `python eljay.py "..."`
|
|
10
|
+
|
|
11
|
+
.. deprecated:: 1.1.0
|
|
12
|
+
Use `eljay` / `python eljay.py` instead.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import sys
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
# Ensure the project root (parent of this file) is on sys.path so the
|
|
19
|
+
# `eljay` module can be imported regardless of the launch directory.
|
|
20
|
+
_PROJECT_ROOT = Path(__file__).resolve().parent
|
|
21
|
+
if str(_PROJECT_ROOT) not in sys.path:
|
|
22
|
+
sys.path.insert(0, str(_PROJECT_ROOT))
|
|
23
|
+
|
|
24
|
+
from eljay import main # noqa: E402
|
|
25
|
+
|
|
26
|
+
# Preserve the old module-level name for any code that imports it.
|
|
27
|
+
from eljay import resolve_model, build_registry # noqa: E402,F401
|
|
28
|
+
|
|
29
|
+
if __name__ == "__main__":
|
|
30
|
+
raise SystemExit(main())
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "eljay-ai",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "ElJay AI — a free, local, terminal-based universal AI assistant with Ollama LLM, web research, image & video generation, skills, knowledge base, and project-local memory. Standard library Python only.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai",
|
|
7
|
+
"agent",
|
|
8
|
+
"coding-agent",
|
|
9
|
+
"ollama",
|
|
10
|
+
"local-ai",
|
|
11
|
+
"cli",
|
|
12
|
+
"terminal",
|
|
13
|
+
"code-generation",
|
|
14
|
+
"universal-ai-assistant",
|
|
15
|
+
"image-generation",
|
|
16
|
+
"web-research",
|
|
17
|
+
"skills",
|
|
18
|
+
"knowledge-base"
|
|
19
|
+
],
|
|
20
|
+
"author": "ElJay AI",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"bin": {
|
|
23
|
+
"eljay": "eljay.js",
|
|
24
|
+
"eljay-ai": "eljay.js"
|
|
25
|
+
},
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=20.0.0",
|
|
28
|
+
"python": ">=3.12.0"
|
|
29
|
+
},
|
|
30
|
+
"preferGlobal": true,
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/eljay-ai/eljay-ai.git"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://github.com/eljay-ai/eljay-ai#readme",
|
|
36
|
+
"funding": {
|
|
37
|
+
"type": "individual",
|
|
38
|
+
"url": "https://github.com/sponsors/eljay-ai"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Fix Attempt Protocol
|
|
2
|
+
|
|
3
|
+
1. Inspect the project structure.
|
|
4
|
+
2. Understand the codebase and locate the relevant code.
|
|
5
|
+
3. Explain the problem clearly.
|
|
6
|
+
4. Propose a fix.
|
|
7
|
+
5. Ask for permission before risky changes.
|
|
8
|
+
6. Make the edit.
|
|
9
|
+
7. Verify the actual tool result — never claim success without evidence.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Root Cause Analysis
|
|
2
|
+
|
|
3
|
+
1. Reproduce the error with the actual command/test.
|
|
4
|
+
2. Read the relevant source files.
|
|
5
|
+
3. Trace data flow from input to failure.
|
|
6
|
+
4. Form a hypothesis about the root cause.
|
|
7
|
+
5. Test the hypothesis with a minimal change or log.
|
|
8
|
+
6. Fix the root cause, not the symptom.
|
|
9
|
+
7. Verify the fix resolves the error and does not introduce new ones.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Communication Guidelines
|
|
2
|
+
|
|
3
|
+
- Be concise and accurate. Never fabricate facts.
|
|
4
|
+
- If unsure, say so and suggest how to find out.
|
|
5
|
+
- Match the user's technical level; explain concepts clearly.
|
|
6
|
+
- Use examples when helpful, but keep answers focused.
|
|
7
|
+
- Structure longer answers with headings and lists for readability.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Laravel Authentication
|
|
2
|
+
|
|
3
|
+
Laravel provides authentication out of the box via Breeze, Jetstream, or Fortify.
|
|
4
|
+
|
|
5
|
+
Key concepts:
|
|
6
|
+
- `php artisan make:auth` (legacy) / `composer require laravel/breeze`
|
|
7
|
+
- Guards define how users are authenticated for each request.
|
|
8
|
+
- Providers define how users are retrieved from the database.
|
|
9
|
+
- Middleware: `auth`, `guest`, `verified`.
|
|
10
|
+
- Sanctum for API tokens; Passport for OAuth2.
|
|
11
|
+
|
|
12
|
+
Common issues:
|
|
13
|
+
- Session not persisting → check SESSION_DRIVER and SESSION_DOMAIN.
|
|
14
|
+
- Token mismatch → ensure CSRF token is included in forms.
|
|
15
|
+
- Email verification → run `php artisan migrate` and use Notifiable trait.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# MySQL Performance
|
|
2
|
+
|
|
3
|
+
- Index columns used in WHERE, JOIN, ORDER BY clauses.
|
|
4
|
+
- Use EXPLAIN to understand query plans.
|
|
5
|
+
- Avoid SELECT *; fetch only needed columns.
|
|
6
|
+
- Prefer InnoDB over MyISAM for transaction support.
|
|
7
|
+
- Set innodb_buffer_pool_size to ~70% of available RAM.
|
|
8
|
+
- Use connection pooling for high-throughput applications.
|
|
9
|
+
- Normalize to 3NF, denormalize for read-heavy reporting where needed.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# PHP Coding Standards
|
|
2
|
+
|
|
3
|
+
- Use PSR-12 formatting.
|
|
4
|
+
- Type hint parameters and return types whenever possible.
|
|
5
|
+
- Use strict comparisons (===, !==).
|
|
6
|
+
- Prefer null coalescing (??) over isset chains.
|
|
7
|
+
- Use named arguments in PHP 8+ for clarity with many parameters.
|
|
8
|
+
- Enable error reporting in development: error_reporting(E_ALL).
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# React Component Best Practices
|
|
2
|
+
|
|
3
|
+
- Keep components small and focused (single responsibility).
|
|
4
|
+
- Use props for configuration, state for mutable data.
|
|
5
|
+
- Extract custom hooks for reusable logic.
|
|
6
|
+
- Avoid side effects in render; use useEffect.
|
|
7
|
+
- Memoize expensive computations with useMemo/useCallback.
|
|
8
|
+
- Test components with the testing-library approach: render, query, assert.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Source Tracking
|
|
2
|
+
|
|
3
|
+
- Always cite sources: title, URL, publication/author, date accessed.
|
|
4
|
+
- Distinguish: direct quotes, paraphrased information, and your own reasoning.
|
|
5
|
+
- Never fabricate a citation or pretend a source was consulted.
|
|
6
|
+
- Prefer official documentation, then primary sources, then reputable secondary sources.
|
|
7
|
+
- Summarize in your own words; include key quotes sparingly and with attribution.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Input Validation and Sanitization
|
|
2
|
+
|
|
3
|
+
- Validate all input on the server side — never trust the client.
|
|
4
|
+
- Use allow-lists (whitelists) over block-lists (blacklists).
|
|
5
|
+
- Sanitize before storing, escape on output.
|
|
6
|
+
- For SQL: use parameterized queries/prepared statements.
|
|
7
|
+
- For HTML: escape output with htmlspecialchars() or a templating engine.
|
|
8
|
+
- For shells: avoid user input in commands; use argument arrays.
|
|
9
|
+
- Set strict limits on input length and character sets.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Pytest Best Practices
|
|
2
|
+
|
|
3
|
+
- Name test files `test_*.py`, test classes `*Tests`, test functions `test_*`.
|
|
4
|
+
- One assertion per test; use parametrize for variations.
|
|
5
|
+
- Mock network/external services; assert on the real contract.
|
|
6
|
+
- Run tests from the project root: `python tests/run_all.py`.
|
|
7
|
+
- Never write a test that depends on a specific LLM response.
|
package/tests/run_all.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Run every test module under tests/.
|
|
2
|
+
|
|
3
|
+
python tests/run_all.py
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import glob
|
|
7
|
+
import os
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main() -> int:
|
|
13
|
+
here = os.path.dirname(os.path.abspath(__file__))
|
|
14
|
+
modules = sorted(glob.glob(os.path.join(here, "test_*.py")))
|
|
15
|
+
if not modules:
|
|
16
|
+
print("No test modules found.")
|
|
17
|
+
return 1
|
|
18
|
+
|
|
19
|
+
failures = 0
|
|
20
|
+
for path in modules:
|
|
21
|
+
print(f"\n=== {os.path.basename(path)} ===")
|
|
22
|
+
result = subprocess.call([sys.executable, path])
|
|
23
|
+
failures += result != 0
|
|
24
|
+
|
|
25
|
+
print()
|
|
26
|
+
if failures:
|
|
27
|
+
print(f"{failures} test module(s) FAILED.")
|
|
28
|
+
return 1
|
|
29
|
+
print(f"All {len(modules)} test modules passed.")
|
|
30
|
+
return 0
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
if __name__ == "__main__":
|
|
34
|
+
raise SystemExit(main())
|