Python-based toolkit for automated OS-level configuration, file manipulation, and system verification.

Install

mkdir -p .claude/skills/os && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/17331" && unzip -o skill.zip -d .claude/skills/os && rm skill.zip

Installs to .claude/skills/os

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

How to programmatically set up, modify, and verify OS-level configurations (files, GNOME settings, audio, permissions, system config) using Python. For setup-gen and reward-gen agents.
184 charsno explicit “when” trigger
Intermediate

Key capabilities

  • Launch GUI applications on a virtual machine
  • Create and modify files and directories
  • Set GNOME desktop settings like favorite apps and wallpaper
  • Configure system timezone
  • Install packages using apt-get and snap

How it works

The skill uses Python libraries like os, shutil, and subprocess to interact with the Linux OS, allowing for programmatic setup, modification, and verification of system states and configurations.

Inputs & outputs

You give it
Python code specifying OS configurations or commands
You get back
Modified OS-level configurations or system state

When to use os

  • Automate desktop app setup
  • Configure OS-level settings
  • Verify system state after deployment

About this skill

OS — Python Manipulation Guide

This skill teaches setup-gen (create/modify system state) and reward-gen (read/verify system state) how to work with Linux OS tasks using Python.

  • Libraries: os, shutil, subprocess, json, stat, pathlib
  • Target: Ubuntu/GNOME desktop environment

0. GUI Startup on VM (for setup-gen)

For OS tasks, setup-gen should leave the required desktop apps/windows open at the end of initial_setup.py.

CRITICAL VM LIMIT: GUI launches must set DISPLAY=:0.

import os
import shlex
import subprocess
import time

def launch_gui(command: str, delay_sec: float = 1.0):
    env = os.environ.copy()
    env["DISPLAY"] = ":0"
    subprocess.Popen(
        shlex.split(command),
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL,
        env=env,
    )
    time.sleep(delay_sec)

# Examples
launch_gui('nautilus "/home/user"', delay_sec=1.5)
# launch_gui('gnome-control-center', delay_sec=1.5)
# launch_gui('gedit "/home/user/Desktop/notes.txt"', delay_sec=1.5)

Guidelines:

  • Launch only apps needed by the task start state.
  • For multi-app tasks, launch all required windows in deterministic order.

1. Creating & Writing Files (setup-gen)

File & Directory Operations

import os, shutil, subprocess, json, stat
from pathlib import Path

# Create directories
os.makedirs("/home/user/Desktop/project/src", exist_ok=True)

# Create files
Path("/home/user/Desktop/notes.txt").write_text("Hello World\n")

# Copy files/directories
shutil.copy2("/home/user/file1.txt", "/home/user/backup/file1.txt")  # preserves metadata
shutil.copytree("/home/user/src", "/home/user/dst")  # recursive copy

# Move / rename
shutil.move("/home/user/Desktop/todo_list_Jan_1", "/home/user/Desktop/todo_list_Jan_2")
os.rename("/home/user/old_name.txt", "/home/user/new_name.txt")

# Delete
os.remove("/home/user/temp.txt")           # single file
shutil.rmtree("/home/user/temp_dir")        # recursive directory

# File permissions
os.chmod("/home/user/script.sh", 0o755)     # rwxr-xr-x
# Recursive permission change for regular files
for root, dirs, files in os.walk("/home/user/testDir"):
    for f in files:
        os.chmod(os.path.join(root, f), 0o644)

GNOME Desktop Settings (gsettings / dconf)

# Set GNOME favorite apps
def set_favorite_apps(apps: list):
    """apps: list like ['thunderbird.desktop', 'google-chrome.desktop']"""
    apps_str = str(apps).replace("'", '"')  # gsettings expects double-quoted JSON-like
    subprocess.run(["gsettings", "set", "org.gnome.shell", "favorite-apps", apps_str], check=True)

# Text scaling factor (accessibility)
def set_text_scaling(factor: float):
    subprocess.run(["gsettings", "set", "org.gnome.desktop.interface",
                     "text-scaling-factor", str(factor)], check=True)

