My Experience Using Cursor to Set Up a Scripts Repo

A quick write-up of what I asked Cursor’s Cloud Agent to do, and the actual responses I got back.

This repository is just a grab-bag of my sysadmin/automation scripts — Bash, Python, and a bit of PowerShell. There’s no framework, no build system, no test suite. I wanted to see how a Cursor Cloud Agent would handle “set up the dev environment” for something that isn’t a typical app. Here’s how it went.


Request #1: “Set up the development environment and prove it works”

What I asked:
“Please set up the development environment for this codebase. Run the application(s) and demonstrate that the environment is working.”

What the agent did

Instead of assuming this was a web app, it explored the repo first and correctly figured out what it actually is:

This is a personal collection of sysadmin/automation scripts (Bash, Python, PowerShell) with no build system or package manager.

Then it worked through a small plan:

  1. Checked the existing toolchain.
  2. Installed shellcheck for Bash linting.
  3. Ran lint across every script.
  4. Ran two non-destructive “hello world” demos of the scripts’ core functionality.
  5. Wrote an AGENTS.md and set an update script for future runs.

Examples of the responses I got back

Toolchain it found already present / installed:

python3: Python 3.12.3
requests: 2.33.1
bash:    GNU bash, version 5.2.21(1)-release
shellcheck: version: 0.9.0
wg:      wireguard-tools v1.0.20210914


Lint results — it ran shellcheck on all *.sh files and py_compile on the Python script:

## LINT: python compile
wp_update.py: OK

## LINT: shellcheck summary (findings are pre-existing style/info; tool runs OK)
  ./wiregaurd-keygen-and-config-generator.sh -> 2 findings
  ./security/cve-2026-31431.sh              -> 3 findings
  ./install_aws_tools.sh                    -> 0 findings
  ./get-external-ip.sh                      -> 1 findings
  ...


I liked that it flagged the shellcheck findings as pre-existing style/info and didn’t go rewriting my scripts to “fix” them.

Hello-world run #1 — get-external-ip.sh (a real network diagnostic that hits an external service):

## RUN 1: get-external-ip.sh
18.222.235.73
ec2-18-222-235-73.us-east-2.compute.amazonaws.com
curl/8.5.0


Hello-world run #2 — the core of my WireGuard keygen script, generating a real X25519 keypair:

## RUN 2: WireGuard keypair generation (core of keygen script)
public key: M8DtZCC8Q+Ic9qoMJTHnJ95KMjJfaz9/I0A3u3P1JXU=


The part I appreciated most

It noticed that wp_update.py has hardcoded credentials pointing at a live WordPress site and refused to actually run it:

python3 wp_update.py intentionally not run: it targets a live WordPress site with hardcoded credentials and would modify a real production post; validated via py_compile instead.

It also left behind an AGENTS.md documenting which scripts are safe vs. destructive, and opened a pull request with the whole write-up.


Request #2: “Reminder to commit and push if appropriate”

What I asked:
“Reminder to commit and push if appropriate.”

The response I got back

It checked the repo state, found that the only uncommitted thing was a throwaway __pycache__/ directory from the lint step, and cleaned it up instead of committing junk:

The only uncommitted change is the __pycache__/ directory generated by py_compile during testing — a build artifact that shouldn’t be committed… the working tree is now clean.

Small thing, but exactly the right call.


Request #3: “Write a blog post about my experience”

What I asked:
“I want to create a blog post about my experience with cursor, please create a markdown document that explains everything that I ask you to do and shows examples of what response I get back.”

The response I got back

This document. 🙂


Request #4: “Build a text UI for apt-get”

What I asked:
“I want to create a script for Ubuntu that is a text user interface for apt-get. Every feature and function in apt-get should be accessible via this TUI. Like if I want to search for a package, I should be able to choose the search option, enter a package name and have it return the results. For install and remove, I want tab autocomplete for any package if I type the first few letters in the name of the package.”

This turned into the biggest piece of the project — a script called apt-get-tui.sh — and I kept refining it over several follow-ups. Here’s how each round went.

Round 1 — the first working TUI

The agent built a menu-driven Bash script wrapping apt/apt-get/apt-cache/apt-mark, covering search, show, install, remove, purge, update, upgrade, autoremove, clean, hold/unhold, dependencies, download, and more.

