gooseworks 0.3.15 → 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/README.md +58 -8
- package/dist/agents/claude.js +1 -1
- package/dist/agents/claude.js.map +1 -1
- package/dist/agents/codex.js +1 -1
- package/dist/agents/codex.js.map +1 -1
- package/dist/agents/skill-links.d.ts +7 -2
- package/dist/agents/skill-links.d.ts.map +1 -1
- package/dist/agents/skill-links.js +10 -5
- package/dist/agents/skill-links.js.map +1 -1
- package/dist/auth/attribution.d.ts +14 -0
- package/dist/auth/attribution.d.ts.map +1 -0
- package/dist/auth/attribution.js +37 -0
- package/dist/auth/attribution.js.map +1 -0
- package/dist/auth/oauth-server.d.ts +4 -4
- package/dist/auth/oauth-server.d.ts.map +1 -1
- package/dist/auth/oauth-server.js +8 -8
- package/dist/auth/oauth-server.js.map +1 -1
- package/dist/commands/call.d.ts.map +1 -1
- package/dist/commands/call.js +6 -5
- package/dist/commands/call.js.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +11 -7
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/login.d.ts +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +13 -27
- package/dist/commands/login.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +6 -2
- package/dist/config.js.map +1 -1
- package/dist/skills/installer.d.ts +9 -0
- package/dist/skills/installer.d.ts.map +1 -1
- package/dist/skills/installer.js +20 -6
- package/dist/skills/installer.js.map +1 -1
- package/dist/skills/master-skill.d.ts +24 -22
- package/dist/skills/master-skill.d.ts.map +1 -1
- package/dist/skills/master-skill.js +392 -149
- package/dist/skills/master-skill.js.map +1 -1
- package/dist/skills/names.d.ts +53 -1
- package/dist/skills/names.d.ts.map +1 -1
- package/dist/skills/names.js +107 -7
- package/dist/skills/names.js.map +1 -1
- package/dist/skills/routes.d.ts +68 -0
- package/dist/skills/routes.d.ts.map +1 -0
- package/dist/skills/routes.js +124 -0
- package/dist/skills/routes.js.map +1 -0
- package/package.json +1 -1
- package/skills/goose-ads/SKILL.md +124 -104
- package/skills/goose-product-photos/SKILL.md +129 -0
- package/skills/gooseworks/SKILL.md +100 -41
- package/skills/routes.json +157 -0
|
@@ -1,17 +1,56 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getEntrySkills = getEntrySkills;
|
|
4
|
+
exports.getEntrySkillNames = getEntrySkillNames;
|
|
4
5
|
exports.getMasterSkillContent = getMasterSkillContent;
|
|
5
6
|
exports.getGooseAdsSkillContent = getGooseAdsSkillContent;
|
|
6
7
|
exports.getGooseVideoSkillContent = getGooseVideoSkillContent;
|
|
7
|
-
|
|
8
|
+
exports.getGooseProductPhotosSkillContent = getGooseProductPhotosSkillContent;
|
|
9
|
+
/**
|
|
10
|
+
* The CLI installs two vendored ENTRY skills into ~/.agents/skills/:
|
|
11
|
+
* - `gooseworks` — the PARENT router (getMasterSkillContent): GTM/data toolkit
|
|
12
|
+
* PLUS a domain router that hands ads/graphics/video work to the dedicated
|
|
13
|
+
* `goose-*` skills below.
|
|
14
|
+
* - `goose-ads` — the ads entry/contract (getGooseAdsSkillContent): ad creative
|
|
15
|
+
* (remix, brand research) AND ad analytics/intelligence. Formerly `ads-remix`.
|
|
16
|
+
* Each is a separate Claude Code skill; Claude auto-loads whichever matches the
|
|
17
|
+
* task by its description. They are domain-scoped on purpose — do NOT merge them.
|
|
18
|
+
*
|
|
19
|
+
* Sibling domain skills NOT vendored here (fetched live from goose-skills):
|
|
20
|
+
* - `goose-graphics` — charts/slides/infographics/branded visuals. Installed via
|
|
21
|
+
* `gooseworks install --with goose-graphics` or fetched on demand.
|
|
22
|
+
* - `goose-video` — video ad remix: fetches the per-format recipe by slug,
|
|
23
|
+
* renders LOCALLY (Playwright + ffmpeg + media proxies), mirrors a script for
|
|
24
|
+
* in-app review, saves the MP4 back over MCP (getGooseVideoSkillContent).
|
|
25
|
+
*
|
|
26
|
+
* Recipe skills (remix-graphic-ad-from-reference, brand-research, meta-ads-analyzer,
|
|
27
|
+
* …) are NOT vendored here — they live in goose-skills and are fetched live on
|
|
28
|
+
* demand via `gooseworks fetch <slug>`, so they're always current.
|
|
29
|
+
*/
|
|
30
|
+
const routes_1 = require("./routes");
|
|
31
|
+
/**
|
|
32
|
+
* THE registry of entry skills (GOOSE-3190) — one list, four consumers:
|
|
33
|
+
* - `gooseworks install` / `update` / login-refresh write exactly these dirs,
|
|
34
|
+
* - `npm run generate:skills` regenerates exactly these `skills/<name>/SKILL.md`,
|
|
35
|
+
* - `skills/names.ts` derives which dirs the CLI is allowed to delete,
|
|
36
|
+
* - the backend raw-fetches these paths for hosted connectors.
|
|
37
|
+
*
|
|
38
|
+
* `goose-product-photos` used to be a hand-maintained `skills/…/SKILL.md` that
|
|
39
|
+
* was on disk and served by the backend but absent here — so it was never
|
|
40
|
+
* regenerated and never refreshed on install. Adding it closes that drift.
|
|
41
|
+
*/
|
|
8
42
|
function getEntrySkills() {
|
|
9
43
|
return [
|
|
10
44
|
{ name: 'gooseworks', content: getMasterSkillContent() },
|
|
11
45
|
{ name: 'goose-ads', content: getGooseAdsSkillContent() },
|
|
12
46
|
{ name: 'goose-video', content: getGooseVideoSkillContent() },
|
|
47
|
+
{ name: 'goose-product-photos', content: getGooseProductPhotosSkillContent() },
|
|
13
48
|
];
|
|
14
49
|
}
|
|
50
|
+
/** Just the directory names, for callers that don't need the bodies. */
|
|
51
|
+
function getEntrySkillNames() {
|
|
52
|
+
return getEntrySkills().map((s) => s.name);
|
|
53
|
+
}
|
|
15
54
|
/**
|
|
16
55
|
* Returns the GTM master SKILL.md content (the `gooseworks` entry skill).
|
|
17
56
|
* It teaches the coding agent how to discover and use GooseWorks skills on
|
|
@@ -26,12 +65,10 @@ function getMasterSkillContent() {
|
|
|
26
65
|
name: gooseworks
|
|
27
66
|
slug: gooseworks
|
|
28
67
|
description: >
|
|
29
|
-
GooseWorks
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Reach for it when you need data at scale, sources behind auth, or a specific provider — not as
|
|
34
|
-
a replacement for your built-in web search/fetch on quick, one-off lookups.
|
|
68
|
+
GooseWorks growth coworker and specialist-skill router. Research brands, customers, competitors,
|
|
69
|
+
creators, markets, and prospects; analyze ads and performance; create ads, product photos,
|
|
70
|
+
graphics, and video; search and scrape public web and social data; find and enrich leads.
|
|
71
|
+
Use it as the single GooseWorks entry point for brand growth, B2B, sales, research, and GTM work.
|
|
35
72
|
category: general
|
|
36
73
|
version: 1.0.0
|
|
37
74
|
author: GooseWorks
|
|
@@ -40,79 +77,120 @@ tags: [gooseworks, data, scraping, search, reddit, twitter, linkedin, email, peo
|
|
|
40
77
|
|
|
41
78
|
# GooseWorks
|
|
42
79
|
|
|
43
|
-
You have access to GooseWorks —
|
|
80
|
+
You have access to GooseWorks — an AI coworker with specialist skills for research, analysis, creative work, lead generation, enrichment, and public web/social data. Use the right specialist when the request needs brand context, a managed creative workflow, data at scale, a source behind authentication, or a specific provider.
|
|
44
81
|
|
|
45
82
|
This skill is also the **parent router** for the GooseWorks family. Data/GTM work you handle here (see "How to Use"); specialized work you hand off to a dedicated \`goose-*\` skill.
|
|
46
83
|
|
|
47
84
|
## Route to the right skill FIRST
|
|
48
85
|
|
|
49
|
-
|
|
86
|
+
First apply the **Common company onboarding** gate below. Preserve the user's original request while onboarding, then continue with it as soon as onboarding is complete. Then load the brand context (**"Load the brand context FIRST"**, immediately below). After that, check whether the request belongs to a specialized domain. If so, **switch to that skill** instead of the data flow below:
|
|
50
87
|
|
|
51
88
|
| If the user wants… | Route to | How |
|
|
52
89
|
| --- | --- | --- |
|
|
53
|
-
|
|
54
|
-
| Charts, infographics, slides, social graphics, branded visual designs from a style/format | **\`goose-graphics\`** | If installed locally, use it. Otherwise \`gooseworks fetch goose-graphics\` (or \`gooseworks install --claude --with goose-graphics\`). |
|
|
55
|
-
| Make a **video** ad — remix a video ad template (e.g. iMessage chat-reveal), or "make the video for project <id>" | **\`goose-video\`** | Installed locally as an entry skill. Just use it. If unavailable, run \`gooseworks install --claude\`. |
|
|
90
|
+
${(0, routes_1.renderDomainRouteTable)()}
|
|
56
91
|
| Anything else — scraping, research, lead gen, enrichment, any data lookup | (stay here) | Follow "How to Use" below. |
|
|
57
92
|
|
|
58
93
|
Examples — all of these route to \`goose-ads\`, not the data flow: "remix this ad with project id 123", "make an ad for my product", "research my brand", "why is my Meta campaign underperforming", "which creatives should I cut".
|
|
59
94
|
|
|
95
|
+
## Load the brand context FIRST (mandatory — before you route, and before you ask anything)
|
|
96
|
+
|
|
97
|
+
**Call \`brand_get_context\` before the first substantive step of ANY task**, and before you route to a specialist skill. It is a cheap, read-only call that returns the brand's canonical facts:
|
|
98
|
+
|
|
99
|
+
| It returns | Use it for |
|
|
100
|
+
| --- | --- |
|
|
101
|
+
| **voice** — tone, style, banned phrasing | Any copy, script, caption, hook, or headline. Don't ask "what tone?" |
|
|
102
|
+
| **products** — names, descriptions, pricing, links, imagery | Picking the product to feature. Don't ask "which product?" — offer the list. |
|
|
103
|
+
| **audience** — segments, demographics, jobs-to-be-done | Targeting, angles, creator fit. Don't ask "who is this for?" |
|
|
104
|
+
| **positioning** — category, value props, proof points, tagline | Angles, offers, competitive framing. Don't ask "what makes you different?" |
|
|
105
|
+
| **research status** — whether the brand's research pass has completed | Whether the facts are trustworthy yet, or still being filled in. |
|
|
106
|
+
|
|
107
|
+
Then:
|
|
108
|
+
|
|
109
|
+
1. **Pass what it returned INTO the routed skill.** When you hand off to \`goose-ads\`, \`goose-video\`, \`goose-product-photos\`, \`goose-graphics\`, or a fetched Brand Growth recipe, carry the voice / products / audience / positioning with you. Do **not** make the routed skill re-derive them, and do **not** re-run brand research when the context is already there.
|
|
110
|
+
2. **Never re-ask the user for something the brand context already answers.** If a routed skill's own prose asks a question the context answers, the context wins — answer it yourself and move on. Ask only for what is genuinely missing or ambiguous.
|
|
111
|
+
3. **If research status is not complete**, say so in one line, use what you have, and continue. Only run brand research when the context comes back empty or the user asks for it.
|
|
112
|
+
4. **If \`brand_get_context\` is unavailable** (no MCP connection), fall back to \`get_brand_kit\` for the selected brand and treat its fields the same way. If neither is available, tell the user the GooseWorks MCP connection is needed rather than guessing brand facts.
|
|
113
|
+
5. **Treat it as read-only.** Writing brand facts back is the reconciliation flow in \`goose-ads\` (ask first, then \`update_brand_kit\`) — not something this router does.
|
|
114
|
+
|
|
115
|
+
Never invent a brand fact. If it isn't in the brand context and the user hasn't said it, ask.
|
|
116
|
+
|
|
60
117
|
## Setup
|
|
61
118
|
|
|
62
119
|
All commands below auto-load credentials from \`~/.gooseworks/credentials.json\`. If a command exits with "Not logged in", tell the user to run: \`npx gooseworks login\`. To log out: \`npx gooseworks logout\`.
|
|
63
120
|
|
|
64
|
-
###
|
|
121
|
+
### Choose the available runtime — MCP first, then CLI
|
|
122
|
+
|
|
123
|
+
Skills may describe a managed provider request as an environment-neutral operation with
|
|
124
|
+
\`provider\`, \`method\`, \`path\`, and optional \`query\` or \`body\`. Execute the operation through
|
|
125
|
+
the first available runtime:
|
|
126
|
+
|
|
127
|
+
1. If the matching GooseWorks MCP tool is registered, use it. For ScrapeCreators, pass the
|
|
128
|
+
operation directly to \`call_data_provider\`. This is the preferred path in ChatGPT, Cowork,
|
|
129
|
+
and other terminal-free clients. Do not shell out and do not ask for a separate provider key.
|
|
130
|
+
2. Otherwise, if a local terminal and the \`gooseworks\` CLI are available, translate the same
|
|
131
|
+
operation into \`gooseworks call <provider> <path>\` with its method, query, and body options.
|
|
132
|
+
3. Otherwise, follow the provider dependency's direct-key path only when the user has supplied
|
|
133
|
+
their own key. If no runtime is available, explain what connection is missing; never pretend
|
|
134
|
+
the provider call ran.
|
|
65
135
|
|
|
66
|
-
|
|
67
|
-
\`mcp__gooseworks__*\` tools are connected, use
|
|
136
|
+
The same selection applies to catalog and account operations. When the CLI is unavailable but the
|
|
137
|
+
\`mcp__gooseworks__*\` tools are connected, use these equivalents:
|
|
68
138
|
- \`gooseworks search <q>\` → the **\`search_skills\`** MCP tool.
|
|
69
139
|
- \`gooseworks fetch <slug>\` → the **\`fetch_skill\`** MCP tool (same content/scripts/files/deps).
|
|
70
140
|
- \`gooseworks credits\` → the **\`get_ad_credits\`** MCP tool.
|
|
71
141
|
|
|
72
|
-
Discovery
|
|
73
|
-
|
|
74
|
-
|
|
142
|
+
Discovery, skill fetching, and ScrapeCreators-backed Brand Growth workflows work fully CLI-free
|
|
143
|
+
this way. Task skills own the endpoint and analysis workflow; this runtime rule owns how the same
|
|
144
|
+
provider operation is executed.
|
|
75
145
|
|
|
76
146
|
To check credit balance:
|
|
77
147
|
\`\`\`bash
|
|
78
148
|
gooseworks credits
|
|
79
149
|
\`\`\`
|
|
80
150
|
|
|
81
|
-
##
|
|
151
|
+
## Common company onboarding
|
|
152
|
+
|
|
153
|
+
Onboarding happens inside the current agent and is the first-run gate for every GooseWorks task. It uses the exact same saved state and step order as the web onboarding. The user does not need to type **\`/gooseworks onboard me\`**; that explicit command only starts or resumes the same flow.
|
|
154
|
+
|
|
155
|
+
Keep the user's original task pending. Call **\`brand_onboarding { action: "status" }\`** before routing or executing it, then:
|
|
156
|
+
|
|
157
|
+
- follow only the returned \`next_step\`;
|
|
158
|
+
- save each answer immediately with \`brand_onboarding\` so web, Claude, Codex, ChatGPT, and Cowork can resume one another;
|
|
159
|
+
- continue the original request immediately when \`onboarding_completed\` is true.
|
|
82
160
|
|
|
83
|
-
|
|
161
|
+
If \`brand_onboarding\` is unavailable, explain that the GooseWorks MCP connection must be enabled. Do not write a parallel local profile and do not run the retired role / discovery-source / ad-owner questionnaire.
|
|
84
162
|
|
|
85
|
-
|
|
86
|
-
- \`update_user_context\` — save it (partial update; only the fields you pass are touched).
|
|
163
|
+
When onboarding returns a review link, show that single link and ask the user to review the creatives and reply \`done\`. When they reply \`done\`, do not restart onboarding: continue the task they originally asked for. If there was no earlier task, ask: **“Let’s start your next campaign. What are you promoting, and what result do you want?”** Use the same preserved-task-or-campaign handoff if onboarding completes while the creatives are still being prepared or could not be generated.
|
|
87
164
|
|
|
88
|
-
###
|
|
165
|
+
### Shared flow
|
|
89
166
|
|
|
90
|
-
|
|
167
|
+
Use the host's native question controls. Ask one short group at a time and rely on the live tool schema for accepted values.
|
|
91
168
|
|
|
92
|
-
|
|
169
|
+
1. **Start** — If status returns \`start\`, ask for the company website or Apple App Store URL. Also offer the optional hero product URL and “Where do you do your work?” choices: Slack, WhatsApp, iMessage, Claude Code, Claude, Codex, and ChatGPT. Call \`action: "start"\`; server-side research begins immediately. If status returns \`select_brand\`, ask which company/client to use. Otherwise reuse the only brand automatically.
|
|
170
|
+
2. **Your coworker** — Ask what they want to name their Growth Coworker. A text-only client may keep the default avatar; do not block on an image. Save with \`action: "save_coworker"\`.
|
|
171
|
+
3. **Your company** — Use the returned \`company_draft\` as the starting point and ask the user to verify or edit: what they sell (\`marketCategory\`), where people buy (\`appPlatforms\`), primary customer, customer problem, promised outcome, and optional differentiator. Save with \`action: "save_company"\`.
|
|
172
|
+
4. **Your taste** — In a terminal or CLI host, use the returned \`taste_url\`: open it when the host supports opening links and always show one clickable **Choose your taste in GooseWorks** link. Ask the user to heart or skip ads on that page, click **Continue** or **Skip this**, return to the agent, and reply \`done\`. Do not print, enumerate, or summarize \`taste_deck\` in the terminal. After \`done\`, call \`brand_onboarding { action: "status" }\` again and follow the refreshed \`next_step\`. In a chat host that renders images, show only the one image attached by the tool and save each Love/Skip decision with \`action: "save_taste"\`; send \`complete: true\` after three hearts or an explicit skip.
|
|
173
|
+
5. **First campaign** — Ask **“What’s happening right now?”**: launch \`launch\`, promotion \`promo\`, seasonal moment \`seasonal\`, or nothing special \`nothing\`, plus an optional note. Call \`action: "propose_campaign"\`, show the returned editable card (name, objective, offer, audience, 2–3 angles, CTA, and product URL), and save edits with \`action: "save_campaign"\`. Send \`accept: true\` only after approval; acceptance can start the complimentary first creatives.
|
|
174
|
+
6. **Where you are** — Ask monthly ad spend (\`none\`, \`under_1k\`, \`1k_5k\`, \`5k_25k\`, \`25k_plus\`), annual revenue (\`under_1m\`, \`1m_10m\`, \`10m_100m\`, \`100m_plus\`), the 90-day goal, current channels (an empty list is a valid “nothing yet”), and at least one channel they are willing to use. Channel values: \`paid_social\`, \`search_ads\`, \`content\`, \`creators\`, \`seo\`, \`communities\`, \`referrals\`, \`partnerships\`, \`outbound\`, \`app_stores\`, \`other\`. Save with \`action: "save_progress"\`.
|
|
175
|
+
7. **Review** — Show the returned founder, researched, and inferred facts with their provenance. The user may correct positioning, audience, voice, value propositions, proof points, or competitors through \`action: "review_research"\`. Complete the review even when research is still running, failed, or sparse; never trap the user waiting for it.
|
|
176
|
+
8. **Channels** — If \`channel_connected\` is already true, this is complete automatically. Otherwise ask whether they want to connect Slack, WhatsApp, or iMessage later, or skip for now. An explicit skip is valid; call \`action: "complete_channels"\`.
|
|
93
177
|
|
|
94
|
-
|
|
95
|
-
1. **What's your company's website?** → \`company_website\`
|
|
96
|
-
2. **What's your role?** → \`role\`
|
|
97
|
-
3. **What are you hoping to use Goose skills for?** (multi-select — pick any): generate ad creatives · research and run ads end-to-end · finding influencers · data scraping (social / ads / reddit) · finding leads & emails · something else → \`use_cases\` (array)
|
|
98
|
-
4. **What high-priority growth / marketing tasks would you like help with right now?** The more context they share, the better you can help. → \`goals\`
|
|
178
|
+
Do not ask for role, discovery source, who makes creatives, who manages ads, or a separate “what do you want to do first?” menu. Those belonged to the retired CLI questionnaire. The task the user already asked for is their first task.
|
|
99
179
|
|
|
100
|
-
|
|
180
|
+
## Brand Growth discovery
|
|
101
181
|
|
|
102
|
-
|
|
103
|
-
1. **Route each answer to the RIGHT tool first — don't blindly search one catalog. Match their use-cases to domains (same routing as "Route to the right skill FIRST" above):**
|
|
104
|
-
- **Make / edit / analyze ADS** (generate ad creatives, research & run ads) → the **\`goose-ads\`** skill (brand research + template remix). Do NOT \`gooseworks search\` for these — ad creation is NOT in the data catalog.
|
|
105
|
-
- **VIDEO ads** → **\`goose-video\`**. **Charts / slides / graphics** → **\`goose-graphics\`**.
|
|
106
|
-
- **GTM / DATA** (finding leads & emails, influencers, scraping social / ads / reddit, enrichment, competitor intel) → run \`gooseworks search "<that task>"\` (free) and recommend the REAL skill slugs it returns.
|
|
107
|
-
Recommend specific, real things BY NAME — never a from-memory playbook, never a skill you assume exists; if a GTM search returns nothing relevant, say so.
|
|
108
|
-
2. **Ground it in THEIR business.** If they gave a company website, read it with your web tools to infer their actual product + ICP, so suggestions are about their company — not a template. (For ad work, prefer \`goose-ads\`'s own brand research over a raw read.)
|
|
109
|
-
3. **Be honest about cost.** Data / lead / enrichment / ad-generation skills bill GooseWorks credits — say so, and estimate before running anything (\`gooseworks credits\` to check balance).
|
|
110
|
-
4. **Offer to start ONE concrete play** built from the ROUTED skill (\`goose-ads\` for ads, a real searched skill for GTM) and ask for the one or two inputs it needs.
|
|
182
|
+
Brand Growth is a collection inside the normal skill catalog, not a command or installable pack. Use these known routes when relevant, while preserving all existing B2B, sales, research, lead-generation, and data behavior:
|
|
111
183
|
|
|
112
|
-
|
|
184
|
+
| Job | Skill |
|
|
185
|
+
| --- | --- |
|
|
186
|
+
${(0, routes_1.renderBrandGrowthTable)()}
|
|
113
187
|
|
|
114
|
-
|
|
115
|
-
|
|
188
|
+
Fetch the named public skill before following it. You already called \`brand_get_context\` — hand the brand's voice, products, audience, and positioning to the fetched skill instead of letting it re-derive or re-ask them. Provider helpers such as \`scrapecreators-api\` and \`transcript-intelligence\` are dependencies, not user-facing results.
|
|
189
|
+
|
|
190
|
+
For a multi-part request, repeat this routing check before each new job. Fetch and follow the
|
|
191
|
+
closest outcome skill first (for example, \`comment-mining\`, \`creator-profile-teardown\`, or
|
|
192
|
+
\`content-repurposing\`) before calling provider APIs or improvising a workflow. Provider calls
|
|
193
|
+
collect inputs for the outcome skill; they do not replace it.
|
|
116
194
|
|
|
117
195
|
## How to Use
|
|
118
196
|
|
|
@@ -152,6 +230,7 @@ Follow the instructions in the skill's \`content\` field. **Save ALL files from
|
|
|
152
230
|
> - **Credentials (only needed before running Python scripts, NOT before gooseworks commands):** replace the python one-liner exports with \`eval $(gooseworks env)\`. Skip entirely if you are only using \`gooseworks call\` — it loads credentials automatically.
|
|
153
231
|
> - **Orthogonal run:** replace \`curl ... /v1/proxy/orthogonal/run ... -d '{"api":"X","path":"/Y","body":{...}}'\` with \`gooseworks call X /Y --body='{...}'\`
|
|
154
232
|
> - **Direct proxy:** replace \`curl ... /v1/proxy/<provider>/<path> ... -d '{...}'\` with \`gooseworks call <provider> <path> --body='{...}'\`
|
|
233
|
+
> - **ScrapeCreators:** call its first-party GooseWorks proxy directly with \`gooseworks call scrapecreators <path> --query='{...}'\`. Use ScrapeCreators' official OpenAPI for endpoint parameters; do not use Orthogonal as its endpoint catalog. GET is the default; add \`--method POST --body='{...}'\` only for an official POST operation.
|
|
155
234
|
> - **Orthogonal search:** replace \`curl ... /v1/proxy/orthogonal/search ... -d '{"prompt":"..."}'\` with \`gooseworks orthogonal find "..."\`
|
|
156
235
|
|
|
157
236
|
1. Save each script from \`scripts\` to \`/tmp/gooseworks-scripts/<slug>/scripts/\` — **NEVER save scripts into the user's project directory**
|
|
@@ -190,9 +269,10 @@ gooseworks call hunter /v2/email-finder --query='{"domain":"stripe.com","first_n
|
|
|
190
269
|
- Output: JSON response data, followed by a \`Cost: <N> credits\` line when applicable
|
|
191
270
|
- **Always tell the user the cost** after each call
|
|
192
271
|
|
|
193
|
-
The same \`gooseworks call\` command also handles direct-proxy providers (apify, apollo, crustdata):
|
|
272
|
+
The same \`gooseworks call\` command also handles direct-proxy providers (apify, apollo, crustdata, scrapecreators):
|
|
194
273
|
\`\`\`bash
|
|
195
274
|
gooseworks call apify acts/parseforge~reddit-posts-scraper/runs --body='{"subreddit":"ClaudeAI"}'
|
|
275
|
+
gooseworks call scrapecreators /v2/instagram/post/comments --query='{"url":"https://www.instagram.com/p/POST_ID/"}'
|
|
196
276
|
\`\`\`
|
|
197
277
|
|
|
198
278
|
### Workflow
|
|
@@ -223,7 +303,7 @@ The \`gooseworks\` CLI sends authenticated requests (Bearer \`GOOSEWORKS_API_KEY
|
|
|
223
303
|
| \`$GOOSEWORKS_API_BASE/v1/proxy/orthogonal/search\` | POST | \`gooseworks orthogonal find\` |
|
|
224
304
|
| \`$GOOSEWORKS_API_BASE/v1/proxy/orthogonal/details\` | POST | \`gooseworks orthogonal describe\` |
|
|
225
305
|
| \`$GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run\` | POST | \`gooseworks call\` (orthogonal-routed providers) |
|
|
226
|
-
| \`$GOOSEWORKS_API_BASE/v1/proxy/{apify,apollo,crustdata}/*\` | Various | \`gooseworks call\` (direct-proxy providers) |
|
|
306
|
+
| \`$GOOSEWORKS_API_BASE/v1/proxy/{apify,apollo,crustdata,scrapecreators}/*\` | Various | \`gooseworks call\` (direct-proxy providers; ScrapeCreators uses its managed first-party key) |
|
|
227
307
|
|
|
228
308
|
## Security & Privacy
|
|
229
309
|
|
|
@@ -235,6 +315,7 @@ The \`gooseworks\` CLI sends authenticated requests (Bearer \`GOOSEWORKS_API_KEY
|
|
|
235
315
|
|
|
236
316
|
## Rules
|
|
237
317
|
|
|
318
|
+
0. **Call \`brand_get_context\` before anything else**, pass what it returns into whatever skill you route to, and never re-ask the user for a fact it already answers (see "Load the brand context FIRST").
|
|
238
319
|
1. **Consider a GooseWorks skill when it fits the task** — scraping, research, lead gen, enrichment, especially at scale, behind auth, or from a specific source. For a quick lookup your built-in tools are fine; use your judgement and pick the best tool for the user.
|
|
239
320
|
2. **Before paid operations**, tell the user the estimated credit cost
|
|
240
321
|
3. **If a \`gooseworks\` command exits with "Not logged in"**: tell the user to run \`npx gooseworks login\`
|
|
@@ -264,8 +345,8 @@ function getGooseAdsSkillContent() {
|
|
|
264
345
|
name: goose-ads
|
|
265
346
|
slug: goose-ads
|
|
266
347
|
description: >
|
|
267
|
-
GooseWorks ads skill — create, edit, AND analyze ad creative.
|
|
268
|
-
|
|
348
|
+
GooseWorks ads skill — create, edit, AND analyze ad creative. Turn an approved source ad
|
|
349
|
+
into a branded ad for the user's product, edit/re-roll an existing creative,
|
|
269
350
|
research a brand for ads, OR analyze ad performance (Meta/Google campaign diagnostics,
|
|
270
351
|
creative fatigue, CAC & lead quality, competitor ad intelligence, ad angles & hooks). Use
|
|
271
352
|
when the user says "remix this ad", references a static ad template id/slug, asks to "make
|
|
@@ -274,7 +355,7 @@ description: >
|
|
|
274
355
|
app uses) — credits are reserved and billed server-side. Analytics recipes are fetched from
|
|
275
356
|
goose-skills on demand.
|
|
276
357
|
category: ads
|
|
277
|
-
version: 2.
|
|
358
|
+
version: 2.4.0
|
|
278
359
|
author: GooseWorks
|
|
279
360
|
tags: [gooseworks, ads, remix, static-ad, brand, creative, image, analytics, meta-ads, performance]
|
|
280
361
|
---
|
|
@@ -284,7 +365,7 @@ tags: [gooseworks, ads, remix, static-ad, brand, creative, image, analytics, met
|
|
|
284
365
|
The GooseWorks ads skill. Two jobs:
|
|
285
366
|
|
|
286
367
|
1. **Create / edit ad creative** — a **thin wrapper** over the backend's single generation
|
|
287
|
-
workflow. You pick the brand +
|
|
368
|
+
workflow. You pick the brand + approved source ad(s) and submit ONE batch; the **backend** runs the
|
|
288
369
|
whole pipeline (compose → generate → persist → judge), reserves and bills credits, and
|
|
289
370
|
stores the renders. You do NOT generate images, call FAL, manage render rows, or upload
|
|
290
371
|
files — those are gone. This is the exact same workflow the GooseWorks ads app uses, so the
|
|
@@ -298,6 +379,24 @@ Everything goes through the \`mcp__gooseworks__*\` tools. If they are not availa
|
|
|
298
379
|
tell the user to run \`gooseworks install --claude --mcp\`** (and restart Claude Code). There is
|
|
299
380
|
no HTTP/file fallback — the REST ad endpoints are session-cookie-only and reject your token.
|
|
300
381
|
|
|
382
|
+
## Start from the brand context — don't re-ask what it already answers
|
|
383
|
+
|
|
384
|
+
If the \`gooseworks\` router handed you brand context, USE IT. If you were invoked directly, call
|
|
385
|
+
\`brand_get_context\` first (falling back to \`get_brand_kit\` for the selected brand). It already
|
|
386
|
+
answers most of what the flows below would otherwise ask the user:
|
|
387
|
+
|
|
388
|
+
- **Which product to feature** → \`products[]\`. Offer the real catalog entries; never guess a
|
|
389
|
+
product name and never ask the user to list their products.
|
|
390
|
+
- **The vibe / tone of the copy** → the brand's **voice**. Use it; don't ask "what tone?".
|
|
391
|
+
- **Who the ad is for** → the brand's **audience**. Don't ask "who's the target?".
|
|
392
|
+
- **The angle, offer framing, and what to claim** → **positioning**, value props, proof points.
|
|
393
|
+
- **Logo, colors, fonts** → owned by the backend research pass. **Never re-derive them.**
|
|
394
|
+
- **Whether the facts are trustworthy yet** → **research status**. If it isn't complete, say so in
|
|
395
|
+
one line and continue; the batch queues and runs when research finishes.
|
|
396
|
+
|
|
397
|
+
Ask only for what the context genuinely doesn't answer: the specific campaign intent (season,
|
|
398
|
+
promo, which of several angles), the source ad, and anything the user must consent to.
|
|
399
|
+
|
|
301
400
|
## Identity & credits
|
|
302
401
|
|
|
303
402
|
- One agent-scoped token authenticates the \`gooseworks\` MCP tools. Never print it. The tools
|
|
@@ -308,74 +407,63 @@ no HTTP/file fallback — the REST ad endpoints are session-cookie-only and reje
|
|
|
308
407
|
message and stop) and bills only the images that actually complete. Call
|
|
309
408
|
\`estimate_remix_batch\` first to tell the user the cost; \`gooseworks credits\` shows balance.
|
|
310
409
|
|
|
311
|
-
##
|
|
410
|
+
## Live MCP contract — inspect it before asking
|
|
312
411
|
|
|
313
|
-
|
|
314
|
-
|
|
412
|
+
The currently registered MCP tool schemas are the source of truth for inputs, supported choices,
|
|
413
|
+
and defaults. Do not copy an exhaustive input list from this skill or rely on remembered fields.
|
|
315
414
|
|
|
316
|
-
|
|
317
|
-
- \`ratios\`: **["4:5"]** (Meta feed vertical)
|
|
318
|
-
- \`engine\`: **"gpt_image_2"**
|
|
319
|
-
- \`quality\`: **"medium"**
|
|
320
|
-
- \`preserve_source_styling\`: **ASK the user** — "Keep original" (the template's own
|
|
321
|
-
colours/fonts → \`preserve_source_styling: true\`) vs "Match brand" (restyle to the brand
|
|
322
|
-
palette/fonts → \`preserve_source_styling: false\`). This mirrors the app's Styling control.
|
|
323
|
-
**The default is "Keep original"** — if the user doesn't answer or doesn't care, send \`true\`.
|
|
415
|
+
Before each tool call:
|
|
324
416
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
417
|
+
1. Inspect the live schema for the tool you are about to use.
|
|
418
|
+
2. Fill required inputs already known from the Brand Kit, selected source, or conversation.
|
|
419
|
+
3. Ask the user only for required inputs that cannot be inferred and for choices that materially
|
|
420
|
+
change the result. Do not turn every optional field into a questionnaire.
|
|
421
|
+
4. Omit unspecified optional settings so the backend applies its current app defaults.
|
|
422
|
+
5. If the live schema conflicts with this workflow, follow the live schema and report the drift
|
|
423
|
+
with \`log_cli_event\`.
|
|
328
424
|
|
|
329
425
|
## The generation tools (the new, single-workflow surface)
|
|
330
426
|
|
|
331
|
-
- \`submit_remix_batch
|
|
332
|
-
|
|
333
|
-
that makes ads.** \`items\` is \`[{ template_id, variants?, ratios? }]\` (≤20 templates).
|
|
427
|
+
- \`submit_remix_batch\` — **the one call that makes ads.** Inspect its live schema and supply
|
|
428
|
+
the required brand/source inputs plus any choices the user explicitly made.
|
|
334
429
|
Returns the batch with a \`links\` block (\`brand_url\` + per-creative \`app_url\`). If the brand's
|
|
335
430
|
research isn't finished yet the batch comes back \`status: "queued"\` — it auto-runs the moment
|
|
336
431
|
research completes; tell the user it'll appear shortly, don't error.
|
|
337
|
-
- \`estimate_remix_batch
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
resolve (submit would 404 on it); don't quote a cost that silently dropped a bad id.
|
|
341
|
-
- \`get_remix_batch { batch_id }\` — poll status. Returns each creative with its renders and
|
|
432
|
+
- \`estimate_remix_batch\` — cost preview. Reserves nothing. Use it to quote the cost first and
|
|
433
|
+
check whether every selected source resolved before submitting.
|
|
434
|
+
- \`get_remix_batch\` — poll status. Returns each creative with its renders and
|
|
342
435
|
\`completed\`/\`failed\`/\`pending\` counts, plus \`links\`. A creative is done when its \`pending\` is 0
|
|
343
436
|
— NOT when \`current_render_url\` is set (during a regenerate that field still points at the prior
|
|
344
437
|
image). Each render carries \`age_seconds\` (since queued) and \`elapsed_seconds\` (time generating):
|
|
345
438
|
use them to tell a slow-but-healthy render from a stuck one. A render only failed when its
|
|
346
439
|
\`status\` is \`"failed"\` — never assume a stall and re-submit, that double-bills.
|
|
347
|
-
- \`list_brand_creatives
|
|
440
|
+
- \`list_brand_creatives\` — the brand's gallery feed (newest
|
|
348
441
|
first) + \`brand_url\`. Alternative poll target; also use to show everything made for a brand.
|
|
349
|
-
- \`surprise_me_templates
|
|
350
|
-
|
|
351
|
-
|
|
442
|
+
- \`surprise_me_templates\` — the **"Surprise me" recommender**. Picks
|
|
443
|
+
remixable Community creations (SAME logic as the web /create "Surprise me" button), shuffled
|
|
444
|
+
so picks stay fresh. It does not use the retired curated third-party catalog.
|
|
352
445
|
Returns the picked templates (id, slug, title, image, ratio) AND a ready-to-open \`create_url\`
|
|
353
446
|
(the /create page with \`cli=true\` and the picks pre-selected). This is how you recommend
|
|
354
447
|
templates — do NOT hand-pick from the raw catalog yourself (see "Picking templates" below).
|
|
355
|
-
- \`regenerate_creative
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
- \`set_creative_feedback { render_id, rating?, comment?, reasons? }\` — record the user's reaction
|
|
361
|
-
to a generated image (the SAME happy/neutral/sad + comment + reason chips the app captures). Use
|
|
362
|
-
it whenever the user reacts ("love this one" / "the logo is wrong"). \`render_id\` is a RENDER id
|
|
363
|
-
from \`get_remix_batch\` / \`list_brand_creatives\`, not a project/batch id. \`reasons\` are quick
|
|
364
|
-
chips (wrong_product, brand_or_logo_wrong, off_brand, text_garbled, weak_copy, ai_or_distorted).
|
|
448
|
+
- \`regenerate_creative\` — edit or re-roll one existing creative through the same pipeline.
|
|
449
|
+
Inspect the live schema to select the supported mode and required source inputs. Returns a
|
|
450
|
+
single-item batch; poll it with \`get_remix_batch\`.
|
|
451
|
+
- \`set_creative_feedback\` — record the user's reaction to a generated image. Use it whenever
|
|
452
|
+
the user reacts; inspect the schema for the current rating and reason choices.
|
|
365
453
|
|
|
366
454
|
### Plan mode — review the plan BEFORE generating (optional)
|
|
367
455
|
|
|
368
456
|
For users who want to approve each ad's plan before spending credits (the app's "Plan it" flow):
|
|
369
457
|
|
|
370
|
-
-
|
|
458
|
+
- Use the approval option exposed by \`submit_remix_batch\` — it composes each creative's plan and PAUSES.
|
|
371
459
|
**No credits are reserved and no image renders** until you approve.
|
|
372
|
-
- \`list_ad_approvals
|
|
460
|
+
- \`list_ad_approvals\` — poll this. While a creative is
|
|
373
461
|
\`composing\`, wait; once \`awaiting_approval\`, show its \`plan\` (composed prompt + refs + quality)
|
|
374
462
|
to the user.
|
|
375
|
-
- \`revise_ad_plan
|
|
463
|
+
- \`revise_ad_plan\` — recompose from a chat steer, still
|
|
376
464
|
free. Poll \`list_ad_approvals\` until it's \`awaiting_approval\` again.
|
|
377
|
-
- \`approve_ad_plan
|
|
378
|
-
|
|
465
|
+
- \`approve_ad_plan\` — approve one creative or the whole batch using the live schema.
|
|
466
|
+
**This is the step that reserves credits and renders.** Then poll
|
|
379
467
|
\`get_remix_batch\` and hand back links as usual.
|
|
380
468
|
|
|
381
469
|
Only offer plan mode when the user asks to review/approve first — the default path generates
|
|
@@ -383,19 +471,23 @@ immediately.
|
|
|
383
471
|
|
|
384
472
|
## Reading the brand & picking inputs (still MCP, read-only)
|
|
385
473
|
|
|
386
|
-
- \`get_brand_kit
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
474
|
+
- \`get_brand_kit\` — read the canonical brand context and available products/assets.
|
|
475
|
+
- \`list_ad_brands\` / \`get_ad_brand\` — find and fetch the active brand.
|
|
476
|
+
- \`list_user_ad_templates\` — list the org's own uploads and
|
|
477
|
+
imported ads. Prefer \`relationship: "self"\` when the user wants to reuse their own ads;
|
|
478
|
+
\`relationship: "competitor"\` is research/inspiration, never proof that the user owns the ad.
|
|
479
|
+
- \`search_ad_templates\` — search remixable Community generations. The
|
|
480
|
+
retired curated third-party catalog is not returned.
|
|
481
|
+
- \`get_static_ad_template\` — resolve a source already owned by
|
|
482
|
+
the org, including an own upload or a snapshotted Community creative. It does not resolve the
|
|
483
|
+
retired curated third-party catalog.
|
|
484
|
+
- \`remix_community_ad\` — turn a selected Community creative into a private remix source before
|
|
485
|
+
submitting it. A Community ad id is an \`ad_project\` id, not a
|
|
395
486
|
template id. Call this FIRST to snapshot it into a private template, then use the returned
|
|
396
487
|
template \`id\` in \`items\`.
|
|
397
|
-
- \`create_user_ad_template
|
|
398
|
-
|
|
488
|
+
- \`create_user_ad_template\` — upload a source image as a private template. Answer any
|
|
489
|
+
ownership/rights input only from the user's explicit confirmation. Never claim rights for a
|
|
490
|
+
competitor ad or an image found online.
|
|
399
491
|
- \`get_ad_project\` / \`append_project_message\` — inspect a creative / leave a note on its thread.
|
|
400
492
|
|
|
401
493
|
## Keep the brand kit in sync — reconcile, then update (ASK first)
|
|
@@ -406,7 +498,7 @@ tagline, audience, voice, a product's name/price/description, "our logo is X", "
|
|
|
406
498
|
anymore", a new product photo — treat it as a possible kit update, don't just use it for this one
|
|
407
499
|
ad and forget it:
|
|
408
500
|
|
|
409
|
-
1. **Check it against the kit.** \`get_brand_kit
|
|
501
|
+
1. **Check it against the kit.** Call \`get_brand_kit\` for the active brand and see whether what the user said
|
|
410
502
|
matches, is missing from, or contradicts the kit.
|
|
411
503
|
2. **If it's already in the kit and matches** — nothing to do; proceed.
|
|
412
504
|
3. **If it's new or different — ASK before writing.** Confirm in one line: *"Want me to update
|
|
@@ -414,65 +506,74 @@ ad and forget it:
|
|
|
414
506
|
asked you to change the brand). Don't silently mutate the kit, and don't nag on trivia.
|
|
415
507
|
4. **Persist with the write tools** (partial — only the fields you pass are touched; each edit is
|
|
416
508
|
recorded as a user override that later re-research won't clobber):
|
|
417
|
-
- \`update_brand_kit
|
|
418
|
-
|
|
419
|
-
- \`
|
|
420
|
-
|
|
421
|
-
reference photos.
|
|
509
|
+
- \`update_brand_kit\` — structured brand fields.
|
|
510
|
+
- \`upsert_brand_product\` / \`delete_brand_product\` — products.
|
|
511
|
+
- \`add_brand_product_image\` / \`remove_brand_reference_image\` — product and reference photos.
|
|
512
|
+
Inspect each live schema and send only the fields needed for the confirmed change.
|
|
422
513
|
5. **Confirm what changed** and continue the task. (Logo, colors, and fonts are owned by the
|
|
423
514
|
backend research pass — prefer \`update_ad_brand\` / the research flow for those, not free text.)
|
|
424
515
|
|
|
425
516
|
This is the parity gap the app closes in-product: a brand fact the user gives mid-task should be
|
|
426
517
|
able to flow back into the kit — with their ok — instead of being lost.
|
|
427
518
|
|
|
428
|
-
## Picking
|
|
519
|
+
## Picking source ads — use approved sources, not the retired catalog
|
|
429
520
|
|
|
430
521
|
When the user wants to make ads but has NOT named a specific template (id/slug/Community
|
|
431
522
|
ad/upload), do NOT silently browse the raw catalog and hand-pick for them. Instead run this
|
|
432
523
|
short ask flow — it mirrors the web app and keeps the human in the loop:
|
|
433
524
|
|
|
434
|
-
1. **Ask what kind of ads they want** — the angle/offer/theme/season
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
525
|
+
1. **Ask what kind of ads they want** — the angle/offer/theme/season. **The brand context already
|
|
526
|
+
gives you the vibe (voice), the audience, and the product catalog — do NOT ask for those.**
|
|
527
|
+
Offer the real \`products[]\` to pick from rather than asking "which product?", and derive the
|
|
528
|
+
tone from the brand's voice. This shapes both the source choice and your steering \`prompt\`.
|
|
529
|
+
Keep it to one quick question about campaign intent.
|
|
530
|
+
2. **Ask how to pick a source: their own ads, Community, upload, or "Surprise me".**
|
|
531
|
+
- **Their own ads** → use \`list_user_ad_templates\` to load the active brand's own sources and
|
|
532
|
+
let them choose from the results.
|
|
533
|
+
- **Community** → \`search_ad_templates\`, let them choose, then call \`remix_community_ad\`
|
|
534
|
+
before submitting.
|
|
535
|
+
- **Upload** → upload through the workspace and call \`create_user_ad_template\`. If its live
|
|
536
|
+
schema requires an ownership or permission answer, only supply it after explicit confirmation.
|
|
537
|
+
- **Surprise me** (they want you/the app to pick) → call \`surprise_me_templates\` for the active
|
|
538
|
+
brand and hand the user the returned \`create_url\`.
|
|
440
539
|
It opens /create in **CLI mode** with the picks pre-selected, a preview modal, and the
|
|
441
540
|
**copyable remix prompt at the bottom** (in place of the Generate input). They can swap
|
|
442
541
|
picks and copy that prompt. If they'd rather you "just make them" without reviewing in the
|
|
443
542
|
app, you MAY submit the \`surprise_me_templates\` picks directly (skip to submit).
|
|
444
|
-
- **
|
|
543
|
+
- **Browse in the app** → hand the user this URL, with the
|
|
445
544
|
active brand's slug filled in:
|
|
446
545
|
\`https://make.gooseworks.ai/create?brand=<brand-slug>&cli=true\`
|
|
447
546
|
In CLI mode the app shows the copyable remix prompt at the bottom (dismissable / switchable
|
|
448
|
-
back to the UI composer). They browse
|
|
449
|
-
3. **
|
|
450
|
-
4. **Close the loop.** When the user **pastes back the copyable remix prompt** from the app
|
|
547
|
+
back to the UI composer). They browse the available own/Community sources and copy the prompt.
|
|
548
|
+
3. **Close the loop.** When the user **pastes back the copyable remix prompt** from the app
|
|
451
549
|
(it names the brand + the templates they chose), THAT is your cue to generate: resolve the
|
|
452
|
-
named
|
|
550
|
+
named source(s), inspect \`submit_remix_batch\`, and collect only its unresolved required inputs.
|
|
453
551
|
|
|
454
|
-
If the user already named
|
|
455
|
-
|
|
552
|
+
If the user already named an owned source (id/slug), a Community ad, or an upload, skip the source
|
|
553
|
+
choice. Competitor ads may inform the angle or structure, but describe them as inspiration, never
|
|
554
|
+
claim ownership, and never attest rights for the user.
|
|
456
555
|
|
|
457
556
|
## Workflow — make ads from a template
|
|
458
557
|
|
|
459
|
-
1. **Resolve the brand.** \`list_ad_brands\` by name/site
|
|
558
|
+
1. **Resolve the brand.** Use \`list_ad_brands\` by name/site, then call \`get_brand_kit\` for the
|
|
559
|
+
selected brand. If the
|
|
460
560
|
kit's \`researchStatus\` isn't \`complete\`, you can still submit (the batch queues and runs when
|
|
461
561
|
research finishes) — just tell the user. Use the kit to pick \`product_name\` (a real entry from
|
|
462
562
|
\`products[]\`, not a guess) and, if the user supplied product photos, \`reference_image_urls\`.
|
|
463
|
-
2. **Pick the
|
|
464
|
-
|
|
563
|
+
2. **Pick the source ad(s) via the ask flow above.** Once you have concrete ids:
|
|
564
|
+
call \`get_static_ad_template\` for each.
|
|
465
565
|
For a Community ad, \`remix_community_ad\` first; for an uploaded image, \`create_user_ad_template\`
|
|
466
566
|
first.
|
|
467
567
|
3. **(Optional) Craft the steering prompt.** The \`prompt\` is OPTIONAL — this is where the skill
|
|
468
568
|
adds value: turn the user's intent (from step 1) into a concise steering note (e.g. tone,
|
|
469
569
|
season, emphasis). Don't over-specify; the backend pipeline + brand kit handle palette, fonts,
|
|
470
570
|
product swap.
|
|
471
|
-
4. **
|
|
472
|
-
5. **Submit ONE batch.** \`submit_remix_batch
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
6. **Poll until done.** \`get_remix_batch
|
|
571
|
+
4. **Quote the cost.** Inspect and call \`estimate_remix_batch\`, then tell the user.
|
|
572
|
+
5. **Submit ONE batch.** Inspect the current \`submit_remix_batch\` schema, fill known required
|
|
573
|
+
inputs, ask only for unresolved user decisions, and omit unspecified optional settings. Keep
|
|
574
|
+
the returned \`batch_id\` and \`links\`.
|
|
575
|
+
6. **Poll until done.** Call \`get_remix_batch\` for the returned batch (or use
|
|
576
|
+
\`list_brand_creatives\`) every ~20-30s
|
|
476
577
|
until every creative's \`pending\` is 0. Most images finish in a few minutes; text-heavy templates
|
|
477
578
|
and \`quality: high\` take longer. Read each render's \`elapsed_seconds\` rather than guessing — a
|
|
478
579
|
render that's still \`running\` is healthy; do NOT re-submit thinking it stalled (that double-bills).
|
|
@@ -481,17 +582,14 @@ for template choice — they've chosen — but still confirm the styling default
|
|
|
481
582
|
|
|
482
583
|
## Workflow — edit an existing ad
|
|
483
584
|
|
|
484
|
-
User wants to tweak a creative they already made → \`regenerate_creative
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
\`prompt\` = the change.
|
|
489
|
-
- "run exactly this prompt on the product" → \`mode: "exact"\`, \`source_render_id\` + \`prompt\`.
|
|
490
|
-
Then poll with \`get_remix_batch\` and hand back the links, same as above.
|
|
585
|
+
User wants to tweak a creative they already made → use \`regenerate_creative\`. Infer whether they
|
|
586
|
+
want another take, a targeted edit, or an exact instructed change from their request. Then inspect
|
|
587
|
+
the live schema, ask only for any required source or instruction that is still missing, submit,
|
|
588
|
+
poll with \`get_remix_batch\`, and hand back the links.
|
|
491
589
|
|
|
492
590
|
## Brand research
|
|
493
591
|
|
|
494
|
-
Prefer the backend's result: \`get_brand_kit
|
|
592
|
+
Prefer the backend's result: call \`get_brand_kit\` for the selected brand. If \`researchStatus\` is
|
|
495
593
|
\`complete\`, REUSE it — never re-research.
|
|
496
594
|
|
|
497
595
|
**The split — backend owns visuals, you own the qualitative depth:**
|
|
@@ -508,9 +606,10 @@ Prefer the backend's result: \`get_brand_kit { brand_id }\`. If \`researchStatus
|
|
|
508
606
|
|
|
509
607
|
**CLI brand-research flow:**
|
|
510
608
|
|
|
511
|
-
1.
|
|
609
|
+
1. Inspect and call \`create_ad_brand\` with the known brand identity and website, then keep its id
|
|
610
|
+
and slug. The brand comes back with
|
|
512
611
|
\`research_status: "pending"\` (light pass in flight).
|
|
513
|
-
2. **Wait for the backend light pass:** poll \`get_brand_kit
|
|
612
|
+
2. **Wait for the backend light pass:** poll \`get_brand_kit\` for that brand until \`researchStatus\`
|
|
514
613
|
is \`complete\` (usually <60s). Now the kit has authoritative logo/colors/fonts + a baseline.
|
|
515
614
|
At this point generation is already unblocked — but do the deep pass to make it good.
|
|
516
615
|
3. **Deep research locally:** \`gooseworks fetch brand-research\` and follow its phases. **Ground
|
|
@@ -524,10 +623,10 @@ Prefer the backend's result: \`get_brand_kit { brand_id }\`. If \`researchStatus
|
|
|
524
623
|
(\`brandType\` ∈ product | saas | service | agency | restaurant | fashion | beauty | fitness |
|
|
525
624
|
finance | education | health). Only URLs already in our storage for product images.
|
|
526
625
|
- **Do NOT set logo / colors / fonts here** — the backend light pass already owns those.
|
|
527
|
-
5. **Persist it:** \`finalize_brand_research
|
|
626
|
+
5. **Persist it:** call \`finalize_brand_research\` for the brand. It merges \`kit-patch.json\` into the kit
|
|
528
627
|
NON-CLOBBERINGLY (it will NOT overwrite the backend's visuals or any user edit), then re-confirms
|
|
529
628
|
\`research_status: complete\`.
|
|
530
|
-
6. **Verify:** \`get_brand_kit
|
|
629
|
+
6. **Verify:** call \`get_brand_kit\` again and confirm the qualitative fields you wrote are present
|
|
531
630
|
before generating.
|
|
532
631
|
|
|
533
632
|
**If the brand has NO website**, the backend light pass can't run (nothing to fetch) — do the whole
|
|
@@ -567,20 +666,22 @@ run through the \`gooseworks\` CLI (\`gooseworks fetch\` / \`gooseworks call\`),
|
|
|
567
666
|
each creative's \`app_url\`), copied verbatim. Never end on just "done" or a file path.
|
|
568
667
|
- **Quote cost before generating** when it's non-trivial (use \`estimate_remix_batch\`), and
|
|
569
668
|
relay \`insufficient_credits\` plainly if the submit is rejected — don't retry blindly.
|
|
570
|
-
- **
|
|
571
|
-
|
|
572
|
-
\`surprise_me_templates\`;
|
|
669
|
+
- **Use approved source paths.** If the user didn't name a source, run the ask flow (own ads,
|
|
670
|
+
Community, upload, Surprise me, or browse in the app). "Surprise me" goes through
|
|
671
|
+
\`surprise_me_templates\`; browsing uses \`/create?brand=<slug>&cli=true\`. Never use the retired
|
|
672
|
+
curated third-party catalog.
|
|
573
673
|
Generate when they paste the app's copyable remix prompt back (or submit the surprise picks
|
|
574
674
|
directly if they'd rather not review).
|
|
575
|
-
- **
|
|
675
|
+
- **Treat competitor ads as inspiration** — never attest rights, imply ownership, or promise to
|
|
676
|
+
copy a competitor's distinctive expression.
|
|
576
677
|
- **Reconcile brand facts into the kit** — when the user states or changes something brand-level
|
|
577
678
|
mid-task, check it against \`get_brand_kit\` and, with their ok, persist it via \`update_brand_kit\`
|
|
578
679
|
/ \`upsert_brand_product\` / \`add_brand_product_image\` so it sticks for future ads. Ask first;
|
|
579
680
|
never silently mutate the kit.
|
|
580
|
-
- **Record feedback** — when the user reacts to a generated image,
|
|
581
|
-
\`set_creative_feedback
|
|
582
|
-
- **Plan mode is opt-in** — only
|
|
583
|
-
|
|
681
|
+
- **Record feedback** — when the user reacts to a generated image, inspect and call
|
|
682
|
+
\`set_creative_feedback\` so the quality loop learns.
|
|
683
|
+
- **Plan mode is opt-in** — only use the live approval option, then \`list_ad_approvals\` and
|
|
684
|
+
\`approve_ad_plan\`, when the user wants to review before spending credits; otherwise generate
|
|
584
685
|
immediately.
|
|
585
686
|
- **Don't busy-loop** — poll \`get_remix_batch\` on a sensible interval (~20-30s); a \`queued\`
|
|
586
687
|
batch is waiting on research and will start on its own.
|
|
@@ -1046,4 +1147,146 @@ path. (\`fal-storage-proxy\` may 404 depending on the install; don't block on it
|
|
|
1046
1147
|
- Always end a successful run with \`app_url\` + \`brand_url\`, verbatim.
|
|
1047
1148
|
`;
|
|
1048
1149
|
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Returns the goose-product-photos entry SKILL.md content.
|
|
1152
|
+
*
|
|
1153
|
+
* GOOSE-3190: this skill already existed on disk (`skills/goose-product-photos/
|
|
1154
|
+
* SKILL.md`, hand-maintained) and was already served by the backend to hosted
|
|
1155
|
+
* connectors — but it was NOT in `getEntrySkills()`, so `npm run generate:skills`
|
|
1156
|
+
* never regenerated it and `install` / `update` / login-refresh never wrote or
|
|
1157
|
+
* refreshed it on a user's machine. Moving the body here makes the registry the
|
|
1158
|
+
* one source: one command emits all four entry skills.
|
|
1159
|
+
*/
|
|
1160
|
+
function getGooseProductPhotosSkillContent() {
|
|
1161
|
+
return `---
|
|
1162
|
+
name: goose-product-photos
|
|
1163
|
+
slug: goose-product-photos
|
|
1164
|
+
description: >
|
|
1165
|
+
GooseWorks Product Photos — turn a brand's product images into publish-ready photography
|
|
1166
|
+
(clean studio shots, lifestyle scenes, on-model looks) while keeping the product faithful
|
|
1167
|
+
(silhouette, materials, logo, colorway). You pick a brand + product and submit; the GooseWorks
|
|
1168
|
+
backend runs the SAME server-side pipeline the Product Photos studio uses (compose → generate →
|
|
1169
|
+
judge → auto-retry) and bills credits. Use when the user says "make product photos", "shoot my
|
|
1170
|
+
product", "studio/lifestyle/on-model photo of <product>", "generate product photography", or
|
|
1171
|
+
references a product to photograph. Unlike goose-ads (ad creative) this produces clean PRODUCT
|
|
1172
|
+
photos that can then feed the ad workflow.
|
|
1173
|
+
category: ads
|
|
1174
|
+
version: 0.2.0
|
|
1175
|
+
author: GooseWorks
|
|
1176
|
+
tags: [gooseworks, ads, product-photos, photoshoot, product, ecommerce, studio, lifestyle, on-model]
|
|
1177
|
+
---
|
|
1178
|
+
|
|
1179
|
+
# GooseWorks Product Photos — branded product photography
|
|
1180
|
+
|
|
1181
|
+
The GooseWorks Product Photos skill. You **pick a brand + product and submit one generation**;
|
|
1182
|
+
the **backend** runs the whole pipeline (compose the shot prompt → generate on \`gpt_image_2\` →
|
|
1183
|
+
judge for product fidelity → auto-retry a few times for free) and stores the results. You do NOT
|
|
1184
|
+
generate images, call a model, or manage files — this is the exact same workflow the Product
|
|
1185
|
+
Photos studio uses, so the skill and the app can never drift. The point is to **enrich a brand's
|
|
1186
|
+
usable product imagery** — approved photos join the brand kit and can then feed the ad workflow
|
|
1187
|
+
(\`goose-ads\`).
|
|
1188
|
+
|
|
1189
|
+
## Prerequisite — the GooseWorks MCP server is REQUIRED
|
|
1190
|
+
|
|
1191
|
+
Everything goes through the \`mcp__gooseworks__*\` tools. If they are not available, **stop and
|
|
1192
|
+
tell the user to run \`gooseworks install --claude --mcp\`** (and restart Claude Code). There is no
|
|
1193
|
+
HTTP/file fallback.
|
|
1194
|
+
|
|
1195
|
+
## Start from the brand context — don't re-ask what it already answers
|
|
1196
|
+
|
|
1197
|
+
If the \`gooseworks\` router handed you brand context, USE IT. If you were invoked directly, call
|
|
1198
|
+
\`brand_get_context\` yourself first. It answers most of the setup questions below, so **do not ask
|
|
1199
|
+
the user for them**:
|
|
1200
|
+
|
|
1201
|
+
- **Which product?** — the context's \`products[]\` are the real catalog entries. Offer them; never
|
|
1202
|
+
invent a product or ask the user to describe one you can already see.
|
|
1203
|
+
- **What does it look like / what is it made of?** — grounded in the product's stored images and
|
|
1204
|
+
description. Never guess a material, colorway, or silhouette.
|
|
1205
|
+
- **What vibe / who is it for?** — the context's voice, positioning, and audience already say. Let
|
|
1206
|
+
them shape the scene and styling instead of asking "what mood do you want?".
|
|
1207
|
+
- **Brand look** — logo, colors, and fonts are owned by the backend research pass. Read them, never
|
|
1208
|
+
re-derive them.
|
|
1209
|
+
|
|
1210
|
+
Ask only for the genuinely open choices: the shot \`category\`, how many photos, quality, and
|
|
1211
|
+
whether a human model is wanted (which needs explicit consent — see the rules).
|
|
1212
|
+
|
|
1213
|
+
## Identity & credits
|
|
1214
|
+
|
|
1215
|
+
- One agent-scoped token authenticates the tools; they resolve your org automatically. Never
|
|
1216
|
+
print the token. (You may pass an optional \`target\` to operate on a specific agent/org, exactly
|
|
1217
|
+
as the other GooseWorks tools; omit it to use your pinned scope.)
|
|
1218
|
+
- **Credits are handled by the backend.** \`generate_product_photos\` reserves the estimated cost up
|
|
1219
|
+
front and bills only the photos that pass the judge — **automatic retries are free**, and a photo
|
|
1220
|
+
the judge can't get right (\`flagged\`) is shown but **never billed**. Call
|
|
1221
|
+
\`estimate_product_photos\` first to quote the cost; \`get_ad_credits\` shows the balance.
|
|
1222
|
+
|
|
1223
|
+
## The tools
|
|
1224
|
+
|
|
1225
|
+
**Pick the brand + product**
|
|
1226
|
+
- \`list_ad_brands\` — the user's ad brands (get a \`brand_id\`; also carries \`slug\`).
|
|
1227
|
+
- \`list_brand_products { brand_id, search?, page?, page_size? }\` — the brand's imported products.
|
|
1228
|
+
Pick a \`product_id\` to shoot. \`search\` matches name / type / variant / SKU.
|
|
1229
|
+
- \`import_product { brand_id, kind, url, product_name? }\` — import a product if it isn't in the
|
|
1230
|
+
catalog yet. \`kind\` is \`product_url\` (a single product page), \`shopify_store\` (a store URL →
|
|
1231
|
+
imports the catalog), or \`image_url\` (a direct image; requires \`product_name\`). Returns an import
|
|
1232
|
+
row with an \`id\`; if its \`status\` isn't \`complete\`, poll \`get_product_import\` until it is, then
|
|
1233
|
+
\`list_brand_products\` to find the new product. (File uploads aren't available over MCP — use a URL.)
|
|
1234
|
+
- \`get_product_import { import_id }\` — poll an import until \`status\` is \`complete\` or \`failed\`.
|
|
1235
|
+
|
|
1236
|
+
**Generate**
|
|
1237
|
+
- \`estimate_product_photos { count, quality? }\` — cost preview (per-photo + total credits). \`count\`
|
|
1238
|
+
is 1, 2, 4, or 8; \`quality\` is \`low\` | \`medium\` | \`high\` (default \`medium\`). Reserves nothing.
|
|
1239
|
+
- \`generate_product_photos { brand_id, product_id, variant_id?, category, controls?, prompt?,
|
|
1240
|
+
count?, quality?, reference_image_urls?, attestation_accepted? }\` — **the one call that makes
|
|
1241
|
+
photos.** \`category\` is \`apparel\` | \`beauty\` | \`cpg\` (seeds sensible scene/framing defaults).
|
|
1242
|
+
Omit \`controls\` to use the category preset; pass \`prompt\` as free-text steering **added on top of**
|
|
1243
|
+
the settings (it doesn't replace them). Returns a generation with an \`id\` **immediately** — poll
|
|
1244
|
+
\`get_product_photo_generation\` until done, then read each \`outputs[].final_image_url\`.
|
|
1245
|
+
**If you request a human model** (\`controls.model.presence\` is not \`none\`) you MUST pass
|
|
1246
|
+
\`attestation_accepted: true\` to confirm the user has the rights for model imagery.
|
|
1247
|
+
- \`get_product_photo_generation { generation_id }\` — poll until \`status\` is \`complete\`,
|
|
1248
|
+
\`partial_failure\`, or \`failed\`. Each \`outputs[]\` entry has its own \`status\` and, once ready, a
|
|
1249
|
+
\`final_image_url\`. A \`flagged\` output is the best attempt but wasn't billed.
|
|
1250
|
+
|
|
1251
|
+
**Use the results**
|
|
1252
|
+
- \`list_product_photos { brand_id, archived? }\` — the brand's generated photos (\`archived: false\`
|
|
1253
|
+
= active, \`true\` = archived).
|
|
1254
|
+
- \`approve_product_photo { output_id }\` — approve a photo: links it to the product and makes it
|
|
1255
|
+
available in the **brand kit**, so \`goose-ads\` can use it. **Photos are not used anywhere until
|
|
1256
|
+
approved.**
|
|
1257
|
+
- \`archive_product_photo { output_id, reason? }\` — archive a photo; archived photos are **excluded**
|
|
1258
|
+
from ad generation.
|
|
1259
|
+
|
|
1260
|
+
## Workflow — shoot a product
|
|
1261
|
+
|
|
1262
|
+
1. **Load the brand context** (\`brand_get_context\`, or reuse what the router passed you) and
|
|
1263
|
+
**resolve the brand + product.** \`list_ad_brands\` → \`brand_id\`. \`list_brand_products\` → pick a
|
|
1264
|
+
\`product_id\` from the catalog you already know about. If the product genuinely isn't there,
|
|
1265
|
+
\`import_product\` (poll \`get_product_import\`).
|
|
1266
|
+
2. **Quote the cost.** \`estimate_product_photos { count, quality }\` → tell the user credits.
|
|
1267
|
+
3. **Generate.** \`generate_product_photos { brand_id, product_id, category, count, quality, prompt? }\`.
|
|
1268
|
+
Build \`prompt\` from the brand's voice/positioning you already have — don't interview the user for it.
|
|
1269
|
+
Returns a generation \`id\` right away.
|
|
1270
|
+
4. **Poll.** \`get_product_photo_generation { generation_id }\` until terminal; hand back each
|
|
1271
|
+
\`final_image_url\`.
|
|
1272
|
+
5. **Approve the keepers.** Show the results and let the user pick; \`approve_product_photo\` the ones
|
|
1273
|
+
they'd publish (that's what puts them in the brand kit for ads), \`archive_product_photo\` the rest.
|
|
1274
|
+
|
|
1275
|
+
## Rules
|
|
1276
|
+
|
|
1277
|
+
- **Never invent product facts.** The backend grounds the shot on the product's real images; don't
|
|
1278
|
+
describe a product you can't see.
|
|
1279
|
+
- **Use the brand context instead of interviewing the user.** Product, audience, voice, positioning,
|
|
1280
|
+
logo/colors/fonts all come from \`brand_get_context\` / the brand kit. Ask only for the shot
|
|
1281
|
+
category, count, quality, and model consent.
|
|
1282
|
+
- **Ask before spending.** Quote the estimate and confirm \`count\` / \`quality\` before
|
|
1283
|
+
\`generate_product_photos\` — it reserves credits.
|
|
1284
|
+
- **Poll, don't re-submit.** A generation that's still \`running\` is not stuck; re-submitting
|
|
1285
|
+
double-bills. Only a \`failed\` generation should be retried.
|
|
1286
|
+
- **Model imagery needs consent.** Only set a human model when the user asks, and pass
|
|
1287
|
+
\`attestation_accepted: true\`.
|
|
1288
|
+
- **Approval is the hand-off to ads.** Remind the user that only **approved** photos reach the brand
|
|
1289
|
+
kit / ad workflow; archived ones never do.
|
|
1290
|
+
`;
|
|
1291
|
+
}
|
|
1049
1292
|
//# sourceMappingURL=master-skill.js.map
|