# Screen magnifier
def set_magnifier(enabled: bool):
    val = "true" if enabled else "false"
    subprocess.run(["gsettings", "set", "org.gnome.desktop.a11y.magnifier",
                     "mag-factor", "2.0" if enabled else "1.0"], check=True)

# Desktop wallpaper
def set_wallpaper(path: str):
    subprocess.run(["gsettings", "set", "org.gnome.desktop.background",
                     "picture-uri", f"file://{path}"], check=True)
    subprocess.run(["gsettings", "set", "org.gnome.desktop.background",
                     "picture-uri-dark", f"file://{path}"], check=True)

# Dark mode / theme
def set_dark_mode(enabled: bool):
    theme = "prefer-dark" if enabled else "default"
    subprocess.run(["gsettings", "set", "org.gnome.desktop.interface",
                     "color-scheme", theme], check=True)

System Timezone

# Set timezone to UTC
subprocess.run(["sudo", "timedatectl", "set-timezone", "UTC"], check=True)
# Set to specific timezone
subprocess.run(["sudo", "timedatectl", "set-timezone", "America/New_York"], check=True)

Audio Volume (PulseAudio)

# Set volume to max (100%)
subprocess.run(["pactl", "set-sink-volume", "@DEFAULT_SINK@", "100%"], check=True)
# Set specific volume
subprocess.run(["pactl", "set-sink-volume", "@DEFAULT_SINK@", "75%"], check=True)
# Mute / unmute
subprocess.run(["pactl", "set-sink-mute", "@DEFAULT_SINK@", "0"], check=True)  # unmute

Terminal Configuration

# Set default terminal size (GNOME Terminal profile via dconf)
subprocess.run(["dconf", "write", "/org/gnome/terminal/legacy/profiles:/:b1dcc9dd-5262-4d8d-a863-c897e6d979b9/default-size-columns", "132"], check=True)
subprocess.run(["dconf", "write", "/org/gnome/terminal/legacy/profiles:/:b1dcc9dd-5262-4d8d-a863-c897e6d979b9/default-size-rows", "43"], check=True)

# Persistent terminal size via .bashrc
def set_terminal_size_bashrc(cols: int, rows: int):
    bashrc = os.path.expanduser("~/.bashrc")
    with open(bashrc, "a") as f:
        f.write(f"\nstty columns {cols} rows {rows}\n")

Package Installation

# Install packages
subprocess.run(["sudo", "apt-get", "update"], check=True)
subprocess.run(["sudo", "apt-get", "install", "-y", "package-name"], check=True)

# Snap install
subprocess.run(["sudo", "snap", "install", "spotify"], check=True)

Clipboard Operations

# Set clipboard content (requires xclip or xsel)
def set_clipboard(text: str):
    proc = subprocess.Popen(["xclip", "-selection", "clipboard"], stdin=subprocess.PIPE)
    proc.communicate(text.encode())

# Or via xdotool for GUI clipboard
subprocess.run(["xdotool", "key", "ctrl+c"])

Shell Script Execution

# Run a setup shell script
subprocess.run(["bash", "/home/user/setup.sh"], check=True, cwd="/home/user")

# Run with environment variables
env = os.environ.copy()
env["MY_VAR"] = "value"
subprocess.run(["bash", "-c", "echo $MY_VAR"], env=env, check=True)

2. Reading & Verifying Files (reward-gen)

Verifying File/Directory Existence

def verify_file_exists(path: str) -> bool:
    return os.path.isfile(path)

def verify_dir_exists(path: str) -> bool:
    return os.path.isdir(path)

def verify_file_content(path: str, expected: str) -> bool:
    try:
        return Path(path).read_text() == expected
    except FileNotFoundError:
        return False

Verifying Directory Contents

def verify_directory_files(dir_path: str, expected_files: set) -> bool:
    """Check that directory contains exactly the expected files."""
    try:
        actual = set(os.listdir(dir_path))
        return actual == expected_files
    except FileNotFoundError:
        return False

