Skip to content
Worix
BrowsePublish
Log inSign Up

task-content-publish

Multi-step TASK — creating and publishing marketing content. Enter when: the merchant asks for a Shopify blog article, an Instagram post, or a Facebook post; the merchant asks to revise or reformat a piece that is not published yet. Do NOT enter: greetings or small talk; a question about existing Brand Voice, Audiences, Style Guide, or a status/list, with no request to create content; setting up, auto-generating, calibrating, or re-scanning Brand IQ (that is task-brand-iq-setup); asking for a content plan or schedule covering a period rather than one piece (that is task-calendar-plan); asking for a promotion plan, campaign ideas or marketing strategy for a period (that is task-promo-plan); asking to change a setting, connect or disconnect a channel, or edit their account (they do that themselves in the Setting Hub); asking how something already published performed — views, clicks, conversions, which piece did best — even when the question contains the word post or article, provided the message does not also ask for a piece to be made (write, draft, make, create, generate one); that is a data question answered directly. Read this skill's full body BEFORE your first action — it carries the node graph you must report progress against, one node at a time.

0 downloads
Free
Reviewed
internal
task
marketing
requires-yepai-tools

Generated from tasks/content-publish/task.yaml by /task-authoring.

Do not edit here — edit the definition and regenerate.

name: task-content-publish description: >- Multi-step TASK — creating and publishing marketing content. Enter when: the merchant asks for a Shopify blog article, an Instagram post, or a Facebook post; the merchant asks to revise or reformat a piece that is not published yet. Do NOT enter: greetings or small talk; a question about existing Brand Voice, Audiences, Style Guide, or a status/list, with no request to create content; setting up, auto-generating, calibrating, or re-scanning Brand IQ (that is task-brand-iq-setup); asking for a content plan or schedule covering a period rather than one piece (that is task-calendar-plan); asking for a promotion plan, campaign ideas or marketing strategy for a period (that is task-promo-plan); asking to change a setting, connect or disconnect a channel, or edit their account (they do that themselves in the Setting Hub); asking how something already published performed — views, clicks, conversions, which piece did best — even when the question contains the word post or article, provided the message does not also ask for a piece to be made (write, draft, make, create, generate one); that is a data question answered directly. Read this skill's full body BEFORE your first action — it carries the node graph you must report progress against, one node at a time. kind: task task_name: "Content creation & publishing" label_template: "<topic> content" nodes:

  • id: brief label: Setting up the brief purpose: Collect format, focus (category and at least one specific featured product), keywords, and the campaign decision for one piece — always via the Quick setup card, whatever the merchant's message holds, including a field it leaves out or fills with a placeholder like [product] — and then STOP, because raising the card ends the turn and the merchant's picks arrive as their next message. advance_by: user expects:
    • content format(s)
    • a category and at least one specific featured product
    • target keywords
    • the campaign decision (attach one, or explicitly none) tools:
    • yepairag_marketing__REQUEST_CONTENT_BRIEF
    • yepairag_marketing__SHOPIFY_GET_PRODUCTS_SUMMARY
    • yepairag_marketing__GET_TRENDING_KEYWORDS
    • yepairag_marketing__CREATE_CAMPAIGN_PROPOSAL
    • yepairag_marketing__SHOPIFY_GET_COLLECTIONS_SUMMARY next:
    • to: keywords when: the merchant submitted the Quick setup card
  • id: keywords label: Settling your keywords purpose: Take the keywords and hashtags the merchant picked on the card exactly as they are, sort them to the channel each belongs to, and settle the per-channel set with the data behind it — the review card is what shows it to the merchant. advance_by: agent tools:
    • yepairag_share__BRAND_IQ_GET
    • yepairag_marketing__GET_TRENDING_KEYWORDS
    • yepairag_marketing__GET_CHANNEL_KEYWORD_CANDIDATES next:
    • to: research when: the per-channel keyword set is settled
  • id: research label: Researching your products and market purpose: Ground the piece in the real catalog and, if useful, current market/web signals for the chosen focus and keywords. advance_by: agent tools:
    • yepairag_marketing__SHOPIFY_GET_PRODUCTS_SUMMARY
    • yepairag_marketing__SHOPIFY_SEARCH_PRODUCTS
    • yepairag_marketing__GOOGLE_SEARCH next:
    • to: compose when: the featured products and any needed research are in hand
  • id: compose label: Writing your content and its picture purpose: Write one piece per requested channel, each from that channel's own writer skill, in the merchant's brand voice and grounded in the real catalog, and PUT EACH ONE IN A CREATE_CONTENT_DRAFT CALL — that call is the only thing that makes a piece exist; text written into the reply reaches nobody, cannot be reviewed, published or found again, and leaves the server's own placeholders unfilled. The words go in the call first, and the hero image is drawn for them inside that same call. advance_by: agent artifact: type: content_draft route: marketing-hub/draft tools:
    • yepairag_marketing__CREATE_CONTENT_DRAFT next:
    • to: illustrate when: a draft has been created for every requested format AND the merchant asked for the picture to change as well — a new piece's hero is already drawn with its draft
    • to: preview when: a draft has been created for every requested format and its hero image is on the cards (the draft result says so) OR the result says it could not be drawn (hero_image not_drawn — an imageless draft is legal and the merchant reviews it as it is), or a rewrite of the words that keeps the picture it had
  • id: preview label: Waiting for your review purpose: Let the merchant review the draft(s) and either approve publishing or ask for a change, asking them once what to change when the request is too vague to act on. advance_by: user tools: [] route: marketing-hub/draft next:
    • to: brief when: the merchant wants a different subject altogether, a NEW separate piece, or chose to have the Quick setup card reopened to redo this piece's brief
    • to: publish when: the merchant approved publishing and named the channel(s)
    • to: compose when: the merchant asks to change the words of this piece, or to add a channel to it, and neither the picture nor the keywords are what they named
    • to: illustrate when: the merchant asks to change the picture itself and the words are fine
    • to: keywords when: the merchant names the keywords or hashtags themselves as the thing to change
  • id: publish label: Publishing your content purpose: Publish the approved draft to each named channel — in chat by signalling the app's deterministic path, headless by the publish tools — and close from the outcomes those paths record in the merchant's Published tab themselves. advance_by: agent artifact: type: published_content route: marketing-hub/draft revisable: false tools:
    • yepairag_marketing__REQUEST_PUBLISH_EXECUTION
    • yepairag_marketing__SHOPIFY_LIST_BLOGS
    • yepairag_marketing__SHOPIFY_CREATE_ARTICLE
    • yepairag_marketing__PUBLISH_CONTENT next:
    • to: publish when: a channel failed and the merchant asks to retry that channel
  • id: illustrate label: Changing the picture purpose: Change the picture of a piece that already has one — editing the image it has, or drawing a new one when they reject the composition outright — and draw the picture a piece is MISSING when its draft answered not_drawn and the merchant wants one. A new piece's hero is otherwise drawn with its draft, not here. advance_by: agent tools:
    • yepairag_marketing__GENERATE_IMAGE
    • yepairag_marketing__EDIT_IMAGE next:
    • to: preview when: the picture was edited or regenerated — it lands on every card of this piece by itself — or there was nothing to change here, or the change failed and the merchant has been told tags: [internal, task, marketing, requires-yepai-tools] license: MIT-0

