@meffecta/agent 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/engine.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "engineTag": "1.0.1",
3
- "builtFrom": "e86fcdf452f5403ce1c90805c904048dacc0c6ae"
2
+ "engineTag": "1.0.2",
3
+ "builtFrom": "6a4ebd7751d2eaeaca8f2f28d699a171d162208b"
4
4
  }
@@ -114,6 +114,24 @@ const INTEGRATIONS = {
114
114
  ],
115
115
  },
116
116
 
117
+ serper: {
118
+ title: "Google search results (Serper)",
119
+ gives:
120
+ "query-serp — who ranks for a query, People Also Ask, news with a time filter, places. Competitor and market research, and rank tracking over time",
121
+ needs: [
122
+ "A Serper account at serper.dev. The first 2,500 queries are free and need no card;",
123
+ "after that credits are bought up front. Every successful call spends one.",
124
+ ],
125
+ steps: [["meffecta-agent set-secret SERPER_API_KEY", "from the Serper dashboard"]],
126
+ more: [
127
+ "This reads Google's actual result list, which the built-in web search does not — it",
128
+ "returns a curated set with no positions and no time filter. Reach for this when the",
129
+ "question is what the SERP looks like; reach for the built-in one to look something up.",
130
+ "A research job should save each response into its memory directory and report the",
131
+ "change since last time: the snapshot is cheap, the series is the point.",
132
+ ],
133
+ },
134
+
117
135
  cloudflare: {
118
136
  title: "Cloudflare",
119
137
  gives: "cloudflare — DNS, cache purge, Pages deployments, certificate checks",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meffecta/agent",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Set up and operate a Meffecta Agent deployment — a self-hosted Claude Code job runner.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -146,6 +146,24 @@ async function checkAhrefs() {
146
146
  : fail("AHREFS_API_KEY", `domain-rating-free → ${status}`);
147
147
  }
148
148
 
149
+ async function checkSerper() {
150
+ if (!env.SERPER_API_KEY) {
151
+ return skip("SERPER_API_KEY", "unset");
152
+ }
153
+ // Every successful call spends a credit, so this asks for the smallest thing there is.
154
+ // An exhausted allowance is a 400, not a bad key — worth telling apart in the output,
155
+ // since one needs a person to top up and the other needs a new key.
156
+ const { status, json } = await http("https://google.serper.dev/search", {
157
+ method: "POST",
158
+ headers: { "X-API-KEY": env.SERPER_API_KEY, "content-type": "application/json" },
159
+ body: JSON.stringify({ q: "example", num: 1 }),
160
+ });
161
+ if (status === 200) {
162
+ return ok("SERPER_API_KEY", `${json?.organic?.length ?? 0} organic results, ${json?.credits ?? "?"} credits/query`);
163
+ }
164
+ return fail("SERPER_API_KEY", json?.message ? `${json.message} (${status})` : `search → ${status}`);
165
+ }
166
+
149
167
  async function checkCloudflare() {
150
168
  if (!env.CLOUDFLARE_API_KEY || !env.CLOUDFLARE_ACCOUNT_ID) {
151
169
  return skip("CLOUDFLARE", "CLOUDFLARE_API_KEY/ACCOUNT_ID not set");
@@ -521,6 +539,7 @@ const CHECKS = [
521
539
  ["SWEEPOS_POSTGRES_URL_READONLY", checkPostgres],
522
540
  ["POSTHOG", checkPosthog],
523
541
  ["AHREFS_API_KEY", checkAhrefs],
542
+ ["SERPER_API_KEY", checkSerper],
524
543
  ["CLOUDFLARE", checkCloudflare],
525
544
  ["ELEVENLABS_API_KEY", checkElevenlabs],
526
545
  ["GOOGLE_API_KEY (Places)", checkPlaces],