just_another_malware_rentfree
v1.0.1
Published
Framework-agnostic agentic coding scaffold for OpenCode — install once, run `ags init` on any project
Maintainers
Readme
agentstack — just_another_malware_rentfree
Framework-agnostic agentic coding scaffold for OpenCode. Install once, run ags init on any project, get a fully configured multi-agent OpenCode setup in under 60 seconds.
Overview
agentstack (aka just_another_malware_rentfree) is a command-line tool that scaffolds a complete multi-agent AI coding environment for any language or framework. It:
- Detects your project's language, framework, and risk profile automatically
- Generates all OpenCode configuration files, agent definitions, and permission blocks
- Provisions agent roles (orchestrator, planner, coder, reviewer, tester, fixer, documenter) with proper model tier assignments
- Manages dependencies, check chains, and escalation procedures per language
No manual YAML editing. No multi-phase setup. Just ags init and you're ready to work with a full agent team.
Features
- 7 language presets: Dart/Flutter, TypeScript/JavaScript, Python, Rust, Go, Swift, Kotlin + Java
- Automatic detection: Language, framework, folder structure, risk signals (auth, payments, DB, etc.)
- Multi-tier agent system:
- Frontier tier (cloud Sonnet/Opus): orchestrator — understands intent, decomposes tasks, writes specs
- Mid tier (cloud Sonnet): planner, reviewer, fixer — judgment work that must be right
- Local tier (Ollama): coder, tester, documenter — workhorse tasks on your machine
- Risk-aware routing: Auth/payment/DB tasks skip local tier, escalate to cloud
- Permission boundaries: Deny reads on
.env, denyrm -rf, denygit push --force - Session hygiene rules: Compact context, one task per session, state file tracking
- Optional MCPs: Serena (symbol-level code intelligence), Context7 (live package docs)
- Git hooks: Lefthook integration for pre-commit/pre-push checks
Prerequisites
Required
- Node.js ≥18 (for the
agsCLI itself) - OpenCode — the agent runtime. Install
- Ollama — for local model execution. Install via
brew install ollamaor ollama.ai
Optional
- uv — Python package manager (only if using Serena MCP)
- lefthook — git hooks framework (
brew install lefthook)
API Keys (add to your shell profile or .env)
export ANTHROPIC_API_KEY="sk-ant-..." # for mid/frontier models
export GOOGLE_API_KEY="..." # for large-context model (Gemini)Installation
1. Install the CLI
npm install -g just_another_malware_rentfreeOr, if developing locally:
git clone https://github.com/yourrepo/agentstack.git
cd agentstack
npm linkVerify:
ags --version2. Set up Ollama (optional but recommended)
If you want local inference on your machine (cheaper, offline, no API keys):
# Install Ollama
brew install ollama
# Pull the recommended local models
ollama pull qwen3-coder-next
ollama pull qwen3:8bWhy these models?
qwen3-coder-next(80B MoE, ~10GB): state-of-the-art code generation, 256K context windowqwen3:8b(8B dense, ~5GB): lightweight model for documentation, commit messages, classification
Both run on 16GB unified memory with good inference speed. If your machine is tight on RAM, fall back to qwen3-coder:30b (30B MoE) or pure dense models.
3. Fix npm cache (one-time, if you hit permission errors)
sudo chown -R $(id -u):$(id -g) ~/.npmQuick Start
Initialize a new project
cd my-project
ags initThe wizard will:
- Detect your language/framework
- Ask to confirm ambiguous fields
- Prompt for cloud provider (Anthropic by default)
- Ask about optional MCPs (Serena, Context7)
- Generate all config files
- Check tool installation
- Offer to pull missing Ollama models
Output:
agentstack v1.0.0
✓ Language: TypeScript (from package.json + tsconfig.json)
✓ Framework: Next.js (from 'next' dependency)
✓ Source root: src/
✓ Folder convention: feature-first
✓ Risk signals: next-auth, stripe, prisma
Confirming settings...
? Backend type: REST (detected) / GraphQL / gRPC / Firebase / Supabase / None
? Cloud provider: Anthropic (recommended) / Google / OpenAI / OpenRouter
? Enable Serena? Y/n
? Enable Context7? Y/n
Generating files...
✓ .ags.json
✓ AGENTS.md
✓ opencode.json
✓ .opencodeignore
✓ .opencode/agents/orchestrator.md
✓ .opencode/agents/planner.md
✓ .opencode/agents/coder.md
✓ .opencode/agents/reviewer.md
✓ .opencode/agents/tester.md
✓ .opencode/agents/fixer.md
✓ .opencode/agents/documenter.md
✓ routing-table.yaml
✓ lefthook.yml
✓ docs/session-state.md
✓ Setup complete. Run 'opencode' to start.Review generated files
cat AGENTS.md # Project identity, risk categories, escalation rules
cat opencode.json # Model config, permissions, MCP servers
cat .opencodeignore # Files excluded from agent context
ls -la .opencode/agents/Commit the setup
git add .ags.json AGENTS.md opencode.json .opencodeignore routing-table.yaml lefthook.yml
git commit -m "chore: init agentstack v1.0.0"Start using OpenCode
opencodeGive your orchestrator a task and it will decompose, delegate, and verify with the full agent team.
Commands Reference
ags init [--manual] [--force]
Initialize agentstack in the current directory.
Options:
--manual— Force the full interactive wizard even if detection is confident--force— Overwrite manually edited files (normally skipped)--dir <path>— Target a different directory
What it does:
- Detects project language, framework, folder structure, risk signals
- Runs wizard for any ambiguous fields
- Generates all config files (AGENTS.md, opencode.json, agent definitions, etc.)
- Checks OpenCode and Ollama installation
- Offers to pull missing Ollama models
- Creates
.ags.jsonstate file to track which files you've manually edited
Output files:
AGENTS.md— Your project's agent playbook (conventions, risk categories, check chain, escalation rules)opencode.json— OpenCode config (model assignment, permissions, MCPs, instructions).opencodeignore— Files and directories excluded from agent context.opencode/agents/*.md— 7 agent definitions with model configs and system promptsrouting-table.yaml— Task category → model tier routing tablelefthook.yml— Pre-commit/pre-push git hooksdocs/session-state.md— Template for tracking context across resets.ags.json— Metadata: version, detected fields, file hashes
ags update [--force]
Re-detect the project and regenerate unmodified files.
When to use:
- After upgrading the
just_another_malware_rentfreepackage - When you want to pick up improved templates
- When your project's structure has changed significantly
Behavior:
- Files you manually edited (detected via hash) are skipped unless
--force - Fields previously marked as manual stay manual (won't be re-detected)
.ags.jsonis always updated
ags validate
Check config consistency and verify files.
Checks:
- All expected files exist and haven't drifted from generation
opencode.jsonis valid JSON with required fields- Secret files (
.env,*.pem,*.key) are denied in permissions - Destructive commands (
rm -rf,git push --force) are denied - Agent files have valid frontmatter and model configuration
Use this before committing to catch stale or malformed configs.
ags check-tools
Report installation status of OpenCode, Ollama, and configured models.
Output:
agentstack check-tools
Required:
✓ OpenCode 1.17.4
✓ Ollama Warning: could not connect to a running Ollama instance
Optional:
○ uv not installed
○ lefthook not installed
Models:
✓ qwen3-coder-next available
✓ qwen3:8b availableags doctor
Comprehensive health check: tools + config validation + permission tests.
Runs:
- Tool installation checks (OpenCode, Ollama, uv, lefthook)
- Model availability (if Ollama is installed)
- Configuration validation (same as
ags validate) - Permission block tests (confirms
*.envis denied,rm -rfis denied, etc.)
Use this to troubleshoot before reporting issues.
ags eject
Copy generated files to ags-templates/ for full customization.
When to use:
- You want to customize AGENTS.md, agent prompts, or permission rules
- You're managing many projects with shared conventions
- You want version control over templates
After ejecting:
- Edit files in
ags-templates/ ags updatewill no longer overwrite them- You own the maintenance burden
Generated Files Reference
AGENTS.md — Your Project's Agent Playbook
This file is the single source of truth for your agent team. It contains:
Identity
# Project: my-app
## Identity
- **Language:** typescript
- **Framework:** nextjs
- **Source root:** src/
- **Folder convention:** feature-first
- **Backend:** restConventions Language/framework-specific best practices. Examples:
- Dart: "Use flutter_bloc pattern: events → bloc → states"
- TypeScript: "Use Server Components by default, Client Components only when interactivity is required"
- Python: "Type hints on all function signatures"
Risk Categories Tasks touching these skip the local tier on first attempt:
- Auth/identity (any authentication or authorization code)
- Payments/billing (Stripe, PayPal, in-app purchases, etc.)
- Database migrations (schema changes touching production)
- Infrastructure/deployment (CI/CD, cloud config, IaC)
- Secrets/signing (API keys, certificates, signing configs)
- Concurrency/native interop (threads, isolates, FFI, CGo)
Escalation Procedure
1. coder (local tier) attempts the task
2. Run the check chain (zero LLM cost)
3. If checks fail, let same tier retry once
4. If checks fail twice, escalate to fixer (mid tier)
5. If fixer fails twice, escalate to mid-tier coder
6. If checks pass, route to reviewer (fresh-context review)
7. Reviewer feedback goes back to coder/fixer (not user)
unless it's a spec-level problemCheck Chain Language-specific verification commands run after every code change:
For TypeScript/Node:
npx tsc --noEmit
npm run lint -- --max-warnings=0
npm testFor Python:
ruff check .
mypy .
pytestFor Rust:
cargo check
cargo clippy -- -D warnings
cargo testBudget Modes | Mode | Retries | Risk Scope | Use Case | |---|---|---|---| | Economy | 3 | auth + payments | Cost-sensitive | | Balanced | 2 | all high-risk | Default | | Quality | 1 | any concern | Production |
Session Hygiene
- Compact context at message 25 (don't wait for auto-compaction)
- One session per distinct task
- Write current state to
docs/session-state.mdbefore resets - Pipe verbose shell output through
| head -200
opencode.json — Agent Runtime Config
Configures the OpenCode agent runtime:
{
"$schema": "https://opencode.ai/config.json",
"model": "anthropic/claude-sonnet-4-6", // Orchestrator (frontier)
"small_model": "ollama/qwen3:8b", // Documentation (local-light)
"default_agent": "orchestrator",
"provider": {
"anthropic": { "options": { "timeout": 600000 } },
"ollama": { "options": { "baseURL": "http://localhost:11434" } }
},
"permission": {
"edit": {
"*": "ask",
"src/**": "allow",
"test/**": "allow",
"*.env": "deny",
"*.lock": "deny",
"*.pem": "deny"
},
"bash": {
"*": "ask",
"rm -rf *": "deny",
"git push --force*": "deny",
"sudo *": "deny"
},
"read": {
"*.env": "deny",
"*.pem": "deny",
"service-account*.json": "deny"
}
},
"mcp": {
// Optional MCPs (Serena, Context7, etc.)
},
"instructions": ["AGENTS.md"]
}Key fields:
model— Default agent (orchestrator). Uses frontier-tier model.small_model— Used for lightweight tasks (documentation, classification).permission.edit— Which files can be edited (allow/deny/ask)permission.bash— Which shell commands can be runpermission.read— Which files can be readinstructions— Files the agents read for context (usually just AGENTS.md)
.opencodeignore — Context Exclusion
Excludes files/dirs from agent context (similar to .gitignore):
# Universal
node_modules/
vendor/
.venv/
target/
dist/
build/
# Secrets
*.env
*.pem
*.key
*.p12
# Language-specific (auto-added)
# TypeScript:
.turbo/
.vercel/
coverage/
*.tsbuildinfo
# Python:
*.pyc
.mypy_cache/
.pytest_cache/
# Dart/Flutter:
*.g.dart
*.freezed.dart
.dart_tool/
ios/Pods/.opencode/agents/*.md — Agent Definitions
Each agent has a markdown file with frontmatter config + system prompt.
Example: .opencode/agents/coder.md
---
description: "Writes code for a single, well-scoped task. Follows specs exactly."
model:
id: "ollama/qwen3-coder-next"
mode: subagent
temperature: 0.2
steps: 30
---
You are a typescript nextjs expert coder.
## Your job
You receive a detailed task spec from the orchestrator. Implement it exactly.
## Rules
- Implement ONLY what the spec asks for. No scope creep.
- Add input validation and error handling even if spec doesn't mention it.
- Add null/undefined checks at boundaries.
- Follow the project conventions in AGENTS.md exactly.
- If the spec is ambiguous, implement the most defensive interpretation.
- Do NOT invoke other agents. If task is too large, say so.
## Output format
End with:
confidence: low|med|high
reason: [one sentence]7 agents provided:
- orchestrator (frontier, cloud) — Understands intent, asks clarifying questions, decomposes
- planner (mid, cloud) — Architecture decisions, file changes, execution order
- coder (local) — Writes code for a single, well-scoped task
- reviewer (mid, cloud) — Fresh-context review, security, performance, spec compliance
- tester (local) — Writes tests covering happy path, boundaries, error cases
- fixer (mid, cloud) — Diagnoses and fixes failing tests with minimal diffs
- documenter (local-light) — Commit messages, documentation, changelog
.ags.json — State File
Tracks what was auto-detected vs. manually confirmed, and file hashes:
{
"version": "1.0.0",
"detectedFields": ["language", "framework", "folderConvention"],
"manualFields": ["backend", "cloudProvider"],
"projectType": {
"language": "typescript",
"framework": "nextjs"
},
"fileHashes": {
"AGENTS.md": "a1b2c3d4...",
"opencode.json": "e5f6g7h8...",
".opencodeignore": "i9j0k1l2..."
}
}Commit this to git. It's used by ags update to:
- Skip manually edited files (hash differs)
- Preserve manual field assignments across re-runs
How It Works
Detection Pipeline
- Language detection — Looks for manifest files (package.json, pubspec.yaml, Cargo.toml, etc.)
- Framework detection — Parses manifests, looks at dependencies
- Folder structure — Detects feature-first, layer-first, or flat convention
- Risk analysis — Scans for auth (Firebase Auth, next-auth), payments (Stripe, PayPal), database (Prisma, SQLAlchemy), infrastructure packages
Rendering
Each file is generated by:
- Reading a template or composing from sections (AGENTS.md uses section composer)
- Substituting language/framework-specific variables
- Writing to disk with a content hash
- Checking against
.ags.json— if manually edited, skipping onags update
Agent Tier Assignment
Tasks are routed based on risk:
Standard risk → local tier (Ollama):
- UI component updates
- CRUD operations
- Test writing
- Documentation
- Refactoring
High risk → mid tier (cloud Sonnet):
- Auth/identity changes
- Payment processing
- Database migrations
- Infrastructure/deployment
- Security config
- Native interop
Escalation on failure:
- Local tries, fails 2x → escalates to fixer (mid)
- Fixer fails 2x → re-runs same task with mid-tier coder
Project Structure
After ags init, your project looks like:
my-project/
├── .ags.json # State file
├── AGENTS.md # Project playbook
├── opencode.json # OpenCode config
├── .opencodeignore # Context exclusion
├── .opencode/
│ ├── agents/
│ │ ├── orchestrator.md
│ │ ├── planner.md
│ │ ├── coder.md
│ │ ├── reviewer.md
│ │ ├── tester.md
│ │ ├── fixer.md
│ │ └── documenter.md
│ └── (future MCPs)
├── routing-table.yaml # Routing rules (reference only)
├── lefthook.yml # Git hooks config
├── docs/
│ └── session-state.md # Template for context tracking
├── src/ # Your source code
├── package.json # (or pubspec.yaml, pyproject.toml, etc.)
└── ...Customization & Advanced Usage
Manual Edits (won't be overwritten)
Once you edit a file, ags update skips it unless you use --force:
# Safe to edit (won't be overwritten):
vim AGENTS.md
vim .opencode/agents/coder.md
vim opencode.json
# Then update other files:
ags updateEjecting Templates
For full control, eject templates to your repo:
ags ejectThis copies all generated files to ags-templates/. Now they're yours; ags update won't touch them.
Adding a New Language
Create
src/detector/presets/newlang.tswith:- Manifest file patterns
- Framework detection rules
- Risk package signatures
- Ignore patterns
- Check commands
- Bash permission rules
Register in
src/detector/presets/index.ts:import { preset as newlang } from './newlang.js'; export const presets: LanguagePreset[] = [ // ... existing presets newlang, ];Rebuild and test:
npm run build npm test
Enabling Serena MCP (Symbol-Level Code Intelligence)
If you said "yes" to Serena during ags init, it's already in opencode.json:
"mcp": {
"serena": {
"type": "local",
"command": ["uvx", "serena-mcp"]
}
}Requires uv (Python package manager). Install:
curl -LsSf https://astral.sh/uv/install.sh | shSerena provides:
- Symbol-level lookups (faster than reading whole files)
- Type hierarchies and implementations
- Call graphs
Model Swaps
To use a different local model:
Pull it:
ollama pull <new-model>Update
.opencode/agents/coder.md:model: id: "ollama/<new-model>"Done. No other files need changes.
Using a Different Cloud Provider
To switch from Anthropic to Google:
Edit
opencode.json:"model": "google/gemini-2.5-pro", "small_model": "google/gemini-2.5-flash"Edit
.opencode/agents/orchestrator.md:model: id: "google/gemini-2.5-pro"Set your API key:
export GOOGLE_API_KEY="..."
Troubleshooting
"Cannot read properties of undefined (reading 'load')"
Cause: js-yaml ESM import issue (rare, usually during development)
Fix:
npm install
npm run build"OpenCode not found" or "Ollama not found"
Fix:
ags check-tools
# Install missing tools
curl -fsSL https://opencode.ai/install | bash # OpenCode
brew install ollama # Ollama (macOS)"Model 'qwen3-coder-next' not found"
Fix:
ollama pull qwen3-coder-nextPermission errors on npm install
Fix:
sudo chown -R $(id -u):$(id -g) ~/.npm"Could not connect to Ollama" warning
Cause: Ollama daemon not running
Fix:
brew services start ollama # macOS
# Or open the Ollama app on macOS, or start the Linux serviceAgent keeps asking to read .env files
Cause: Permission blocks aren't configured
Fix:
ags doctor # Verify permissions
ags validate # Check configYou should see:
✓ read[*.env] = denyLimits & Caveats
Model Context Windows
- Local models (qwen3-coder-next): 256K tokens
- Cloud Sonnet: 200K tokens
- Cloud Gemini 2.5: 1M tokens (use for large-codebase scans)
Long conversations will trigger auto-compaction. Write state to docs/session-state.md before forcing resets.
Ollama RAM Usage
qwen3-coder-next(MoE): ~10GB on 16GB unified memoryqwen3:8b: ~5GB- Both models in memory simultaneously: ~15GB (tight on 16GB)
Ollama auto-unloads idle models after 5 minutes. For back-to-back sessions, they load fast from disk.
Git Hooks (Lefthook)
After ags init, install hooks:
lefthook installHooks run the check chain on every commit/push. Disable with:
lefthook disableBest Practices
1. One Session Per Task
Decompose large features into multiple sessions. Agents lose context after ~25 messages. Start a new OpenCode session for each feature/bug.
2. Write Session State Before Context Reset
# Before /clear or context rollover
echo "## Current state
- Completed: user auth flow
- In progress: email verification
- Next: reset password endpoint
- Blockers: none" >> docs/session-state.md3. Review AGENTS.md Conventions
Before asking the team to build something, read the conventions section:
cat AGENTS.md | grep -A 20 "## Conventions"It tells agents language-specific best practices (error handling, state management, etc.).
4. Pipe Verbose Output
If check chains or shell commands produce long output:
# Instead of:
pytest
# Do:
pytest | head -200Saves tokens on large test outputs.
5. Commit AGENTS.md Changes
When you manually edit AGENTS.md (e.g., add a new risk category), commit it:
git add AGENTS.md
git commit -m "docs(agents): add new risk category X"This documents conventions for future team members (and LLMs reading git history).
6. Validate Before Committing
ags validateCatches stale or malformed configs before they hit production.
FAQ
Q: Do I have to use Ollama?
A: No. You can use only cloud models. Set localCoderModel to a cloud model during ags init (though this defeats the purpose of fast, local inference).
Q: Can I use models other than the defaults?
A: Yes. Edit .opencode/agents/*.md to reference different models. ags doesn't lock you in.
Q: What if my project is monorepo with multiple languages?
A: Run ags init in each language subdirectory. Each gets its own opencode.json and agent configs.
Q: Can I customize the agent prompts?
A: Yes. Edit .opencode/agents/*.md. After you edit, ags update will skip them (change detected via hash).
Q: What's the cost of using frontier models for the orchestrator? A: Frontiers models (Sonnet 4.6, Opus 4.8) are more expensive than Haiku. But orchestrator is called once per high-level task (not per file edit), so the cost is acceptable for better decomposition. A 10-minute development session might cost $0.50–$2 in API calls depending on context size.
Q: Can I run the agents offline? A: Partially. Local tier (coder, tester, documenter) runs entirely offline via Ollama. Mid and frontier tiers require cloud API access. You can work on standard-risk tasks offline, but high-risk tasks (auth, payments, infra) need internet.
Q: How often should I run ags update?
A: After upgrading the just_another_malware_rentfree package. The tool evolves; ags update picks up improvements to templates while respecting your manual edits.
Contributing
Found a bug? Want to add a language preset? Open an issue or PR at the repository.
Adding a preset:
- Create
src/detector/presets/yourlang.ts - Register in
src/detector/presets/index.ts - Add tests in
tests/detector.test.ts - Run
npm testto verify
Reporting issues:
- Run
ags doctorfirst (it's comprehensive) - Include your output and OS/Node.js version
License
MIT. See LICENSE.
Acknowledgments
Inspired by OpenCode's agent SDK and the Anthropic SDK. Built to be the missing scaffold for multi-agent development.
Questions? Stuck? Run ags doctor or ags validate to troubleshoot. Both are comprehensive and usually point to the issue.