Task — Content creation & publishing

Flow

flowchart TD
    brief("Setting up the brief")
    keywords["Settling your keywords"]
    research["Researching your products and market"]
    illustrate["Changing the picture"]
    compose["Writing your content and its picture"]
    preview("Waiting for your review")
    publish["Publishing your content"]

    brief --> keywords
    keywords --> research
    research --> compose
    compose --> preview
    compose -.-> illustrate
    illustrate --> preview
    preview --> publish
    preview -.-> compose
    preview -.-> illustrate
    preview -.-> keywords
    preview -.-> brief
    publish -.-> publish

    classDef terminal stroke-width:3px
    class publish terminal

Rounded = waiting on the merchant · square = you are working · dashed = going back or retrying · bold border = terminal.

brief

Setting up the brief — Collect format, focus (category and at least one specific featured product), keywords, and the campaign decision for one piece — always via the Quick setup card, whatever the merchant's message holds, including a field it leaves out or fills with a placeholder like [product] — and then STOP, because raising the card ends the turn and the merchant's picks arrive as their next message.

  • Report the brief node FIRST, before any other tool call this turn — including before REQUEST_CONTENT_BRIEF. The report is what opens the run; do not call REQUEST_CONTENT_BRIEF (or anything else) ahead of it.
  • A change to the piece already on screen is NOT a new piece, and must not re-enter this node. "Change the hero image to a plain white background", "swap the photo", "make it shorter", "use a different title", "keep the copy but change the picture" are all edits to the draft the merchant is looking at. Route straight to the node that owns what they named — illustrate for the picture, compose for the words, keywords for the terms — and leave the brief untouched: same subject, same products, same campaign. Only a piece that does not exist yet starts here.
  • The signal is a change verb aimed at something only the current draft has. change / swap / replace / redo / make it, pointed at its image, its title, its length, its tone. That is an edit, however the sentence is phrased — "change the hero image to a plain white background, keep every word of the copy" included. Re-collecting a brief for an edit turns it into a whole new piece on another subject while the thing they asked about never changes; there is nothing to collect.
  • The first content request in a chat, and every request for a NEW standalone piece, must go through this node from the start — even a similar topic, even a bare "write another one" counts as new. Re-enter this node and call REQUEST_CONTENT_BRIEF again; never carry the previous piece's category, products, keywords, or campaign into a new one.
  • The card is the only way to collect the four brief fields (format, focus, keywords, campaign), and it is raised for EVERY new piece, whatever the merchant's message holds — all four fields, some, none, or a placeholder such as [product] or [topic]. Both directions end at the card: a message that states everything is still not a submitted card, and a field the message leaves out, blurs or fills with a placeholder is exactly what the card is for, never a reason to ask first. So never skip REQUEST_CONTENT_BRIEF on the strength of what they typed, never ask for any of the four in prose instead — not even "which product?" — and never hold this node open on a question of your own. On the turn that raises the card, it is also your whole reply: add NO prose — no "I've opened the Quick setup card", no list of what it collects, no "once you're done I'll write" — the card asks for everything itself and the app hides any text you add to that turn. (A turn that leaves an ALREADY open card standing — case 4 of the next rule — is the opposite case: there prose IS the answer.)
  • Once the card is up, the merchant's next message is exactly one of four things — decide which, in this order. An unsubmitted card never blocks a new one: only case 4 keeps the merchant on it.
    1. The submitted card. Its picks are the settled brief — full stop, and that includes the subject: the piece is about the card's category and featured products, so a [topic] or a vague subject left in the merchant's original message is not a question still open. Do NOT compare them back against the merchant's original bare request or flag any apparent mismatch (different product, different category than first mentioned): the card supersedes it by design, submitting it is the merchant's confirmation. Move straight into keywords on what the card returned; never re-confirm a submitted card's picks in any form.
    2. Any content request — whatever its format or platform, and whether or not it looks like the piece the open card is for: another piece ("Write a social post for my product"), the same request again ("Write a blog post about my product" while a blog card waits), or a change to what the open card collects — a topic/focus change ("actually make it about scarves"), a keyword, any partial or redirecting reply. Report brief again and raise a NEW card, REQUEST_CONTENT_BRIEF with the format_hint the request names, as for any new piece; the merchant sets their new wishes on it. The unsubmitted card lapses and the app hides it, so never mention it, never say it is still open, and never ask them to finish it first.
    3. A request another task-* description's Enter when matches — a monthly content calendar (task-calendar-plan), a promotion plan (task-promo-plan) — or a data or advice question. Enter that task or answer the question exactly as if no card were open; the unsubmitted card lapses, and the merchant is never asked to submit or close it first.
    4. A question about the card itself, or small talk — what a field means, how to fill it in, a thank-you. Only here does the card stay: do NOT call REQUEST_CONTENT_BRIEF again. Report the brief node again (you are staying where you were, not moving), answer in prose, and point the merchant back at the still-open card to finish filling it in. Only once a card is submitted does this node's exit condition fire.
  • The channels you write for are exactly three: Shopify blog article, Instagram post, Facebook post. Never offer, and never write from, anything else — in particular do not offer "Email newsletter" or "Product description rewrite". If the merchant asks for one via "something else", say it cannot be published or applied from here; the words, if they still want them, go in your reply as plain text, outside this task.
  • The featured-products field requires at least one specific product — a category alone does not satisfy this node's exit condition.
  • A campaign that came from the CARD is already live — you do not create it. The card creates the discount in Shopify when the merchant submits it, and the brief then names the live code together with its per-channel codes (WINTERSALE10-IG and so on). Do NOT call CREATE_CAMPAIGN_PROPOSAL for it; pass the code and its per-channel codes into CREATE_CONTENT_DRAFT's campaign argument as given.
  • When the merchant asks for a discount in CHAT and no card has been submitted, open the card — do not create the discount yourself. Call REQUEST_CONTENT_BRIEF and let them fill in the campaign section; that path creates the real discount and its per-channel codes together, which is the only way an Instagram caption can be attributed. Reserve CREATE_CAMPAIGN_PROPOSAL for the case where they stated every field outright (name, code, amount, scope, dates) and reopening the card would be asking them to type it twice — and even then, it creates a REAL, live discount the moment it succeeds, so never describe the result as a proposal, pending, or awaiting approval.
  • A date the merchant did not give is a date you leave out. When you do call CREATE_CAMPAIGN_PROPOSAL, omit starts_at/ends_at entirely unless the merchant named a window — omitted means "starts now, never expires", which is what someone who did not name one meant. Never infer a window from the month, from the publish schedule, or from anything else: an invented window can close before the first post it promotes goes out, and the tool refuses a window that has already closed, so inventing one costs the merchant their campaign, not merely its accuracy.
  • Never print a discount code that no tool has confirmed exists. A code you composed, or one carried over from a campaign that was only discussed, is refused at checkout for every shopper who types it — and CREATE_CONTENT_DRAFT refuses the draft rather than publishing one.
  • Once this node's exit condition is met and you move on, do not return to it to re-collect the same piece's brief. REQUEST_CONTENT_BRIEF opens one card per piece — once a piece's card is submitted, the only second card it ever gets is the reopen the merchant chooses at preview, called with reopen_for_revision: true (an unsubmitted card is no such limit: a content request replaces it, case 2 above); a single turn must never contain both this node's card call and any tool from compose or illustrate.
  • Raising the card ends your turn. There is nothing left to do in it: no research, no product pull, no draft. The merchant's picks arrive as their next message and the work starts there. The server holds you to this — CREATE_CONTENT_DRAFT refuses, and saves nothing, while the card you opened is unanswered — and a refusal is not something to work around: stop the turn. A draft in that turn is a whole article written from guesses, and the app hides a brief card in a turn that also produced a piece, so the merchant never even sees the card.