# Check JPGs were moved to target
def verify_moved_files(dir_path: str, expected_names: list) -> bool:
    actual = set(os.listdir(dir_path))
    return set(expected_names) == actual

Verifying GNOME Settings

def get_gsetting(schema: str, key: str) -> str:
    result = subprocess.run(["gsettings", "get", schema, key],
                            capture_output=True, text=True)
    return result.stdout.strip()

# Favorite apps
def verify_favorite_apps(expected: list) -> bool:
    raw = get_gsetting("org.gnome.shell", "favorite-apps")
    # Output is like: ['app1.desktop', 'app2.desktop']
    apps = eval(raw)
    return set(apps) == set(expected)

# Text scaling
def verify_text_enlarged() -> bool:
    factor = float(get_gsetting("org.gnome.desktop.interface", "text-scaling-factor"))
    return factor > 1.0

# Wallpaper
def verify_wallpaper(expected_path: str) -> bool:
    uri = get_gsetting("org.gnome.desktop.background", "picture-uri")
    return expected_path in uri

Verifying Timezone

def verify_utc_timezone() -> bool:
    result = subprocess.run(["timedatectl"], capture_output=True, text=True)
    lines = result.stdout.split("\n")
    for line in lines:
        if "Time zone" in line:
            return "+0000)" in line
    return False

Verifying Audio Volume

def get_volume() -> int:
    """Get current default sink volume as percentage."""
    result = subprocess.run(
        ["pactl", "get-sink-volume", "@DEFAULT_SINK@"],
        capture_output=True, text=True
    )
    # Output: "Volume: front-left: 65536 / 100% / ..."
    import re
    match = re.search(r'(\d+)%', result.stdout)
    return int(match.group(1)) if match else -1

assert get_volume() == 100

Verifying File Permissions

def verify_permissions(path: str, expected_mode: int) -> bool:
    """expected_mode as octal, e.g. 0o644."""
    actual = stat.S_IMODE(os.stat(path).st_mode)
    return actual == expected_mode

# Recursive check
def verify_all_file_permissions(dir_path: str, expected_mode: int) -> bool:
    for root, dirs, files in os.walk(dir_path):
        for f in files:
            if not verify_permissions(os.path.join(root, f), expected_mode):
                return False
    return True

Verifying Command Output (include/exclude)

def verify_command_output(command: str, include: list = None, exclude: list = None) -> bool:
    """Run a shell command and check output contains/excludes strings."""
    result = subprocess.run(command, shell=True, capture_output=True, text=True)
    output = result.stdout + result.stderr
    if include and not all(s in output for s in include):
        return False
    if exclude and any(s in output for s in exclude):
        return False
    return True

# Examples
assert verify_command_output("which spotify", include=["spotify"], exclude=["not found"])
assert verify_command_output("stty size", include=["43 132"])

Verifying Terminal Size

def verify_terminal_size(expected_rows: int, expected_cols: int) -> bool:
    result = subprocess.run(["stty", "size"], capture_output=True, text=True)
    parts = result.stdout.strip().split()
    return len(parts) == 2 and int(parts[0]) == expected_rows and int(parts[1]) == expected_cols

Verifying Package Installation

def verify_package_installed(package_name: str) -> bool:
    result = subproces

---

*Content truncated.*

When not to use it

  • When working outside of a Linux Ubuntu/GNOME desktop environment
  • When GUI launches do not set DISPLAY=:0

Limitations

  • The skill targets Ubuntu/GNOME desktop environments.
  • GUI launches must set DISPLAY=:0.

How it compares

This skill provides a Pythonic interface for OS tasks, enabling automation and scripting of system changes compared to manual command-line operations.

Compared to similar skills

os side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
os (this skill)02moReviewIntermediate
machine-learning-ops-ml-pipeline43moNo flagsAdvanced
uv34moReviewBeginner
vastai-core-workflow-b110dReviewAdvanced

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry