Awesome—here’s a crisp, build-ready plan for Automations and AI Agents inside the SearchJet WordPress plugin. I’ve split it into folders, classes, responsibilities, hooks, REST routes, settings, and a first-wave of minimal/valuable automations.

⸻

Folder & Class Structure

/includes
  /Automations
    Manager.php
    Registry.php
    Runner.php
    Schedules.php
    Logger.php
    Webhooks.php
    Events.php
    DataContracts.php
    /Integrations
      N8nClient.php
      ZapierClient.php (optional stub)
  /AI
    AgentManager.php
    AgentRegistry.php
    Router.php
    Toolbox.php
    /Agents
      SearchTunerAgent.php
      QueryRewriteAgent.php
      MerchandisingAgent.php
    /Tools
      SearchApiTool.php
      WPContentTool.php
      WooCatalogTool.php
  /API
    RestController.php
    AutomationController.php
    AIController.php
  /Admin
    AutomationPage.php
    AgentsPage.php


⸻

Responsibilities (what each class does)

Automations
	•	Automations\Manager
	•	Bootstraps the system.
	•	Registers built‑in automations (via Registry).
	•	Exposes WordPress hooks/filters to third‑party devs.
	•	Automations\Registry
	•	Keeps a list of “automation definitions” (id, label, input schema, trigger type, action).
	•	Allows registration via do_action('searchjet_register_automation', $def).
	•	Automations\Runner
	•	Executes an automation (validates payload → calls action → logs result).
	•	Supports sync & async (WP-Cron) execution.
	•	Automations\Schedules
	•	Manages WP-Cron schedules (hourly, twice daily, daily, custom).
	•	Adds/removes cron events per automation.
	•	Automations\Logger
	•	Centralized do_log($channel, $level, $context) to error_log + optional DB table wp_searchjet_automation_logs (optional).
	•	Automations\Webhooks
	•	Outbound webhook dispatcher (to n8n, Zapier, custom endpoints).
	•	Verifies shared secret; retries with exponential backoff.
	•	Automations\Events
	•	Provides high-level events (e.g., search_performed, zero_results, index_completed) and maps them to triggers.
	•	Automations\DataContracts
	•	Defines canonical payload shapes (PHP arrays) for events and actions:
	•	SearchEvent, ZeroResultEvent, IndexStats, ProductDelta, etc.
	•	Automations\Integrations\N8nClient
	•	Minimal HTTP client for posting events to n8n flows.
	•	Adds HMAC signature header (e.g., X-SearchJet-Signature).

AI
	•	AI\AgentManager
	•	Initializes enabled agents, resolves config from options, provides run($agentId, $input).
	•	AI\AgentRegistry
	•	Registers agent definitions (id, name, description, input schema, tools required).
	•	AI\Router
	•	Optional: routes tasks to the best agent based on a simple rule set (e.g., if “no-results rate high” ⇒ run QueryRewriteAgent).
	•	AI\Toolbox
	•	DI container for tools agents can call (Search API, WP content, Woo catalog).
	•	AI\Agents*
	•	SearchTunerAgent: analyzes analytics & suggests synonyms/boosts/exclusions.
	•	QueryRewriteAgent: proposes query rewrites for 0-result queries (preserves intent).
	•	MerchandisingAgent: suggests featured items/pinned results for high-volume queries.
	•	AI\Tools*
	•	SearchApiTool (wraps SearchJet API calls).
	•	WPContentTool (fetches posts/pages/terms safely).
	•	WooCatalogTool (reads products, stock, prices).

REST API
	•	API\RestController
	•	Base class with helpers (auth checks, error responses).
	•	API\AutomationController
	•	POST /searchjet/v1/automations/run (manual run)
	•	POST /searchjet/v1/automations/webhook (ingest or relay)
	•	GET  /searchjet/v1/automations (list definitions + status)
	•	API\AIController
	•	POST /searchjet/v1/agents/run (execute agent)
	•	GET  /searchjet/v1/agents (list agents + config requirements)

