gooseworks 0.4.4 → 0.5.0-dev.5.1ff84a4f
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 +27 -10
- package/dist/agents/staging.d.ts +38 -0
- package/dist/agents/staging.d.ts.map +1 -0
- package/dist/agents/staging.js +309 -0
- package/dist/agents/staging.js.map +1 -0
- package/dist/auth/credentials.d.ts +1 -0
- package/dist/auth/credentials.d.ts.map +1 -1
- package/dist/auth/credentials.js +26 -8
- package/dist/auth/credentials.js.map +1 -1
- package/dist/auth/oauth-server.d.ts.map +1 -1
- package/dist/auth/oauth-server.js +18 -2
- package/dist/auth/oauth-server.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +17 -8
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/formats.js +2 -2
- package/dist/commands/formats.js.map +1 -1
- package/dist/commands/graphics/publish-flow.js +1 -1
- package/dist/commands/graphics/publish-flow.js.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +20 -0
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/launch.d.ts +3 -0
- package/dist/commands/launch.d.ts.map +1 -0
- package/dist/commands/launch.js +35 -0
- package/dist/commands/launch.js.map +1 -0
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +7 -0
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.d.ts.map +1 -1
- package/dist/commands/logout.js +3 -1
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/skills.d.ts +16 -0
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +52 -1
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/styles.js +2 -2
- package/dist/commands/styles.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +20 -0
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/video-local.d.ts.map +1 -1
- package/dist/commands/video-local.js +2 -2
- package/dist/commands/video-local.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +11 -3
- package/dist/config.js.map +1 -1
- package/dist/environment.d.ts +9 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +103 -0
- package/dist/environment.js.map +1 -0
- package/dist/index.js +12 -45
- package/dist/index.js.map +1 -1
- package/dist/lib/graphics-cache.d.ts.map +1 -1
- package/dist/lib/graphics-cache.js +2 -2
- package/dist/lib/graphics-cache.js.map +1 -1
- package/dist/program.d.ts +2 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +54 -0
- package/dist/program.js.map +1 -0
- package/dist/skills/custom-video-skill.d.ts +1 -1
- package/dist/skills/custom-video-skill.d.ts.map +1 -1
- package/dist/skills/custom-video-skill.js +1 -1
- package/dist/skills/custom-video-skill.js.map +1 -1
- package/dist/skills/installer.d.ts.map +1 -1
- package/dist/skills/installer.js +42 -24
- package/dist/skills/installer.js.map +1 -1
- package/dist/skills/master-skill.d.ts +12 -9
- package/dist/skills/master-skill.d.ts.map +1 -1
- package/dist/skills/master-skill.js +745 -343
- package/dist/skills/master-skill.js.map +1 -1
- package/dist/skills/releases.d.ts +1 -1
- package/dist/skills/releases.d.ts.map +1 -1
- package/dist/skills/releases.js +8 -5
- package/dist/skills/releases.js.map +1 -1
- package/dist/skills/routes.js +7 -7
- package/dist/skills/routes.js.map +1 -1
- package/dist/skills/staging-content.d.ts +3 -0
- package/dist/skills/staging-content.d.ts.map +1 -0
- package/dist/skills/staging-content.js +12 -0
- package/dist/skills/staging-content.js.map +1 -0
- package/package.json +12 -4
- package/skills/goose-ads/SKILL.md +363 -224
- package/skills/goose-product-photos/SKILL.md +84 -58
- package/skills/goose-video/SKILL.md +223 -14
- package/skills/goose-video-local/SKILL.md +195 -24
- package/skills/gooseworks/SKILL.md +106 -24
- package/skills/make-custom-video/SKILL.md +231 -10
- package/skills/manifest.json +7 -7
- package/skills/routes.json +7 -7
- package/dist/skills/fetcher.d.ts +0 -18
- package/dist/skills/fetcher.d.ts.map +0 -1
- package/dist/skills/fetcher.js +0 -118
- package/dist/skills/fetcher.js.map +0 -1
|
@@ -65,6 +65,146 @@ an existing approved run's recorded package; changing that harness requires a re
|
|
|
65
65
|
and approval before spending. Hosted installed snapshots use the existing Skills Update action.
|
|
66
66
|
Skill content and a host's cached MCP tool schemas are separate: refreshing one does not refresh
|
|
67
67
|
the other. Check the actual advertised tools before using new fields.`;
|
|
68
|
+
const VIDEO_GUIDE_COMPATIBILITY = `**Follow the connector's full-guide requirement when available.** Fetch
|
|
69
|
+
\`catalog_fetch { type: "skill", slug: "gooseworks-guide" }\` when the connector requires it.
|
|
70
|
+
The only older-server exception is below; it never removes brand preparation or approvals.
|
|
71
|
+
|
|
72
|
+
| Returned guide/workflow state on the selected connection | Required action |
|
|
73
|
+
| --- | --- |
|
|
74
|
+
| Guide returns \`not_found\`, and this same connection already returned the complete current matching video entry with its required dependencies | Continue with that authoritative entry's workflow, full brand preparation and existing approvals. |
|
|
75
|
+
| Guide has another error, no response, or incomplete content; or the matching entry/dependencies are missing, incomplete or from another connection | Stop before creative work, project writes or paid calls; resolve a compatible connection on this same environment. |
|
|
76
|
+
|
|
77
|
+
A missing custom entry or required custom tool/schema remains unavailable: never substitute
|
|
78
|
+
a template or an import to bypass it. Never hide other fetch errors or continue from cached
|
|
79
|
+
instructions merely because the guide was not found.`;
|
|
80
|
+
/**
|
|
81
|
+
* The Brain-first entry contract, shared by the router, goose-ads and every video
|
|
82
|
+
* entry. A fresh agent read the Kit, then asked the user for angles and proof
|
|
83
|
+
* the Brand Brain already held: no entry made the search a step, and several
|
|
84
|
+
* told it to ask. Searching is free and read-only, so it needs no approval.
|
|
85
|
+
*/
|
|
86
|
+
const BRAIN_FIRST_ENTRY = `## Search the Brand Brain, then propose — before any creative choice or question
|
|
87
|
+
|
|
88
|
+
The Brand Kit is a summary. The brand's saved knowledge (its Brain) holds what the Kit does not:
|
|
89
|
+
rules from past feedback, approved and rejected creatives, customer evidence, approved claims,
|
|
90
|
+
reports and documents. **After \`brand_read\`, and before you choose an angle, claim, hook,
|
|
91
|
+
product emphasis, format or source ad — and before you ask the user for any brand fact — call
|
|
92
|
+
\`knowledge_search { brand_id, query }\`** when it is registered. It is free and read-only: no
|
|
93
|
+
approval, no announcement to the customer and no questionnaire.
|
|
94
|
+
|
|
95
|
+
1. **Search for this task, not the whole Brain.** Run one short query (under 500 characters) in
|
|
96
|
+
the user's own words plus the product (for example "ads for <product>: what worked, what to
|
|
97
|
+
avoid") and one with
|
|
98
|
+
\`source_types: ["evidence", "claim", "learning", "creative", "document"]\` for proof and past
|
|
99
|
+
creative results. Add a query only for a specific open question. Reuse results from this run.
|
|
100
|
+
2. **Keep these states distinct** and record which one each query returned:
|
|
101
|
+
|
|
102
|
+
| Result | Means | Do |
|
|
103
|
+
| --- | --- | --- |
|
|
104
|
+
| \`status: "ok"\` with matches | Saved knowledge exists | Use it; keep each fact's citation in your working brief |
|
|
105
|
+
| \`status: "empty"\` | Nothing saved matches this query | Say "no saved evidence for <topic>", never "the brand has no proof" |
|
|
106
|
+
| \`refresh_required\` | The results shown are current; some changed sources were left out | Use them; search again shortly for anything missing |
|
|
107
|
+
| \`building\` | The index is not ready | Retry once shortly, then continue with the gap stated |
|
|
108
|
+
| An error, or the tool is not registered | Retrieval failed or is unavailable | Retry an error once, then continue from \`brand_read\` and treat evidence as unchecked |
|
|
109
|
+
| An empty Kit field | Only that field is blank | Not a search result: still search before asking |
|
|
110
|
+
|
|
111
|
+
3. **Let the findings change the plan.** A \`dont\`/\`must\` learning or a rejected creative rules
|
|
112
|
+
options out; an approved or well-rated past creative is a proven angle to lead with; a report
|
|
113
|
+
shows what worked. Claim-grade proof is a result with \`approved_ad_claim: true\` or the kit's
|
|
114
|
+
\`approvedClaims\` within their stated applicability; the kit's \`proofPoints\` are what the
|
|
115
|
+
backend allows an ad to state, used as written. Other Kit text, documents and performance
|
|
116
|
+
numbers are context, never public claims. Never invent an offer, price or result. Judge
|
|
117
|
+
relevance and skip results about another product or business.
|
|
118
|
+
4. **Propose; don't interview.** Lead with one recommended direction (angle, product, source or
|
|
119
|
+
format) and a one-line reason naming what you found, with up to two alternatives. When several
|
|
120
|
+
directions fit (two audiences, products or campaigns), pick the one the evidence favours, such
|
|
121
|
+
as an active campaign or approved past creatives, and name the other as an alternative instead
|
|
122
|
+
of asking. Ask only for a decision the brand read and the search cannot settle, or for spend
|
|
123
|
+
approval. Never ask the user for a fact the Brain already answered.
|
|
124
|
+
Keep directions already chosen (the user's words, a project's creative brief, handed-off
|
|
125
|
+
defaults, approved plans): search only to fill empty fields and to apply saved rules. When a
|
|
126
|
+
returned card or picker presents the choice, your recommendation is its one acknowledgement
|
|
127
|
+
line and the saved plan's defaults, not a separate list.
|
|
128
|
+
5. **Carry an evidence brief** into the routed skill, writer or plan: findings with citations,
|
|
129
|
+
the state of each query, what it ruled out and the open gaps. Tell the customer the findings
|
|
130
|
+
in plain words; the citations stay in the brief.
|
|
131
|
+
|
|
132
|
+
On an approved resume, keep the saved brief and evidence; search again only for a new decision.`;
|
|
133
|
+
/** One prerequisite for template, custom and delegated video entry. */
|
|
134
|
+
function videoEntryPreparation(slug) {
|
|
135
|
+
return `## Prepare the video workflow and brand before creative work
|
|
136
|
+
|
|
137
|
+
**Installed entry files are bootstrap instructions.** For new work started from an installed
|
|
138
|
+
file or an old chat, fetch \`catalog_fetch { type: "skill", slug: "${slug}" }\` on the selected
|
|
139
|
+
connection and read its returned content and dependencies before continuing. Use the already
|
|
140
|
+
fetched body when this entry came from that connection in this run; do not recursively fetch
|
|
141
|
+
the same entry. A CLI freshness warning does not block using the current connected package.
|
|
142
|
+
Keep the fetched package and hashes in a new run folder; do not replace edited installed files.
|
|
143
|
+
If current instructions cannot be loaded, resolve the connection before format suggestions,
|
|
144
|
+
script writing or production. Do not continue from an old installed workflow or session notes.
|
|
145
|
+
|
|
146
|
+
${VIDEO_GUIDE_COMPATIBILITY}
|
|
147
|
+
|
|
148
|
+
**For an existing project or batch, read \`video_project_read\` first.** Determine its actual
|
|
149
|
+
route and saved review state before fetching a recipe or doing local work. Resume an approved
|
|
150
|
+
run with its recorded packages, brand inputs, script and ingredients; do not silently replace
|
|
151
|
+
them with today's release or brand rules. Follow returned preparation requirements and use
|
|
152
|
+
the existing affected review/approval flow for an intentional change. Reads, free drafts,
|
|
153
|
+
imports and existing-job retrieval do not grant permission for new paid production.
|
|
154
|
+
|
|
155
|
+
**For every new plan, resolve the brand and call**
|
|
156
|
+
\`brand_read { brand_id, sections: ["summary", "kit", "products", "learnings"] }\` **before**
|
|
157
|
+
suggesting formats, mining video angles, writing any script, creating a production plan or
|
|
158
|
+
handing the work to another agent. Use \`brand_get_context\` with those same four sections only
|
|
159
|
+
when advertised. Reuse a complete read from this run on the same connection and brand.
|
|
160
|
+
Onboarding completion, a summary-only response and earlier session notes do not supply the
|
|
161
|
+
kit, selected product facts or saved rules. If the full read is unavailable, resolve it before
|
|
162
|
+
creative work. Use known kit facts while research is incomplete; do not restart research
|
|
163
|
+
solely because its status is pending. Never invent a product fact or accept a campaign to
|
|
164
|
+
bypass preparation. Then search the Brand Brain (next section) before suggesting formats,
|
|
165
|
+
choosing an angle or asking the user for a brand fact.
|
|
166
|
+
|
|
167
|
+
Carry that context through custom/template/idea routing and delegation. Before writing, make
|
|
168
|
+
the workflow's brand-rules file from those sources: pronunciations, required spoken copy,
|
|
169
|
+
prohibited claims, real logo, font, palette and the selected product's supported facts.
|
|
170
|
+
Entries prefixed \`Video preference:\` and visual/pacing instructions are creative direction,
|
|
171
|
+
not spoken lines. Use the kit's audience, offer and voice as defaults without an interview.
|
|
172
|
+
The rules file mirrors context; it is not proof of a read or permission to spend. Keep the
|
|
173
|
+
route's existing script, ingredient and budget approvals, including its allowed previews.
|
|
174
|
+
|
|
175
|
+
**Use the server's brand bundle when the selected API returns it.** Project create/read may
|
|
176
|
+
return top-level
|
|
177
|
+
\`brand_context\`: \`{ version: 1, brand_id, digest, loaded_at, sections, brand, kit, products,
|
|
178
|
+
learnings }\`. Its sections cover summary, kit, products and learnings.
|
|
179
|
+
|
|
180
|
+
| Returned brand/project response on the selected connection | Required action |
|
|
181
|
+
| --- | --- |
|
|
182
|
+
| A complete authoritative version-1 \`brand_context\` is returned | Binding is required: use its contents for the plan/rules and include \`script_drafts.brand_context_digest = brand_context.digest\` with each new/changed script save. |
|
|
183
|
+
| An older API returns the actual four brand sections but no \`brand_context\` in either the brand read or project response | Prepare from those full sections, write the brand rules and follow the selected connection's existing approval flow and advertised fields. Do not fabricate a receipt or send nonexistent bundle/digest fields. |
|
|
184
|
+
|
|
185
|
+
An incomplete/malformed bundle or missing brand section is a preparation failure, never the
|
|
186
|
+
older-API exception. Once this connection returns an authoritative bundle, use its binding
|
|
187
|
+
contract. \`script_drafts.video_brand_context\` is server-owned: do not author, replace or forge
|
|
188
|
+
it, and do not invent a read receipt or hash local brand facts into one. Keep the full bundle
|
|
189
|
+
out of client review payloads. If managed generation returns HTTP 409
|
|
190
|
+
\`video_brand_context_required\`, reload the project and bind the plan to its returned bundle
|
|
191
|
+
through the normal review flow before retrying. That refusal never permits the older-API
|
|
192
|
+
fallback, skipping sections or retrying paid calls blindly. Unchanged approved legacy resumes
|
|
193
|
+
retain their package, context and approvals; an upgrade alone needs no extra approval.
|
|
194
|
+
|
|
195
|
+
**To apply a deliberate brand correction to a new or revised plan**, make a fresh, unfiltered
|
|
196
|
+
\`brand_read\` of those four sections. When it returns the authoritative bundle, use its
|
|
197
|
+
returned \`brand_context.digest\` in the complete revised \`script_drafts\` through the existing
|
|
198
|
+
\`video_project_upsert\` \`patch.script\` save; the server verifies the current brand and replaces
|
|
199
|
+
its snapshot with the saved plan. On an older API with no bundle contract, apply the actual
|
|
200
|
+
four-section correction and save the revised draft through its existing flow without inventing
|
|
201
|
+
digest fields. If a connection that already returned a bundle cannot supply the fresh bundle,
|
|
202
|
+
resolve that failure before rebinding. Review and approve the affected script, ingredients and
|
|
203
|
+
budget through the normal flow. Never refresh an ongoing approved run automatically; its
|
|
204
|
+
recorded package and brand inputs stay pinned until an intentional change.
|
|
205
|
+
|
|
206
|
+
${BRAIN_FIRST_ENTRY}`;
|
|
207
|
+
}
|
|
68
208
|
const CUSTOMER_TALK = `## How to talk to the customer (applies to every message you send them)
|
|
69
209
|
|
|
70
210
|
The customer is a marketer or founder, not an engineer. Everything in this skill about tools,
|
|
@@ -135,8 +275,9 @@ review set; do not add a separate approval round.`;
|
|
|
135
275
|
const DURABLE_BRAND_CAPTURE = `## Save durable brand answers, then verify them
|
|
136
276
|
|
|
137
277
|
Read the selected brand with \`brand_read { brand_id, sections: ["summary", "kit", "products", "learnings", "onboarding"] }\`
|
|
138
|
-
(
|
|
139
|
-
research and your own hypotheses distinct. Reuse
|
|
278
|
+
(older clients: \`brand_get_context\` with the same sections, only when that tool is advertised).
|
|
279
|
+
Keep founder answers, user corrections, research and your own hypotheses distinct. Reuse
|
|
280
|
+
matching saved answers; ask only about gaps.
|
|
140
281
|
|
|
141
282
|
When the user asks to remember a rule, answers a brand interview, or explicitly corrects a
|
|
142
283
|
standing fact, save that answer in the same turn. The capture request authorizes those answers;
|
|
@@ -271,7 +412,7 @@ description: >
|
|
|
271
412
|
Capture founder answers, brand rules, audience depth, and video taste in the existing brand.
|
|
272
413
|
Use it as the single GooseWorks entry point for brand growth, B2B, sales, research, and GTM work.
|
|
273
414
|
category: general
|
|
274
|
-
version: 1.
|
|
415
|
+
version: 1.1.2
|
|
275
416
|
author: GooseWorks
|
|
276
417
|
tags: [gooseworks, data, scraping, search, reddit, twitter, linkedin, email, people, research, gtm, leads, prospecting]
|
|
277
418
|
---
|
|
@@ -286,7 +427,9 @@ ${CUSTOMER_TALK}
|
|
|
286
427
|
|
|
287
428
|
## Route to the right skill FIRST
|
|
288
429
|
|
|
289
|
-
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)
|
|
430
|
+
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. For video work, load the current matching workflow from the selected connection first: \`goose-video\` for a new request, \`make-custom-video\` for an explicit original/reference brief, or \`goose-video-local\` for an existing template project/batch. Read an existing project first to determine its actual route and retain its approved packages. Fetch with the advertised \`catalog_fetch { type: "skill", slug }\`; an installed copy or old chat is only a bootstrap. Then load the brand context (**"Load the brand context FIRST"**, immediately below), search the Brand Brain for the task (**"Search the Brand Brain, then propose"**), and follow the matching workflow with both. For other specialized work, **switch to that skill** after loading the brand instead of the data flow below:
|
|
431
|
+
|
|
432
|
+
${VIDEO_GUIDE_COMPATIBILITY}
|
|
290
433
|
|
|
291
434
|
For "interview me about the brand", "save our brand rules", "refine our audience", or "remember
|
|
292
435
|
our video taste", stay here and follow **Guided brand capture** below. This extends the current
|
|
@@ -303,23 +446,34 @@ Examples — all of these route to \`goose-ads\`, not the data flow: "remix this
|
|
|
303
446
|
|
|
304
447
|
**Call \`brand_read { brand_id, sections: ["summary", "kit", "products", "learnings", "onboarding"] }\` before the first substantive step of ANY task**, and before you route to a specialist skill. Older clients can use \`brand_get_context\` with the same sections only when that tool is advertised. It is a read-only call that returns the brand's canonical facts and saved rules:
|
|
305
448
|
|
|
449
|
+
For videos, read the current workflow first as described above, then load all four creative
|
|
450
|
+
sections (summary, kit, products and learnings) before suggesting formats, choosing angles or
|
|
451
|
+
writing a script. Onboarding facts alone are insufficient. Carry saved rules and kit assets
|
|
452
|
+
into the specialist's brand preparation. \`Video preference:\` rules describe the look, voice
|
|
453
|
+
and pacing; they are not lines to read aloud. On an approved resume, preserve the saved brand
|
|
454
|
+
inputs and packages; an intentional change uses the existing affected review/approval gates.
|
|
455
|
+
|
|
306
456
|
| It returns | Use it for |
|
|
307
457
|
| --- | --- |
|
|
308
458
|
| **voice** — tone, style, banned phrasing | Any copy, script, caption, hook, or headline. Don't ask "what tone?" |
|
|
309
459
|
| **products** — names, descriptions, pricing, links, imagery | Picking the product to feature. Don't ask "which product?" — offer the list. |
|
|
310
460
|
| **audience** — segments, demographics, jobs-to-be-done | Targeting, angles, creator fit. Don't ask "who is this for?" |
|
|
311
|
-
| **positioning** — category, value props, proof points, tagline | Angles, offers, competitive framing. Don't ask "what makes you different?" |
|
|
461
|
+
| **positioning** — category, value props, proof points, tagline | Angles, offers, competitive framing. Don't ask "what makes you different?" Kit proof points are proof an ad may state as written; other positioning text is context. |
|
|
312
462
|
| **research status** — whether the brand's research pass has completed | Whether the facts are trustworthy yet, or still being filled in. |
|
|
313
463
|
|
|
314
464
|
Then:
|
|
315
465
|
|
|
316
|
-
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.
|
|
317
|
-
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,
|
|
466
|
+
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, plus the evidence brief from the Brain search below. Do **not** make the routed skill re-derive them, and do **not** re-run brand research when the context is already there.
|
|
467
|
+
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 or the Brain search answers, they win — answer it yourself and move on. Ask only for what is genuinely missing after both, or a decision that is the user's to make.
|
|
318
468
|
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.
|
|
319
469
|
4. **If \`brand_read\` is unavailable**, refresh the GooseWorks connection or tool list. An older connection may expose \`brand_get_context\` / \`get_brand_kit\`; use those only when actually advertised. Never require a legacy tool name or guess brand facts.
|
|
320
470
|
5. **A read grants no write permission.** Save explicit durable answers/corrections with the capture policy below. Propose agent-derived changes for review; never overwrite confirmed knowledge with research or a guess.
|
|
321
471
|
|
|
322
|
-
Never invent a brand fact. If it isn't in the brand context and the user hasn't said it,
|
|
472
|
+
Never invent a brand fact. If it isn't in the brand context and the user hasn't said it, search
|
|
473
|
+
the Brand Brain next. Ask the user only when that search cannot answer it and the answer is
|
|
474
|
+
theirs to give.
|
|
475
|
+
|
|
476
|
+
${BRAIN_FIRST_ENTRY}
|
|
323
477
|
|
|
324
478
|
## Setup
|
|
325
479
|
|
|
@@ -331,20 +485,31 @@ Skills may describe a managed provider request as an environment-neutral operati
|
|
|
331
485
|
\`provider\`, \`method\`, \`path\`, and optional \`query\` or \`body\`. Execute the operation through
|
|
332
486
|
the first available runtime:
|
|
333
487
|
|
|
334
|
-
1. If the matching GooseWorks MCP tool is registered, use it. For ScrapeCreators, pass
|
|
335
|
-
operation directly to \`
|
|
336
|
-
|
|
488
|
+
1. If the matching GooseWorks MCP tool is registered, use it. For ScrapeCreators, pass a GET
|
|
489
|
+
operation directly to \`data_call_provider\` (\`provider\`, \`path\`, \`query\`) and a POST
|
|
490
|
+
operation to \`data_post_provider\` (\`provider\`, \`path\`, \`body\`, optional \`query\`).
|
|
491
|
+
This is the preferred path in ChatGPT, Cowork, and other terminal-free clients.
|
|
492
|
+
Do not shell out and do not ask for a separate provider key.
|
|
337
493
|
2. Otherwise, if a local terminal and the \`gooseworks\` CLI are available, translate the same
|
|
338
494
|
operation into \`gooseworks call <provider> <path>\` with its method, query, and body options.
|
|
339
495
|
3. Otherwise, follow the provider dependency's direct-key path only when the user has supplied
|
|
340
496
|
their own key. If no runtime is available, explain what connection is missing; never pretend
|
|
341
497
|
the provider call ran.
|
|
342
498
|
|
|
499
|
+
Managed provider calls are paid on the MCP and CLI runtimes alike (a ScrapeCreators call costs 1
|
|
500
|
+
credit today, and each result reports what it charged). Before a skill's first paid call, tell the
|
|
501
|
+
user roughly how many calls it will make and the credit total, and get their yes.
|
|
502
|
+
|
|
343
503
|
The same selection applies to catalog and account operations. When the CLI is unavailable but the
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
- \`gooseworks
|
|
347
|
-
- \`gooseworks
|
|
504
|
+
GooseWorks MCP tools are connected, use these equivalents. Match on the tool name: a coding agent
|
|
505
|
+
may show a server prefix (for example \`mcp__gooseworks__catalog_search\`), a chat app may not.
|
|
506
|
+
- \`gooseworks search <q>\` → **\`catalog_search { type: "skill", query: "<q>" }\`**.
|
|
507
|
+
- \`gooseworks fetch <slug>\` → **\`catalog_fetch { type: "skill", slug: "<slug>" }\`** (same content/scripts/files/deps).
|
|
508
|
+
- \`gooseworks credits\` → **\`account_whoami\`** (the balance is \`credits.available_credits\`).
|
|
509
|
+
|
|
510
|
+
If one of these tools is missing, the GooseWorks connection or its tool list is stale: ask the
|
|
511
|
+
user to reconnect or refresh GooseWorks. Installing or updating the \`gooseworks\` CLI never fixes
|
|
512
|
+
a missing connector tool, so never send a chat-app user to a terminal for it.
|
|
348
513
|
|
|
349
514
|
Discovery, skill fetching, and ScrapeCreators-backed Brand Growth workflows work fully CLI-free
|
|
350
515
|
this way. Task skills own the endpoint and analysis workflow; this runtime rule owns how the same
|
|
@@ -394,8 +559,8 @@ already volunteered in this chat, and **save known information first** using the
|
|
|
394
559
|
mapping below. Do not run a long questionnaire as a prerequisite for making an ad.
|
|
395
560
|
|
|
396
561
|
For facts needed by the task but absent from the read, call \`knowledge_search\` first if it is
|
|
397
|
-
registered
|
|
398
|
-
not proof that the brand has no answer. Do not re-scrape or ask the founder for a fact already
|
|
562
|
+
registered, as in **"Search the Brand Brain, then propose"**. Use returned citations and states
|
|
563
|
+
honestly: an empty, building or failed index is not proof that the brand has no answer. Do not re-scrape or ask the founder for a fact already
|
|
399
564
|
answered by trustworthy saved knowledge.
|
|
400
565
|
|
|
401
566
|
Ask one short group of missing human-only facts at a time, in plain language, with the relevant
|
|
@@ -561,7 +726,7 @@ The \`gooseworks\` CLI sends authenticated requests (Bearer \`GOOSEWORKS_API_KEY
|
|
|
561
726
|
|
|
562
727
|
0. **Read the canonical brand context before substantive work**, 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").
|
|
563
728
|
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.
|
|
564
|
-
2. **Before paid operations**, tell the user the estimated credit cost
|
|
729
|
+
2. **Before paid operations**, tell the user the estimated credit cost and get their yes
|
|
565
730
|
3. **If a \`gooseworks\` command exits with "Not logged in"**: tell the user to run \`npx gooseworks login\`
|
|
566
731
|
4. **Parse JSON responses** and present data in a readable format to the user
|
|
567
732
|
5. **When running scripts**: save to \`/tmp/gooseworks-scripts/\`, install pip deps, then execute. NEVER pollute the user's project directory
|
|
@@ -569,20 +734,42 @@ The \`gooseworks\` CLI sends authenticated requests (Bearer \`GOOSEWORKS_API_KEY
|
|
|
569
734
|
7. **Prefer \`gooseworks call\` over raw curl** — if it returns an error, first fix the parameters (check types, required fields, format) and retry. Only fall back to raw curl if you have strong reason to believe it is a CLI bug, not a parameter issue.
|
|
570
735
|
`;
|
|
571
736
|
}
|
|
737
|
+
/**
|
|
738
|
+
* How an entry skill that runs on the GooseWorks connector says what to do when
|
|
739
|
+
* a tool is missing (QA-26 / VWR14). A chat agent that could not find a tool
|
|
740
|
+
* used to tell the customer to run `gooseworks install` in a terminal they do
|
|
741
|
+
* not have; a missing connector tool is fixed by reconnecting, never by a CLI.
|
|
742
|
+
*/
|
|
743
|
+
function connectorPrerequisite(exampleTool, extra = '') {
|
|
744
|
+
return `## Prerequisite — the GooseWorks connector tools
|
|
745
|
+
|
|
746
|
+
Everything below runs through the GooseWorks connector's tools, by the names this skill uses.
|
|
747
|
+
Match on the tool name: a coding agent may show a server prefix (for example
|
|
748
|
+
\`mcp__gooseworks__${exampleTool}\`), a chat app may not.${extra}
|
|
749
|
+
|
|
750
|
+
If a tool named here is missing, the GooseWorks connection or its tool list is stale: ask the
|
|
751
|
+
user to reconnect or refresh GooseWorks in their app's connector settings. Installing or
|
|
752
|
+
updating the \`gooseworks\` CLI never fixes a missing connector tool, so never send a chat-app
|
|
753
|
+
user to a terminal for it. Only a terminal coding agent (Claude Code, Codex, Cursor) that has no
|
|
754
|
+
GooseWorks tools at all connects them, in that terminal, with \`gooseworks install --mcp\` plus
|
|
755
|
+
\`--claude\`, \`--codex\` or \`--cursor\`, then a restart.
|
|
756
|
+
|
|
757
|
+
Older notes or skill copies may name tools the connector no longer lists. Use the tool this skill
|
|
758
|
+
names instead; \`catalog_fetch { type: "skill", slug: "gooseworks-guide" }\` maps every old name.`;
|
|
759
|
+
}
|
|
572
760
|
/**
|
|
573
761
|
* Returns the goose-ads entry SKILL.md content (the `goose-ads` entry skill,
|
|
574
762
|
* formerly `ads-remix`).
|
|
575
763
|
*
|
|
576
764
|
* This is the ads domain skill and a THIN WRAPPER over the backend's single ad
|
|
577
|
-
* generation workflow (adRemixBatchesService, exposed
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
*
|
|
583
|
-
*
|
|
584
|
-
*
|
|
585
|
-
* ad, research a brand for ads, or analyze ad performance.
|
|
765
|
+
* generation workflow (adRemixBatchesService, exposed on the connector as
|
|
766
|
+
* `ads_generate` / `ads_creative_edit` — the SAME workflow the ads frontend
|
|
767
|
+
* uses). The skill never generates images, manages renders, or uploads files
|
|
768
|
+
* itself; the backend reserves credits, runs the cloud pipeline, and bills. The
|
|
769
|
+
* skill ALSO routes ad analytics/intelligence to recipe skills fetched on demand
|
|
770
|
+
* from goose-skills. Chat apps reach it through `catalog_fetch`, so every tool it
|
|
771
|
+
* names must be one the connector lists (QA-26 / VWR14; guarded by
|
|
772
|
+
* tests/skills/master-skill.test.ts against tests/fixtures/connector-tool-names.json).
|
|
586
773
|
*/
|
|
587
774
|
function getGooseAdsSkillContent() {
|
|
588
775
|
return `---
|
|
@@ -599,7 +786,7 @@ description: >
|
|
|
599
786
|
app uses) — credits are reserved and billed server-side. Analytics recipes are fetched from
|
|
600
787
|
goose-skills on demand.
|
|
601
788
|
category: ads
|
|
602
|
-
version: 2.
|
|
789
|
+
version: 2.6.1
|
|
603
790
|
author: GooseWorks
|
|
604
791
|
tags: [gooseworks, ads, remix, static-ad, brand, creative, image, analytics, meta-ads, performance]
|
|
605
792
|
---
|
|
@@ -617,41 +804,68 @@ The GooseWorks ads skill. Two jobs:
|
|
|
617
804
|
2. **Analyze ad performance** — fetch ad-analytics recipes from goose-skills on demand
|
|
618
805
|
(these are unrelated to generation; see "Analyze / intelligence" below).
|
|
619
806
|
|
|
620
|
-
|
|
807
|
+
It works the same in a chat app (ChatGPT, claude.ai, Cowork) and in a terminal coding agent:
|
|
808
|
+
everything except the few steps labelled terminal-only goes through the connector's tools.
|
|
621
809
|
|
|
622
|
-
|
|
810
|
+
${CUSTOMER_TALK}
|
|
623
811
|
|
|
624
|
-
|
|
625
|
-
tell the user to run \`gooseworks install --claude --mcp\`** (and restart Claude Code). There is
|
|
626
|
-
no HTTP/file fallback — the REST ad endpoints are session-cookie-only and reject your token.
|
|
812
|
+
${connectorPrerequisite('ads_generate', ' There is no HTTP or file fallback: the REST ad\nendpoints are session-cookie-only and reject your token.')}
|
|
627
813
|
|
|
628
814
|
## Start from the brand context — don't re-ask what it already answers
|
|
629
815
|
|
|
630
|
-
If the \`gooseworks\` router handed you brand context, USE
|
|
631
|
-
\`brand_read { brand_id, sections: ["summary","kit","products","learnings"] }\`
|
|
632
|
-
|
|
816
|
+
If the \`gooseworks\` router handed you brand context and an evidence brief, USE THEM. If you were
|
|
817
|
+
invoked directly, call \`brand_read { brand_id, sections: ["summary","kit","products","learnings"] }\`
|
|
818
|
+
first, then search the Brand Brain (next section). Together they answer most of what the flows
|
|
819
|
+
below would otherwise ask the user:
|
|
633
820
|
|
|
634
|
-
- **Which product to feature** → \`products
|
|
821
|
+
- **Which product to feature** → \`products.items\`. Recommend one real catalog entry; never guess a
|
|
635
822
|
product name and never ask the user to list their products.
|
|
636
823
|
- **The vibe / tone of the copy** → the brand's **voice**. Use it; don't ask "what tone?".
|
|
637
824
|
- **Who the ad is for** → the brand's **audience**. Don't ask "who's the target?".
|
|
638
|
-
- **The angle
|
|
825
|
+
- **The angle and offer framing** → **positioning** and value props, sharpened by the Brain:
|
|
826
|
+
lead with an angle past approved creatives proved, and drop anything a saved rule forbids.
|
|
827
|
+
- **What to claim** → only claim-grade proof: a search result with \`approved_ad_claim: true\`, the
|
|
828
|
+
kit's approved claims, or its proof points as written. Other Kit text, documents and
|
|
829
|
+
performance numbers are context.
|
|
639
830
|
- **Logo, colors, fonts** → owned by the backend research pass. **Never re-derive them.**
|
|
640
831
|
- **Whether the facts are trustworthy yet** → **research status**. If it isn't complete, say so in
|
|
641
832
|
one line and continue; the batch queues and runs when research finishes.
|
|
642
833
|
|
|
643
|
-
|
|
644
|
-
|
|
834
|
+
Don't ask for the angle, product or tone: recommend them with a one-line reason. Ask only for a
|
|
835
|
+
decision the brand read and the Brain search cannot settle (for example an offer or season the
|
|
836
|
+
user hasn't mentioned) and for anything the user must consent to (rights, spend).
|
|
837
|
+
|
|
838
|
+
${BRAIN_FIRST_ENTRY}
|
|
839
|
+
|
|
840
|
+
## Credits — state the total, then get a yes
|
|
645
841
|
|
|
646
|
-
|
|
842
|
+
- One token authenticates the GooseWorks tools and resolves your org; never print it. The
|
|
843
|
+
generation tools need no \`target\`.
|
|
844
|
+
- **Nothing paid runs without the user's explicit yes in this chat, given after you state the
|
|
845
|
+
credit total.** The paid calls are \`ads_generate\` (without \`dry_run\`), every
|
|
846
|
+
\`ads_creative_edit\` action, \`ads_approval_decide\` with \`decision: "approve"\`, and every
|
|
847
|
+
\`data_call_provider\` / \`data_post_provider\` call (the data calls an analysis recipe or brand
|
|
848
|
+
research makes; \`gooseworks call\` in a terminal). Reads, dry runs, \`ads_creative_update\` and
|
|
849
|
+
\`request_campaign_generation\` (it only composes plans) are free.
|
|
850
|
+
- The balance is \`credits.available_credits\` from \`account_whoami\`; a dry-run \`estimate\` also
|
|
851
|
+
carries \`available_credits\`.
|
|
852
|
+
- The backend reserves the quoted credits when a paid call starts and bills only the images
|
|
853
|
+
that complete. A rejection with \`insufficient_credits\` means the wallet is short: tell the
|
|
854
|
+
user the total and their balance in plain words, offer fewer images or a top-up, and stop.
|
|
855
|
+
Never retry blindly.
|
|
647
856
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
857
|
+
How to get the total for each paid call:
|
|
858
|
+
|
|
859
|
+
| Paid call | Credit total to state |
|
|
860
|
+
| --- | --- |
|
|
861
|
+
| \`ads_generate\` with \`source.template_ids\` | The same call with \`dry_run: true\` returns \`estimate\`: \`total_credits\` for \`images\` images (plus \`credits_per_image\`, \`rates\` and \`unknown_template_ids\`). |
|
|
862
|
+
| \`ads_generate\` with \`source.community_ad_ids\` or \`source.creative_ids\` | No dry run (it returns \`not_available\`; these are priced when submitted). Pass \`quality\` explicitly (the user's choice, else \`high\`, the app default) and quote the images (each source's \`variants\` × its \`ratios\`) × \`estimate.rates.<quality>\` as the most it will cost (an engine without quality tiers costs the lower \`rates.low\`). \`rates\` comes with any template dry run; with no template at hand, dry-run one Surprise-me pick. |
|
|
863
|
+
| \`ads_creative_edit\` \`animate\` | The same call with \`dry_run: true\` returns its \`estimate\`. |
|
|
864
|
+
| \`ads_creative_edit\` \`regenerate\` / \`precision_edit\` | No dry run. Pass \`quality\` in the action's payload (without it \`precision_edit\` copies the source render's tier) and quote the images × \`estimate.rates.<quality>\` as the most it will cost: \`regenerate\` with \`mode: "variation"\` makes one per ratio (omitted \`ratios\` make three); \`edit\`, \`exact\` and \`precision_edit\` make one. |
|
|
865
|
+
| \`ads_creative_edit\` \`resize\` | No dry run and no quality setting: it renders at the server's default tier (\`high\` today). Quote one image per placement × the larger of \`estimate.rates.high\` and \`credits_per_image\` from a template dry run without \`quality\` (that dry run uses the server's default tier) as the most it will cost. \`platforms\` expands to every placement: meta 4, google 4, tiktok 2, linkedin 3, reddit 3, x 2; pass \`targets\` for fewer. |
|
|
866
|
+
| \`ads_creative_edit\` \`layerize\` | No dry run. It holds about 80 credits while it runs and charges the actual cost of the split (usually less). Say so and get the yes before sending \`layerize: { confirmed: true }\`. |
|
|
867
|
+
| \`ads_approval_decide\` approve | The \`credits\` that \`request_campaign_generation\` and \`ads_creative_read { brand_id, view: "approvals", batch_id }\` return for those plans. |
|
|
868
|
+
| \`data_call_provider\` / \`data_post_provider\` | The calls a recipe will make × their price: a ScrapeCreators call costs 1 credit today, and each result reports what it charged. A fal or ElevenLabs POST quotes free with the same call plus \`query: { quote_only: true }\`. State the rough total for the whole recipe once, before its first paid call. |
|
|
655
869
|
|
|
656
870
|
## Live MCP contract — inspect it before asking
|
|
657
871
|
|
|
@@ -664,77 +878,82 @@ Before each tool call:
|
|
|
664
878
|
2. Fill required inputs already known from the Brand Kit, selected source, or conversation.
|
|
665
879
|
3. Ask the user only for required inputs that cannot be inferred and for choices that materially
|
|
666
880
|
change the result. Do not turn every optional field into a questionnaire.
|
|
667
|
-
4. Omit unspecified optional settings so the backend applies its current app defaults.
|
|
881
|
+
4. Omit unspecified optional settings so the backend applies its current app defaults. Two
|
|
882
|
+
exceptions: always pass \`ratios\` on every source (omitted ratios make three images per
|
|
883
|
+
variant), and keep the same \`quality\` setting in the quote and the paid call (both omitted
|
|
884
|
+
for a template dry run, or the explicit \`quality\` the credits table asks for).
|
|
668
885
|
5. If the live schema conflicts with this workflow, follow the live schema and report the drift
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
## The
|
|
672
|
-
|
|
673
|
-
- \`
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
\`
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
\`
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
(
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
\`
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
886
|
+
(see "Report problems" in the rules).
|
|
887
|
+
|
|
888
|
+
## The ad tools
|
|
889
|
+
|
|
890
|
+
- \`ads_generate\` — **the one call that makes ads.** Needs \`brand_id\` and exactly one \`source\`:
|
|
891
|
+
\`template_ids: [{ template_id, variants?, ratios }]\` (the brand's own templates, Surprise-me
|
|
892
|
+
picks, Community rows whose \`item_type\` is \`template\`), \`community_ad_ids: [{ community_id,
|
|
893
|
+
variants?, ratios }]\` (Community rows whose \`item_type\` is \`creative\`; the backend snapshots
|
|
894
|
+
them), or \`creative_ids: [{ project_id, render_id?, variants?, ratios }]\` (remix the user's own
|
|
895
|
+
finished ads). Optional: \`product_name\` (a real product), \`prompt\` (a short steering note),
|
|
896
|
+
\`reference_image_urls\`, \`quality\`. \`dry_run: true\` quotes template sources and reserves
|
|
897
|
+
nothing. A real call GENERATES at once and returns \`{ job_id }\` (\`kind: "ads_batch"\`) and the
|
|
898
|
+
\`batch\`, which already carries its \`links\` (below). If the
|
|
899
|
+
brand's research is still running the batch is \`queued\` and starts on its own when research
|
|
900
|
+
finishes: tell the user it'll appear shortly, don't error.
|
|
901
|
+
- \`job_get { job_id, kind: "ads_batch" }\` — poll a batch. \`status\` is \`queued\`, \`running\`,
|
|
902
|
+
\`complete\`, \`partial_failure\` or \`failed\`; \`progress\` counts \`completed\` / \`failed\` /
|
|
903
|
+
\`pending\` images. \`result.creatives[]\` carry each creative's \`renders[]\` (\`id\`, \`status\`,
|
|
904
|
+
\`ratio\`, \`output_url\`, \`age_seconds\` since queued, \`elapsed_seconds\` generating). A creative
|
|
905
|
+
is done when its \`pending\` is 0, NOT when \`current_render_url\` is set (during a regenerate it
|
|
906
|
+
still points at the prior image). A render only failed when its \`status\` is \`"failed"\`: a slow
|
|
907
|
+
render is healthy, and re-submitting it double-bills. \`result.links\` holds the app links you end
|
|
908
|
+
the run with: \`brand_url\` (the brand's page, with all its ads) and \`creative_links: [{
|
|
909
|
+
project_id, app_url }]\` (each creative's page). \`brand_url\` is \`null\` and the list empty only
|
|
910
|
+
if the link lookup failed; the ads are still made. A server older than this skill returns no
|
|
911
|
+
\`links\` (and no \`app_url\` / \`brand_url\` on creative reads): then hand back the images
|
|
912
|
+
only and don't mention links.
|
|
913
|
+
- \`ads_creative_read { brand_id }\` — the brand's generated creatives, newest first (filter with
|
|
914
|
+
\`batch_id\`, \`tags\`, \`approved_only\`); each row has its \`app_url\` and the list has the
|
|
915
|
+
\`brand_url\`. \`creative_id\` reads one with its \`renders\`, plus \`creative.app_url\` and
|
|
916
|
+
\`creative.brand_url\`.
|
|
917
|
+
- \`ads_template_read\` — find or inspect a source (see "Picking source ads"). \`template_id\` reads one.
|
|
918
|
+
- \`ads_creative_edit { brand_id, creative_id, action }\` — every paid edit of one creative, one
|
|
919
|
+
\`action\` per call: \`regenerate\` (\`regenerate: { mode: "variation" }\` for another take;
|
|
920
|
+
\`mode: "edit"\` or \`"exact"\` with \`source_render_id\` and \`prompt\`), \`precision_edit\` (\`source_render_id\`
|
|
921
|
+
plus a \`note\` or region \`annotations\`), \`resize\` (\`source_render_id\` plus \`platforms\` or
|
|
922
|
+
\`targets\`), \`layerize\` (\`confirmed: true\`), \`animate\` (\`source_image_url\`; only when
|
|
923
|
+
\`account_whoami\` shows the Animate Images feature; for the full flow fetch the \`animate-image\`
|
|
924
|
+
skill). Returns \`{ job_id }\`: poll \`job_get\` with \`kind: "ads_batch"\` (regenerate, resize,
|
|
925
|
+
precision_edit) or \`kind: "animate"\`; for layerize read
|
|
926
|
+
\`ads_creative_read { brand_id, creative_id, include: ["layers"] }\`. While the brand's research is
|
|
927
|
+
still running, \`regenerate\`, \`resize\` and \`precision_edit\` refuse with
|
|
928
|
+
\`brand_research_in_progress\`: tell the user and try again when it finishes.
|
|
929
|
+
- \`ads_creative_update { brand_id, creative_id, patch }\` — free. \`patch.feedback: { render_id, rating:
|
|
930
|
+
"happy" | "neutral" | "sad", comment?, reasons? }\` records the user's reaction (it feeds the
|
|
931
|
+
quality loop); \`patch.tags\` replaces the creative's tags.
|
|
932
|
+
- \`ads_template_create { brand_id, source, rights_attested? }\` — register the user's own image as a
|
|
933
|
+
private source template (see "Upload" below).
|
|
934
|
+
|
|
935
|
+
### Campaigns — the only plan-and-approve path
|
|
936
|
+
|
|
937
|
+
\`ads_generate\` has no plan step: the dry-run quote and the user's yes are the checkpoint, and a
|
|
938
|
+
submit generates at once. Never promise a review step before the images render. Plans exist only
|
|
939
|
+
for a campaign's concepts (planned with \`campaign_read\`, \`campaign_upsert\` and
|
|
940
|
+
\`add_campaign_concept\`; follow the connector guide for those):
|
|
941
|
+
|
|
942
|
+
1. \`request_campaign_generation { campaign_id }\` composes the plans for the concepts with no
|
|
943
|
+
creatives yet (\`concept_ids\` re-runs chosen ones; \`count\` only for a number the user named). It
|
|
944
|
+
spends nothing and returns \`batch_ids\` and \`credits\`. Never say generation has started.
|
|
945
|
+
2. Tell the user what will be made and the credit total, and wait for their explicit yes in this
|
|
946
|
+
chat. Never send them to a button in the app; a campaign link is only a place to look.
|
|
947
|
+
3. Read \`ads_creative_read { brand_id, view: "approvals", batch_id }\` until that batch's plans are
|
|
948
|
+
\`awaiting_approval\` and none is \`composing\`. If its credit total differs from what they
|
|
949
|
+
agreed to, state the new total and ask again.
|
|
950
|
+
4. \`ads_approval_decide { brand_id, decision: "approve", batch_id, user_quote: "<their exact words>" }\`
|
|
951
|
+
for each batch, then poll the batch ids it returns with \`job_get\` (\`kind: "ads_batch"\`) and
|
|
952
|
+
end with each batch's \`result.links\`, as in step 7 of the workflow below.
|
|
953
|
+
|
|
954
|
+
Before approving, a steer is free: \`ads_approval_decide { brand_id, creative_id, decision: "revise",
|
|
955
|
+
revise: { message } }\` recomposes that plan (read the approvals view again), and
|
|
956
|
+
\`decision: "edit_plan"\` patches it directly. Editing the campaign in between discards these plans.
|
|
738
957
|
|
|
739
958
|
## Keep the brand kit in sync — reconcile, then save or propose
|
|
740
959
|
|
|
@@ -767,159 +986,206 @@ ${DURABLE_BRAND_CAPTURE}
|
|
|
767
986
|
## Picking source ads — use approved sources, not the retired catalog
|
|
768
987
|
|
|
769
988
|
When the user wants to make ads but has NOT named a specific template (id/slug/Community
|
|
770
|
-
ad/upload), do NOT silently browse the raw catalog and hand-pick for them. Instead
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
1. **
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
2. **
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
- **
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
\`
|
|
794
|
-
|
|
795
|
-
|
|
989
|
+
ad/upload), do NOT silently browse the raw catalog and hand-pick for them. Instead send **one
|
|
990
|
+
proposal** — it mirrors the web app and keeps the human in the loop without an interview:
|
|
991
|
+
|
|
992
|
+
1. **Propose the direction yourself.** From the brand read and the evidence brief, recommend the
|
|
993
|
+
product, angle/offer and tone, with a one-line reason naming what the Brain showed (a past
|
|
994
|
+
approved angle, a rule it respects). **Do NOT ask what kind of ads they want, which product,
|
|
995
|
+
or the vibe.** Keep any direction the user already gave. This shapes both the source choice
|
|
996
|
+
and your steering \`prompt\`.
|
|
997
|
+
2. **Recommend a source in the same message: their own ads, Community, upload, or "Surprise me".**
|
|
998
|
+
Default to their own approved ads when suitable ones exist, otherwise Surprise-me picks for
|
|
999
|
+
the brand; list the other paths as one-line alternatives. You may resolve the picks and run the
|
|
1000
|
+
free dry run first so the proposal already carries the credit total. Show a list of sources as
|
|
1001
|
+
one table with every row and its image link, and mark your one suggestion.
|
|
1002
|
+
- **Their own ads** → \`ads_template_read { brand_id, mode: "mine", filters: { relationship: "self" } }\`
|
|
1003
|
+
and let them choose. \`mode: "competitor"\` rows are research and inspiration, never proof that
|
|
1004
|
+
the user owns the ad.
|
|
1005
|
+
- **Community** → \`ads_template_read { brand_id, mode: "query", query: "<the angle and look>" }\`
|
|
1006
|
+
ranks Community ads by meaning; each row's \`sourceId\` (with \`title\` and \`thumbnailUrl\`) goes
|
|
1007
|
+
in \`source.community_ad_ids[].community_id\`. To browse the feed instead, use \`mode:
|
|
1008
|
+
"community"\`: its rows carry \`item_type\`, and a \`template\` id goes in \`source.template_ids\`,
|
|
1009
|
+
a \`creative\` id in \`source.community_ad_ids\`. The backend snapshots a Community creative
|
|
1010
|
+
itself; there is no separate step. Let the user choose.
|
|
1011
|
+
- **Upload** → the user's own image becomes a private template: \`media_upload\` it (\`scope:
|
|
1012
|
+
"brand"\`, \`scope_id: <brand_id>\`, \`kind: "image"\`; in a chat app \`source.type: "bytes"\`), then
|
|
1013
|
+
\`ads_template_create { brand_id, source: { type: "media", media_id } }\` (or \`source: { type:
|
|
1014
|
+
"url", url }\` for a public image). Set \`rights_attested: true\` only after the user explicitly
|
|
1015
|
+
confirms they own it; this is the ownership/rights input. Never claim rights for a competitor
|
|
1016
|
+
ad or an image found online.
|
|
1017
|
+
- **Surprise me** (they want you/the app to pick) → \`ads_template_read { brand_id, mode:
|
|
1018
|
+
"surprise", count: 4 }\` picks remixable Community ads for the brand, shuffled so picks stay
|
|
1019
|
+
fresh. Every pick is a template: show them, and generate
|
|
1020
|
+
from the ones the user keeps (or from all of them if they said "just make them").
|
|
1021
|
+
- **Browse in the app** → the one link you build yourself: \`<app>/create?brand=<brand-slug>&cli=true\`,
|
|
1022
|
+
with the active brand's slug, where \`<app>\` is the origin of a \`brand_url\` a tool returned
|
|
1023
|
+
(the part before \`/?brand=\`: \`https://ads-staging.gooseworks.ai/?brand=acme\` gives
|
|
1024
|
+
\`https://ads-staging.gooseworks.ai\`), so it opens on the user's own environment. Reuse a
|
|
1025
|
+
\`brand_url\` you already have from this run, or read one cheaply with
|
|
1026
|
+
\`ads_creative_read { brand_id, limit: 1 }\`; if none comes back, use \`https://make.gooseworks.ai\`.
|
|
1027
|
+
In this mode the app shows a copyable remix prompt at the bottom (dismissable / switchable
|
|
1028
|
+
back to the UI composer). They browse their own and Community sources and copy the prompt.
|
|
796
1029
|
3. **Close the loop.** When the user **pastes back the copyable remix prompt** from the app
|
|
797
1030
|
(it names the brand + the templates they chose), THAT is your cue to generate: resolve the
|
|
798
|
-
named source(s)
|
|
1031
|
+
named source(s) with \`ads_template_read\`, quote, and collect only the unresolved required inputs.
|
|
799
1032
|
|
|
800
1033
|
If the user already named an owned source (id/slug), a Community ad, or an upload, skip the source
|
|
801
1034
|
choice. Competitor ads may inform the angle or structure, but describe them as inspiration, never
|
|
802
|
-
claim ownership, and never attest rights for the user.
|
|
1035
|
+
claim ownership, and never attest rights for the user. Never use the retired curated third-party
|
|
1036
|
+
catalog.
|
|
803
1037
|
|
|
804
1038
|
## Workflow — make ads from a template
|
|
805
1039
|
|
|
806
|
-
1. **Resolve the brand
|
|
807
|
-
selected brand
|
|
808
|
-
|
|
809
|
-
research finishes) — just tell the user. Use the
|
|
810
|
-
\`products
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
1040
|
+
1. **Resolve the brand and its evidence.** List brands with \`brand_read\` (no \`brand_id\`), then
|
|
1041
|
+
read the selected brand's summary, kit, products and
|
|
1042
|
+
learnings and search the Brand Brain as above. If research isn't \`complete\`, you can still
|
|
1043
|
+
submit (the batch queues and runs when research finishes) — just tell the user. Use the read to
|
|
1044
|
+
pick \`product_name\` (a real entry from \`products.items\`, not a guess) and, if the user supplied
|
|
1045
|
+
product photos, \`reference_image_urls\` (public URLs; \`media_upload\` a local file first).
|
|
1046
|
+
2. **Pick the source ad(s) via the proposal above.** Read each chosen template with
|
|
1047
|
+
\`ads_template_read { brand_id, template_id }\`. Community creatives (a query row's \`sourceId\`,
|
|
1048
|
+
a feed row with \`item_type: "creative"\`) and the user's own finished ads go straight into
|
|
1049
|
+
\`source.community_ad_ids\` / \`source.creative_ids\`.
|
|
815
1050
|
3. **(Optional) Craft the steering prompt.** The \`prompt\` is OPTIONAL — this is where the skill
|
|
816
1051
|
adds value: turn the user's intent (from step 1) into a concise steering note (e.g. tone,
|
|
817
1052
|
season, emphasis). Don't over-specify; the backend pipeline + brand kit handle palette, fonts,
|
|
818
1053
|
product swap.
|
|
819
|
-
4. **Quote the cost.**
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
the
|
|
823
|
-
|
|
824
|
-
\`
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
render
|
|
828
|
-
|
|
829
|
-
|
|
1054
|
+
4. **Quote the cost.** Call \`ads_generate\` with the exact arguments you will submit plus
|
|
1055
|
+
\`dry_run: true\` (template sources), or work out the total as in the credits table. Drop or
|
|
1056
|
+
replace anything in \`unknown_template_ids\`. State the image count and credit total in one line
|
|
1057
|
+
and wait for the user's explicit yes.
|
|
1058
|
+
5. **Submit ONE batch** after that yes: the same \`ads_generate\` call without \`dry_run\`. Keep the
|
|
1059
|
+
returned \`job_id\`.
|
|
1060
|
+
6. **Poll until done.** \`job_get { job_id, kind: "ads_batch" }\` every ~20-30s until every creative's
|
|
1061
|
+
\`pending\` is 0. Most images finish in a few minutes; text-heavy templates and \`quality: high\`
|
|
1062
|
+
take longer. Read each render's \`elapsed_seconds\` rather than guessing; do NOT re-submit
|
|
1063
|
+
thinking it stalled (that double-bills). If \`ads_generate\` refused with
|
|
1064
|
+
\`brand_research_required\`, the brand was never researched: run "Brand research" below, then
|
|
1065
|
+
quote and submit again.
|
|
1066
|
+
7. **Hand back the ads with their links.** Show every finished image (\`renders[].output_url\` of
|
|
1067
|
+
completed renders) and say in one line what failed, if anything. Then give the links from the
|
|
1068
|
+
last \`job_get\`'s \`result.links\`, copied verbatim: the \`brand_url\` where all the brand's
|
|
1069
|
+
ads are, and the \`app_url\` of each creative with a finished image (match
|
|
1070
|
+
\`creative_links[].project_id\` to \`result.creatives[].id\`; skip a creative whose renders all
|
|
1071
|
+
failed). For a big batch (more than about 8 creatives) give the \`brand_url\` and offer the
|
|
1072
|
+
rest. Skip a missing or \`null\` link; never build an app URL yourself. Never end on just
|
|
1073
|
+
"done" or a file path.
|
|
830
1074
|
|
|
831
1075
|
## Workflow — edit an existing ad
|
|
832
1076
|
|
|
833
|
-
User wants to tweak a creative they already made →
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
1077
|
+
User wants to tweak a creative they already made → \`ads_creative_edit\`. Read the creative first
|
|
1078
|
+
(\`ads_creative_read { brand_id, creative_id }\`) to get the render they mean. Infer the action
|
|
1079
|
+
from their request: another take (\`regenerate\`, \`mode: "variation"\`), a targeted change
|
|
1080
|
+
(\`regenerate\` with \`mode: "edit"\`, or \`precision_edit\` when they point at a region), an exact
|
|
1081
|
+
instructed change (\`mode: "exact"\`), new placements (\`resize\`), editable layers (\`layerize\`) or a
|
|
1082
|
+
short video (\`animate\`). Ask only for a required source or instruction that is still missing,
|
|
1083
|
+
state the credit total from the credits table, get the yes, submit, poll as above, and hand back
|
|
1084
|
+
the new images with their links: \`result.links\` from \`job_get\` for \`regenerate\`, \`resize\` and
|
|
1085
|
+
\`precision_edit\`; \`creative.app_url\` and \`creative.brand_url\` from \`ads_creative_read { brand_id,
|
|
1086
|
+
creative_id }\` for \`animate\` and \`layerize\`.
|
|
837
1087
|
|
|
838
1088
|
## Brand research
|
|
839
1089
|
|
|
840
|
-
Prefer the backend's result
|
|
841
|
-
\`complete\`, REUSE it — never re-research.
|
|
1090
|
+
Prefer the backend's result. \`brand_read { brand_id, sections: ["summary"] }\`: if
|
|
1091
|
+
\`research_status\` is \`complete\`, REUSE it — never re-research. Proof points and the full product
|
|
1092
|
+
catalog keep arriving until \`enrichment.settled\` is true.
|
|
842
1093
|
|
|
843
1094
|
**The split — backend owns visuals, you own the qualitative depth:**
|
|
844
1095
|
|
|
845
|
-
- **Backend LIGHT pass (automatic).**
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
every fact on the fetched site** — if the site can't be read, say so and ask the user; never
|
|
1096
|
+
- **Backend LIGHT pass (automatic).** A new brand comes from the connector's setup flow
|
|
1097
|
+
(\`brand_onboarding { action: "status" }\`, then its \`next_step\`). For an additional brand, check
|
|
1098
|
+
it is absent (\`brand_read\` with no \`brand_id\`), then \`brand_create { name, website_url }\` (free).
|
|
1099
|
+
The website starts the same backend research the web app uses: it resolves the
|
|
1100
|
+
**authoritative logo, colors, and fonts** plus a baseline kit and returns \`research_job_id\`; poll
|
|
1101
|
+
\`job_get { job_id: research_job_id, kind: "brand_research" }\` (or \`brand_read\`) until
|
|
1102
|
+
\`research_status\` is \`complete\` — usually under a minute. If it returns \`reused_existing: true\`,
|
|
1103
|
+
tell the user and use that brand. You can't reproduce those visual signals, so **never
|
|
1104
|
+
re-derive logo/colors/fonts.**
|
|
1105
|
+
- **Your DEEP pass (optional).** You add the qualitative depth the light pass leaves thin —
|
|
1106
|
+
positioning, audience, voice, brand type, value props, proof points, products — grounded on
|
|
1107
|
+
the actual site.
|
|
1108
|
+
|
|
1109
|
+
**Deep research flow:**
|
|
1110
|
+
|
|
1111
|
+
1. Fetch the \`brand-research\` skill (\`catalog_fetch { type: "skill", slug: "brand-research" }\` in a
|
|
1112
|
+
chat app; \`gooseworks fetch brand-research\` in a terminal) and follow its phases. Its data
|
|
1113
|
+
calls are paid: state the credit total (credits table) and get the yes first. **Ground every
|
|
1114
|
+
fact on the brand's own site** — if the site can't be read, say so and ask the user; never
|
|
865
1115
|
guess a category from the brand name alone.
|
|
866
|
-
|
|
867
|
-
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
1116
|
+
2. **Save what you improved.**
|
|
1117
|
+
- **As proposals (the default):** \`brand_update { brand_id,
|
|
1118
|
+
knowledge_intent: "agent_proposal", rationale, patch: { knowledge: { positioning?, audience?,
|
|
1119
|
+
voice?, brandType?, tagline?, valueProps? } } }\`. They stay pending until the user accepts
|
|
1120
|
+
them in the app.
|
|
1121
|
+
- **As the full research pack (only when you wrote all of it; in a chat app, only for a brand
|
|
1122
|
+
with no website, see below):** with \`file_write\`, under
|
|
1123
|
+
\`agent-config/brands/<slug>/brand-research/\`, write all four docs \`brand-summary.md\`,
|
|
1124
|
+
\`visual-identity.md\`, \`audience.md\` and \`competitors.md\` (real content, at least a few
|
|
1125
|
+
sentences each) plus \`kit-patch.json\`: \`{ positioning?, audience?, voice?, brandType?,
|
|
1126
|
+
tagline?, valueProps?: string[], proofPoints?: [{ text, source_url }], products?: [{ name,
|
|
1127
|
+
description?, link?, pricing?, imageUrls?: string[] }] }\` with only the fields you improved;
|
|
1128
|
+
every proof point copied word for word from the brand's own page at \`source_url\`; product
|
|
1129
|
+
images only from URLs already in GooseWorks storage; **no logo / colors / fonts**. Then
|
|
1130
|
+
\`brand_update { brand_id, patch: { finalize_research: true } }\` merges it NON-CLOBBERINGLY
|
|
1131
|
+
(never over the backend's visuals or a user edit). **If any of the four docs is missing or
|
|
1132
|
+
nearly empty, finalize fails and marks the brand's research as failed**, so never finalize a
|
|
1133
|
+
partial pack.
|
|
1134
|
+
3. **Verify:** \`brand_read\` again (\`summary\`, \`kit\`) and confirm what you saved before generating.
|
|
1135
|
+
|
|
1136
|
+
**If the brand has NO website**, the backend light pass can't run and generation goes ahead with
|
|
1137
|
+
an empty kit, so ads come out off-brand. Do the deep pass from what the user tells you and save the
|
|
1138
|
+
full research pack, so the brand has a kit and a record to debug a wrong run (this is how a bad
|
|
1139
|
+
classification, e.g. mislabelling a SaaS as a "drink company", used to vanish).
|
|
884
1140
|
|
|
885
1141
|
## Analyze / intelligence (fetched recipes — NOT generation)
|
|
886
1142
|
|
|
887
|
-
These are analysis recipes you fetch
|
|
888
|
-
|
|
889
|
-
|
|
1143
|
+
These are analysis recipes you fetch and follow; they don't use the generation tools, but their
|
|
1144
|
+
data calls are paid (credits table: state the total and get the yes before the first one). Fetch with \`catalog_fetch { type: "skill", slug: "<slug>" }\` in a chat app or
|
|
1145
|
+
\`gooseworks fetch <slug>\` in a terminal. Pick the closest match; if unsure, search first with
|
|
1146
|
+
\`catalog_search { type: "skill", query: "<what the user wants>" }\` (terminal:
|
|
1147
|
+
\`gooseworks search "<what the user wants>"\`):
|
|
890
1148
|
- **Campaign performance diagnosis** ("why is my Meta/Google campaign underperforming",
|
|
891
|
-
creative fatigue, learning phase, pacing, auction overlap) → \`
|
|
1149
|
+
creative fatigue, learning phase, pacing, auction overlap) → \`meta-ads-analyzer\`
|
|
892
1150
|
(or \`ad-campaign-analyzer\` for cross-platform).
|
|
893
1151
|
- **Lead/CAC quality** ("are these ads driving qualified leads", true CAC vs vanity CPA,
|
|
894
|
-
Scale/Keep/Investigate/Cut) → \`
|
|
1152
|
+
Scale/Keep/Investigate/Cut) → \`ad-lead-quality-analyzer\`.
|
|
895
1153
|
- **Competitor ad intelligence** ("what ads are competitors running") →
|
|
896
|
-
\`
|
|
897
|
-
|
|
898
|
-
- **
|
|
899
|
-
\`gooseworks fetch trending-ad-hook-spotter\`.
|
|
900
|
-
- **Policy / landing-page checks** → \`gooseworks fetch meta-ad-policy-checker\` /
|
|
901
|
-
\`gooseworks fetch ad-to-landing-page-auditor\`.
|
|
1154
|
+
\`competitor-ad-intelligence\` (Meta Ad Library: \`meta-ad-scraper\`; Google: \`google-ad-scraper\`).
|
|
1155
|
+
- **Creative ideation** (ad angles, winning hooks) → \`ad-angle-miner\` / \`trending-ad-hook-spotter\`.
|
|
1156
|
+
- **Policy / landing-page checks** → \`meta-ad-policy-checker\` / \`ad-to-landing-page-auditor\`.
|
|
902
1157
|
|
|
903
|
-
|
|
904
|
-
|
|
1158
|
+
A recipe's provider calls go through the connector in a chat app (\`data_call_provider\` for GET,
|
|
1159
|
+
\`data_post_provider\` for POST) and through \`gooseworks call\` in a terminal; both are billed. Saving and running
|
|
1160
|
+
its scripts (under \`/tmp/gooseworks-scripts/<slug>/\`) is terminal-only: without a terminal, do
|
|
1161
|
+
that step's analysis yourself from the data the tools return, and never ask the user to run a
|
|
1162
|
+
command.
|
|
905
1163
|
|
|
906
1164
|
## Rules
|
|
907
1165
|
|
|
908
|
-
- **
|
|
909
|
-
|
|
910
|
-
-
|
|
1166
|
+
- **Connector tools only** — every step uses the tool names above. A missing tool means the
|
|
1167
|
+
GooseWorks connection is stale: ask the user to reconnect or refresh GooseWorks. Never send a
|
|
1168
|
+
chat-app user to a terminal or a CLI install.
|
|
1169
|
+
- **One backend workflow** — generation is \`ads_generate\` / \`ads_creative_edit\` ONLY.
|
|
911
1170
|
Do NOT call FAL, the media proxy, \`submit_render\`, \`update_render_status\`, or upload render
|
|
912
|
-
files yourself; do NOT
|
|
913
|
-
- **
|
|
914
|
-
|
|
915
|
-
- **
|
|
916
|
-
|
|
917
|
-
- **
|
|
918
|
-
|
|
919
|
-
\`
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
1171
|
+
files yourself; do NOT fetch a local remix recipe to generate. The backend owns it.
|
|
1172
|
+
- **State the credit total and get an explicit yes before every paid call** (credits table above).
|
|
1173
|
+
Relay \`insufficient_credits\` plainly if the submit is rejected — don't retry blindly.
|
|
1174
|
+
- **No plan step for one-off ads.** Only a campaign's plans wait for approval
|
|
1175
|
+
(\`request_campaign_generation\` → \`ads_approval_decide\` with the user's words as \`user_quote\`).
|
|
1176
|
+
- **Always end a successful run with the finished images and their links**, copied verbatim:
|
|
1177
|
+
each creative's \`app_url\` and the \`brand_url\` from \`result.links\`, or from the creative
|
|
1178
|
+
read (\`creative.app_url\`, \`creative.brand_url\`) after \`animate\` or \`layerize\`. When the
|
|
1179
|
+
server returns no links, end with the images only. Never end on just "done" or a file path, and
|
|
1180
|
+
never build an app URL yourself (the one exception is the browse link below).
|
|
1181
|
+
- **Search the Brain before proposing.** After the brand read and before choosing an angle,
|
|
1182
|
+
claim or source — or asking for a brand fact — run the task's \`knowledge_search\` and carry
|
|
1183
|
+
its evidence brief. A failed or empty search is stated as such, never as "no evidence exists".
|
|
1184
|
+
- **Use approved source paths.** If the user didn't name a source, recommend one in the single
|
|
1185
|
+
proposal (own ads, Community, upload, Surprise me, or browse in the app). Surprise me is
|
|
1186
|
+
\`ads_template_read\` with \`mode: "surprise"\`; browsing uses \`/create?brand=<slug>&cli=true\`.
|
|
1187
|
+
Never use the retired curated third-party catalog. Generate when they paste the app's copyable
|
|
1188
|
+
remix prompt back, or when they accept the surprise picks.
|
|
923
1189
|
- **Treat competitor ads as inspiration** — never attest rights, imply ownership, or promise to
|
|
924
1190
|
copy a competitor's distinctive expression.
|
|
925
1191
|
- **Reconcile brand facts into the kit** — when the user states or changes something brand-level
|
|
@@ -927,17 +1193,15 @@ run through the \`gooseworks\` CLI (\`gooseworks fetch\` / \`gooseworks call\`),
|
|
|
927
1193
|
\`brand_update\` with correction intent and the user's exact statement, or the user's own
|
|
928
1194
|
images through \`media_upload\`; read back before saying saved. Proposed improvements stay
|
|
929
1195
|
pending. Ask only when it is unclear whether a one-ad direction should apply to future ads.
|
|
930
|
-
- **Record feedback** — when the user reacts to a generated image,
|
|
931
|
-
\`
|
|
932
|
-
- **
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
call the **\`log_cli_event\`** MCP tool (\`event_type\`: \`error\`/\`blocker\`/\`missing_input\`/\`confusion\`,
|
|
940
|
-
with the real error + step in \`details\`) so the team gets visibility. Still tell the user too.
|
|
1196
|
+
- **Record feedback** — when the user reacts to a generated image, call \`ads_creative_update\`
|
|
1197
|
+
with \`patch.feedback\` so the quality loop learns.
|
|
1198
|
+
- **Don't busy-loop** — poll \`job_get\` on a sensible interval (~20-30s); a \`queued\` batch is
|
|
1199
|
+
waiting on research and will start on its own.
|
|
1200
|
+
- **Report problems so we can fix them** — when a batch fails or is rejected and you can't resolve
|
|
1201
|
+
it, a required brand input/asset is missing, or an instruction is ambiguous or contradictory:
|
|
1202
|
+
in a terminal run \`gooseworks log "<what happened>" --event-type <error|blocker|missing_input|confusion> --details '<json with the real error and step>'\`,
|
|
1203
|
+
or call the \`log_cli_event\` tool if your connection lists it. A chat app without either skips
|
|
1204
|
+
this step. Always tell the user too.
|
|
941
1205
|
`;
|
|
942
1206
|
}
|
|
943
1207
|
/** Card-aware video entry. Shell execution and widget display are independent. */
|
|
@@ -951,7 +1215,7 @@ description: >
|
|
|
951
1215
|
goose-video-local; a chat host hands the same project to the GooseWorks coworker. Review
|
|
952
1216
|
one complete template plan and total credits before production. Custom videos retain two authenticated review gates in this chat.
|
|
953
1217
|
category: ads
|
|
954
|
-
version: 3.0.
|
|
1218
|
+
version: 3.0.5
|
|
955
1219
|
author: GooseWorks
|
|
956
1220
|
tags: [gooseworks, ads, video, local-render, coworker, chat]
|
|
957
1221
|
---
|
|
@@ -972,9 +1236,82 @@ and \`available_here\`, never a guess from the host's name. Template-remix revie
|
|
|
972
1236
|
chat. Custom videos use separate authenticated script and ingredient approvals in this same chat.
|
|
973
1237
|
Studio is an optional review surface.
|
|
974
1238
|
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1239
|
+
${videoEntryPreparation('goose-video')}
|
|
1240
|
+
|
|
1241
|
+
## Custom videos: check formats first
|
|
1242
|
+
|
|
1243
|
+
First check the catalog: when the brief names or implies a listed format (for example a street interview, testimonial, podcast or chat video), show that format and its fit through the format flow below, including its support status. Go custom only when no format fits and the customer chooses custom after hearing why; custom keeps that format's hard constraints. For an original brief without a reference template, an Instagram reel/post URL or a direct video URL to study, fetch \`catalog_fetch { type: "skill", slug: "make-custom-video" }\` and follow it in this same session. It creates format:"custom", custom_mode:"generate" with the brief and optional reference_url. Growth executes in its managed sandbox; connected agents use their shell. Script and actual ingredients are reviewed and separately approved in the same chat before paid production; Studio is optional. Do not force a template that does not fit or that the customer declined, and do not import the reference as a finished video.
|
|
1244
|
+
|
|
1245
|
+
## Run the format's route check before proposing it
|
|
1246
|
+
|
|
1247
|
+
A catalog row says what a format is best for and ranks it for the brand. It does not say whether
|
|
1248
|
+
the format can make the setup the customer asked for (how many people, mic only, no product).
|
|
1249
|
+
Some renderers declare a route selector that decides that; today that is the street interview
|
|
1250
|
+
(\`render-street-interview\`). Before you propose, script or create a street-interview project,
|
|
1251
|
+
template or custom, check the request against its routes:
|
|
1252
|
+
|
|
1253
|
+
| Street route | On screen | Needs | Makes |
|
|
1254
|
+
| --- | --- | --- | --- |
|
|
1255
|
+
| Guessing (\`product-guess\`) | Interviewer and up to four people | A physical product to hand over, photographed on its own | A finished video |
|
|
1256
|
+
| Conversation (\`mic-only\`, \`product-sample\`, \`concept-challenge\`) | Interviewer and one person | No product photo, phone, screen or UI | A script and prompt preview only, no finished video yet |
|
|
1257
|
+
| Street testimonial (its own format) | One person talking to camera, no interviewer | The creator still its recipe prescribes | A finished video, when the catalog lists it |
|
|
1258
|
+
|
|
1259
|
+
Neither interview route takes a photo of a person: people are described in text, so never
|
|
1260
|
+
propose putting a founder's or creator's face in one. Keep the customer's named setup: never
|
|
1261
|
+
change the interaction, mode or number of people just to make a check pass.
|
|
1262
|
+
|
|
1263
|
+
- **Without a shell** (a chat host), decide from this table. Do not fetch the renderer: its
|
|
1264
|
+
package is far too large for a chat.
|
|
1265
|
+
- **With a shell** (the customer's computer or the coworker sandbox), also run its free
|
|
1266
|
+
selector, which makes no paid call. If the fetch or the run fails, decide from the table.
|
|
1267
|
+
1. Fetch the renderer to a file, not into the conversation: its inline package is over a
|
|
1268
|
+
million characters. Either save the JSON from \`gooseworks fetch render-street-interview > <file.json>\`,
|
|
1269
|
+
then write each \`scripts\` entry as
|
|
1270
|
+
\`/tmp/gooseworks-scripts/render-street-interview/scripts/<name>\` and each \`files\` entry at
|
|
1271
|
+
\`/tmp/gooseworks-scripts/render-street-interview/<path>\`. Or call
|
|
1272
|
+
\`catalog_fetch { type: "skill", slug: "render-street-interview", delivery: "archive" }\`,
|
|
1273
|
+
extract the ZIP, check each file against its \`manifest.json\` hashes and copy the contents of its
|
|
1274
|
+
\`agent-config/skills/render-street-interview/\` folder into
|
|
1275
|
+
\`/tmp/gooseworks-scripts/render-street-interview/\`. Either way the selector reads
|
|
1276
|
+
\`references/street-reference-library.json\` from that folder.
|
|
1277
|
+
2. Write a brief JSON. \`mode\` and \`interaction_type\` go in pairs: \`product-guess\` with
|
|
1278
|
+
\`product-guess\`, or \`conversation\` with \`mic-only\`, \`product-sample\` or \`concept-challenge\`.
|
|
1279
|
+
\`offering_type\` is exactly \`physical\`, \`service\` or \`digital\` (software, SaaS and apps are
|
|
1280
|
+
\`digital\`). \`participants\` is a whole number: people interviewed on screen, not counting
|
|
1281
|
+
the interviewer. Leave it out when the customer named no count; the selector then uses the
|
|
1282
|
+
route's usual cast. When the customer named no interaction, run each mode that could fit.
|
|
1283
|
+
3. Run \`python3 /tmp/gooseworks-scripts/render-street-interview/scripts/prepare_script_context.py --brief <brief.json> --out <context.json>\`.
|
|
1284
|
+
Read \`status\` and \`brief_gaps\` in the output file, not the exit code: it exits 2 for every
|
|
1285
|
+
status except \`ready-for-writing\`. A Python traceback is not a verdict: the brief or the
|
|
1286
|
+
saved files are wrong (for example the reference library in the wrong folder). Fix them and
|
|
1287
|
+
run it again.
|
|
1288
|
+
4. A run with any \`brief_gaps\` has not checked the route. Fix every gap and run it again.
|
|
1289
|
+
|
|
1290
|
+
**An unsupported setup is a stop.** \`unsupported-route\`, or a request the table rules out,
|
|
1291
|
+
means this setup can't be made. Tell the customer plainly, in one line, for example: "A
|
|
1292
|
+
three-person mic-only street interview isn't something we can make yet: that version takes one
|
|
1293
|
+
person, and the three-person version needs a physical product to hand over." Then offer the
|
|
1294
|
+
closest supported options in plain words, each with how it differs. With a shell, these are the
|
|
1295
|
+
selector's \`alternatives\`. Without one, take them from the table:
|
|
1296
|
+
|
|
1297
|
+
- when only the number of people was the problem, the same setup within its limit: guessing
|
|
1298
|
+
(a physical product only) with up to four people, a finished video; or a conversation with
|
|
1299
|
+
one person, a script preview only;
|
|
1300
|
+
- for something people can't hold (software, a service), a one-person conversation instead
|
|
1301
|
+
of guessing;
|
|
1302
|
+
- one person talking to camera with no interviewer, if the catalog lists that format;
|
|
1303
|
+
- a custom video, untested, that keeps the street format's limits.
|
|
1304
|
+
|
|
1305
|
+
Never use route names or the script's wording. Do not create the project or write a script for
|
|
1306
|
+
it. Go custom only if the customer picks it; a custom video keeps the street format's hard
|
|
1307
|
+
constraints, which make-custom-video lists.
|
|
1308
|
+
|
|
1309
|
+
**A supported setup.** With empty \`brief_gaps\`, any other status means the route exists.
|
|
1310
|
+
\`needs-reference\` means no observed reference ad matched yet: it does not block proposing the
|
|
1311
|
+
format; carry it into the handoff so the script step resolves or reports it before script
|
|
1312
|
+
approval. Carry the route too: which one, how many people, finished video or preview only, and
|
|
1313
|
+
no person photos. A preview-only route makes a script and prompt preview, not a finished video:
|
|
1314
|
+
say so before the customer chooses it.
|
|
978
1315
|
|
|
979
1316
|
## Route first: is this a new video?
|
|
980
1317
|
|
|
@@ -984,9 +1321,10 @@ Hand off to **\`goose-video-local\`** now, and stop following this skill, for:
|
|
|
984
1321
|
- the app's copy-for-Claude command (it names \`goose-video-local\`);
|
|
985
1322
|
- "remix this video ad template" for a specific app template.
|
|
986
1323
|
|
|
987
|
-
|
|
1324
|
+
Load the current \`goose-video-local\` entry with
|
|
988
1325
|
\`catalog_fetch { type: "skill", slug: "goose-video-local" }\` on the GooseWorks MCP (older clients:
|
|
989
|
-
\`fetch_skill("goose-video-local")\`)
|
|
1326
|
+
\`fetch_skill("goose-video-local")\`), unless already fetched on this connection in this run.
|
|
1327
|
+
It reads the project first and retains an approved run's recorded recipe packages.
|
|
990
1328
|
|
|
991
1329
|
When they ask **what** to make ("give me video ad ideas", "what angles should I use?", "what's
|
|
992
1330
|
working for my competitors?"), fetch **\`ad-angle-miner\`** (\`catalog_fetch { type: "skill", slug: "ad-angle-miner" }\`,
|
|
@@ -1042,14 +1380,15 @@ bypass setup. Keep the original request.
|
|
|
1042
1380
|
### 2. Keep the goal and propose defaults
|
|
1043
1381
|
|
|
1044
1382
|
Never ask what the ad is for before showing formats. Keep the customer's exact direction.
|
|
1045
|
-
Otherwise propose defaults from the verified kit's products, audience, offer and voice
|
|
1046
|
-
|
|
1383
|
+
Otherwise propose defaults from the verified kit's products, audience, offer and voice and the
|
|
1384
|
+
Brain search's evidence brief (proven angles, saved rules, approved claims). Show those defaults
|
|
1385
|
+
in the saved plan so any can be changed. Never invent proof or product facts.
|
|
1047
1386
|
Idea requests still follow ad-angle-miner with the video output.
|
|
1048
1387
|
|
|
1049
1388
|
### 3. Show the picker or its text fallback
|
|
1050
1389
|
|
|
1051
1390
|
Call \`video_catalog_list { kind: "formats", brand_id }\`. On the customer's computer, when you
|
|
1052
|
-
can actually execute shell commands, include \`client: { shell: true }\`; in a chat host omit
|
|
1391
|
+
can actually execute shell commands, you MUST choose local execution and include \`client: { shell: true }\`; in a chat host omit
|
|
1053
1392
|
that claim. Inside a coworker sandbox follow its reported capabilities, never claim to be the
|
|
1054
1393
|
customer's computer. Respect requested limit and next_cursor for more item pages; the card may
|
|
1055
1394
|
contain a full picker independently of the item page.
|
|
@@ -1061,6 +1400,9 @@ contain a full picker independently of the item page.
|
|
|
1061
1400
|
Write "no demo yet" when absent. Never put links only in a question control.
|
|
1062
1401
|
- A format whose card contradicts what they asked for is never Suggested. Never offer
|
|
1063
1402
|
available_here:false as an executable choice. Relay not_available_here in one short line.
|
|
1403
|
+
- \`suggested\` ranks a row for the brand; it never means the row makes the setup they named.
|
|
1404
|
+
Never tell the customer a row is "exactly" what they asked for beyond what its card says. A
|
|
1405
|
+
street interview still needs the route check above first.
|
|
1064
1406
|
- Missing required assets are missing; unknown suitability is “needs review.” Inspect the
|
|
1065
1407
|
selected format's candidates before spending. Never promise an unverified asset is ready.
|
|
1066
1408
|
- Template formats use **one plan, one approval with the total in credits**, not approval for
|
|
@@ -1072,7 +1414,7 @@ contain a full picker independently of the item page.
|
|
|
1072
1414
|
Never tell a chat host it needs Claude Code to start. Browser-only formats remain unavailable
|
|
1073
1415
|
here; give computer setup guidance only if asked how to make one.
|
|
1074
1416
|
- **Local shell:** run \`gooseworks doctor --no-browser\` for common setup (auth/MCP, Node 18+,
|
|
1075
|
-
ffmpeg with libx264
|
|
1417
|
+
ffmpeg with libx264 (libass only for an ASS caption route), ffprobe). Then fetch the selected template and its capabilities,
|
|
1076
1418
|
and install documented dependencies in its fetched folder. Do not guess a renderer from a
|
|
1077
1419
|
format name. For each Node renderer using default Playwright Chromium, run
|
|
1078
1420
|
\`gooseworks doctor --renderer-script "/absolute/path/to/the/fetched/scripts/record.js"\` with
|
|
@@ -1088,7 +1430,8 @@ contain a full picker independently of the item page.
|
|
|
1088
1430
|
### 5. Create the project and hand it off, in this session
|
|
1089
1431
|
|
|
1090
1432
|
1. \`video_project_upsert { brand_id, name, format: <template_id> }\` with no brief (a brief creates
|
|
1091
|
-
a concept batch).
|
|
1433
|
+
a concept batch). A street interview is created only after its route check found a supported
|
|
1434
|
+
setup. Include client:{shell:true} only for real local execution. Default
|
|
1092
1435
|
creation_intent:"format" keeps the style with this brand's content; source_remix requires an
|
|
1093
1436
|
explicit choice to use source content.
|
|
1094
1437
|
If they already chose a campaign/concept, include its verified campaign_id and optional
|
|
@@ -1096,9 +1439,10 @@ contain a full picker independently of the item page.
|
|
|
1096
1439
|
to it. Omit unknown IDs and never infer a link or create a campaign solely to file a video.
|
|
1097
1440
|
2. **Verified local shell or coworker sandbox:** load
|
|
1098
1441
|
\`catalog_fetch { type: "skill", slug: "goose-video-local" }\` and follow it on the same project_id.
|
|
1099
|
-
Carry the customer's words, verified defaults, campaign
|
|
1442
|
+
Carry the customer's words, verified defaults, campaign, selected angle and a street
|
|
1443
|
+
interview's route check result into its brief.
|
|
1100
1444
|
3. **Chat host:** \`goose_run_task { brand_id, project_id, message }\` with the request, selected
|
|
1101
|
-
format and
|
|
1445
|
+
format, defaults and a street interview's route check result. Keep task_id. Continue questions/edits with the same task and project.
|
|
1102
1446
|
A saved free draft is not a started worker or a complete plan. Follow actual saved state.
|
|
1103
1447
|
4. When follow.card_follows is true, the card follows progress: do not re-read it in a loop.
|
|
1104
1448
|
Read again on a customer reply, card action or requested update. A failure or missing saved
|
|
@@ -1177,7 +1521,7 @@ description: >
|
|
|
1177
1521
|
video_project_read. A hosted connector with no shell hands this same project to the GooseWorks coworker. To start a NEW video ad in chat,
|
|
1178
1522
|
use goose-video first.
|
|
1179
1523
|
category: ads
|
|
1180
|
-
version: 0.6.
|
|
1524
|
+
version: 0.6.7
|
|
1181
1525
|
author: GooseWorks
|
|
1182
1526
|
tags: [gooseworks, ads, video, remix, imessage, podcast, ugc, local-render, sandbox, byoa]
|
|
1183
1527
|
---
|
|
@@ -1186,6 +1530,8 @@ tags: [gooseworks, ads, video, remix, imessage, podcast, ugc, local-render, sand
|
|
|
1186
1530
|
|
|
1187
1531
|
${CUSTOMER_TALK}
|
|
1188
1532
|
|
|
1533
|
+
${videoEntryPreparation('goose-video-local')}
|
|
1534
|
+
|
|
1189
1535
|
## Chat hosts and cards
|
|
1190
1536
|
|
|
1191
1537
|
First perform the mandatory route check below. Then, without a shell, hand a verified template
|
|
@@ -1406,7 +1752,7 @@ the skill. It's fire-and-forget, never counts against you, and never blocks your
|
|
|
1406
1752
|
1. **Sandbox →** see "Running in a GooseWorks sandbox": ffmpeg + ffprobe (+ PIL on demand); no
|
|
1407
1753
|
Chromium, so browser formats stop there.
|
|
1408
1754
|
2. **CLI present →** run \`gooseworks doctor --no-browser\` for login, MCP, Node 18+, ffmpeg
|
|
1409
|
-
with libx264
|
|
1755
|
+
with libx264, and ffprobe. Require libass only for a selected ASS caption route; caption-burn uses Pillow overlays and does not need it. This is common setup only. After fetching the selected
|
|
1410
1756
|
capabilities in Step 2, check each browser renderer's actual launch before ANY paid
|
|
1411
1757
|
ingredient. An unscoped \`gooseworks doctor\` checks only the calling folder's browser;
|
|
1412
1758
|
it cannot certify a different fetched renderer.
|
|
@@ -1643,7 +1989,7 @@ the app's "N concepts" flow: one composer submission fans out into **N independe
|
|
|
1643
1989
|
**Loop shape (ONE approval for the batch, isolated work per concept):**
|
|
1644
1990
|
1. Run **Step 1 + Step 1.5 + Step 2 + Step 2.5 + Step 3-assemble** for EACH concept project (each
|
|
1645
1991
|
has its own \`project_id\`, brief, \`GW_PROJECT_ID\` and \`working/\` folder — never cross-write
|
|
1646
|
-
between concepts). The brand read (Step 1 item
|
|
1992
|
+
between concepts). The brand read (Step 1 item 2) and \`brand-rules.json\` (Step 1.7) are per
|
|
1647
1993
|
BRAND: do them once for the batch and copy the file into each concept's \`working/\`. The read is
|
|
1648
1994
|
~90K characters. Step 2.5's angle bank is shared per brand AND product: load or build it once, and
|
|
1649
1995
|
give every concept whose angle is \`auto\` a DIFFERENT angle from that list, so the batch is N
|
|
@@ -1686,8 +2032,8 @@ written per-project; a batch just runs it N times with the shared approval gate
|
|
|
1686
2032
|
|
|
1687
2033
|
The composer already collected the user's creative direction onto the project. **Read it and treat
|
|
1688
2034
|
it as ground truth — it OVERRIDES the template recipe's defaults, and it REPLACES the clarifying
|
|
1689
|
-
questions you would otherwise ask.**
|
|
1690
|
-
|
|
2035
|
+
questions you would otherwise ask.** For a field the brief leaves empty, use the Brain search's
|
|
2036
|
+
evidence brief first, then the recipe default, then (last) asking. Map the fields you WILL honor:
|
|
1691
2037
|
|
|
1692
2038
|
- \`creative_brief.productName\` / \`.offer\` / \`.angle\` → the product, offer/code, and angle. Do
|
|
1693
2039
|
**not** ask "which product / what offer / what angle" if these are set.
|
|
@@ -1705,20 +2051,24 @@ for a field the brief leaves empty. Map the fields you WILL honor:
|
|
|
1705
2051
|
"also 1:1" option included).
|
|
1706
2052
|
- \`polish_policy\` (\`standard\` | \`extra\`) → \`extra\` means spend the extra pass on QC/polish.
|
|
1707
2053
|
|
|
1708
|
-
2. \`
|
|
1709
|
-
\`recipe\`, \`format\` (e.g. "podcast-skit", "imessage"), \`extracted_script\`, \`how_to\`, \`remix_spec\`.
|
|
1710
|
-
3. Brand gate: \`brand_read { brand_id, sections: ["summary", "kit", "products", "learnings"] }\`
|
|
2054
|
+
2. Brand gate: \`brand_read { brand_id, sections: ["summary", "kit", "products", "learnings"] }\`
|
|
1711
2055
|
(older clients: \`brand_get_context\` with the same sections). Ask for all four: the default
|
|
1712
2056
|
leaves out the kit and the brand's saved rules, and a video made without them is off-brand.
|
|
1713
2057
|
If the kit's \`researchStatus\` (or the brand's \`research_status\`) is \`complete\`, REUSE it —
|
|
1714
|
-
never re-research.
|
|
1715
|
-
|
|
2058
|
+
never re-research. A pending status alone does not require research; use verified stored
|
|
2059
|
+
facts and ask only for an actual gap. If the context is empty or the customer requests
|
|
2060
|
+
research, load \`catalog_fetch { type: "skill", slug:
|
|
2061
|
+
"brand-research" }\` and follow its stored-pack workflow. Only when that verified pack is
|
|
1716
2062
|
saved in the supported research workspace, finalize with
|
|
1717
2063
|
\`brand_update { brand_id, patch: { finalize_research: true } }\`, then read the brand back.
|
|
1718
2064
|
Never send raw research JSON through \`kit_patch\`: the public tool accepts only the existing
|
|
1719
2065
|
\`video_lab\` asset slot there. If there is no verified stored pack, submit researched facts
|
|
1720
2066
|
through typed \`patch.knowledge\` / \`patch.kit\` as pending agent proposals; do not pretend
|
|
1721
2067
|
research is finalized or its proposals are approved. Then do Step 1.7 with verified facts.
|
|
2068
|
+
3. For a new plan, \`catalog_fetch { type: "template", slug: <source_sample_id> }\` → the source
|
|
2069
|
+
video: \`media_url\`, \`recipe\`, \`format\` (e.g. "podcast-skit", "imessage"),
|
|
2070
|
+
\`extracted_script\`, \`how_to\`, \`remix_spec\`. For an approved resume, restore the recorded
|
|
2071
|
+
package and dependencies instead of fetching today's recipe over the saved plan.
|
|
1722
2072
|
|
|
1723
2073
|
### Step 1.6 — a remix of a FINISHED video (the project read has a \`remix\` block)
|
|
1724
2074
|
|
|
@@ -1747,8 +2097,9 @@ Its \`video_project_read\` returns a top-level \`remix\` block
|
|
|
1747
2097
|
|
|
1748
2098
|
### Step 1.7 — the brand rules file and the brand assets (every run, before any writing)
|
|
1749
2099
|
|
|
1750
|
-
|
|
1751
|
-
|
|
2100
|
+
Before new writing, write \`working/brand-rules.json\` from the Step 1 brand read. Preserve an
|
|
2101
|
+
approved run's saved rules on resume; reconcile an intentional rule change through the existing
|
|
2102
|
+
review gate. Every later step reads THIS file, not your memory of the chat:
|
|
1752
2103
|
|
|
1753
2104
|
\`\`\`json
|
|
1754
2105
|
{
|
|
@@ -1902,7 +2253,16 @@ of ad performance. The existing Step 3 review and approval remain unchanged.
|
|
|
1902
2253
|
evidence and proof plan, not only its hook. Reuse the shared video-angle-bank.v1 from
|
|
1903
2254
|
the brand's video-scripts workspace or this run. Prepare angle-context.json with the
|
|
1904
2255
|
writer's preparation script with \`--brief working/script/creative-brief.json\` and use
|
|
1905
|
-
its strict rule check before review.
|
|
2256
|
+
its strict rule check before review. First run the fetched writer's free
|
|
2257
|
+
\`python3 <saved-writer-package>/scripts/verify_handoff.py --package-dir <saved-writer-package> --out working/script/writer-handoff-check.json\` check against those
|
|
2258
|
+
actual saved prepare/lint scripts. Retain the result and script hashes with the run.
|
|
2259
|
+
A provided writer package with a missing checker, failed check or unsupported flag
|
|
2260
|
+
is incompatible: stop this handoff and refresh the package on the same connection.
|
|
2261
|
+
Never use the provisional agent path after a provided package fails validation.
|
|
2262
|
+
Only an actual \`not_found\` for an optional writer permits the explicit provisional
|
|
2263
|
+
agent check below; a required writer remains blocked. Never silently remove the brief,
|
|
2264
|
+
strict check or new shape requirement to run an older parser.
|
|
2265
|
+
Save the sourced brief in the writer's documented
|
|
1906
2266
|
shape: exact product/variant, buyer situation, supported mechanism, offer/CTA, constraints,
|
|
1907
2267
|
delivery intent, source references, locked copy, applicable prior decisions and unknowns.
|
|
1908
2268
|
New custom/template shapes set \`requires_creative_brief: true\`; both writer and critic
|
|
@@ -1917,16 +2277,20 @@ of ad performance. The existing Step 3 review and approval remain unchanged.
|
|
|
1917
2277
|
a catalogue card alone cannot establish fit. An impossible essential visual blocks
|
|
1918
2278
|
the proposal until repaired. Do not force a testimonial into every format.
|
|
1919
2279
|
- **Research only what is missing.** Fetching the miner does not spend or rerun research.
|
|
1920
|
-
Reuse current facts and prior evidence.
|
|
2280
|
+
Reuse current facts and prior evidence. The Brain search's evidence brief (citations, the
|
|
2281
|
+
state of each query and open gaps) is the first source for the brief's source references and
|
|
2282
|
+
prior decisions. If paid collection is needed, its permission
|
|
1921
2283
|
rides in the existing choices round. A new product with no reviews can use verified
|
|
1922
2284
|
facts and a feasible demo; do not require paid research merely to fill a quote quota.
|
|
1923
2285
|
- **Choose eligible concepts only.** Take the strongest supported concept and validated
|
|
1924
2286
|
hook into review, with up to two viable alternatives when the direction is open.
|
|
1925
2287
|
Do not pad three concepts or select the highest-ranked rejected one. If all fail,
|
|
1926
2288
|
repair within the brief and recipe before Step 3.
|
|
1927
|
-
- **
|
|
1928
|
-
|
|
1929
|
-
|
|
2289
|
+
- **Optional writer not found or unavailable research.** Only when the optional writer
|
|
2290
|
+
returns \`not_found\`, complete an explicit agent check of claim support, recipe limits,
|
|
2291
|
+
visual feasibility and hook payoff. Record missing provenance and say in the review when
|
|
2292
|
+
research is provisional. A provided incompatible writer or another fetch error stops
|
|
2293
|
+
the handoff. Never report a failed check as a pass.
|
|
1930
2294
|
- **The user's exact lines** remain verbatim; use report-only checks and raise material
|
|
1931
2295
|
timing, claim or format conflicts without silently rewriting them.
|
|
1932
2296
|
- **No spoken words.** Still fit the visual promise, reveal, cards and CTA to the silent
|
|
@@ -1938,9 +2302,14 @@ of ad performance. The existing Step 3 review and approval remain unchanged.
|
|
|
1938
2302
|
|
|
1939
2303
|
Fetch \`video-production-harness\` and read its \`references/editorial-review.md\`,
|
|
1940
2304
|
\`references/specialist-handoff.md\` and \`references/hook-compatibility.md\`, plus the
|
|
1941
|
-
review/edit/polish/promote/wrap steps when used.
|
|
1942
|
-
|
|
1943
|
-
|
|
2305
|
+
review/edit/polish/promote/wrap steps when used. Verify every named file is returned as
|
|
2306
|
+
nonempty text before relying on that package. A version/content hash alone cannot establish
|
|
2307
|
+
that the required guides were published. Missing guides block new template creative work
|
|
2308
|
+
before project writes or paid previews; resolve the package on this same connection. Keep
|
|
2309
|
+
an unchanged approved resume on its recorded package and approvals.
|
|
2310
|
+
Save the fetched version/content hash with this run's capability records. These supply
|
|
2311
|
+
craft and evidence rules inside the template flow; this entry's existing review, paid
|
|
2312
|
+
approval, storage and two-repair limit still apply.
|
|
1944
2313
|
Do not turn a template into a custom project or import the custom host's extra gates.
|
|
1945
2314
|
|
|
1946
2315
|
Before executing a fetched recipe atom, pass the exact brief/script revision, scene/beat IDs,
|
|
@@ -2069,8 +2438,25 @@ ingredient here is only a genuinely separate SOURCE clip the format needs (e.g.
|
|
|
2069
2438
|
about start / blocked / complete.
|
|
2070
2439
|
After EVERY progress callback inspect stop. If true, start no new paid step; record
|
|
2071
2440
|
status:"stopped" with a plain note and report what is kept and credits used. SPEND_CAP_REACHED
|
|
2072
|
-
stops the same way
|
|
2073
|
-
|
|
2441
|
+
stops the same way. Never raise a video's budget on your own judgment. Raise it only when a paid
|
|
2442
|
+
step was refused with SPEND_CAP_REACHED or the progress card offers "Finish it" or a choice past the budget.
|
|
2443
|
+
Then read the project and say cost.raise_quote in one line: "Finishing needs up to <by_credits>
|
|
2444
|
+
more credits, so your budget goes from <from_credits> to <to_credits>. OK?" Only after the
|
|
2445
|
+
customer's yes to that number: patch.approve { scope:"raise_cap", total_credits: <to_credits>,
|
|
2446
|
+
user_quote: "<their exact words>" }. total_credits is the new budget itself, never credits to
|
|
2447
|
+
add; do not send raise_cap_credits for one video. If they pick a smaller choice past the
|
|
2448
|
+
budget, send that choice's new budget as total_credits (never above to_credits). Sending the same
|
|
2449
|
+
total_credits again changes nothing (already_raised: carry on). An earlier yes, or "I don't care
|
|
2450
|
+
about the cost", is not approval of a new budget. If cost.raise_quote is null because the plan was saved
|
|
2451
|
+
again since its approval (plan_status is not "approved"), show the plan with its total and
|
|
2452
|
+
approve it again; otherwise the approved budget already covers the work: carry on, do not ask.
|
|
2453
|
+
After a raise, open a new render that reuses the saved pieces. A refused raise changes nothing:
|
|
2454
|
+
cap_raise_not_needed means carry on within the budget, or, when it says the plan was saved again,
|
|
2455
|
+
show the plan with its total and approve the plan again; cap_raise_total_required means read the
|
|
2456
|
+
project again and send total_credits equal to cost.raise_quote.to_credits after the customer
|
|
2457
|
+
approves that number; cap_raise_changed or cap_raise_too_large mean read the project again and
|
|
2458
|
+
show the current cost.raise_quote. Custom videos never use raise_cap.
|
|
2459
|
+
Send render.steps with the same neutral names each time and a live count only in the
|
|
2074
2460
|
current detail; use render.choices when blocked.
|
|
2075
2461
|
2. Now generate every PAID piece you showed as a prompt in Step 3 — the AI stills/video, lipsync
|
|
2076
2462
|
clips, voice, music — through the media proxies (below), each from its approved prompt, with
|
|
@@ -2398,6 +2784,10 @@ ${STORED_FOOTAGE_GUIDANCE}`;
|
|
|
2398
2784
|
* never regenerated it and `install` / `update` / login-refresh never wrote or
|
|
2399
2785
|
* refreshed it on a user's machine. Moving the body here makes the registry the
|
|
2400
2786
|
* one source: one command emits all four entry skills.
|
|
2787
|
+
*
|
|
2788
|
+
* QA-26 / VWR14: chat apps fetch it with `catalog_fetch`, so it names only the
|
|
2789
|
+
* tools the connector lists (`photos_generate` / `photos_read` / `photos_update`,
|
|
2790
|
+
* `brand_read`, `brand_update`, `job_get`).
|
|
2401
2791
|
*/
|
|
2402
2792
|
function getGooseProductPhotosSkillContent() {
|
|
2403
2793
|
return `---
|
|
@@ -2413,7 +2803,7 @@ description: >
|
|
|
2413
2803
|
references a product to photograph. Unlike goose-ads (ad creative) this produces clean PRODUCT
|
|
2414
2804
|
photos that can then feed the ad workflow.
|
|
2415
2805
|
category: ads
|
|
2416
|
-
version: 0.
|
|
2806
|
+
version: 0.3.0
|
|
2417
2807
|
author: GooseWorks
|
|
2418
2808
|
tags: [gooseworks, ads, product-photos, photoshoot, product, ecommerce, studio, lifestyle, on-model]
|
|
2419
2809
|
---
|
|
@@ -2421,28 +2811,29 @@ tags: [gooseworks, ads, product-photos, photoshoot, product, ecommerce, studio,
|
|
|
2421
2811
|
# GooseWorks Product Photos — branded product photography
|
|
2422
2812
|
|
|
2423
2813
|
The GooseWorks Product Photos skill. You **pick a brand + product and submit one generation**;
|
|
2424
|
-
the **backend** runs the whole pipeline (compose the shot prompt → generate
|
|
2425
|
-
|
|
2814
|
+
the **backend** runs the whole pipeline (compose the shot prompt → generate → judge for product
|
|
2815
|
+
fidelity → auto-retry a few times for free) and stores the results. You do NOT
|
|
2426
2816
|
generate images, call a model, or manage files — this is the exact same workflow the Product
|
|
2427
2817
|
Photos studio uses, so the skill and the app can never drift. The point is to **enrich a brand's
|
|
2428
2818
|
usable product imagery** — approved photos join the brand kit and can then feed the ad workflow
|
|
2429
2819
|
(\`goose-ads\`).
|
|
2430
2820
|
|
|
2431
|
-
|
|
2821
|
+
It shoots a **physical catalog product** (apparel, beauty, consumer goods). A software
|
|
2822
|
+
screenshot or an app mockup is not a product photo: that is an image edit, not this skill.
|
|
2432
2823
|
|
|
2433
|
-
|
|
2824
|
+
${CUSTOMER_TALK}
|
|
2434
2825
|
|
|
2435
|
-
|
|
2436
|
-
tell the user to run \`gooseworks install --claude --mcp\`** (and restart Claude Code). There is no
|
|
2437
|
-
HTTP/file fallback.
|
|
2826
|
+
${connectorPrerequisite('photos_generate')}
|
|
2438
2827
|
|
|
2439
2828
|
## Start from the brand context — don't re-ask what it already answers
|
|
2440
2829
|
|
|
2441
2830
|
If the \`gooseworks\` router handed you brand context, USE IT. If you were invoked directly, call
|
|
2442
|
-
\`brand_read
|
|
2443
|
-
the user for
|
|
2831
|
+
\`brand_read { brand_id, sections: ["summary","kit","products","learnings"] }\` yourself first, then
|
|
2832
|
+
\`knowledge_search { brand_id, query: "<the shoot, in the user's words>" }\` for saved rules and past
|
|
2833
|
+
feedback (an archived photo's reason is saved as a \`dont\` rule). They answer most of the setup
|
|
2834
|
+
questions below, so **do not ask the user for them**:
|
|
2444
2835
|
|
|
2445
|
-
- **Which product?** — the context's \`products
|
|
2836
|
+
- **Which product?** — the context's \`products\` are the real catalog entries. Offer them; never
|
|
2446
2837
|
invent a product or ask the user to describe one you can already see.
|
|
2447
2838
|
- **What does it look like / what is it made of?** — grounded in the product's stored images and
|
|
2448
2839
|
description. Never guess a material, colorway, or silhouette.
|
|
@@ -2454,79 +2845,90 @@ the user for them**:
|
|
|
2454
2845
|
Ask only for the genuinely open choices: the shot \`category\`, how many photos, quality, and
|
|
2455
2846
|
whether a human model is wanted (which needs explicit consent — see the rules).
|
|
2456
2847
|
|
|
2457
|
-
##
|
|
2848
|
+
## Credits — state the total, then get a yes
|
|
2458
2849
|
|
|
2459
|
-
- One
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2850
|
+
- One token authenticates the tools and resolves your org; never print it. Omit \`target\`.
|
|
2851
|
+
- **Quote first.** Call \`photos_generate\` with the exact arguments you will submit plus
|
|
2852
|
+
\`dry_run: true\`. It reserves nothing and returns \`creditsPerOutput\` and \`totalCredits\`. Pass
|
|
2853
|
+
\`count\` and \`quality\` explicitly in both calls so the quote matches the run.
|
|
2854
|
+
- **Nothing paid runs without the user's explicit yes in this chat, given after you state that
|
|
2855
|
+
credit total.** Then submit the same call without \`dry_run\`.
|
|
2856
|
+
- The submit reserves the quoted credits and bills only the photos that pass the judge:
|
|
2857
|
+
**automatic retries are free**, and a photo the judge can't get right (\`flagged\`) is shown but
|
|
2858
|
+
**never billed**. The balance is \`credits.available_credits\` from \`account_whoami\`. If the
|
|
2859
|
+
wallet is short, say so plainly with the total and the balance, and stop.
|
|
2466
2860
|
|
|
2467
2861
|
## The tools
|
|
2468
2862
|
|
|
2469
2863
|
**Pick the brand + product**
|
|
2470
|
-
- \`
|
|
2471
|
-
- \`
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2864
|
+
- \`brand_read\` with no \`brand_id\` — the user's brands (each row's \`id\` is the \`brand_id\`).
|
|
2865
|
+
- \`brand_read { brand_id, sections: ["products"], products_query: "<name>" }\` — the brand's
|
|
2866
|
+
imported products in \`products.items\`; a product's \`id\` is the \`product_id\` to shoot.
|
|
2867
|
+
\`products_query\` matches name / type / variant / SKU / description.
|
|
2868
|
+
- Import a product that isn't in the catalog yet (free):
|
|
2869
|
+
\`brand_update { brand_id, patch: { products: [{ import_url, import_kind, name? }] } }\`.
|
|
2870
|
+
\`import_kind\` is \`product_url\` (a single product page), \`shopify_store\` (a store URL → imports
|
|
2871
|
+
the catalog), or \`image_url\` (a direct image; also needs \`name\`). It returns \`jobs[]\`: poll
|
|
2872
|
+
\`job_get { job_id, kind: "product_import" }\` until it finishes, then read the products again.
|
|
2873
|
+
To add a photo the user attached to an existing product:
|
|
2874
|
+
\`media_upload { brand_id, scope: "product", scope_id: <product_id>, kind: "reference", source: { type: "bytes", filename, content_base64 } }\`.
|
|
2479
2875
|
|
|
2480
2876
|
**Generate**
|
|
2481
|
-
- \`
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
\`get_product_photo_generation\` until done, then read each \`outputs[].final_image_url\`.
|
|
2877
|
+
- \`photos_generate { brand_id, product_id, variant_id?, category, controls?, prompt?, count,
|
|
2878
|
+
quality, reference_image_urls?, attestation_accepted?, dry_run? }\` — **the one call that makes
|
|
2879
|
+
photos** (and, with \`dry_run: true\`, its free quote). \`category\` is \`apparel\` | \`beauty\` |
|
|
2880
|
+
\`cpg\` (seeds sensible scene/framing defaults). \`count\` is 1, 2, 4, or 8; \`quality\` is
|
|
2881
|
+
\`low\` | \`medium\` | \`high\`. Omit \`controls\` to use the category preset; pass \`prompt\` as
|
|
2882
|
+
free-text steering **added on top of** the settings (it doesn't replace them). Returns the
|
|
2883
|
+
generation with its \`id\` **immediately**.
|
|
2489
2884
|
**If you request a human model** (\`controls.model.presence\` is not \`none\`) you MUST pass
|
|
2490
2885
|
\`attestation_accepted: true\` to confirm the user has the rights for model imagery.
|
|
2491
|
-
- \`
|
|
2492
|
-
\`partial_failure\`, or \`failed
|
|
2886
|
+
- \`photos_read { brand_id, generation_id }\` — poll until \`status\` is \`complete\`,
|
|
2887
|
+
\`partial_failure\`, or \`failed\` (\`job_get { job_id: <generation id>, kind: "photo_generation" }\`
|
|
2888
|
+
works too). Each \`outputs[]\` entry has its own \`id\`, \`status\` and, once ready, a
|
|
2493
2889
|
\`final_image_url\`. A \`flagged\` output is the best attempt but wasn't billed.
|
|
2494
2890
|
|
|
2495
2891
|
**Use the results**
|
|
2496
|
-
- \`
|
|
2497
|
-
= active, \`true\` = archived).
|
|
2498
|
-
- \`
|
|
2499
|
-
available in the **brand kit**, so \`goose-ads\` can use it. **Photos are
|
|
2500
|
-
approved.**
|
|
2501
|
-
- \`
|
|
2502
|
-
from ad generation.
|
|
2892
|
+
- \`photos_read { brand_id, archived?, product_id?, status? }\` — the brand's generated photos
|
|
2893
|
+
(\`archived: false\` = active, \`true\` = archived).
|
|
2894
|
+
- \`photos_update { brand_id, output_id, action: "approve" }\` — approve a photo: links it to the
|
|
2895
|
+
product and makes it available in the **brand kit**, so \`goose-ads\` can use it. **Photos are
|
|
2896
|
+
not used anywhere until approved.**
|
|
2897
|
+
- \`photos_update { brand_id, output_id, action: "archive", reason? }\` — archive a photo; archived
|
|
2898
|
+
photos are **excluded** from ad generation, and the reason is saved as a \`dont\` rule.
|
|
2503
2899
|
|
|
2504
2900
|
## Workflow — shoot a product
|
|
2505
2901
|
|
|
2506
|
-
1. **Load the brand context** (\`brand_read\`, or reuse what the router passed
|
|
2507
|
-
**resolve the brand + product.** \`
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2902
|
+
1. **Load the brand context** (\`brand_read\` + \`knowledge_search\`, or reuse what the router passed
|
|
2903
|
+
you) and **resolve the brand + product.** Pick a \`product_id\` from the catalog you already
|
|
2904
|
+
know about. If the product genuinely isn't there, import it and poll the import.
|
|
2905
|
+
2. **Quote the cost.** \`photos_generate\` with \`dry_run: true\` and the exact \`brand_id\`,
|
|
2906
|
+
\`product_id\`, \`category\`, \`count\` and \`quality\` → tell the user the credit total and wait
|
|
2907
|
+
for their explicit yes.
|
|
2908
|
+
3. **Generate.** The same \`photos_generate\` call without \`dry_run\` (add \`prompt\` built from the
|
|
2909
|
+
brand's voice/positioning you already have — don't interview the user for it). Returns a
|
|
2910
|
+
generation \`id\` right away.
|
|
2911
|
+
4. **Poll.** \`photos_read { brand_id, generation_id }\` every ~20-30s until terminal; show each
|
|
2515
2912
|
\`final_image_url\`.
|
|
2516
|
-
5. **Approve the keepers.** Show the results and let the user pick; \`
|
|
2517
|
-
they'd publish (that's what puts them in the brand kit for ads),
|
|
2913
|
+
5. **Approve the keepers.** Show the results and let the user pick; \`photos_update\` with
|
|
2914
|
+
\`action: "approve"\` the ones they'd publish (that's what puts them in the brand kit for ads),
|
|
2915
|
+
\`action: "archive"\` the rest.
|
|
2518
2916
|
|
|
2519
2917
|
## Rules
|
|
2520
2918
|
|
|
2919
|
+
- **Connector tools only** — a missing tool means the GooseWorks connection is stale: ask the
|
|
2920
|
+
user to reconnect or refresh GooseWorks. Never send a chat-app user to a terminal or a CLI
|
|
2921
|
+
install.
|
|
2521
2922
|
- **Never invent product facts.** The backend grounds the shot on the product's real images; don't
|
|
2522
2923
|
describe a product you can't see.
|
|
2523
2924
|
- **Use the brand context instead of interviewing the user.** Product, audience, voice, positioning,
|
|
2524
2925
|
logo/colors/fonts all come from \`brand_read\` / the brand kit. Ask only for the shot
|
|
2525
2926
|
category, count, quality, and model consent.
|
|
2526
|
-
- **Ask before spending.**
|
|
2527
|
-
\`
|
|
2927
|
+
- **Ask before spending.** State the dry-run credit total and get the user's explicit yes before
|
|
2928
|
+
the real \`photos_generate\` — it reserves credits.
|
|
2528
2929
|
- **Poll, don't re-submit.** A generation that's still \`running\` is not stuck; re-submitting
|
|
2529
|
-
double-bills.
|
|
2930
|
+
double-bills. A \`failed\` generation may still hold \`flagged\` photos (shown, never billed):
|
|
2931
|
+
show those first, and run again only after a new quote and the user's yes.
|
|
2530
2932
|
- **Model imagery needs consent.** Only set a human model when the user asks, and pass
|
|
2531
2933
|
\`attestation_accepted: true\`.
|
|
2532
2934
|
- **Approval is the hand-off to ads.** Remind the user that only **approved** photos reach the brand
|
|
@@ -2535,6 +2937,6 @@ whether a human model is wanted (which needs explicit consent — see the rules)
|
|
|
2535
2937
|
}
|
|
2536
2938
|
/** Thin GooseWorks connection to the catalog-published production harness. */
|
|
2537
2939
|
function getMakeCustomVideoSkillContent() {
|
|
2538
|
-
return custom_video_skill_1.CUSTOM_VIDEO_ADAPTER_CONTENT.replace("\n# Agent version\n", `\n# Agent version\n\n${CUSTOMER_TALK}\n\n${ENVIRONMENT_IDENTITY}\n\n${ASSET_READINESS}\n`) + STORED_FOOTAGE_GUIDANCE;
|
|
2940
|
+
return custom_video_skill_1.CUSTOM_VIDEO_ADAPTER_CONTENT.replace("\n# Agent version\n", `\n# Agent version\n\n${CUSTOMER_TALK}\n\n${videoEntryPreparation('make-custom-video')}\n\n${ENVIRONMENT_IDENTITY}\n\n${ASSET_READINESS}\n`) + STORED_FOOTAGE_GUIDANCE;
|
|
2539
2941
|
}
|
|
2540
2942
|
//# sourceMappingURL=master-skill.js.map
|