keywords

Settling your keywords — Take the keywords and hashtags the merchant picked on the card exactly as they are, sort them to the channel each belongs to, and settle the per-channel set with the data behind it — the review card is what shows it to the merchant.

  • The merchant already picked their keywords and hashtags on the card, and the brief hands them to you ALREADY SPLIT — one row per channel. Your job is not to sort them: it is to use each channel's own row and nothing else. A blog is written on the SEO terms under the blog's row; an Instagram post carries the hashtags under Instagram's row (a literal #, never %). Never move a word from one row to another — a blog's SEO term is not an Instagram hashtag, and printing it as one is the merchant's brand making a claim they never made. Never drop one they chose, never quietly swap one for something with more volume, and never top a row up to some count you think looks right.
  • Keywords serve the piece; they do not choose its subject. The subject is the featured products and the angle the merchant asked for. A settled keyword the merchant did not type themselves — a default the card pre-filled — is a discoverability hook to weave in, never a brief to write to; compose says how. A misfit is never a reason to look for a replacement: the SET stays exactly as settled — never re-open the candidates, never swap. What a misfit loses is its place in the COPY, not its place in the set: a pre-filled term the products cannot honestly carry (medicaid on a snowboard piece) stays on the card with its figure and stays OUT of the prose — compose owns that call. There is no contradiction between "keep their keywords" and "never keep one that does not fit", and nothing to settle by calling the candidates tool again: keep it in the set, judge it for the copy.
  • A channel whose row is empty gets nothing. Not a word inferred from the copy, the products, the season — and not a word borrowed from another channel's row, which is the way this rule actually gets broken. An empty row is a real answer and it is the merchant's answer: hashtags are theirs to choose, and a tag you added is a claim about their brand that they never made.
  • An empty BLOG row is no exception: the article is written without SEO terms. Brand IQ and high-ranking Google terms are what the card offered as defaults; once the merchant cleared them, they stay cleared — and they are never a way to manufacture hashtags.
  • Read seo-keywords before settling them: it carries where each channel's words come from, how the merchant sees them, and what to do when the merchant asks to change them. Read it, do not work from memory of it.
  • The card's defaults were applied before the merchant saw it. Whatever row you receive — filled, edited or emptied — is theirs: never fill it or write over it, not on a later turn and not when a better candidate appears.
  • The candidates arrive already ranked, and that ranking carries signals you cannot see (their own store's history among them). So take the order you were given: do not re-sort it, do not substitute your own idea of the strongest term, and quote each candidate's figure as it came back.
  • Brand IQ's product keywords are read-only here. Never write back to them, and never keep a second copy of the list.
  • The settled set needs no prose line: it rides the review card with its figures, and the turn that lands the drafts hides any text anyway. Name the set out loud only in a turn that ends WITHOUT a draft (the merchant asked about the terms) — one line, not a section, never a question. The numbers come from ONE GET_CHANNEL_KEYWORD_CANDIDATES call for the piece's channels. A pick that call did not return has no number and goes in without one: the same call again returns the same list, and from the third time the server refuses it.

research

Researching your products and market — Ground the piece in the real catalog and, if useful, current market/web signals for the chosen focus and keywords.

compose

Writing your content and its picture — Write one piece per requested channel, each from that channel's own writer skill, in the merchant's brand voice and grounded in the real catalog, and PUT EACH ONE IN A CREATE_CONTENT_DRAFT CALL — that call is the only thing that makes a piece exist; text written into the reply reaches nobody, cannot be reviewed, published or found again, and leaves the server's own placeholders unfilled. The words go in the call first, and the hero image is drawn for them inside that same call.

  • The article does not exist until CREATE_CONTENT_DRAFT returns. Writing it in your reply is not writing it. The body, the title, the meta description, the markers — all of them are ARGUMENTS to that call, never message text. A piece that goes into the reply instead reaches nobody: no card, nothing to publish, nothing saved, and the server's placeholders — [[IMAGE: …]], (product:<handle>) — left as raw text. Having written the piece in your head is not the step. Making the call is the step — and if a call fails, the piece still does not exist: fix the arguments and call again in the same turn.
  • Every CREATE_CONTENT_DRAFT carries hero_scene: one or two sentences of scene direction for this piece's picture — the situation, place or activity the copy is about, plus light, angle and mood ("a rider carving a groomed run at dusk, the board graphics catching the last light"). The server draws the hero WITH the draft, from your scene plus the piece's title, opening and the real product photos, and puts it on every card of the piece. Write the SCENE, not a product shot and not a summary of the article — what the scene does not say, the picture will not show (a halfpipe review whose scene never says halfpipe gets no halfpipe). Write it in clear English even when the conversation is in another language; it improves what comes back. Never ask for text, logos, event marks or flags — the product's own graphics are the only branding allowed. On the piece's SECOND format pass the same hero_scene or leave it out; the picture is drawn once and the second card picks it up.
  • Create exactly the formats the merchant chose in brief — no extras, none dropped. Two formats means exactly two CREATE_CONTENT_DRAFT calls, never more; before each call, check you have not already drafted that format this turn. The list is theirs and it is closed. It is the card's ticked formats, or the channels their message named — nothing else joins it, and a channel they ruled out ("blog only", "no Instagram") stays out no matter how well it would round the piece off. Say the list to yourself before each call and check this format is on it; a piece nobody asked for still lands in their pool for them to review and delete.
  • All featured products for this piece go into the same single draft per format — never a separate draft per product.
  • The piece is about the merchant's products; the keywords are how it gets found, not what it is about. Every draft is built around the featured products — what they are, who they are for, why this merchant's — and the settled keywords are woven into that story where they fit (title / H2 / hashtags, per the channel's writer skill). Never let a keyword set the subject. When a keyword and the products do not meet — an event term against an everyday product — the products win: a keyword that still has an honest hook gets AT MOST the frame (a hook, one sentence of context, a hashtag), and a pre-filled default the products cannot honestly carry at all (medicaid on snowboards) is left out of the copy entirely — hashtag form included — while staying in the settled set on the card, where the merchant can see and change it. Never force a hook or a tag for form's sake; a term the merchant TYPED themselves always keeps its place (that is their claim to make). If the merchant's own request named an angle ("for beginners", "for the holidays"), that angle is the piece's; the card's picks say WHAT to feature, not what to say about it.
  • A blog article marks where its in-body pictures go; a social post never does. Inside a Shopify blog body, put [[IMAGE: <scene in English>]] on its own line at up to 3 natural section breaks where a section genuinely benefits — none when the merchant said no in-body images — and the server draws each one and places it for you — see writer-blog. Never write an <img> tag or a URL: you do not have the address, and neither the draft result nor any other tool will ever give you one. Rewriting the article? Its markers come BACK to you in the draft result — keep them where they are and the pictures stay as they are. Instagram and Facebook captions carry no markers at all; their one picture is the hero, attached to the card.
  • The draft brings its own picture — do not call GENERATE_IMAGE here. The hero is drawn inside CREATE_CONTENT_DRAFT, from your hero_scene, for the copy that call is filing, and it lands on every card of this piece by itself. A separate image call here makes a second picture that belongs to nothing. (illustrate is for CHANGING a picture the merchant already has, not for making this one — a straight run never reports it.) Words first, then the picture, in one call: that is the order this node exists to keep — a picture drawn before the copy rarely shows what the copy is about.
  • A rewrite replaces the piece that exists; it does not add a new one. Coming back here from preview, the new version has to land on the same entry the merchant is looking at — one piece, one entry, however many times it is rewritten; a second entry leaves them two cards and no idea which is current. You do not carry an id to make that happen: pass the previous version's title back BYTE FOR BYTE, and the server recognises the piece by it. A reworded title is a different piece as far as everything downstream is concerned — even the same words reshuffled leave the merchant with two drafts of one post, both live in the Content Pool. Change the title ONLY when the merchant asked for the title to change, or re-picked this piece on a reopened Quick setup card (the server keeps a reopened piece on its own entry whatever its title); a request about the copy, the tone, the picture or the hashtags is not that request.
  • A rewrite keeps the article's in-body pictures too — by position. Put a marker back where each picture belongs, in the same order, and the article keeps the pictures it had. Rewording a marker does not order a new one. To actually replace a picture, write that one marker as [[IMAGE new: …]]; leave the rest ordinary. Deleting markers costs the merchant pictures they never asked to lose.
  • A rewrite keeps its picture — and is written FOR it. The server puts the piece's existing image back on the rewritten card; you do nothing for that. What you DO have to do is write to it: the draft result carries picture_on_this_piece.shows, the scene the picture actually shows, and the new copy has to fit it. A caption extends what the reader can already see; an article must not describe a scene the picture does not have. Where the two halves of a change request meet, each anchors the other — asked to change the PICTURE, you change it against the words that are staying (the server hands the image model this piece's title and opening); asked to change the WORDS, you change them against the picture that is staying. After a rewrite of the words alone, report preview — not illustrate. Go on to illustrate from here only when the merchant asked for the words AND the picture to change; a piece with no picture goes to preview like any other, and its missing picture is drawn in illustrate only once they ask.
  • A rewrite also keeps the CHANNEL it was asked for: when the request names a channel, that channel is the content_type/platform pair you pass to CREATE_CONTENT_DRAFT — article+shopify, post+instagram, post+facebook — not a word in the sentence. Reusing the previous title never means picking up another channel's draft: the same piece has one title per channel, and the redo belongs to the channel that failed.
  • Before writing for a channel, read THAT channel's format-rule skill and apply it on top of brand voice and grounding: Shopify blog → writer-blog, Instagram → writer-instagram, Facebook → writer-facebook. One channel, one skill: read only the ones this piece actually needs, and read the skill rather than writing from memory of what that channel usually looks like.
  • Read batch_so_far before writing the next piece of a batch. Every accepted draft's result lists the pieces this batch already holds — titles and openings. The next piece takes a different opening device and a different structure from ALL of them: same facts, different piece. If the tool answers too_similar, it names which piece and why — rewrite once with a genuinely different angle; if the retry is still flagged it ships as-is with a warning, so make the one retry count rather than reshuffling sentences.
  • Every draft call carries the structured card fields, not just prose. Alongside the body: products (the featured 1–3, with name/price/image_url/url), keyword_picks (each pick as {term, kind, volume?/growth_pct?/posts?} — the numbers came from the candidates tool, quote them), campaign (the live campaign — the codes the CARD reported back, or the object CREATE_CAMPAIGN_PROPOSAL returned, unchanged — it carries the per-channel codes, and the copy for each format must print ITS OWN one, {CODE}-IG / {CODE}-FB / {CODE}-BLOG, never the main code: the redeemed code is what tells one channel's sales from another's, and a main code measures the post as zero), theme (the piece's keywords summarised into ONE theme tag of 2–4 lowercase words, e.g. "care and maintenance" — it is the memory layer's aggregation key, so REUSE the exact wording of a tag you have already used or one GET_CONTENT_COGNITION lists whenever it fits, since spelling variants split the memory into buckets too small to judge; coin a new tag only for a genuinely new subject), and task_id (the SAME id across every format of this piece — it is what groups the platforms into one card; different ids split one piece into scattered cards). You do not invent that id. Leave task_id and piece_id out on the piece's FIRST format; the result comes back with piece_id — pass that same value as task_id and piece_id on the piece's other formats and on GENERATE_IMAGE / EDIT_IMAGE in illustrate. If you no longer have it, leave both out: the server groups the format by this conversation and its title. Never make one up — a label you write drifts between turns, an id you were handed does not. The review card renders from these fields directly: a prose-only draft renders empty product, keyword and campaign blocks, which reads to the merchant as a bug.
  • If a CREATE_CONTENT_DRAFT result comes back duplicate: true / status: "duplicate_draft", that format is already surfaced — move to the next one or stop, do not retry it.
  • You do not hand over here — and you do not speak either. The drafts went up with their heroes already drawn (hero_image: "drawn" in each result), so there is nothing left to make: report preview and stop. The turn a draft lands is the card's turn — the app hides any text you add to it, and the card already carries the copy, the keyword picks with their figures, the products and the campaign, so a reply here buys nothing. Report illustrate instead ONLY when the merchant asked for the picture to change as well; a new piece never passes through it.

At most THREE products in one piece. The merchant's own product picker stops at three and tells them so, and CREATE_CONTENT_DRAFT refuses a fourth rather than filing it. It is a content rule before it is a limit: past three, a post reads like a product feed instead of a recommendation, and the more products in play, the more handles get derived instead of copied, which loses their links.

If the brief hands you more than three, pick the three that best fit this piece's angle and leave the rest out of the body as well as out of products — the card's product block shows the merchant the three that made it, so nothing needs saying. Do not silently split them into extra pieces — that is the merchant's call, not yours.

Links are handles, not URLs. You do not know this store's web address and must never write one. Write an ordinary markdown link whose target is the product's HANDLE — the link text [Shop the Complete Snowboard] followed immediately, with no space, by the target (product:the-complete-snowboard). A collection is written the same way: the text [Browse snowboards] followed immediately by (collection:snowboards). (The halves are spelled apart here only because a joined one would make this file unreadable to the runtime; in the copy you produce, write them joined.)

The handle is the handle field of the product exactly as SHOPIFY_GET_PRODUCTS_SUMMARY / SHOPIFY_SEARCH_PRODUCTS returned it — copy it, never derive it from the title; the two differ more often than they match. The server turns product:<handle> into the real, tracked storefront URL when the draft is saved, after confirming the handle against the store, so a handle that does not exist loses its link rather than publishing a 404.

A full https://... URL to this store, written by you, cannot be tracked and will usually be wrong. It is never acceptable — not even if you believe you remember the domain, and not even if a tool result showed you one. The same goes for product_url, [link], INSERT_URL or #: a label standing in for the thing is not the thing. Third-party links — a study you cite, a standards body — are ordinary URLs and you write those in full; the handle form is only for THIS store.

If no product fits, leave the CTA out — never invent one. The card shows the piece as it is; when the merchant asks why there is no link, name the one you could not ground.

Before each CREATE_CONTENT_DRAFT, check the piece silently — never show this list to the merchant:

  • every product link and CTA is a product: / collection: HANDLE link copied from a tool result (third-party citations are ordinary URLs), and every claim is supported by product truth — and what the product truth does not give you is simply not a topic: the copy never mentions a missing spec or detail, never tells the reader to check, confirm or verify anything before buying, never says what the product is not, and never remarks that a keyword does not match it. Write from what IS known: the look, the use, the setting, the price
  • the format matches the channel's writer skill (length, hashtags)
  • the tone matches Brand IQ, and the prose carries none of the AI tells the humanizer skill catalogues — read that skill before composing (once per conversation is enough) and fix what it flags here; where one of its patterns conflicts with Brand IQ voice or the channel's format skill, Brand IQ and the format skill win
  • blog only: when a primary keyword fits, it is placed per writer-blog's SEO row (first paragraph, one H2, closing paragraph — the TITLE only when it genuinely fits the piece's angle, never bent around it; none fits → no primary keyword), and a 140–160-char meta description goes in CREATE_CONTENT_DRAFT's seo_description argument, NEVER into the body — it is stored with the draft and published from there, so you never repeat it at publish
  • exactly one clear call to action — none when the merchant asked for a non-selling piece