⸻

Admin UI (new pages)
	•	Admin\AutomationPage
	•	Submenu: SearchJet → Automations
	•	Toggles (enable/disable each automation)
	•	n8n URL + Secret config fields
	•	Simple log viewer (last N runs)
	•	“Run now” button per automation
	•	Admin\AgentsPage
	•	Submenu: SearchJet → AI Agents
	•	Enable agents, set allowed tools, guardrails (e.g., read-only vs write suggestions)
	•	“Preview suggestions” area; export suggestions as JSON.

Both pages follow the same pattern used by SettingsPage (nonce checks, capability checks, sanitized options).

⸻

Options & Feature Flags
	•	searchjet_automations_enabled (bool)
	•	searchjet_n8n_url (string)
	•	searchjet_n8n_secret (string)
	•	searchjet_automation_map (array: automation_id => settings/cron schedule)
	•	searchjet_agents_enabled (bool)
	•	searchjet_agent_permissions (array: agent_id => [tools => […], can_write => bool])
	•	searchjet_agent_suggestions_cache (array or transient key)

All settings saved via register_setting('searchjet_settings', ...) in their own sections on the new admin pages.

⸻

Security & Permissions
	•	Admin pages gated by manage_options.
	•	REST routes require:
	•	Logged-in admin or
	•	HMAC header (for inbound webhooks) validated against stored secret.
	•	Nonces for all admin actions.
	•	Sanitization: enforce URL/secret formats; whitelist schedules; validate payload schemas.

⸻

Triggers (Phase 1 — minimal but useful)
	1.	Daily Search Health Check (cron)
	•	Pulls analytics: total searches, zero-result rate, top queries.
	•	Emits:
	•	automation:health_snapshot → n8n webhook (optional)
	•	Stores daily snapshot (option or custom table for 30–90 days)
	2.	Zero-Result Burst Monitor (on request / cached)
	•	Hook into your existing search endpoint (server or JS beacon).
	•	If 0-results occurs N times in 10 minutes ⇒ trigger webhook & log.
	3.	Index Delta Monitor (post save/delete batch)
	•	When bulk reindex completes ⇒ send summary (added/updated/skipped).
	4.	Woo Product Drift (optional)
	•	On product update (price/stock) ⇒ push delta event (minimal payload).

⸻

Actions (Phase 1)
	•	WebhookDispatch → n8n:
	•	POST {n8n_url} with body:

{
  "site": {"id": 123, "url": "https://example.com"},
  "event": "zero_results_burst",
  "payload": { "query": "hoodie", "count": 14, "window": "10m" },
  "ts": "2025-08-04T10:10:00Z",
  "signature": "hmac-sha256..."
}


	•	AI Suggestion Generate (local):
	•	Use AgentManager to run QueryRewriteAgent for the past day’s worst queries.
	•	Store suggestions in a transient or option for review in Agents page.

No automatic writes to site content in Phase 1—read-only suggestions by default.

⸻

Minimal Data Contracts (PHP array shapes)

// Automations\DataContracts
public static function searchSnapshot(array $analytics): array;
public static function zeroResultEvent(string $query, int $count, array $samples = []): array;
public static function indexSummary(int $added, int $updated, int $skipped): array;
public static function productDelta(array $product): array;


⸻

REST Routes (examples)

// API\AutomationController
register_rest_route('searchjet/v1', '/automations', ['methods' => 'GET',  'callback' => [$this, 'listAutomations'], 'permission_callback' => [$this, 'adminOnly']]);
register_rest_route('searchjet/v1', '/automations/run', ['methods' => 'POST', 'callback' => [$this, 'runAutomation'], 'permission_callback' => [$this, 'adminOnly']]);
register_rest_route('searchjet/v1', '/automations/webhook', ['methods' => 'POST', 'callback' => [$this, 'receiveWebhook'], 'permission_callback' => '__return_true']);

