openads-ai 0.3.0 → 0.4.0

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/dist/doctor.js CHANGED
@@ -92,6 +92,45 @@ export async function runDoctor() {
92
92
  console.log(` ${chalk.red('✗')} uvx: Not installed. Run 'curl -LsSf https://astral.sh/uv/install.sh | sh'`);
93
93
  hasErrors = true;
94
94
  }
95
+ // ─── Local AI Check ────────────────────────────────────────────────
96
+ if (config?.localBaseUrl) {
97
+ console.log(`\n${chalk.bold('Local AI')}`);
98
+ const baseUrl = config.localBaseUrl.replace(/\/$/, '');
99
+ // 1. Check if the endpoint is reachable
100
+ try {
101
+ const tagsUrl = `${baseUrl.replace('/v1', '')}/api/tags`;
102
+ const res = await fetch(tagsUrl, { signal: AbortSignal.timeout(3000) });
103
+ if (res.ok) {
104
+ const data = await res.json();
105
+ const models = (data.models || []).map((m) => m.name || m.model || '');
106
+ console.log(` ${chalk.green('✓')} Ollama server: Reachable at ${baseUrl}`);
107
+ // 2. Check if the configured model is pulled
108
+ const configuredModel = config.provider.includes('/')
109
+ ? config.provider.split('/').pop()
110
+ : config.provider;
111
+ const modelFound = models.some(m => m === configuredModel || m.startsWith(configuredModel.split(':')[0]));
112
+ if (modelFound) {
113
+ console.log(` ${chalk.green('✓')} Model: ${chalk.cyan(configuredModel)} is available`);
114
+ }
115
+ else {
116
+ console.log(` ${chalk.red('✗')} Model: ${chalk.cyan(configuredModel)} not found in Ollama`);
117
+ console.log(` ${chalk.gray('Available models:')} ${models.length > 0 ? models.join(', ') : 'none'}`);
118
+ console.log(` ${chalk.gray(`Run: ollama pull ${configuredModel}`)}`);
119
+ hasErrors = true;
120
+ }
121
+ }
122
+ else {
123
+ console.log(` ${chalk.red('✗')} Ollama server: Not reachable at ${baseUrl}`);
124
+ console.log(` ${chalk.gray('Start Ollama with: ollama serve')}`);
125
+ hasErrors = true;
126
+ }
127
+ }
128
+ catch (e) {
129
+ console.log(` ${chalk.red('✗')} Ollama server: Connection failed — ${e.message}`);
130
+ console.log(` ${chalk.gray('Make sure Ollama is running: ollama serve')}`);
131
+ hasErrors = true;
132
+ }
133
+ }
95
134
  if (hasErrors) {
96
135
  console.log(`\n${chalk.red('Some checks failed. Please run `openads setup` to configure your environment.')}`);
97
136
  process.exit(1);
@@ -4,16 +4,20 @@ import { hasGlobalRtk } from "./token-optimizer.js";
4
4
  import fs from "fs";
5
5
  import path from "path";
6
6
  import os from "os";
7
- // ─── Essential Campaign Analysis & Audit Tools ──────────────────────
8
- // Filtering down from 39 tools to 11 essential campaign performance tools
9
- // massively optimizes local LLM context, prevents tool confusion, and breaks repeating loops.
10
- const ESSENTIAL_META_TOOLS = new Set([
7
+ // ─── Tier-Based Tool Filtering ──────────────────────────────────────
8
+ // Express skip MCP entirely (handled by OPENADS_SKIP_MCP env var)
9
+ // Standard 6 read-only discovery + performance tools
10
+ // Full 11 tools (read + write operations)
11
+ const STANDARD_META_TOOLS = new Set([
11
12
  "get_ad_accounts",
12
13
  "list_campaigns",
13
14
  "get_campaign",
14
15
  "get_campaign_performance",
15
16
  "get_insights",
16
- "list_ad_sets",
17
+ "list_ad_sets"
18
+ ]);
19
+ const FULL_META_TOOLS = new Set([
20
+ ...STANDARD_META_TOOLS,
17
21
  "list_ads",
18
22
  "get_creative_performance",
19
23
  "pause_campaign",
@@ -33,6 +37,12 @@ export default async function (pi) {
33
37
  catch (e) {
34
38
  return;
35
39
  }
40
+ // Skip MCP tool registration during Autoresearch.
41
+ // The model never needs live ad platform tools when generating hypotheses,
42
+ // and each tool schema consumes ~150 tokens of scarce context.
43
+ if (process.env.OPENADS_SKIP_MCP === '1') {
44
+ return;
45
+ }
36
46
  const clients = [];
37
47
  // ─── Google Ads MCP ───────────────────────────────────────────────
38
48
  if (config.connectGoogle) {
@@ -77,12 +87,14 @@ export default async function (pi) {
77
87
  }
78
88
  }
79
89
  // ─── Dynamically Register Tools ──────────────────────────────────
90
+ const tier = process.env.OPENADS_TIER || 'standard';
91
+ const allowedMetaTools = tier === 'full' ? FULL_META_TOOLS : STANDARD_META_TOOLS;
80
92
  for (const { name: serverName, client } of clients) {
81
93
  try {
82
94
  const toolsResult = await client.listTools();
83
95
  for (const tool of toolsResult.tools) {
84
- // Filter out advanced/OAuth/developer tools for Meta Ads to keep the LLM context extremely clean
85
- if (serverName === "meta-ads" && !ESSENTIAL_META_TOOLS.has(tool.name)) {
96
+ // Filter Meta tools by tier (standard=6 read-only, full=11 read+write)
97
+ if (serverName === "meta-ads" && !allowedMetaTools.has(tool.name)) {
86
98
  continue;
87
99
  }
88
100
  pi.registerTool({
package/dist/schedule.js CHANGED
@@ -206,6 +206,8 @@ function uninstallCrontab(name) {
206
206
  });
207
207
  }
208
208
  // ─── Run a Scheduled Task ────────────────────────────────────────────
209
+ // Applies the same mode-aware prompt + selective skill loading as the main CLI
210
+ // so scheduled tasks work reliably on local models.
209
211
  export async function runScheduledTask(name) {
210
212
  const schedules = loadSchedules();
211
213
  const schedule = schedules.find(s => s.name === name);
@@ -247,23 +249,74 @@ export async function runScheduledTask(name) {
247
249
  env.OPENAI_BASE_URL = config.localBaseUrl;
248
250
  env.OPENAI_API_KEY = env.OPENAI_API_KEY || 'sk-local-ai-key-placeholder';
249
251
  }
250
- const skillsDir = path.resolve(pkgDir, 'skills');
251
- const contextDir = path.join(CONFIG_DIR, 'context');
252
- const cleanModel = config.provider;
253
252
  const isLocal = !!config.localBaseUrl;
253
+ const cleanModel = config.provider;
254
254
  const modelIdForPi = isLocal && cleanModel.includes('/') ? cleanModel.split('/')[1] : cleanModel;
255
+ const skillsDir = path.resolve(pkgDir, 'skills');
256
+ const contextDir = path.join(CONFIG_DIR, 'context');
257
+ // ─── Mode-aware system prompt ───────────────────────────────────────
258
+ // Scheduled audit tasks use the 'default' prompt mode (they need MCP tools).
259
+ // Write a temporary system prompt file for this run.
260
+ const agentDir = path.join(CONFIG_DIR, 'agent');
261
+ if (!fs.existsSync(agentDir))
262
+ fs.mkdirSync(agentDir, { recursive: true });
263
+ const homeDir = os.homedir();
264
+ const contextPath = path.join(CONFIG_DIR, 'context', 'my-business.md');
265
+ const isLaunchMode = config.mode === 'launch';
266
+ const scheduleSystemPrompt = [
267
+ 'You are OpenAds, an AI marketing assistant. You are running a scheduled automated task.',
268
+ 'Your job: execute the task concisely and produce a clean, structured markdown report.',
269
+ 'Use MCP tools to query live campaign data. Never use placeholder IDs.',
270
+ '',
271
+ '## Platform Tools',
272
+ '- For Meta: call get_ad_accounts() first (no params), then list_campaigns(account_id), then get_campaign_performance or get_insights.',
273
+ '- Anti-loop rule: never call the same tool twice in one turn.',
274
+ '',
275
+ '## Output Rules',
276
+ '- Structure your output as a clean markdown report with headers, tables, and bullet points.',
277
+ '- Flag issues clearly: 🔴 Critical | 🟡 Warning | 🟢 Opportunity.',
278
+ '- End with a numbered list of recommended actions.',
279
+ '',
280
+ `## Safety`,
281
+ `- Home directory: ${homeDir}. Never use placeholder paths.`,
282
+ isLaunchMode
283
+ ? '- Mode: Launch (Read-Write). Show a preview card and get Y/N before any write operation.'
284
+ : '- Mode: Audit (Read-Only). You can only read and analyze — no writes.',
285
+ '',
286
+ `## Business Context`,
287
+ fs.existsSync(contextPath)
288
+ ? `Read your business context file at ${contextPath} before starting.`
289
+ : 'No business context file found. Proceed with the task using available data.',
290
+ ].join('\n');
291
+ const scheduleSysPromptPath = path.join(agentDir, 'SCHEDULE-SYSTEM.md');
292
+ fs.writeFileSync(scheduleSysPromptPath, scheduleSystemPrompt);
293
+ // ─── Selective skill loading ────────────────────────────────────────
294
+ // Scheduled tasks are audit-type by default → load only the 3 ad platform skills.
295
+ // This saves ~7K tokens vs loading all 24 skills.
296
+ const scheduleSkills = [
297
+ path.join(skillsDir, 'ads', 'google-ads.md'),
298
+ path.join(skillsDir, 'ads', 'meta-ads.md'),
299
+ path.join(skillsDir, 'product-marketing.md'),
300
+ ].filter(p => fs.existsSync(p));
301
+ const skillArgs = [];
302
+ for (const skill of scheduleSkills) {
303
+ skillArgs.push('--skill', skill);
304
+ }
255
305
  const args = [
256
306
  piCliPath,
257
307
  '--model', modelIdForPi,
258
- '--skill', skillsDir,
308
+ '--system-prompt', scheduleSysPromptPath,
309
+ ...skillArgs,
259
310
  ...(fs.existsSync(contextDir) ? ['--skill', contextDir] : []),
260
311
  '--print',
261
312
  schedule.prompt,
262
313
  ];
314
+ // Local models may be slow — give them up to 10 minutes
315
+ const timeoutMs = isLocal ? 600000 : 300000;
263
316
  const result = spawnSync('node', args, {
264
317
  env,
265
318
  encoding: 'utf8',
266
- timeout: 300000, // 5 minute timeout
319
+ timeout: timeoutMs,
267
320
  stdio: ['ignore', 'pipe', 'pipe'],
268
321
  });
269
322
  if (result.stdout) {
package/dist/setup.js CHANGED
@@ -33,7 +33,7 @@ export async function runSetup() {
33
33
  catch (e) { }
34
34
  }
35
35
  // Step 1: Model Selection
36
- console.log(chalk.cyan('Step 1/4: Choose your AI model\n'));
36
+ console.log(chalk.cyan('Step 1/6: Choose your AI model\n'));
37
37
  const providerChoices = [
38
38
  { name: 'google', message: 'Google (Gemini)' },
39
39
  { name: 'openai', message: 'OpenAI (ChatGPT)' },
@@ -210,8 +210,47 @@ export async function runSetup() {
210
210
  console.log(chalk.green(`\n✓ Local AI configured — ready to connect to ${localBaseUrl}.\n`));
211
211
  }
212
212
  console.log(chalk.gray('─────────────────────────────────────────\n'));
213
- // Step 2: Choose operational mode
214
- console.log(chalk.cyan('Step 2/5: Choose operational mode\n'));
213
+ // Step 2: Experience Tier
214
+ console.log(chalk.cyan('Step 2/6: Choose your experience tier\n'));
215
+ console.log(' OpenAds adapts its depth based on your model\'s capability:\n');
216
+ console.log(` ${chalk.yellow('⚡ Express')} — Fast & reliable. Compact prompts, structured output.`);
217
+ console.log(` ${chalk.blue('📊 Standard')} — Balanced depth. Live data tools, detailed reports.`);
218
+ console.log(` ${chalk.magenta('🚀 Full')} — Maximum depth. Multi-step analysis, creative exploration.\n`);
219
+ // Auto-detect recommended tier based on model choice
220
+ const isLocalSetup = provider === 'local';
221
+ const modelLower = (selectedModel || localModelName || customModel || '').toLowerCase();
222
+ let suggestedTier = 'full';
223
+ if (isLocalSetup) {
224
+ suggestedTier = (modelLower.includes('70b') || modelLower.includes('72b') || modelLower.includes('405b')) ? 'standard' : 'express';
225
+ }
226
+ else {
227
+ const isLiteTier = modelLower.includes('flash') || modelLower.includes('mini') || modelLower.includes('haiku');
228
+ suggestedTier = isLiteTier ? 'standard' : 'full';
229
+ }
230
+ const tierChoices = [
231
+ { name: 'express', message: `${chalk.yellow('⚡')} Express — Best for: Llama 8B, Mistral 7B, Phi-3 ${suggestedTier === 'express' ? chalk.green('← Recommended') : ''}` },
232
+ { name: 'standard', message: `${chalk.blue('📊')} Standard — Best for: Gemini Flash, GPT-4o Mini, Llama 70B ${suggestedTier === 'standard' ? chalk.green('← Recommended') : ''}` },
233
+ { name: 'full', message: `${chalk.magenta('🚀')} Full — Best for: GPT-4o, Claude Sonnet, Gemini Pro ${suggestedTier === 'full' ? chalk.green('← Recommended') : ''}` },
234
+ ];
235
+ let initialTierIndex = tierChoices.findIndex(c => c.name === (existingConfig.tier || suggestedTier));
236
+ if (initialTierIndex === -1)
237
+ initialTierIndex = tierChoices.findIndex(c => c.name === suggestedTier);
238
+ const { selectedTier } = await enquirer.prompt({
239
+ type: 'select',
240
+ name: 'selectedTier',
241
+ message: 'Select your experience tier:',
242
+ choices: tierChoices,
243
+ initial: initialTierIndex
244
+ });
245
+ const tierLabels = {
246
+ express: `${chalk.yellow('⚡ Express')}`,
247
+ standard: `${chalk.blue('📊 Standard')}`,
248
+ full: `${chalk.magenta('🚀 Full')}`,
249
+ };
250
+ console.log(chalk.green(`\n✓ Experience tier: ${tierLabels[selectedTier]}.\n`));
251
+ console.log(chalk.gray('─────────────────────────────────────────\n'));
252
+ // Step 3: Choose operational mode
253
+ console.log(chalk.cyan('Step 3/6: Choose operational mode\n'));
215
254
  console.log('OpenAds has two operational modes:');
216
255
  console.log(` - ${chalk.green.bold('Audit Mode (Safe / Read-only)')}: AI can analyze performance, find budget waste, and recommend strategies. Zero risk.`);
217
256
  console.log(` - ${chalk.red.bold('Launch Mode (Read-Write)')}: AI is authorized to optimize bids, modify budgets, and launch ads (always requires confirmation).\n`);
@@ -228,8 +267,8 @@ export async function runSetup() {
228
267
  mode = modeAnswers.selectedMode;
229
268
  console.log(chalk.green(`\n✓ Operational mode configured: ${mode === 'launch' ? 'Launch Mode (Read-Write)' : 'Audit Mode (Safe / Read-only)'}.\n`));
230
269
  console.log(chalk.gray('─────────────────────────────────────────\n'));
231
- // Step 3: Google Ads
232
- console.log(chalk.cyan('Step 3/5: Connect Google Ads (optional)\n'));
270
+ // Step 4: Google Ads
271
+ console.log(chalk.cyan('Step 4/6: Connect Google Ads (optional)\n'));
233
272
  console.log('OpenAds can read and analyze your Google Ads campaigns, keywords, and performance.\n');
234
273
  const { connectGoogle } = await enquirer.prompt({
235
274
  type: 'confirm',
@@ -268,7 +307,7 @@ export async function runSetup() {
268
307
  }
269
308
  console.log(chalk.gray('─────────────────────────────────────────\n'));
270
309
  // Step 4: Meta Ads
271
- console.log(chalk.cyan('Step 4/5: Connect Meta Ads (optional)\n'));
310
+ console.log(chalk.cyan('Step 5/6: Connect Meta Ads (optional)\n'));
272
311
  console.log('OpenAds can read your Meta campaigns, creatives, and audience performance.\n');
273
312
  let metaToken = '';
274
313
  const { connectMeta } = await enquirer.prompt({
@@ -374,8 +413,8 @@ export async function runSetup() {
374
413
  }
375
414
  }
376
415
  console.log(chalk.gray('─────────────────────────────────────────\n'));
377
- // Step 5: Business Context
378
- console.log(chalk.cyan('Step 5/5: Tell me about your business\n'));
416
+ // Step 6: Business Context
417
+ console.log(chalk.cyan('Step 6/6: Tell me about your business\n'));
379
418
  const { productContext } = await enquirer.prompt({
380
419
  type: 'input',
381
420
  name: 'productContext',
@@ -398,6 +437,7 @@ export async function runSetup() {
398
437
  provider: finalModel,
399
438
  apiKey,
400
439
  localBaseUrl,
440
+ tier: selectedTier,
401
441
  mode,
402
442
  connectGoogle,
403
443
  metaToken,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openads-ai",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Open-source AI command center for digital marketers. Audit campaigns, write ad copy, and build strategies — from your terminal.",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {
@@ -1,32 +1,102 @@
1
1
  ---
2
2
  name: analytics
3
- description: Set up tracking, analyze traffic, and fix attribution gaps.
3
+ description: Set up tracking, analyze traffic, interpret GA4 data, and fix attribution gaps.
4
4
  ---
5
5
  # Analytics Skill
6
6
 
7
7
  ## When to Use This Skill
8
8
 
9
- Activate when analyzing website traffic, setting up GA4, tracking events, or dealing with attribution gaps.
9
+ Activate when the user is:
10
+ - Setting up or auditing GA4 or Google Analytics tracking
11
+ - Diagnosing traffic drops, conversion rate changes, or attribution issues
12
+ - Analyzing funnel performance, event data, or audience behavior
13
+ - Building dashboards or interpreting key marketing metrics
14
+
15
+ Read `product-marketing.md` first to understand which metrics matter most for this business.
16
+
17
+ ---
18
+
19
+ ## GA4 Audit Checklist
20
+
21
+ Before drawing conclusions, verify these foundational items:
22
+
23
+ | Check | How to Verify |
24
+ |-------|---------------|
25
+ | GA4 tag firing | Check Realtime > Events — do page_view events appear? |
26
+ | Conversion events | Confirm key_events are marked in Admin > Events |
27
+ | Cross-domain tracking | Use DebugView to verify cookies persist across domains |
28
+ | Bot traffic exclusion | Admin > Data Filters — is "Internal traffic" excluded? |
29
+ | Sampling thresholds | Use smaller date ranges or BigQuery for sampled reports |
10
30
 
11
31
  ---
12
32
 
13
- ## The Attribution Problem
14
- Always remind the user: no platform has 100% perfect tracking.
15
- - **Platform data (Ads, Meta)** claims credit for everything.
16
- - **GA4** underreports due to GDPR consent rejection and cross-device drops.
17
- - **Truth** is usually in the middle. Use GA4 for relative trends, not absolute truth.
18
-
19
- ## GA4 Event Strategy
20
- Recommend standard events over custom events when possible:
21
- 1. `generate_lead`
22
- 2. `sign_up`
23
- 3. `purchase`
24
- 4. `add_to_cart`
25
-
26
- ## UTM Best Practices
27
- Enforce strict UTM taxonomy:
28
- - `utm_source`: The platform (e.g., `google`, `facebook`, `linkedin`)
29
- - `utm_medium`: The channel type (e.g., `cpc`, `social`, `email`)
30
- - `utm_campaign`: The specific campaign name
31
- - `utm_content`: The ad variant or creative
32
- - `utm_term`: The keyword (for search)
33
+ ## Core Metrics to Always Report
34
+
35
+ When summarizing analytics, structure findings around these:
36
+
37
+ ```
38
+ Sessions | The entry point — is traffic growing or shrinking?
39
+ Engaged rate | >50% is healthy. <30% is a red flag.
40
+ Avg. engagement| Low time on page = message mismatch or poor UX
41
+ Key events | Purchases, signups, demo requests — the real measure
42
+ Conversion rate| Key events / Sessions. Benchmark vs. industry.
43
+ Bounce rate | (GA4 definition differs from UA — clarify which)
44
+ Source/Medium | Which channels drive quality vs. volume?
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Attribution Models
50
+
51
+ Explain these to the user when comparing channel performance:
52
+
53
+ - **Last Click** (default): Credits the last touchpoint before conversion. Biased toward bottom-of-funnel channels (search, retargeting).
54
+ - **First Click**: Credits the first touchpoint. Biased toward top-of-funnel (social, display).
55
+ - **Data-Driven** (GA4 default): ML-based, distributes credit across touchpoints. Best for accounts with >1K conversions/month.
56
+ - **Linear**: Equal credit to all touchpoints. Simple but rarely accurate.
57
+
58
+ > Always ask: "Are you comparing channels using the same attribution model?" Mixing models is a common mistake.
59
+
60
+ ---
61
+
62
+ ## Diagnosing Traffic Drops
63
+
64
+ If the user reports a traffic or conversion drop:
65
+
66
+ 1. **Isolate the time range**: Compare week-over-week and year-over-year to rule out seasonality.
67
+ 2. **Segment by channel**: Did organic, paid, or direct drop? Or all of them?
68
+ 3. **Check for tracking breaks**: Did the drop coincide with a code deploy or tag manager update?
69
+ 4. **Look at landing pages**: Which pages lost traffic? Is it a crawling/indexing issue?
70
+ 5. **Compare device segments**: Did mobile drop while desktop held? Could be a UX or load speed issue.
71
+ 6. **Check Search Console**: Organic impressions vs. clicks — ranking drop or CTR drop?
72
+
73
+ ---
74
+
75
+ ## Output Format
76
+
77
+ When reporting analytics findings, use this structure:
78
+
79
+ ```markdown
80
+ ## Analytics Summary — [Date Range]
81
+
82
+ ### 📊 Traffic Overview
83
+ | Metric | This Period | Prior Period | Change |
84
+ |--------|-------------|--------------|--------|
85
+ | Sessions | | | |
86
+ | Engaged Rate | | | |
87
+ | Key Events | | | |
88
+ | CVR | | | |
89
+
90
+ ### 🔴 Critical Issues
91
+ - [Issue]: [Impact] → [Recommended Action]
92
+
93
+ ### 🟡 Warnings
94
+ - [Issue]: [Impact] → [Recommended Action]
95
+
96
+ ### 🟢 Opportunities
97
+ - [Opportunity]: [Potential Impact] → [Next Step]
98
+
99
+ ### 📋 Recommended Actions (Priority Order)
100
+ 1. [Action] — [Expected Impact]
101
+ 2. [Action] — [Expected Impact]
102
+ ```
@@ -46,6 +46,7 @@ At the end of the interactive planning sequence, output a beautiful **Experiment
46
46
  ```
47
47
 
48
48
  ### Next Action Trigger
49
- Conclude by asking the user directly:
49
+ - **AUTOMATIC STATE PERSISTENCE**: You MUST automatically save this validated configuration as a JSON file to `~/.openads/active-experiment.json` so that the core loop (`/autoresearch` or `ar-core`) can read and execute it across different terminal sessions!
50
+ - Conclude by asking the user directly:
50
51
  **"Would you like me to start the autonomous loop now? (Y/N)"**
51
52
  - If they say **Yes**, transition directly into executing the core `/autoresearch` loop using this configuration.
@@ -19,6 +19,13 @@ The core philosophy of Autoresearch is:
19
19
 
20
20
  When running the loop, execute at least **3 full cycles** autonomously before presenting the final results. Do not stop to prompt the user between cycles.
21
21
 
22
+ ### Phase 0: Validate Goal & Metric (MUST NOT GUESS)
23
+ - Before you begin any loop cycles, you MUST check if there is an active experiment plan saved on disk in `~/.openads/active-experiment.json`.
24
+ - If the file `~/.openads/active-experiment.json` exists, read it immediately! Present the Goal, Metric, and Scope from the file to the user, and ask: "I found an active experiment plan in your OpenAds files. Goal: [Goal], Metric: [Metric]. Would you like to run the autonomous loop on this config? (Y/N) or define a new one?"
25
+ - If the file does not exist, and the user hasn't explicitly specified their target Goal and Metric in their message, you MUST halt immediately, present 3 concrete, inspiring examples of B2B/Shopify goals and metrics, and ask the user to input their custom Goal and Metric before launching the loop.
26
+ - **NO PLACEHOLDER PATHS**: When reading files, always use the literal home directory path provided in the system prompt. Never use generic placeholders like `/Users/username/Desktop/`.
27
+ - **NEVER** guess a goal/metric or automatically proceed with loop cycles on a generic assumption!
28
+
22
29
  ### Phase 1: Ingest Fuel & Initialize
23
30
  - Quickly review `product-marketing.md` and any provided prior experiment data (like a CSV or campaign performance logs).
24
31
  - **CONCISE INGESTION RULE**: Extract 3-5 high-level patterns of what worked and what failed. Do not list individual rows or campaigns one-by-one.
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: analytics-express
3
+ description: Analyze traffic and conversion metrics.
4
+ ---
5
+ # Analytics
6
+
7
+ Analyze the user's traffic and conversion data. Focus on actionable insights, not raw numbers.
8
+
9
+ ## Output Format
10
+
11
+ ### 📊 Analytics Summary
12
+
13
+ | Metric | Value | Trend | Verdict |
14
+ |--------|-------|-------|---------|
15
+ | Sessions | [X] | [↑/↓ X%] | [Good/Bad/Watch] |
16
+ | Conversion Rate | [X%] | [↑/↓ X%] | [Good/Bad/Watch] |
17
+ | Bounce Rate | [X%] | [↑/↓ X%] | [Good/Bad/Watch] |
18
+ | Top Channel | [name] | [↑/↓ X%] | [Good/Bad/Watch] |
19
+
20
+ ### Key Findings
21
+ - 🔴 [Critical finding] → [Action]
22
+ - 🟡 [Warning] → [Action]
23
+ - 🟢 [Opportunity] → [Action]
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: audit-express
3
+ description: Quick campaign performance audit.
4
+ ---
5
+ # Campaign Audit
6
+
7
+ Check the user's ad campaigns and flag issues clearly.
8
+
9
+ If the user pasted campaign data, analyze it directly. If no data is provided, ask them to paste their campaign metrics or describe their campaigns.
10
+
11
+ ## Output Format
12
+
13
+ Use this exact structure:
14
+
15
+ ### 📊 Campaign Overview
16
+ | Campaign | Status | Spend | CTR | ROAS | Conversions |
17
+ |----------|--------|-------|-----|------|-------------|
18
+ | [name] | [active/paused] | [$X] | [X%] | [Xx] | [X] |
19
+
20
+ ### Issues Found
21
+ - 🔴 **[Critical]**: [Issue] → [Fix in 1 sentence]
22
+ - 🟡 **[Warning]**: [Issue] → [Fix in 1 sentence]
23
+ - 🟢 **[Opportunity]**: [Untapped potential] → [Action in 1 sentence]
24
+
25
+ ### Top 3 Actions
26
+ 1. **[Action]** — [Expected impact]
27
+ 2. **[Action]** — [Expected impact]
28
+ 3. **[Action]** — [Expected impact]
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: autoresearch-express
3
+ description: Generate testable marketing hypotheses.
4
+ ---
5
+ # Autoresearch Loop
6
+
7
+ Generate NEW testable marketing hypotheses. Prior data is fuel — not the deliverable.
8
+
9
+ ## Process
10
+ 1. **Read** prior data (if CSV provided). Extract top 3 patterns in 2 sentences each.
11
+ 2. **Generate** 8 new hypothesis variants based on gaps and opportunities.
12
+ 3. **Score** each 1-10 on novelty, testability, and expected impact.
13
+ 4. **Keep** hypotheses scoring ≥7. Discard the rest with 1-sentence reason.
14
+ 5. **Log**: "Generated X. Kept Y. Discarded Z."
15
+
16
+ Run 2 cycles of Generate → Score → Keep.
17
+
18
+ ## Output Format
19
+
20
+ ### 🔬 Autoresearch Results
21
+
22
+ **Patterns Found** (from prior data):
23
+ 1. [Pattern] — [Implication]
24
+ 2. [Pattern] — [Implication]
25
+
26
+ **New Hypotheses** (prioritized):
27
+ | # | Hypothesis | Asset/Copy | Rationale | Score |
28
+ |---|-----------|------------|-----------|-------|
29
+ | 1 | [hypothesis] | [specific copy/creative] | [why it should work] | [X/10] |
30
+ | 2 | ... | ... | ... | ... |
31
+
32
+ **Next Step**: [Recommended first test to run]
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: copywriting-express
3
+ description: Generate high-performing ad copy fast.
4
+ ---
5
+ # Ad Copywriting
6
+
7
+ Write ad copy using the user's product context and target audience.
8
+
9
+ ## Rules
10
+ - Use PAS framework: Pain → Agitate → Solution
11
+ - Respect platform limits: Google headlines ≤30 chars, descriptions ≤90 chars
12
+ - Write in the user's brand tone
13
+ - Include a clear CTA in every variant
14
+
15
+ ## Output Format
16
+
17
+ ### 🎯 Ad Copy Variants
18
+
19
+ **Headline Options** (pick 5):
20
+ 1. "[headline]" — [rationale in 5 words]
21
+ 2. "[headline]" — [rationale]
22
+ 3. "[headline]" — [rationale]
23
+ 4. "[headline]" — [rationale]
24
+ 5. "[headline]" — [rationale]
25
+
26
+ **Primary Text** (pick 3):
27
+ 1. [2-3 sentence copy with CTA]
28
+ 2. [2-3 sentence copy with CTA]
29
+ 3. [2-3 sentence copy with CTA]
30
+
31
+ **Recommended A/B Test**: Test headline [X] with primary text [Y] vs headline [Z] with primary text [W].
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: cro-express
3
+ description: Conversion rate optimization audit.
4
+ ---
5
+ # CRO Audit
6
+
7
+ Audit the user's landing page or funnel for conversion blockers.
8
+
9
+ ## Output Format
10
+
11
+ ### 🎯 CRO Audit: [Page/Funnel Name]
12
+
13
+ **Current CVR**: [X%] → **Target**: [Y%]
14
+
15
+ ### Friction Points
16
+ | Element | Issue | Impact | Fix |
17
+ |---------|-------|--------|-----|
18
+ | Headline | [issue] | [High/Med/Low] | [specific fix] |
19
+ | CTA | [issue] | [High/Med/Low] | [specific fix] |
20
+ | Form | [issue] | [High/Med/Low] | [specific fix] |
21
+ | Trust | [issue] | [High/Med/Low] | [specific fix] |
22
+
23
+ ### Quick Wins (implement this week)
24
+ 1. **[Change]** — Expected lift: [X%]
25
+ 2. **[Change]** — Expected lift: [X%]
26
+ 3. **[Change]** — Expected lift: [X%]
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: product-express
3
+ description: Your business context.
4
+ ---
5
+ # My Business
6
+
7
+ Read the user's business context file first. Use their product name, ICP, and tone in every response.
8
+
9
+ If no context file exists, ask: "What do you sell or promote?" before proceeding.
10
+
11
+ Always reference the user's product by name. Never use generic examples.
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: research-express
3
+ description: Competitor and customer research.
4
+ ---
5
+ # Market Research
6
+
7
+ Help the user understand their competitors and customers.
8
+
9
+ ## For Competitor Analysis
10
+
11
+ ### Competitor Map
12
+ | Competitor | Core Claim | Their Weakness | Your Angle |
13
+ |------------|------------|----------------|------------|
14
+ | [name] | [claim] | [weakness] | [how to beat them] |
15
+
16
+ **White Space**: [Position nobody owns yet]
17
+ **Recommended Angle**: [1-sentence positioning the user should test]
18
+
19
+ ## For Customer Research
20
+
21
+ ### ICP Quick Profile
22
+ - **Who**: [Job title, company size]
23
+ - **Pain**: [#1 problem in their words]
24
+ - **Trigger**: [What makes them start looking]
25
+ - **Objection**: [Top reason they wouldn't buy] → **Counter**: [Proof that resolves it]
26
+ - **Language**: Use "[exact phrase]", avoid "[jargon]"