How to Setup AGENTS.md & opencode.json in OpenCode (Full Code & Rules)
AGENTS.md & opencode.json Files
AGENTS.md File
Here are the exact AGENTS.md and opencode.json files I use! Feel free to copy, paste, and adapt them for your own workspace.
# AGENTS.md
Project conventions and rules for AI agents and contributors working on this codebase.
## Tech Stack
- HTML
- Vanilla JavaScript (no frameworks, no libraries)
- Plain CSS
- Data persistence via `localStorage`
- No inline CSS and no inline JavaScript
## Project Structure
```
products/
├── index.html
├── css/
│ └── style.css
├── js/
│ └── app.js
└── AGENTS.md
```
- All stylesheets live in `css/`.
- All JavaScript files live in `js/`.
- All HTML files live in the project root.
- Link CSS with `<link rel="stylesheet" href="css/style.css">`.
- Load JavaScript with `<script src="js/app.js"></script>` placed before the closing `</body>` tag.
## Naming Conventions
### Variables
- Use descriptive, meaningful names. Never use single letters like `a`, `b`, `p`, `x`.
- Use `camelCase`.
- Names must describe the value they hold.
Good:
```javascript
const categoryName = "Electronics";
let productName = "Wireless Mouse";
const productPrice = 25.99;
const productList = [];
const selectedCategoryId = 3;
```
Bad:
```javascript
const a = "Electronics";
let p = "Wireless Mouse";
const x = 25.99;
const b = [];
```
### Functions
- Use descriptive verb-first names in `camelCase`.
- Names must clearly state the action being performed.
Good:
```javascript
function addProduct(productName, productPrice, categoryName) { }
function deleteProduct(productId) { }
function updateProduct(productId, updatedProduct) { }
function validateProductForm() { }
function saveProductsToLocalStorage(productList) { }
```
Bad:
```javascript
function doIt(a, b) { }
function handle(x) { }
function f() { }
```
### Function Parameters
- Parameter names must be meaningful and describe the expected value.
Good:
```javascript
function calculateTotalPrice(productPrice, quantity) { }
function filterProductsByCategory(productList, categoryName) { }
```
Bad:
```javascript
function calculateTotalPrice(a, b) { }
function filterProductsByCategory(list, c) { }
```
### HTML and CSS
- Use `kebab-case` for CSS class and ID names.
- Use meaningful IDs for form fields and elements.
```html
<input id="product-name" class="form-input" type="text">
<button id="add-product-button" class="primary-button">Add Product</button>
```
```css
.form-input { }
.primary-button { }
.product-list { }
```
## Coding Rules
### No Ternary Operators
Never use the ternary operator (`condition ? valueA : valueB`). Always use traditional `if` / `else`.
Good:
```javascript
let productStatus;
if (productQuantity > 0) {
productStatus = "In Stock";
} else {
productStatus = "Out of Stock";
}
```
Bad:
```javascript
let productStatus = productQuantity > 0 ? "In Stock" : "Out of Stock";
```
### Template Literals
Use template literals instead of string concatenation.
Good:
```javascript
const productLabel = `${productName} - $${productPrice}`;
```
Bad:
```javascript
const productLabel = productName + " - $" + productPrice;
```
### Keep Files Short and Focused
- Do not create long files.
- Split logic into small, focused functions.
- Separate concerns: DOM rendering, validation, and storage logic should live in separate functions.
- If a file grows too large, split it into multiple files inside the `js/` directory.
### Form Validation
Every form must be validated before processing or saving data.
- Validate required fields are not empty.
- Validate numeric fields contain valid numbers.
- Validate the price is a positive number.
- Validate the quantity is a non-negative integer.
- Show clear error messages next to the relevant field or in an error container.
- Never save invalid data to `localStorage`.
Example:
```javascript
function validateProductForm(productName, productPrice, productQuantity) {
if (productName.trim() === "") {
return "Product name is required.";
}
if (productPrice <= 0) {
return "Product price must be greater than zero.";
}
if (productQuantity < 0) {
return "Product quantity cannot be negative.";
}
return "";
}
```
### Local Storage
All persistent data must be stored in `localStorage` as JSON.
- Use clear, descriptive storage keys.
- Always parse stored data with error handling.
- Always stringify data before saving.
```javascript
const PRODUCTS_STORAGE_KEY = "products";
function saveProductsToLocalStorage(productList) {
localStorage.setItem(PRODUCTS_STORAGE_KEY, JSON.stringify(productList));
}
function getProductsFromLocalStorage() {
const storedProducts = localStorage.getItem(PRODUCTS_STORAGE_KEY);
if (storedProducts === null) {
return [];
}
try {
return JSON.parse(storedProducts);
} catch (parseError) {
console.error("Failed to parse stored products:", parseError);
return [];
}
}
```
## General Guidelines
- Use `const` by default, `let` only when reassignment is required. Never use `var`.
- Use strict equality (`===` and `!==`).
- Use semicolons.
- Use 4-space indentation for JavaScript.
- Add clear error handling for all data operations.
- Keep the user interface responsive and accessible (labels, `alt` text, semantic HTML).
- Test all changes in the browser before considering the task complete.
## Verification Checklist
Before finishing any task:
- [ ] No inline CSS or inline JavaScript in HTML files.
- [ ] CSS files are in `css/`, JavaScript files are in `js/`.
- [ ] All variable and function names are descriptive (no single-letter names).
- [ ] No ternary operators used.
- [ ] Template literals used for dynamic strings.
- [ ] Forms include validation.
- [ ] Data is saved to and loaded from `localStorage`.
- [ ] Files remain short and focused.
opencode.json file
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"edit": "allow",
"bash": {
"*": "allow",
"rm *": "deny",
"rm": "deny",
"rmdir *": "deny",
"rmdir": "deny",
"rd *": "deny",
"rd": "deny",
"del *": "deny",
"del": "deny",
"erase *": "deny",
"erase": "deny",
"Remove-Item *": "deny",
"Remove-Item": "deny",
"remove-item *": "deny",
"remove-item": "deny",
"ri *": "deny",
"ri": "deny",
"git rm *": "deny",
"git clean *": "deny"
}
}
}