// API\AIController
register_rest_route('searchjet/v1', '/agents', ['methods' => 'GET', 'callback' => [$this, 'listAgents'], 'permission_callback' => [$this, 'adminOnly']]);
register_rest_route('searchjet/v1', '/agents/run', ['methods' => 'POST', 'callback' => [$this, 'runAgent'], 'permission_callback' => [$this, 'adminOnly']]);


⸻

Hooks for Extensibility
	•	do_action('searchjet_register_automation', $definition)
	•	do_action('searchjet_automation_ran', $automation_id, $result)
	•	apply_filters('searchjet_automation_payload', $payload, $automation_id)
	•	do_action('searchjet_register_agent', $agent_def)
	•	apply_filters('searchjet_agent_tools', $tools, $agent_id)

⸻

First-Focus Automations (minimal payload, high value)
	1.	Zero-Result Alerts → n8n
	•	Trigger: burst of 0-result queries.
	•	Payload: site info + query + count + timeframe.
	2.	Daily Snapshot → n8n
	•	Trigger: WP-Cron daily.
	•	Payload: total searches, zero-result count, top 5 queries.
	3.	Index Summary → n8n
	•	Trigger: after reindexAll completes.
	•	Payload: added/updated/skipped + duration.
	4.	AI Suggestions (review UI)
	•	Trigger: daily cron.
	•	Action: generate query rewrites & synonym suggestions; store for review.

⸻

Admin Pages (what they show)
	•	Automations
	•	Global toggle
	•	n8n URL + Secret
	•	Enable/Disable each automation (4 above)
	•	“Send Test Event” buttons
	•	Log table (last 50 runs)
	•	AI Agents
	•	Global toggle
	•	Enable agents (SearchTuner, QueryRewrite, Merchandising)
	•	Tool access checkboxes
	•	“Run Preview” & “Export JSON”

⸻

Where to Wire In (hooks you already have)
	•	After index completes (existing searchjet_manual_reindex flow):
	•	do_action('searchjet_index_completed', $summary_array);
	•	Automations\Manager listens → Runner → Webhooks.
	•	During search (server or JS):
	•	On 0-result, call small endpoint POST /searchjet/v1/automations/webhook (internal enqueue) or local Events::trackZeroResult($query) which increments a rolling window (transient) and emits when threshold reached.

⸻

If you want, I can scaffold the files/classes with stubs exactly as above and add the new Automations and AI Agents submenus (no logic yet)—say the word and I’ll drop in the code structure so you can start filling in actions/agents.

---

## Versioned Implementation Plan (ship-by-ship)

> Goal: build in small, verifiable slices. Each version is shippable and includes admin visibility + basic tests.

### **v1.1.0 — Automations Core (foundation)**
**Primary files to implement (in this order):**
1) `includes/Automations/Manager.php`  
   - `init()` — wires WP hooks, loads registry, registers cron schedules.
   - `register_hooks()` — attaches to plugin load, `admin_init`, and custom actions (`searchjet_index_completed` etc.).
   - `is_enabled()` — reads `searchjet_automations_enabled` option.

2) `includes/Automations/Registry.php`  
   - `register($definition)`; `all()`; `get($id)`; simple in‑memory store.
   - Built‑ins registered here (ids): `daily_health_snapshot`, `zero_result_burst`, `index_summary`.

3) `includes/Automations/DataContracts.php`  
   - Static builders: `searchSnapshot(array $a)`, `zeroResultEvent(string $q, int $c, array $samples = [])`, `indexSummary(int $added, int $updated, int $skipped)`.
   - All must return **flat arrays** with `site`, `event`, `payload`, `ts`.

4) `includes/Automations/Logger.php`  
   - `log($level, $message, array $context = [])` → `error_log` with channel `searchjet.automation`.
   - Later can extend to table `wp_searchjet_automation_logs` (v1.3.0).

