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:
- Checked the existing toolchain.
- Installed
shellcheckfor Bash linting. - Ran lint across every script.
- Ran two non-destructive “hello world” demos of the scripts’ core functionality.
- Wrote an
AGENTS.mdand 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.pyintentionally not run: it targets a live WordPress site with hardcoded credentials and would modify a real production post; validated viapy_compileinstead.
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 bypy_compileduring 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/--lightcommand-line flags- an
APT_TUI_THEME=dark|lightenvironment 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.shbuild, 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.