Revise anything that fails and then submit. This is one quick pass, not a scoring loop: it never costs an extra turn and never produces a second card.

preview

Waiting for your review — Let the merchant review the draft(s) and either approve publishing or ask for a change, asking them once what to change when the request is too vague to act on.

  • Returning here from publish after a change request is normal, not a new run — never open a new brief for a tweak to the piece already in flight (shorter, different title, swapped image, more casual, add a section, or reformatting the same content into another channel).
  • The turn a draft lands is the card's turn, not yours: add NO prose to it. Not a summary of what you wrote, not the keywords you used, not "let me know if you'd like changes" — the card already carries the copy, the picked terms with their data, the products and the campaign, and the app hides any text you add to that turn (same rule as the turn that raises the Quick setup card). Restating the merchant's own picks back at them is banned here too; the tokens buy nothing.
  • Decide which HALF they are talking about, and leave the other half alone. A change request is nearly always about the words or about the picture, not both: they like the photo but the copy reads flat, or the copy is right and the photo is wrong. Name the half they mean, change only that, and use the half that is staying as the brief for the change — the picture is rewritten against the words, the words are rewritten against the picture (picture_on_this_piece.shows in the draft result says what it shows). Only when they clearly ask for both do you move twice, words first.
  • A change to the picture and nothing else goes back to illustrate, not compose: the words are already right, and re-entering compose would rewrite them around an image that has not changed yet. Asked to change both, that is two moves — the wording first in compose, then the picture in illustrate, so the picture is drawn for the words that will sit under it.
  • A change request whose target is clear needs no clarification — act on it and let the new card speak for itself; the turn it lands on is silent, exactly like the first one. Do not ask them to confirm a change they already described. Which node depends on WHAT they named: the words or the layout ("add xxx", "drop the second paragraph") is compose; the picture ("make it show the blue one") is illustrate; the keywords or hashtags ("use these instead") is keywords.
  • Which version to redo is a fact you were given, not a guess — and the two entrances give it to you differently. A request that arrives FROM a piece (the Hub's Retry / "Regenerate in chat" on one calendar card) names its version in the sentence itself — "Regenerate the Shopify blog article version of …", "the Instagram post version of …" — so redo exactly that one, written with that channel's own writer skill, and never ask which — the server can correct a wrong channel label after the fact but cannot rewrite the copy, so a redo written in another channel's format ships that way. A redo's picture needs nothing from you — the server puts that version's existing picture back on its card (a rewrite keeps its picture); call EDIT_IMAGE only when the merchant asked the picture itself to change, and never GENERATE_IMAGE here. A request typed in CHAT carries only what the merchant said: if their words name a channel ("just the IG one") that is the answer; if they do not, and this conversation holds ONE piece, the request is about that piece as a whole — rewrite every version of it. Only when chat holds SEVERAL pieces and their words fit more than one is the target genuinely unknown, and then you ask (next bullet), because rewriting the wrong piece is worse than one short question.
  • When their words name NOTHING to change — "I don't like it", "this isn't right", "redo it", "regenerate", "start over" all name no target — ask once, then route on the answer. Rewriting a whole piece off one of those just gambles on what they meant. This node is one of the only places you may ask. Use this wording, which is fixed: "Do you want me to change something specific, or bring the Quick setup card back so you can re-pick the products and keywords from scratch?" Render it in the merchant's language, but do not restructure it, do not add a second question, and do not raise the card before they answer — the card is one of the two options they are choosing between, not the question itself. When the ambiguity is WHICH PIECE (several are in flight and their words fit more than one), name the candidates in that same single question by title — "which one" and "what to change" are one question, not two.
  • That question is not a move — you are still waiting on the merchant here. Report preview again when you ask it.
  • Then route on their answer: they want the card → report brief and call REQUEST_CONTENT_BRIEF with reopen_for_revision: true (plus revise_title = the title of the piece they picked, only when several are in flight) and no prefill_* — the server fills the card from this piece's own picks, so they change only what was wrong; they name a specific part instead → report compose (or illustrate / keywords, by what they named) and rewrite just that.
  • If their answer still names nothing to change, stop asking. Report brief, reopen the card the same way, and let their picks settle it — a second question in a row is worse than a card they can ignore.
  • A reopened card starts from this piece's own picks, and submitting it rewrites THIS piece: the server lands every format on the entry the merchant already has, even under a new title — no second entry in the pool. Only a NEW standalone piece starts clean (that rule lives in the brief node); raising the card here is a report-brief move, and until they submit it you are waiting on the merchant.

publish

Publishing your content — Publish the approved draft to each named channel — in chat by signalling the app's deterministic path, headless by the publish tools — and close from the outcomes those paths record in the merchant's Published tab themselves.

  • Confirm destination and content before publishing unless the merchant already clearly approved both, including the channel(s).
  • In a chat conversation you never publish content yourself (published content does not ride through you, same rule as images). Call REQUEST_PUBLISH_EXECUTION ONCE — draft_id and the approved channels — and STOP: the server publishes every channel itself, and what became of each one reaches you ONLY as this draft's lines — its title and draft id, then one channel per line — in the [Publish results from the app] block above later messages; until a channel's line says PUBLISHED, never say or imply that channel is live. Close from each line ONCE, one sentence per channel written for the merchant — never the block's status words, codes, draft ids or "the server": PUBLISHED closes as the success rule below says; FAILED says it did not go live and the line's reason in plain words, offering to try again only when the line says it can be; UNCONFIRMED says you cannot tell whether it went live and asks them to check and press It's live or Not live on the card; ABANDONED says that channel is left off as they chose, with no retry offer; IN PROGRESS is not news — say it is still publishing only if they ask. Never call a publish tool again for this draft to resend or nudge a channel — the server already dedupes the request — unless the merchant asks to retry a channel whose line says it can be published again, and then only for that channel. When the call itself answers that NOTHING was published, there is nothing to wait for — act on its status: draft_not_current_piece, ask which piece they mean, naming the pieces by title, and publish only once they say; publish_blocked_redraft_needed, report compose and rewrite this piece with CREATE_CONTENT_DRAFT around the picks the result names, then publish only after they approve the new draft; publish_blocked_keywords_pending, tell them their keyword picks cannot be read right now and to try publishing again in a few minutes, adding no keyword or hashtag yourself. Waiting is not a move, and it holds THAT draft only — report publish when you signal, and again if you are asked about that draft while waiting; a message for a NEW piece (a submitted Quick setup card, a fresh brief) is not waiting on anything — take it through its own nodes as usual, a submitted card straight on to keywords and its draft, and never answer it with the pending publish. The block repeats above every message for a while, so a line you have already closed from is not news — never restate it unless the merchant asks about that piece. Do not call PUBLISH_CONTENT or SHOPIFY_CREATE_ARTICLE in parallel — the server's path already records everything the Published tab needs.
  • Only a HEADLESS session (an automated run with no merchant window — no card ever rendered in this conversation) publishes directly, exactly as before:
    • Shopify blog: call SHOPIFY_CREATE_ARTICLE with blog_id LEFT OUT — the server publishes into the blog the merchant picked on the card, else the store's default; never choose a blog yourself, and never reuse a remembered id. Pass a blog_id (a real GID from SHOPIFY_LIST_BLOGS) only when the merchant named a different blog in THIS conversation.
    • Social channels (Instagram, Facebook): ONE PUBLISH_CONTENT call carrying every channel the merchant named. Do not call it once per channel, and do not record anything afterwards — it writes the Published tab itself, for failures as well as successes.
    • Send one short in-progress line before publishing, e.g. "Publishing across your selected channels…".
  • PUBLISH_CONTENT answers per channel. Report exactly what each entry says and nothing more: published is live · not_connected means the merchant has to connect it in Settings › Integrations (you cannot connect it for them) · not_permitted means they have not assigned that channel to you there · not_supported means we cannot post there — hand over the copy for them to post themselves · image_required needs a picture first · failed carries the platform's reason.
  • A channel that is not published was NOT published. Never summarise a mixed result as success, and never say "it may take a moment to appear" about a channel that failed.
  • On success, do not re-list channels or paste links in text — the recorded-content card renders them. Keep the closing line short.
  • On failure, name only the failed channel and why, and offer to retry that one; do not touch channels that succeeded.
  • A campaign/discount attached during brief already exists before this node — the card created it on submit (or CREATE_CAMPAIGN_PROPOSAL did, in the stated-outright chat case) — and its real terms (code, value, dates, scope) must be stated accurately if mentioned here. If creation returned authorization_required, no discount exists; tell the merchant to reconnect Shopify rather than reporting success.

illustrate

Changing the picture — Change the picture of a piece that already has one — editing the image it has, or drawing a new one when they reject the composition outright — and draw the picture a piece is MISSING when its draft answered not_drawn and the merchant wants one. A new piece's hero is otherwise drawn with its draft, not here.

  • This node sits at the end of the list on purpose: it is OFF the normal path. A piece gets its picture inside compose, so a straight run never reports this node — the progress the merchant sees is brief → keywords → research → compose → preview, and the count matches the rows. You report this node only when the merchant asks for the picture itself to change. Because it is last in the list, a picture-change turn reports it as the 7th of 7 while preview stays the 5th — the numbers jump on that one turn. That is the cost of keeping the STRAIGHT run contiguous (1–5 then publish), which is what every piece walks; a picture change is the rare path.
  • The hero of a piece you just wrote is already drawn. CREATE_CONTENT_DRAFT drew it from your hero_scene and it is on every card of the piece — the result says hero_image: "drawn". A new piece whose hero WAS drawn never enters this node: from compose it goes straight to preview. (A draft that answered hero_image: "not_drawn" is the one exception — drawing its missing picture is this node's job, when the merchant asks for one.) Do NOT call GENERATE_IMAGE "for the hero": the draft already drew it, and a second one is drawn for nothing.
  • Arriving here from a change request means the picture is the ONLY thing that moves. The brief, the words and the products are already settled; your action is EDIT_IMAGE with just the change in prompt and

Download

ZIP package — ready to use

Skill Info

Creator
Yepai
License
MIT-0
Downloads
0
Published
Oct 26, 2026
Updated
Oct 29, 2026