5) `includes/Automations/Webhooks.php`  
   - `dispatch(string $event, array $payload): array` — posts to n8n if configured.
   - HMAC header: `X-SearchJet-Signature: sha256=<hash>` of `json_payload|timestamp`.
   - Minimal retry (1 immediate retry on 5xx).

6) `includes/Automations/Events.php`  
   - Helpers to emit normalized events; small rolling-cache util for burst detection (transient).

**Admin**
- Settings: add `searchjet_automations_enabled` (checkbox), `searchjet_n8n_url`, `searchjet_n8n_secret` (text/password).  
- Surface a tiny status card in **SearchJet → Automations** (page scaffold in v1.1.2).

**Test/Verify**
- Toggle enable/disable and confirm Manager doesn’t attach hooks when disabled.
- Use `do_action('searchjet_index_completed', ['added'=>1,'updated'=>0,'skipped'=>0]);` and verify Logger output.

---

### **v1.1.1 — Schedules + Runner + Daily Health Snapshot**
**Files to implement (in this order):**
1) `includes/Automations/Schedules.php`  
   - `ensure_schedules()` adds `searchjet_twice_daily` if missing.  
   - `schedule(string $automation_id, string $recurrence)` registers WP‑Cron.

2) `includes/Automations/Runner.php`  
   - `run(string $automation_id, array $input = []): array` (validate → execute action → log → return status).

3) Extend `Registry.php` definitions to include callable actions for:  
   - `daily_health_snapshot` → calls SaaS analytics endpoint, builds payload via `DataContracts::searchSnapshot()`, then `Webhooks::dispatch()`.

**Admin**
- Cron indicator on Automations page (next run time).

**Test/Verify**
- Manually trigger via `do_action('searchjet_automation_run', 'daily_health_snapshot')` (temporary) and check webhook call & logs.

---

### **v1.1.2 — Zero-Result Burst Monitor + REST (Automations API)**
**Files to implement:**
1) `includes/API/RestController.php` (base)  
   - helpers: `admin_only()`, `ok($data)`, `err($message, $code=400)`.

2) `includes/API/AutomationController.php`  
   - `GET /searchjet/v1/automations` → list registry entries + status.  
   - `POST /searchjet/v1/automations/run` → run by id (admin only).  
   - `POST /searchjet/v1/automations/webhook` → accept inbound pings (verify HMAC if header present).

3) `Events.php`  
   - `track_zero_result($query)` → transient rollup and emission when threshold (default: 10 in 10m).

**Admin**
- **SearchJet → Automations** basic UI (toggle, n8n config, “Run now” for health snapshot).

---

### **v1.1.3 — Index Summary Automation + UX polish**
- Wire `do_action('searchjet_index_completed', $summary)` at the end of bulk/reindex flows.  
- Registry action `index_summary` → fire webhook with `DataContracts::indexSummary()`.  
- UI: add a small log viewer (last 50 from `error_log` tail or transient queue).

---

### **v1.1.4 — n8n Client + Test Buttons**
- `includes/Automations/Integrations/N8nClient.php` with `post(array $body): array`.  
- Automations page: “Send Test Event” buttons per automation (calls REST → Runner).

---

### **v1.2.0 — AI Core (read‑only suggestions)**
**Files to implement (in this order):**
1) `includes/AI/AgentManager.php` — `run($agentId, $input)`; reads permissions.  
2) `includes/AI/AgentRegistry.php` — register agents (ids: `query_rewrite`, `search_tuner`, `merchandising`).  
3) `includes/AI/Tools/SearchApiTool.php` — thin wrapper to analytics/search endpoints (read‑only).  
4) `includes/API/AIController.php` — `GET /agents`, `POST /agents/run` (admin).

**Admin**
- **SearchJet → AI Agents** page scaffold with global toggle and per‑agent enable switches.

---

