student@ubuntu:~$
Guide

Coding Agents and Launch Scripts

Understand coding agents, configure permissions, and write launch scripts that automate AI workflows.

You set up OpenCode and connected GitHub Copilot. Now you are going to learn what coding agents actually are, how to customize them, and how to write launch scripts that automate your workflow.

By the end of this page, you will have built a shell script that launches an AI agent to do work for you.


What Is a Coding Agent?

A coding agent is an AI that can act, not just answer.

  Chatbot Coding Agent
Read your code Yes Yes
Answer questions Yes Yes
Write/edit files No Yes
Run terminal commands No Yes
Iterate on errors No Yes
Multi-step plans No Yes

When you tell a coding agent “add tests for the login module,” it:

  1. Reads your login code to understand it
  2. Creates a test file
  3. Writes test cases
  4. Runs the tests
  5. Fixes any failures
  6. Repeats until green

That loop — read, plan, act, observe, adjust — is what makes it an agent.


Overview: Coding Agents in 2026

Tool Open Source Terminal-Native Free Option
OpenCode Yes Yes GitHub Copilot (Student Pack)
Claude Code No (proprietary) Yes No (requires Claude subscription)
Cursor No (proprietary) No (IDE) Limited free tier
Aider Yes Yes Bring your own API key
Continue Yes No (IDE plugin) Bring your own API key

We use OpenCode because it is free, open-source, runs in the terminal, and works with GitHub Copilot. No vendor lock-in.


OpenCode’s Built-In Agents

OpenCode has two primary agents you switch between with the Tab key:

Plan Agent

Creates an implementation plan without making changes.

# Press Tab to switch to Plan mode (you will see "plan" in the bottom-right)
I need to add user authentication to this Express app

It will outline the steps, files to create/modify, and dependencies needed — but it will not touch anything.

Build Agent

Executes code changes step by step.

# Press Tab again to switch back to Build mode
implement the authentication plan we just made

This is the agent that actually writes files and runs commands.

Switch between them anytime with the Tab key. There are also built-in subagents (General and Explore) that you can invoke with @general or @explore in your message.


Creating Custom Agents

You define custom agents as markdown files in .opencode/agents/. Each file sets a name, model, available tools, and a system prompt.

Create .opencode/agents/reviewer.md:

---
name: reviewer
description: Strict code reviewer for CSCD 240
mode: subagent
tools:
  write: false
  edit: false
  bash: false
---

You are a strict code reviewer for CSCD 240.

Rules:
- Check for proper error handling on every system call
- Verify all file descriptors are closed
- Flag any hardcoded paths (should use constants or args)
- Check for buffer overflow risks in C code
- Ensure consistent formatting (4-space indent, K&R braces)

Output format:
For each issue, show:
1. File and line number
2. The problem
3. How to fix it
4. Why it matters

Be direct. Do not sugarcoat.

Now inside OpenCode:

@reviewer review all .c files in src/

That agent now enforces CSCD 240 review standards on any file set you point it at.


Permissions: Autonomy vs. Safety

Every agent needs a permission model. Here is why:

