Agent & Skills

Skills, permission modes, the agent workspace, browser automation, multi-step tasks, and the audit log.

Overview

Luna's agent layer is built on an OpenClaw-style permission model. Every action Luna can take — searching the web, launching an app, reading a file — is a registered tool. Tools are grouped into skills and each has an individually-configurable permission mode.

The Agent page in the Luna sidebar shows all installed skills, current permissions, workspace files, browser status, active tasks, and the live audit stream.

Skills

A skill is a package that extends Luna with new capabilities. Skills live in two locations:

  • skills/ — skills shipped with the repo (version-controlled).
  • data/workspace/skills/ — user-created or agent-created skills (gitignored).

Each skill directory contains two files:

FilePurpose
skill.jsonMachine-readable manifest — name, description, version, and registered commands.
SKILL.mdHuman-readable description. Luna reads this to understand what the skill does and when to use it.

List all installed skills via the API:

terminal
curl http://localhost:8899/api/agent/skills

Create a skill

Skills follow a simple two-file structure. Here is a minimal example:

skills/my-skill/skill.json
{
  "name": "my-skill",
  "version": "1.0.0",
  "description": "A short description of what this skill does.",
  "commands": [
    {
      "name": "do_thing",
      "description": "Does the thing with the given input.",
      "parameters": {
        "input": { "type": "string", "description": "What to process." }
      }
    }
  ]
}
skills/my-skill/SKILL.md
# My Skill

This skill enables Luna to do the thing.

## When to use
Call `do_thing` when the user asks to process something.

## Examples
- "Do the thing with this text"
- "Can you process X for me?"
📌
Command implementation

Commands declared in skill.json must be registered inbackend/services/tool_registry.py with matching names and handler functions. The manifest describes the schema; the registry provides the implementation.

After adding a skill, restart the backend. Luna will load it on startup and make it available to the LLM as a tool call option.

Permission modes

Every registered tool has a permission mode. Modes are stored per-user indata/permissions.json and are configurable from the Agent page in the UI.

ModeBehaviourSuitable for
allowTool executes immediately without any user prompt.Safe, idempotent tools — web search, reading files, weather lookup.
confirmLuna pauses and shows a confirmation banner in the UI. You must approve or reject before execution continues.Destructive or irreversible actions — writing files, launching apps, Spotify control.
blockThe tool call is silently dropped. Luna is told the tool is unavailable.Tools you want to disable entirely — e.g. camera, browser automation.

Update a tool's permission via the API:

terminal
curl -X POST http://localhost:8899/api/agent/permissions/web_search   -H "Content-Type: application/json"   -d '{"mode": "allow"}'

Workspace

Agent-created files are restricted to data/workspace/. This acts as a sandbox — Luna can read and write files within the workspace but cannot access the rest of your filesystem without explicit OS-level permission escalation.

Read and write workspace files via the API:

terminal
# List workspace contents
GET /api/agent/workspace

# Read a file
GET /api/agent/workspace/read?path=notes/ideas.md

# Write a file
POST /api/agent/workspace/write
{"path": "notes/ideas.md", "content": "..."}
ℹ️
Gitignored

data/workspace/ is gitignored. Files created by Luna live here and are never committed to the repository.

Browser automation

Luna's default browser layer uses HTTP requests via httpx — it can fetch and parse public web pages without a real browser. This is fast and lightweight.

For pages that require JavaScript rendering, Luna supports optional Playwrightintegration. Install it separately if needed:

terminal
pip install playwright
playwright install chromium

Browser automation routes:

terminal
# Check browser status
GET /api/agent/browser/status

# Open a URL (Playwright required for JS-rendered pages)
POST /api/agent/browser/open
{"url": "https://example.com"}

# Read page content
POST /api/agent/browser/read
{"url": "https://example.com"}

Agent tasks

Luna supports multi-step agent tasks — goals that require multiple tool calls planned and executed over time. Tasks are created, planned, and tracked in the database.

terminal
# List all tasks
GET /api/agent/tasks

# Create a new task
POST /api/agent/tasks
{"title": "Research competitors", "description": "..."}

From the chat UI, tell Luna to start a task:

"Start a research task: find the top 5 competitors to Notion and summarise their pricing."

Luna will break this into steps, plan an execution sequence, and work through it — asking for confirmation at each confirm-mode tool call.

Audit log

Every tool call Luna executes is appended to data/audit.log with a timestamp, tool name, input parameters, and outcome. This gives you full visibility into what Luna has done.

terminal
# Stream the live audit log via the API
GET /api/agent/audit

The Agent page in the sidebar shows the audit stream in real time. Each entry shows the tool, whether it was auto-allowed or user-confirmed, and the result summary.

💡
Reviewing past actions

Open data/audit.log directly to review the full history. Entries are newline-delimited JSON objects, easy to parse or grep.