### **v1.2.1 — QueryRewriteAgent**
- Implement `Agents/QueryRewriteAgent.php` — input: top zero‑result queries; output: suggested rewrites (JSON).  
- Store suggestions in transient `searchjet_agent_suggestions_cache` (24h).  
- Admin page: “Run Preview” + “Export JSON”.

---

### **v1.2.2 — Merchandising & Search Tuner Agents**
- `MerchandisingAgent` suggests pinned results for high‑volume queries.  
- `SearchTunerAgent` recommends synonyms/boosting candidates (read‑only).

---

### **v1.3.0 — Persistent Logs (optional)**
- Create table `wp_searchjet_automation_logs` with basic columns `(id, event, status, message, context_json, created_at)`.  
- Extend `Logger` to write both to DB and error_log.  
- Admin log viewer with filters.

---

## Coding Order (TL;DR)

1. `Automations/Manager.php` ✅ **Start here**  
2. `Automations/Registry.php`  
3. `Automations/DataContracts.php`  
4. `Automations/Logger.php`  
5. `Automations/Webhooks.php`  
6. `Automations/Events.php`  
7. `Automations/Schedules.php`  
8. `Automations/Runner.php`  
9. `API/RestController.php` → `API/AutomationController.php`  
10. Admin page for Automations

(Then move to AI stack v1.2.x)

---

## Minimal Method Signatures (copy‑paste when creating files)

```php
// includes/Automations/Manager.php
namespace SearchJet\Automations;
class Manager {
  public static function init(): void {}
  public static function is_enabled(): bool { return (bool) get_option('searchjet_automations_enabled', false); }
  protected static function register_hooks(): void {}
}
```

```php
// includes/Automations/Registry.php
namespace SearchJet\Automations;
class Registry {
  protected static array $defs = [];
  public static function register(array $def): void {}
  public static function all(): array { return self::$defs; }
  public static function get(string $id): ?array { return self::$defs[$id] ?? null; }
}
```

```php
// includes/Automations/DataContracts.php
namespace SearchJet\Automations;
class DataContracts {
  public static function searchSnapshot(array $a): array { return []; }
  public static function zeroResultEvent(string $q, int $c, array $samples = []): array { return []; }
  public static function indexSummary(int $added, int $updated, int $skipped): array { return []; }
}
```

```php
// includes/Automations/Logger.php
namespace SearchJet\Automations;
class Logger {
  public static function log(string $level, string $message, array $context = []): void {}
}
```

```php
// includes/Automations/Webhooks.php
namespace SearchJet\Automations;
class Webhooks {
  public static function dispatch(string $event, array $payload): array { return ['ok'=>false,'status'=>0]; }
}
```

```php
// includes/Automations/Runner.php
namespace SearchJet\Automations;
class Runner {
  public static function run(string $automation_id, array $input = []): array { return ['ok'=>false]; }
}
```

```php
// includes/API/RestController.php
namespace SearchJet\API;
abstract class RestController {
  protected function admin_only() {}
  protected function ok($data) {}
  protected function err($msg, $code = 400) {}
}
```

This keeps implementation small and sequenced. When you're ready, say **“Scaffold v1.1.0 core files”** and I’ll add the actual PHP class stubs in the paths above.

---
## Progress & Status — v1.1.x

### ✅ Done (merged / working)
- **Admin menus**
  - Top-level **SearchJet** + subpages: **Automations**, **AI Agents** (under `admin.php?page=searchjet`).
- **Automations core scaffolding**
  - `Automations\Manager` (init + feature flag `searchjet_automations_enabled`).
  - `Automations\Registry` (built-ins: `daily_health_snapshot`, `zero_result_burst`, `index_summary`).
  - `Automations\DataContracts` (flat payload builders).
  - `Automations\Logger` (logs with `searchjet.automation` channel).
  - **Provider-aware webhooks** in `Automations\Webhooks`  
    - Provider: `custom` / `n8n` / `zapier`  
    - URLs: `searchjet_webhook_url`, `searchjet_webhook_url_n8n`, `searchjet_webhook_url_zapier`  
    - Optional HMAC via `searchjet_webhook_secret`, minimal retry.