You: "clean up the temp files"
Agent: rm -rf /tmp/*     ← could wipe system temp files
Agent: rm ./tmp/*.log    ← safe, scoped to project

The Three Levels

Ask (default, safest): The agent shows you every command and file write before executing. You approve each one.

Allow (autonomous): The agent runs everything without asking. Use this when you trust the agent and the task.

Deny: Block specific dangerous operations.

Granular Rules

{
  "permission": {
    "edit": {
      "*": "ask",
      "src/**": "allow",
      "tests/**": "allow"
    },
    "bash": {
      "*": "ask",
      "make *": "allow",
      "gcc *": "allow",
      "git status": "allow",
      "git diff": "allow",
      "rm -rf *": "deny",
      "sudo *": "deny"
    },
    "read": {
      "*": "allow",
      "*.env": "deny",
      "*.key": "deny"
    }
  }
}

Start with ask. Switch to allow only for well-understood, reversible tasks.


Launch Scripts: Automating Agent Workflows

A launch script is a shell script that starts an agent with a specific prompt and configuration. Instead of typing instructions every time, you script them.

Basic Launch Script

Create ~/bin/code-review.sh:

#!/usr/bin/env bash
# Launch OpenCode as a code reviewer for the current directory
set -euo pipefail

if [ ! -d ".git" ]; then
    echo "Error: run this from a git repository root" >&2
    exit 1
fi

PROJECT_NAME=$(basename "$PWD")
echo "Starting code review for: $PROJECT_NAME"

opencode run "Review all source files in this project. For each file:
1. Check for bugs and logic errors
2. Check for security issues
3. Check for style violations
4. Suggest improvements
Output a summary at the end with total issues found."

Make it executable and run it:

chmod +x ~/bin/code-review.sh
cd ~/your-project
code-review.sh

Task-Based Routing

One script, multiple modes:

#!/usr/bin/env bash
# ~/bin/ai-task.sh — route different tasks to different prompts
set -euo pipefail

TASK="${1:?Usage: ai-task.sh <review|test|docs|fix>}"

case "$TASK" in
    review)
        PROMPT="Review all source files for bugs, security issues, and style problems."
        ;;
    test)
        PROMPT="Find all functions without tests. Write comprehensive test cases for each one."
        ;;
    docs)
        PROMPT="Add or update documentation: README, function docstrings, and inline comments where logic is non-obvious."
        ;;
    fix)
        PROMPT="Run the test suite. Fix every failing test. Do not skip any."
        ;;
    *)
        echo "Unknown task: $TASK" >&2
        echo "Options: review, test, docs, fix" >&2
        exit 1
        ;;
esac

echo "Running task: $TASK"
opencode run "$PROMPT"
ai-task.sh review    # code review
ai-task.sh test      # generate tests
ai-task.sh docs      # update docs
ai-task.sh fix       # fix failing tests

The Agent-Lane Pattern

The agent-lane system used in this course takes this further: it connects a launch script to a task database so the agent knows what to work on without manual prompts.

The pattern:

  1. A database holds tasks (quests) with status tracking
  2. The launch script reads the database for the next task
  3. It constructs a prompt from the task details
  4. It launches the agent with that prompt
  5. The agent works the task and updates the database when done
#!/usr/bin/env bash
# Simplified agent-lane concept
set -euo pipefail

DB="$HOME/.local/share/profdb/databases/quests.db"
LANE="$1"

# Get the next pending quest for this lane
QUEST=$(sqlite3 "$DB" "SELECT id FROM quests WHERE status='available' LIMIT 1;")

if [ -z "$QUEST" ]; then
    echo "No pending quests in lane $LANE"
    exit 0
fi

TITLE=$(sqlite3 "$DB" "SELECT title FROM quests WHERE id='$QUEST';")
STEPS=$(sqlite3 "$DB" "SELECT description FROM quest_steps WHERE quest_id='$QUEST' AND status='pending' ORDER BY step_num;")

echo "Working on: $TITLE"
echo "Steps: $STEPS"

opencode run "You are assigned to quest: $TITLE.
Your pending steps are:
$STEPS

Work through each step. When you complete a step, say STEP DONE."

This is the foundation of autonomous agent systems — AI that picks up work, does it, and moves on.


Your Turn: Build Something

Challenge 1 (15 min): Create a custom agent for your favorite language. Put it in .opencode/agents/ with at least 5 specific review rules.

Challenge 2 (20 min): Write a launch script that accepts a GitHub repo URL, clones it to a temp directory, and runs a security audit using OpenCode.

Challenge 3 (30 min): Extend the agent-lane concept to work with a simple JSON file instead of SQLite. Tasks go in tasks.json, the script reads the first pending task, launches OpenCode, and marks it done.


Student Launcher: A Working Example

We built a task runner you can use right now. It is 78 lines of bash, every line commented, using only commands from this course.

Files: student-launcher.sh and tasks.txt

# Copy into your project, make executable, run
cp student-launcher.sh tasks.txt ~/cscd240/lab1/
cd ~/cscd240/lab1
chmod +x student-launcher.sh

./student-launcher.sh            # Run the next undone task
./student-launcher.sh status     # Show progress bar
./student-launcher.sh add "run valgrind on this program"  # Add a task

The task file is plain text:

[ ] 1. Explain what the main function does
[x] 2. Add comments above every function
[ ] 3. Find unchecked return values for fopen or malloc

The script reads the first [ ] line, sends the description to opencode run, and marks it [x] when done.

Read the script — it IS teaching material. Every command in it (grep, sed, cut, head, echo) is something you will use in CSCD 240. See the launcher README for a full breakdown.


Sources and Further Reading