gooseworks 0.3.6 → 0.3.8

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.
@@ -1 +1 @@
1
- {"version":3,"file":"master-skill.d.ts","sourceRoot":"","sources":["../../src/skills/master-skill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,oDAAoD;AACpD,wBAAgB,cAAc,IAAI,UAAU,EAAE,CAM7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CA8K9C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAoOhD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CA+MlD"}
1
+ {"version":3,"file":"master-skill.d.ts","sourceRoot":"","sources":["../../src/skills/master-skill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,oDAAoD;AACpD,wBAAgB,cAAc,IAAI,UAAU,EAAE,CAM7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CA8K9C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CA2QhD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CA6OlD"}
@@ -393,10 +393,49 @@ Then poll with \`get_remix_batch\` and hand back the links, same as above.
393
393
 
394
394
  ## Brand research
395
395
 
396
- Research normally runs in the GooseWorks backend (on onboarding). Just read the result with
397
- \`get_brand_kit\`. If a brand doesn't exist yet, you may \`create_ad_brand\` and let backend
398
- research run; you don't need to research locally. (A standalone local recipe still exists via
399
- \`gooseworks fetch brand-research\` if the user explicitly wants the agent to do it.)
396
+ Prefer the backend's result: \`get_brand_kit { brand_id }\`. If \`researchStatus\` is
397
+ \`complete\`, REUSE it never re-research.
398
+
399
+ **The split backend owns visuals, you own the qualitative depth:**
400
+
401
+ - **Backend LIGHT pass (automatic).** \`create_ad_brand\` with a \`website_url\` kicks off the same
402
+ backend research the web app uses, in \`mode: "light"\`: it resolves the **authoritative logo,
403
+ colors, and fonts** (Brandfetch + context.dev) plus a baseline kit, then flips
404
+ \`research_status\` to \`complete\` — usually under a minute. You can't reproduce those visual
405
+ signals locally, so **never re-derive logo/colors/fonts.** (Web onboarding via \`/api/ads/onboard\`
406
+ runs the full thing; nothing to do but read it.)
407
+ - **Your DEEP pass (local, agentic).** You add the qualitative depth the light pass leaves thin —
408
+ positioning, audience segments, voice, brandType, value props, proof points, products — grounded
409
+ on the actual site.
410
+
411
+ **CLI brand-research flow:**
412
+
413
+ 1. \`create_ad_brand { name, website_url }\` → keep \`brand_id\` + \`slug\`. The brand comes back with
414
+ \`research_status: "pending"\` (light pass in flight).
415
+ 2. **Wait for the backend light pass:** poll \`get_brand_kit { brand_id }\` until \`researchStatus\`
416
+ is \`complete\` (usually <60s). Now the kit has authoritative logo/colors/fonts + a baseline.
417
+ At this point generation is already unblocked — but do the deep pass to make it good.
418
+ 3. **Deep research locally:** \`gooseworks fetch brand-research\` and follow its phases. **Ground
419
+ every fact on the fetched site** — if the site can't be read, say so and ask the user; never
420
+ guess a category from the brand name alone.
421
+ 4. **Write the pack** with \`write_file\` under \`agent-config/brands/<slug>/\`:
422
+ - the \`brand-research/*.md\` docs + \`brand-assets/manifest.json\` (human-readable pack), AND
423
+ - \`brand-research/kit-patch.json\` — the STRUCTURED fields the web UI renders. Field-for-field
424
+ contract; only what you put here reaches the kit. Shape:
425
+ \`{ positioning?: string, audience?: string, voice?: string, brandType?: string, tagline?: string, valueProps?: string[], proofPoints?: string[], products?: [{ name, description?, link?, pricing?, imageUrls?: string[] }] }\`
426
+ (\`brandType\` ∈ product | saas | service | agency | restaurant | fashion | beauty | fitness |
427
+ finance | education | health). Only URLs already in our storage for product images.
428
+ - **Do NOT set logo / colors / fonts here** — the backend light pass already owns those.
429
+ 5. **Persist it:** \`finalize_brand_research { brand_id }\` merges \`kit-patch.json\` into the kit
430
+ NON-CLOBBERINGLY (it will NOT overwrite the backend's visuals or any user edit), then re-confirms
431
+ \`research_status: complete\`.
432
+ 6. **Verify:** \`get_brand_kit { brand_id }\` — confirm the qualitative fields you wrote are present
433
+ before generating.
434
+
435
+ **If the brand has NO website**, the backend light pass can't run (nothing to fetch) — do the whole
436
+ thing locally (steps 3–6) and finalize; an un-finalized brand has no kit for generation and leaves
437
+ no artifact to debug a wrong run (this is how a bad local classification, e.g. mislabelling a SaaS
438
+ as a "drink company", used to vanish without a trace).
400
439
 
401
440
  ## Analyze / intelligence (fetched recipes — NOT generation)
402
441
 
@@ -496,9 +535,24 @@ id). The app NEVER runs you — it is the viewer + review surface; you are the r
496
535
  (the render-file route) from the org's DEFAULT agent, but MCP file writes default to your
497
536
  token's pinned agent — which can be a DIFFERENT agent, so a render written with the default
498
537
  scope is **invisible in the app**. First resolve the Ads agent: \`list_accessible_scopes\` → the
499
- scope with \`is_org_default: true\` its \`agent_id\` is \`ADS_AGENT\`. Then pass
500
- \`target: { type: "agent", agent_id: ADS_AGENT }\` on EVERY \`get_upload_url\` / \`get_download_url\`
501
- / \`write_file\` / \`list_directory\` / \`read_file\` NEVER omit \`target\`.
538
+ scope with \`is_org_default: true\` (the ORG default — NOT the \`is_default\` / \`default_agent_id\`
539
+ fields, which are the *user's* default agent and are often a DIFFERENT agent). Its \`agent_id\` is
540
+ \`ADS_AGENT\` (name "Ads agent", slug \`org-default\`; usually also the \`agent_id\` in
541
+ credentials.json). Then pass \`target: { type: "agent", agent_id: ADS_AGENT }\` on EVERY
542
+ \`get_upload_url\` / \`get_download_url\` / \`write_file\` / \`list_directory\` / \`read_file\` — NEVER
543
+ omit \`target\`.
544
+ - **CRITICAL — publish under the PROJECT FOLDER, not the workspace root (the #1 "video renders but
545
+ is invisible" bug).** \`get_upload_url\` stores at \`<ADS_AGENT>/files/<path>\` verbatim, but the
546
+ render-file route reads from
547
+ \`<ADS_AGENT>/files/agent-config/brands/<brand_slug>/projects/<project_id>/<path>\`
548
+ (see backend \`resolveProjectFileKey\`). So EVERY publish/preview \`path\` MUST be prefixed with
549
+ \`agent-config/brands/<brand_slug>/projects/<project_id>/\` — e.g. upload to
550
+ \`agent-config/brands/<brand_slug>/projects/<project_id>/working/final.mp4\`, NEVER bare
551
+ \`working/final.mp4\`. A bare path 404s in the app even though the render row AND a bare-path
552
+ \`get_download_url\` both "succeed" (they resolve the wrong key). The render \`output_url\` still
553
+ stays the project-relative \`...render-file?path=working/final.mp4\` — the route re-prepends the
554
+ prefix itself. Always verify with \`get_download_url\` on the FULL \`agent-config/...\` path (must
555
+ be non-empty; curl it for HTTP 200) BEFORE marking the render complete.
502
556
  - Media generation (FAL / ElevenLabs) is billed to the agent through the GooseWorks proxies.
503
557
  \`submit_render { kind: "full" }\` debits **1 ad credit at row creation** — so sequence it LAST
504
558
  (render + verify a good MP4 first), and never re-submit on a guess (that double-bills). Call
@@ -513,31 +567,34 @@ id). The app NEVER runs you — it is the viewer + review surface; you are the r
513
567
  never re-research. If not, run brand research first (\`gooseworks fetch brand-research\`,
514
568
  follow it, then \`finalize_brand_research { brand_id }\`) before continuing.
515
569
 
516
- ## Step 2 — fetch the recipe + its pack skills for the format
570
+ ## Step 2 — read the template's recipe (it carries everything; NO hardcoded format map)
517
571
 
518
- The video-ad format skills live in the goose-skills **\`video-ad-formats\`** pack. Map the project's
519
- \`format\` to its recipe slug:
572
+ The ad format is a **template (data) in the ad_sample DB**, not a per-format skill.
573
+ \`get_ad_template(source_sample_id)\` returns the template's \`recipe\` — a self-contained brief you
574
+ read and execute. **Do NOT map \`format\` to a hardcoded recipe slug** (there is no such table):
520
575
 
521
- | format | recipe slug | renderer + atoms it drives |
522
- | --- | --- | --- |
523
- | \`imessage\` | \`remix-imessage-ad-from-sample\` | create-imessage-video-ad, create-imessage-mockup, stitch-videos-ffmpeg, mix-master, watch |
524
- | \`chatgpt\` | \`remix-chatgpt-ad-from-sample\` | create-chatgpt-video-ad, create-chatgpt-mockup, render-ios-keyboard, stitch-videos-ffmpeg, watch |
525
- | \`apple-notes\` | \`remix-apple-notes-ad-from-sample\` | create-apple-notes-video-ad, create-apple-notes-mockup, stitch-videos-ffmpeg, watch |
576
+ - \`recipe.format\` the format label (e.g. \`vignette\`), for display only.
577
+ - \`recipe.atoms\` the **capabilities** this template composes (e.g. \`create-video-seedance-2-fal\`,
578
+ \`create-image-gpt-image-fal\`, \`review-ugc-render\`, \`watch\`). \`gooseworks fetch <name>\` each — they
579
+ live in \`skills/ads/capabilities/\` and are reused across templates (so they cache).
580
+ - \`recipe.instructions\` the **playbook** to follow: \`instructions.inline\` prose, or
581
+ \`instructions.doc_url\` (an S3 markdown doc — fetch it).
582
+ - \`recipe.config\` — every param (prompts, layout, timings, palette, model choices).
583
+ - \`recipe.inputs\` — the brand-asset contract (which product / logo / offer this template needs).
584
+ - \`recipe.assets\` — reference material as S3 links (reference render, style guide, example frames) —
585
+ fetch as needed.
526
586
 
527
- (photo-grid + music-video coming.) Pack skills are fetchable individually by slug but do NOT
528
- auto-resolve dependencies (no \`dependencySkills\`), so \`gooseworks fetch\` the recipe **and** each
529
- skill in its row e.g. for iMessage:
587
+ Runtime: **read the recipe \`gooseworks fetch\` each capability in \`recipe.atoms\` follow
588
+ \`recipe.instructions\` with \`recipe.config\` + the brand's bound \`inputs\`.** The template IS the recipe;
589
+ there is no \`format recipe-slug\` table and no per-format skill to fetch.
530
590
 
531
- \`\`\`bash
532
- for s in remix-imessage-ad-from-sample create-imessage-video-ad create-imessage-mockup \\
533
- stitch-videos-ffmpeg mix-master watch; do gooseworks fetch "$s"; done
534
- \`\`\`
591
+ Save each fetched capability's scripts + files under \`/tmp/gooseworks-scripts/<name>/\`. If a capability
592
+ is a Node package (a phone-mockup renderer), \`npm install\` in its folder so its \`generate.js\` +
593
+ Playwright resolve, and point the recorder's \`NODE_PATH\` at it.
535
594
 
536
- Each prints \`{ content, scripts, files }\`. Save each skill's scripts + files under
537
- \`/tmp/gooseworks-scripts/<slug>/\` and FOLLOW the recipe's SKILL.md it orchestrates the others.
538
- The renderer (the \`create-*-mockup\` atom for the format) is a Node package —
539
- \`npm install\` in its folder so its \`generate.js\` + Playwright resolve, and point the recorder's
540
- \`NODE_PATH\` at it.
595
+ > **Migration note:** older phone-mockup formats (\`imessage\` / \`chatgpt\` / \`apple-notes\`) whose DB
596
+ > recipe does not yet carry \`atoms\` / \`instructions\` still hold the legacy \`recipe.thread\` payload;
597
+ > migrate them to this shape (capabilities + instructions in the DB) do not reintroduce a CLI map.
541
598
 
542
599
  ## Step 3 — prepare ALL the ingredients, then review ONCE (always, before any paid render)
543
600
 
@@ -549,7 +606,10 @@ ingredients out one at a time.
549
606
  that's typically: the **script** (the bubble thread), the **image(s)** shown in the conversation
550
607
  (one or more), and the **end card**. Richer templates add more (hook frame, background, product
551
608
  shots, music bed…). Read the recipe for the exact ingredient list. Generate the visuals NOW
552
- (media proxies / recipe), and \`get_upload_url\` each preview asset to \`working/review/<name>\`.
609
+ (media proxies / recipe), and \`get_upload_url\` each preview asset to the project folder
610
+ \`agent-config/brands/<brand_slug>/projects/<project_id>/working/review/<name>\` (the same
611
+ path-prefix rule as final publish — a bare \`working/review/<name>\` won't render in the panel).
612
+ In \`script_drafts\`, set each ingredient's \`path\` to the project-relative \`working/review/<name>\`.
553
613
  You may ask the user a couple of clarifying questions about the generation first if the recipe
554
614
  calls for it (angle, which product, offer/code) — batch them, then prepare everything.
555
615
  2. **Mirror the whole ingredient set for review** — \`update_ad_project_script { project_id,
@@ -581,11 +641,18 @@ ingredients out one at a time.
581
641
  \`append_project_message\` instead.
582
642
  3. QC by watching: run the \`watch\` skill on the master — verify bubble/beat order + SFX, that
583
643
  the brand's product (not the source's) is shown, the end card has the real wordmark + code,
584
- and the duration is within ~20% of the source.
644
+ and the duration is within ~20% of the source. For UGC/Seedance formats there are no captions
645
+ and often no local Whisper key: extract frames with ffmpeg for the visual pass, and get the
646
+ spoken transcript by running \`fal-ai/whisper\` through the SAME \`fal-proxy\` (upload the audio,
647
+ pass its \`get_download_url\` as \`audio_url\`) — confirm the transcript matches the script and the
648
+ brand name is pronounced right, with no word-repeat dysfluency, BEFORE spending the render credit.
585
649
  4. Publish: \`get_upload_url { target: { type: "agent", agent_id: ADS_AGENT } }\` → PUT the master
586
- to \`working/final.mp4\` and a poster to \`working/final-thumb.jpg\`. **Always target ADS_AGENT**
587
- (see Identity — a file on your token's own agent is invisible to the app). Verify servable:
588
- \`get_download_url { target: ADS_AGENT, path: "working/final.mp4" }\` must return a non-empty URL.
650
+ and poster **under the project folder** (see Identity's path-prefix rule) to
651
+ \`agent-config/brands/<brand_slug>/projects/<project_id>/working/final.mp4\` and
652
+ \`.../working/final-thumb.jpg\`. **Always target ADS_AGENT AND use the full project-folder path**
653
+ — a bare \`working/final.mp4\`, even on the right agent, 404s in the app. Verify servable:
654
+ \`get_download_url { target: ADS_AGENT, path: "agent-config/brands/<brand_slug>/projects/<project_id>/working/final.mp4" }\`
655
+ must return a non-empty URL (curl it for HTTP 200).
589
656
  Then \`update_render_status { render_id, status: "complete", output_url, thumbnail_url }\` where
590
657
  **output_url MUST be the durable render-file URL**
591
658
  \`/api/ads/projects/<project_id>/render-file?path=working/final.mp4\` (the app re-presigns it on
@@ -643,7 +710,9 @@ def fal_generate(model_path, payload, timeout_s=180, poll_s=3):
643
710
 
644
711
  ElevenLabs (VO / music) is the same shape against \`<api_base>/api/internal/elevenlabs-proxy\`
645
712
  with \`?token=&agent_id=\`. Feed FAL a local image by storing it (\`get_upload_url\`) and passing its
646
- \`get_download_url\` presigned URL as an \`image_urls\` entry, or POST the bytes to \`fal-storage-proxy\`.
713
+ \`get_download_url\` presigned URL as an \`image_urls\` / \`audio_url\` entry this is the reliable
714
+ path. (\`fal-storage-proxy\` may 404 depending on the install; don't block on it — prefer the
715
+ \`get_download_url\` presigned URL.)
647
716
 
648
717
  ## Rules
649
718
 
@@ -1 +1 @@
1
- {"version":3,"file":"master-skill.js","sourceRoot":"","sources":["../../src/skills/master-skill.ts"],"names":[],"mappings":";;AA4BA,wCAMC;AAWD,sDA8KC;AAiBD,0DAoOC;AAcD,8DA+MC;AAlpBD,oDAAoD;AACpD,SAAgB,cAAc;IAC5B,OAAO;QACL,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,qBAAqB,EAAE,EAAE;QACxD,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,uBAAuB,EAAE,EAAE;QACzD,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,yBAAyB,EAAE,EAAE;KAC9D,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,qBAAqB;IACnC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4KR,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAgB,uBAAuB;IACrC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkOR,CAAC;AACF,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,yBAAyB;IACvC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6MR,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"master-skill.js","sourceRoot":"","sources":["../../src/skills/master-skill.ts"],"names":[],"mappings":";;AA4BA,wCAMC;AAWD,sDA8KC;AAiBD,0DA2QC;AAcD,8DA6OC;AAvtBD,oDAAoD;AACpD,SAAgB,cAAc;IAC5B,OAAO;QACL,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,qBAAqB,EAAE,EAAE;QACxD,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,uBAAuB,EAAE,EAAE;QACzD,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,yBAAyB,EAAE,EAAE;KAC9D,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,qBAAqB;IACnC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4KR,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAgB,uBAAuB;IACrC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyQR,CAAC;AACF,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,yBAAyB;IACvC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2OR,CAAC;AACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gooseworks",
3
- "version": "0.3.6",
3
+ "version": "0.3.8",
4
4
  "description": "GooseWorks CLI — give your coding agent real data tools",
5
5
  "bin": {
6
6
  "gooseworks": "./dist/index.js"