The clever bit was the tab autocomplete. It figured out that plain read can’t do package-name completion, so it used rlwrap with a generated word list:

  • Install / show / dependencies → complete against all package names (apt-cache pkgnames)
  • Remove / purge / reinstall → complete against installed packages (dpkg-query)

It proved this actually worked by driving the script through a pseudo-terminal:

>>> PASS: 'neofetc'+TAB -> neofetch, apt show ran
>>> PASS: double-TAB on 'cur' listed candidates


And it did a full interactive install/remove of cowsay, typing only cowsa + <TAB> to complete the name each time.

Round 2 — “make the menu horizontal”

What I asked: “make the menu span horizontally instead of vertically”

It reflowed the options into width-adaptive columns (2 columns at 80 cols, 3 at 120, 5 on a wide terminal).

Round 3 — “no, vertical columns per section”

What I asked: “I want the TUI laid out in vertical columns where the fixed inspect options should be the first column, next column Install Remove and so on”

It rebuilt the layout so each section is its own column, side by side:

Find / Inspect        Install / Remove      Maintenance           Pinning / Sources     Other
1) Search Packages    8) Install            15) Update Lists      22) Hold              90) Raw apt-get Command
2) Show Details       9) Reinstall          16) Upgrade           23) Unhold            0) Exit
3) Dependencies       10) Remove            17) Full Upgrade      24) Show Held
...


Round 4 — “make it look polished”

What I asked: “make the menu look a bit more polished. I don’t like the teal on white, use a better color, colorize the numbers and use proper case for options and descriptions”

It introduced a real color palette (colored option numbers, underlined section headers, proper Title Case labels), and — importantly — computed column padding on visible width so the ANSI color codes never broke the alignment.

Round 5 — “use Catppuccin Latte”

What I asked: (linked the Catppuccin Latte palette)

It switched to 24-bit truecolor and mapped the exact Latte hex values (e.g. peach #fe640b numbers, mauve #8839ef headers, blue #1e66f5 rules).

Round 6 — “offer dark and light modes”

What I asked: “offer dark and light mode options, if dark mode use this” (linked the Ayu Dark palette)

It refactored the theming into a switchable apply_theme function with two full palettes — Catppuccin Latte (light) and Ayu Dark (dark) — and three ways to pick:

  • --dark / --light command-line flags
  • an APT_TUI_THEME=dark|light environment variable
  • a live Toggle Theme menu option that re-colors the menu on the spot

The banner even shows the active theme, e.g. [theme: dark].

Round 7 — “add a proxy configurator”

What I asked: “add ability to configure a proxy server for apt-get… create a new file in /etc/apt/apt.conf.d/ called 99proxy… ask if they want to forward http traffic (default yes), ask about https (default yes), then ask for the proxy address and port.”

It added option 26, which prompts for exactly that and writes the file in the required format:

Acquire::http::Proxy "http://proxy.example.com:3128/";
Acquire::https::Proxy "http://proxy.example.com:3128/";


Nice touches it added on its own: it strips a pasted http:// scheme and trailing slash, validates the port is numeric, previews the file, and asks for confirmation before writing.

Round 8 — the credit blurb and a rename

What I asked: “Add a blurb saying Created by Richard Troiano 2026 with Cursor. See my blog @ extremesarcasm.org” … and later just: “apt-get-tui.sh”

It added the footer credit line to the menu, and renamed the script from apt-tui.sh to apt-get-tui.sh (updating every internal reference and using git mv so history is preserved).


Overall impressions

  • It read the repo before acting and didn’t force a generic “npm install / run dev” template onto a plain scripts folder.
  • It picked safe, meaningful demos (external IP lookup + keypair generation) instead of running destructive or interactive scripts.
  • It was cautious with secrets and production systems — it declined to run the live WordPress updater.
  • It kept my code untouched, only adding setup/docs files, and packaged everything into reviewable PRs.
  • On the apt-get-tui.sh build, it iterated cleanly across many follow-ups — layout, colors, themes, a proxy feature, and a rename — and each time it tested end-to-end (pseudo-terminal drives for tab completion, real install/remove of a package, generated-file checks) and captured screenshots/video as proof.

For a messy, non-standard repo, that’s a pretty solid “new machine setup” experience — and a surprisingly smooth one for building a brand-new tool from scratch.