- **REST events bootstrap**
  - `SearchJet\Rest\EventsController::init()` registered.
- **Zero‑result burst plumbing**
  - `Automations\Events` with rolling window (transients) + emitter hook.
- **Admin UI**
  - Automations page: enable toggle, provider radio, URLs, secret.  
  - Submenu routing fixed (no stray `/wp-admin/searchjet-automations`).

### 🚧 In Progress
- **Automations page → Available Automations**  
  Persisting enabled list (checkbox array) without clobbering other options.
- **Zero‑result burst trigger**  
  Thresholds (N in M minutes) + dispatch link.
- **Index summary trigger**  
  Ensure `do_action('searchjet_index_completed', $summary)` fires post‑reindex and is dispatched.

### ⏭️ Next Up (to finish v1.1.0)
1. **Settings save fix (Automations page)**
   - Separate option group `searchjet_automations_group`.
   - Options:  
     - `searchjet_automations_enabled` (bool)  
     - `searchjet_automations_enabled_list` (array of ids)  
     - `searchjet_webhook_provider` + provider URLs + `searchjet_webhook_secret`
   - Add nonce + `sanitize_callback` for arrays/URLs.

2. **Events → Webhook wire‑up in Manager**
   - Listen to:
     - `searchjet_zero_result_detected` → `Webhooks::dispatch('search.zero_result_burst', DataContracts::zeroResultEvent(...))`
     - `searchjet_index_completed` → `Webhooks::dispatch('search.index_summary', DataContracts::indexSummary(...))`

3. **Smoke‑test buttons**
   - REST `POST /searchjet/v1/automations/run` for `daily_health_snapshot` from admin.

4. **Help docs**
   - Help tab on Automations page with provider/HMAC notes & n8n example.

### 🎯 Acceptance Criteria (v1.1.0)
- Enable toggle attaches/detaches hooks.
- Provider change + **Send Test Event** hits destination (n8n/Zapier/custom).
- ≥N zero‑result searches in 10m ⇒ one webhook (deduped window).
- Reindex completion ⇒ single index summary webhook.

### 📦 Planned Next Versions
- **v1.1.1 — Schedules + Runner + Daily Health Snapshot**  
  `Schedules`, `Runner::run(id)`, cron indicator + “Run now”.
- **v1.1.2 — REST (Automations API) + Zero‑result polish**  
  `GET /automations`, `POST /run`, inbound `/webhook`, threshold/dedupe tune.
- **v1.1.3 — Index Summary + Log viewer**  
  Wire summary + transient‑based tail viewer.
- **v1.1.4 — n8n Client + per‑automation tests**  
  Optional `Integrations\N8nClient`; “Send Test Event” per automation.
- **v1.2.x — AI (read‑only suggestions)**  
  Agents core + QueryRewriteAgent first; preview/export JSON.
- **v1.3.0 — Persistent logs (optional)**  
  `wp_searchjet_automation_logs` + filterable admin list.

### 📝 Backlog (nice‑to‑haves)
- Per‑automation routing (automation → provider).
- Provider‑specific transforms (Zapier‑flat vs nested JSON).
- Backoff/queue for retries (WP‑Cron).
- Role caps for viewing/triggering automations (beyond `manage_options`).
- Multisite feature flags + per‑site overrides.
- Security: inbound HMAC validator examples; rate limit inbound `/webhook`.
- Analytics tie‑ins: UI surfacing last burst & snapshot summaries.
- AI: Merchandising & Search Tuner agents; CSV export of suggestions.

### 🧪 Quick Test Plan
- Toggle between Custom/n8n/Zapier; verify headers + endpoint delivery.
- Force zero‑result queries; confirm single burst notification in window.
- Run reindex; confirm `index_summary` payload (added/updated/skipped/duration).
- Save Automations page repeatedly; other SearchJet settings remain intact.

---