Friday, 9:40 pm. Three side-project ideas. One Sunday deadline.
By Saturday noon I had killed two of them. That decision is the whole article.
Most weekend projects die from scope, not from code. That is the boring truth.
Why "just add an agent loop" ruins the weekend
A loop needs state, retries, and a stop condition. That is a week of work.
You have two days. So I keep one rule: one job, one endpoint, one smoke test.
Everything below is a build log for a helper that reads stdin and prints stdout. It is small on purpose.
1. Write the job in one sentence
If you cannot say the job in one sentence, you do not have a project yet.
Bad: "An AI assistant that helps me organize my notes."
Good: "Read a raw meeting transcript on stdin, print five action items on stdout."
The second version has a falsifier. You can fail it in ten seconds. Ambition does not ship; a falsifier does.
Write that sentence in a notes file. Do not open an editor yet.
2. Score every feature, then cut
List every feature you want. Then score each one honestly.
Anything above 30 minutes of debug risk gets cut on pass one. You can add it next weekend.
| Candidate | Build (min) | Debug risk | Cut? | Reason |
|---|---|---|---|---|
| stdin/stdout CLI | 20 | low | no | this is the demo |
| one retry with backoff | 25 | medium | no | networks fail |
| plain text log to disk | 10 | low | no | you will need it |
| web UI | 120 | high | yes | stdout is enough |
| agent loop | 180 | high | yes | no stop condition |
| accounts and auth | 90 | high | yes | one user: you |
The table is the real artifact here. Rebuild it for your own idea. Print it and tape it next to the monitor.
Then say the painful part out loud: "This weekend, the demo is a terminal command." Nobody is watching anyway.
3. Prove the endpoint before you build anything
Do not write application code until a single HTTP call returns real output.
This is the step people skip. They build a UI first, then discover the request shape is wrong.
Save this as smoke.sh. It is a template, not a finished tool.
#!/usr/bin/env bash
# smoke.sh - template. Fill variables from the docs you were given.
set -euo pipefail
: "${BASE_URL:?export BASE_URL from your dashboard}"
: "${API_KEY:?export API_KEY from your dashboard}"
: "${MODEL:?export MODEL from your documentation}"
# Never guess this path. Copy it from the docs you were given.
PATH_SUFFIX="${PATH_SUFFIX:-/v1/chat/completions}"
BUDGET_SECONDS="${BUDGET_SECONDS:-20}"
payload() {
cat <<JSON
{"model":"${MODEL}","messages":[{"role":"user","content":"Reply with one word: ok"}],"max_tokens":8}
JSON
}
run_once() {
curl --silent --show-error \
--max-time "${BUDGET_SECONDS}" \
--write-out '\n%{http_code} %{time_total}\n' \
--header "Authorization: Bearer ${API_KEY}" \
--header 'Content-Type: application/json' \
--data "$(payload)" \
"${BASE_URL}${PATH_SUFFIX}"
}
out="$(run_once)"
code="$(printf '%s' "$out" | tail -n1 | awk '{print $1}')"
secs="$(printf '%s' "$out" | tail -n1 | awk '{print $2}')"
body="$(printf '%s' "$out" | sed '$d' | sed '$d')"
printf 'http=%s time=%ss\n' "$code" "$secs"
[ "$code" = "200" ] || { echo "FAIL: non-200. Body:"; echo "$body"; exit 1; }
# Adjust this field name to your provider's response shape.
printf '%s' "$body" | grep -q '"content"' || { echo "FAIL: no content field"; exit 1; }
echo "PASS in ${secs}s"
Run it with three exported variables. Read the failure text, not just the status code.
export BASE_URL='https://...' # from your dashboard
export API_KEY='...' # from your dashboard
export MODEL='...' # from the docs you were given
chmod +x smoke.sh && ./smoke.sh
The script asserts three things: a 200, a non-empty content field, and a time budget. Each assertion maps to one class of weekend bug.
4. Measure the spread, not one lucky call
One fast call proves nothing. Shared capacity is shared.
for i in 1 2 3 4 5; do ./smoke.sh | tail -n1; done
Record five numbers. Drop the first one, that is your cold start. The rest is your real budget.
Now set your timeout from the spread, not from your hopes. I have never regretted measuring this before writing UI code.
5. Ship the smallest surface that survives a reboot
My helper is one script and one long-running process. That is the entire deployment.
If your free server is a Linux box you can SSH into, a systemd unit is the smallest durable thing.
[Unit]
Description=weekend helper
After=network-online.target
[Service]
EnvironmentFile=/home/me/.helper.env
ExecStart=/home/me/helper/run.sh
Restart=on-failure
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Enable it, then watch the logs:
sudo systemctl enable --now weekend-helper
journalctl -u weekend-helper -f
If your server is not a Linux box, use whatever supervisor it exposes. The rule is the same. One process, restart on failure, logs to stdout.
6. Where free access actually changed my plan
Two decisions simply disappeared from this weekend's list.
First, billing. Free model access deleted the "add a payment method, add usage caps, add a quota screen" branch. That branch is not hard, but it costs an afternoon.
Second, the deploy target. A free server option deleted the provider comparison. I stopped reading pricing pages and started writing the smoke test.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
I am deliberately not publishing latency or throughput numbers for it. I do not have a reproducible benchmark, and shared capacity varies by hour and region. Run the loop in step 4 and trust your own measurements instead.
7. What I skipped on purpose
- Web UI. The terminal demo is enough for one user.
- A database. Append JSON lines to a file instead.
- Multi-step retries. One retry with backoff covers most transient failures.
- Model switching. Two models means two behaviors to debug.
- Test suite beyond
smoke.sh. One assertion beats zero, and five would be theater.
Each skip has a trigger. Add the feature when a real user asks for it, not before.
8. Limits you should assume
- Free capacity is shared. Expect variance you did not cause.
- There is no SLA here. Accept a broken demo, or build a fallback path.
- Do not send client, health, or personal data to a service you have not reviewed yourself.
- Free access can change. Keep an exit plan: isolate the call in one function so you can swap it.
- Model output is unverified text. Validate it before it touches anything real.
9. Who should not use this workflow
Skip this approach if you need contractual uptime, pinned model versions for audits, or data residency guarantees. Skip it if your "weekend" is really a product launch with a date.
This is a build log for a disposable helper. Treat it that way.
Takeaways
One job. One endpoint. One smoke test. One process.
Cut the table until Sunday feels boring. A boring Sunday ships.
If you try it, run smoke.sh before you write the app. Tell me which assertion caught your first bug.
Top comments (0)