Every software engineer knows the "pre-deploy anxiety". You've tested your code, your CI is green, and you are ready to click that shiny "Merge" button. But what if there's an ongoing PagerDuty incident on your microservice? What if a third-party API you rely on (like Stripe or AWS) is currently degraded? What if the Sentry error rate spiked 10 minutes ago due to another team's deploy?
Checking all of this manually takes 10 to 15 minutes, which means most teams simply don't do it. They merge, pray, and react if things blow up.
This weekend, I built Harbourmaster — a CLI tool that automatically queries 6 different sources (GitHub, Sentry, Datadog, PagerDuty, StatusGator, and Linear) in seconds, and uses Google’s Gemini 2.5 Flash to give a definitive [GO], [CAUTION], or [HOLD] verdict.
Here is exactly how I built it without writing a mountain of API integration boilerplate, and how you can reproduce it.
The Secret Sauce: Coral SQL
If I had to write REST API integrations for 6 different platforms, this project would have taken a month. Dealing with pagination, rate limits, OAuth, and different JSON schemas for Sentry, Datadog, and PagerDuty is a nightmare.
Instead, I used Coral — an incredible open-source SQL engine that lets you query APIs as if they were Postgres databases.
With Coral installed, I simply authenticated my sources via CLI (coral source add github, etc.) and then ran standard SQL queries.
For example, to check for active PagerDuty incidents on my service:
SELECT title, status, urgency, created_at
FROM pagerduty.incidents
WHERE status = 'triggered' OR status = 'acknowledged'
ORDER BY created_at DESC
LIMIT 10
To see if all issues tied to my release milestone in Linear were actually closed:
SELECT title, state_name AS state, label_names AS label, priority, updated_at
FROM linear.issues
WHERE label_names LIKE '%v2.4.1%'
ORDER BY updated_at DESC
Bridging Coral to Node.js
I built the CLI using TypeScript and Commander.js. Because Coral handles all the heavy lifting, my data-fetching layer is incredibly thin. Since I’m on Windows, I invoked Coral via WSL using Node's execFile, ensuring all the SQL queries ran flawlessly.
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
const execFileAsync = promisify(execFile);
async function executeCoralQuery(query: string): Promise<string> {
const pathPrefix = 'PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"';
const escapedQuery = query.replace(/\s+/g, ' ').replace(/"/g, '\\"');
const { stdout } = await execFileAsync('wsl', [
'--', 'bash', '-c', `${pathPrefix} coral sql "${escapedQuery}"`
]);
return stdout;
}
By executing 6 of these queries sequentially, Harbourmaster aggregates a snapshot of the entire engineering environment in just a few seconds.
Bringing in the AI: Gemini 2.5 Flash
Having a bunch of raw tabular data from Coral is great, but engineers don't want to read tables during a deploy. They want an executive summary.
This is where Gemini 2.5 Flash shines. Flash is ridiculously fast and has excellent reasoning capabilities for structured data.
I wrote a parser that converts Coral's stdout tables into a clean JSON object representing the "Readiness Snapshot". I then feed this JSON directly to Gemini with a strict system prompt:
const prompt = `
You are the Harbourmaster AI. Your job is to analyze the engineering environment snapshot and determine if it is safe to deploy.
Respond ONLY with a JSON object containing:
- verdict: "GO", "CAUTION", or "HOLD"
- riskScore: Number 0-100 (0=safe, 100=disaster)
- confidence: "low", "medium", or "high"
- reasoning: A 2-4 sentence explanation.
- onCall: Array of on-call engineers.
Here is the snapshot:
${JSON.stringify(snapshot, null, 2)}
`;
The result? The AI notices when the Sentry error rate is 5x the baseline, correlates it with a failed CI run on GitHub, and halts the deploy while alerting the on-call engineer pulled directly from PagerDuty.
Formatting for the Terminal
A CLI tool is only as good as its UX. I used chalk and boxen to render beautiful, easy-to-read output. Instead of cluttering the terminal with emojis, I used clean ASCII tags like [PASS], [WARN], and [HOLD].
╭──────────────────────────────────────────────────╮
│ HARBOURMASTER CHECK │
│ service: payments-service release: v2.4.1 │
╰──────────────────────────────────────────────────╯
[WARN] Sentry Error rate 1.4× above 24h baseline. No new fatals.
[PASS] Datadog All 5 monitors green.
[FAIL] PagerDuty ACTIVE INCIDENT · "Auth service degraded" · P2 · 14m
──────────────────────────────────────────────────────────
Risk Score: ████████████████████████░░░░░░ 78/100
I also built a --json flag so this CLI can run autonomously in a GitHub Action and block PR merges automatically.
Conclusion
By combining Coral's ability to abstract away API complexity and Gemini's ability to reason over structured data, I built a highly complex enterprise workflow agent in a single weekend.
Deploy readiness doesn't have to be a manual checklist, and building internal tooling doesn't have to require maintaining hundreds of API client libraries.
You can check out the source code and try it yourself at my GitHub repo!
Top comments (0)