@aicopycoders/exodus 2026.6.2400
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/assets/references/awareness-framework.md +156 -0
- package/assets/references/cast-video.md +165 -0
- package/assets/references/copy-blocks.md +138 -0
- package/assets/references/creative-strategy.md +990 -0
- package/assets/references/editing-rules.md +81 -0
- package/assets/references/hook-quality-checklist.md +153 -0
- package/assets/references/iterations.md +73 -0
- package/assets/references/scrawls.md +483 -0
- package/assets/references/segments.md +79 -0
- package/assets/skills/exodus/SKILL.md +50 -0
- package/assets/skills/exodus-brand/SKILL.md +117 -0
- package/assets/skills/exodus-browse/SKILL.md +96 -0
- package/assets/skills/exodus-creative/SKILL.md +94 -0
- package/assets/skills/exodus-drive/SKILL.md +118 -0
- package/assets/skills/exodus-foundation/SKILL.md +170 -0
- package/assets/skills/exodus-genesis/SKILL.md +159 -0
- package/assets/skills/exodus-idea/SKILL.md +78 -0
- package/assets/skills/exodus-image/SKILL.md +224 -0
- package/assets/skills/exodus-meme/SKILL.md +183 -0
- package/assets/skills/exodus-primer/SKILL.md +145 -0
- package/assets/skills/exodus-strategist/SKILL.md +217 -0
- package/assets/skills/exodus-swipe/SKILL.md +85 -0
- package/assets/skills/exodus-template/SKILL.md +106 -0
- package/assets/skills/exodus-write/SKILL.md +157 -0
- package/assets/skills/genesis-bots/.env.example +12 -0
- package/assets/skills/genesis-bots/README.txt +29 -0
- package/assets/skills/genesis-bots/SKILL.md +219 -0
- package/assets/skills/genesis-bots/scripts/genesis-stream.mjs +307 -0
- package/assets/skills/genesis-bots/scripts/genesis-stream.py +220 -0
- package/dist/bin/exodus.d.ts +2 -0
- package/dist/bin/exodus.js +177 -0
- package/dist/commands/__tests__/genesis.hookgate.test.d.ts +1 -0
- package/dist/commands/__tests__/genesis.hookgate.test.js +12 -0
- package/dist/commands/brand.d.ts +24 -0
- package/dist/commands/brand.js +292 -0
- package/dist/commands/browse.d.ts +9 -0
- package/dist/commands/browse.js +132 -0
- package/dist/commands/creative.d.ts +2 -0
- package/dist/commands/creative.js +223 -0
- package/dist/commands/doctor.d.ts +21 -0
- package/dist/commands/doctor.js +590 -0
- package/dist/commands/drive.d.ts +2 -0
- package/dist/commands/drive.js +154 -0
- package/dist/commands/foundation.d.ts +2 -0
- package/dist/commands/foundation.js +468 -0
- package/dist/commands/genesis.d.ts +64 -0
- package/dist/commands/genesis.js +564 -0
- package/dist/commands/idea.d.ts +53 -0
- package/dist/commands/idea.js +333 -0
- package/dist/commands/image.d.ts +2 -0
- package/dist/commands/image.js +249 -0
- package/dist/commands/init.d.ts +13 -0
- package/dist/commands/init.js +70 -0
- package/dist/commands/keys.d.ts +2 -0
- package/dist/commands/keys.js +101 -0
- package/dist/commands/meme.d.ts +12 -0
- package/dist/commands/meme.js +272 -0
- package/dist/commands/migrate.d.ts +3 -0
- package/dist/commands/migrate.js +158 -0
- package/dist/commands/primer.d.ts +2 -0
- package/dist/commands/primer.js +540 -0
- package/dist/commands/read-doc.d.ts +3 -0
- package/dist/commands/read-doc.js +62 -0
- package/dist/commands/status.d.ts +6 -0
- package/dist/commands/status.js +205 -0
- package/dist/commands/swipe.d.ts +2 -0
- package/dist/commands/swipe.js +398 -0
- package/dist/commands/template.d.ts +2 -0
- package/dist/commands/template.js +225 -0
- package/dist/commands/whoami.d.ts +2 -0
- package/dist/commands/whoami.js +51 -0
- package/dist/lib/ad-library-write.d.ts +15 -0
- package/dist/lib/ad-library-write.js +67 -0
- package/dist/lib/assets.d.ts +3 -0
- package/dist/lib/assets.js +23 -0
- package/dist/lib/backend-hint.d.ts +2 -0
- package/dist/lib/backend-hint.js +22 -0
- package/dist/lib/cc-command.d.ts +1 -0
- package/dist/lib/cc-command.js +13 -0
- package/dist/lib/client.d.ts +23 -0
- package/dist/lib/client.js +213 -0
- package/dist/lib/format.d.ts +8 -0
- package/dist/lib/format.js +172 -0
- package/dist/lib/intel-format.d.ts +1 -0
- package/dist/lib/intel-format.js +38 -0
- package/dist/lib/keys-sync.d.ts +16 -0
- package/dist/lib/keys-sync.js +88 -0
- package/dist/lib/layout.d.ts +38 -0
- package/dist/lib/layout.js +153 -0
- package/dist/lib/load-env.d.ts +1 -0
- package/dist/lib/load-env.js +47 -0
- package/dist/lib/pixar-orchestrator-types.d.ts +54 -0
- package/dist/lib/pixar-orchestrator-types.js +1 -0
- package/dist/lib/poll.d.ts +14 -0
- package/dist/lib/poll.js +32 -0
- package/dist/lib/preflight.d.ts +18 -0
- package/dist/lib/preflight.js +56 -0
- package/dist/lib/prompts.d.ts +9 -0
- package/dist/lib/prompts.js +99 -0
- package/dist/lib/reel-write.d.ts +14 -0
- package/dist/lib/reel-write.js +59 -0
- package/dist/lib/release.d.ts +4 -0
- package/dist/lib/release.js +81 -0
- package/dist/lib/scaffold.d.ts +8 -0
- package/dist/lib/scaffold.js +67 -0
- package/dist/lib/scout-hydrate.d.ts +1 -0
- package/dist/lib/scout-hydrate.js +10 -0
- package/dist/lib/state.d.ts +6 -0
- package/dist/lib/state.js +49 -0
- package/dist/lib/template-constants.d.ts +4 -0
- package/dist/lib/template-constants.js +85 -0
- package/dist/lib/version.d.ts +1 -0
- package/dist/lib/version.js +19 -0
- package/package.json +30 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: exodus-brand
|
|
3
|
+
description: List, switch, inspect, or troubleshoot the brand workspaces the Exodus CLI has access to — "brands" here means the Exodus dashboard's brand workspaces, nothing else. Admins use a single API key with a local active-brand pointer; switching is one `npx @aicopycoders/exodus brand use <slug>` call, no .env editing. **This is the only way to verify which brands the CLI sees — `whoami` only shows the active brand, NOT the list.** Pick the right subcommand from intent — don't ask the user "list, switch, or inspect?". Only invoke when the user has explicitly invoked Exodus — they said "exodus" in the request ("exodus brand list", "switch my exodus brand", "which exodus brand am I on"), named this skill or /exodus-brand, ran an `npx exodus` command, referenced the Exodus CLI or dashboard ("the CLI doesn't see my new brand", "I just created a brand on the dashboard"), or the exodus hub skill routed here. Never claim generic brand questions ("what's our brand strategy", "update the brand colors") — in shared folders those may belong to the user's other tools.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
```operator-guide
|
|
7
|
+
Subcommands:
|
|
8
|
+
list Show all brands available to your key
|
|
9
|
+
use <slug> Set the active brand for this CLI
|
|
10
|
+
current Print the active brand
|
|
11
|
+
inspect <slug> Show the brand's full config (foundation, primer, account)
|
|
12
|
+
clear Stop overriding — fall back to the key's default brand
|
|
13
|
+
Returns:
|
|
14
|
+
Plain text summary (no JSON). The starred row is the active brand.
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
# Brand — Move the CLI Between Brands
|
|
18
|
+
|
|
19
|
+
## Strategic Context
|
|
20
|
+
|
|
21
|
+
One API key, many brands. **Any user can create and own unlimited brands** — via `npx @aicopycoders/exodus brand create "<name>"` or the dashboard. This is NOT admin-only, and brand names are scoped per user (two different users can each have a "Matt Beard"). The key works for every brand the user OWNS (admin keys see everything); the CLI attaches `X-Active-Brand: <slug>` on every request. The ONLY "pinned to one brand" case is a brand someone ELSE invited the user into: they don't own it, so the header is ignored for it and it's the single brand their key sees. Never tell a user they can't create brands or are "locked to one brand" because their key shows `role: member` — a member who owns brands sees and creates as many as they want.
|
|
22
|
+
|
|
23
|
+
The active brand resolves **folder > pointer > key default**: on a multi-brand install each brand has a subfolder (marked by `.exodus-brand.json`), and running from inside one targets that brand automatically — it wins over the `{ activeBrand: "<slug>" }` pointer in `.exodus/state.json` that `brand use` writes. `brand current` tells you which one applied.
|
|
24
|
+
|
|
25
|
+
The dashboard's brand-switcher in the top-right is independent — your CLI active brand and your dashboard active brand can differ. That's a feature: read reports on Brand A while the CLI generates ads for Brand B.
|
|
26
|
+
|
|
27
|
+
## Read the Intent, Pick the Subcommand
|
|
28
|
+
|
|
29
|
+
Don't surface a "list, switch, or inspect?" menu to the user — figure it out from what they said:
|
|
30
|
+
|
|
31
|
+
| User says... | Run |
|
|
32
|
+
|---|---|
|
|
33
|
+
| "What brand am I on?" / "Which brand right now?" | `current` (then `inspect` if they want detail) |
|
|
34
|
+
| "List my brands" / "What brands do I have?" | `list` |
|
|
35
|
+
| "Create a new brand" / "Add a brand called X" / "Set up brand Y" | `create "<name>"` (no admin needed; switches you in) |
|
|
36
|
+
| "Switch to dlc" / "Change to brand X" | `use <slug>` |
|
|
37
|
+
| "Show me the foundation for brand X" / "What's brand Y configured with?" | `inspect <slug>` |
|
|
38
|
+
| "The new brand isn't showing up" | `list` first — if visible, suggest `use`; if not, the dashboard create didn't propagate |
|
|
39
|
+
|
|
40
|
+
## Common Commands
|
|
41
|
+
|
|
42
|
+
### List brands
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npx @aicopycoders/exodus brand list
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Shows role, the active brand (marked `★`), and the full accessible list. Flags it if the local active brand points at something you no longer have access to.
|
|
49
|
+
|
|
50
|
+
### Create a new brand
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npx @aicopycoders/exodus brand create "Matt Beard"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Creates a brand the user owns (any user can — no admin role required), then switches the CLI into it and, on multi-brand installs, sets up its subfolder. Brand names are scoped per user, so this succeeds even if another account already has a brand by that name (the slug is auto-disambiguated under the hood). Tell the user the next step is the primer (`exodus, set up my brand primer`). If the dashboard ever reports a name conflict for a brand the user is *sure* they've never made, that's a separate bug — not a sign the name is taken for them.
|
|
57
|
+
|
|
58
|
+
### Switch the active brand
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npx @aicopycoders/exodus brand use new-brand-slug
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Validates the slug, writes it to local state, and (multi-brand installs) creates the brand's subfolder + pulls its `state/brand-profile.md` if missing. Every subsequent CLI call (genesis, creative, template, foundation, etc.) targets the new brand — unless you run from inside a different brand's subfolder, which wins.
|
|
65
|
+
|
|
66
|
+
### Print the active brand
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npx @aicopycoders/exodus brand current
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Cheap pre-flight check before kicking off a long pipeline.
|
|
73
|
+
|
|
74
|
+
### Inspect a brand's config
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npx @aicopycoders/exodus brand inspect <slug>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Surfaces foundation completeness, primer status, connected ad account, and writing-mode defaults. Use this when the user asks "is brand X ready to run?" — don't guess.
|
|
81
|
+
|
|
82
|
+
### Clear the override
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npx @aicopycoders/exodus brand clear
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Falls back to the brand the API key was originally minted for.
|
|
89
|
+
|
|
90
|
+
## Anticipate the Next Move
|
|
91
|
+
|
|
92
|
+
Brand operations are almost never the goal. Read what's next and offer it:
|
|
93
|
+
|
|
94
|
+
- After `use <slug>` — "Want me to confirm foundation completeness with `inspect`, or jump straight to a Genesis run?"
|
|
95
|
+
- After `list` shows a new brand — "Switching to it now and walking through `exodus-foundation` if you want."
|
|
96
|
+
- After `inspect` reveals missing primers — "Foundation isn't ready. Want me to walk through it from a source doc?"
|
|
97
|
+
- After `current` — "Ready to run `exodus-genesis` on this brand?"
|
|
98
|
+
|
|
99
|
+
## After Creating a New Brand on the Dashboard
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# 1. Confirm the new brand is visible
|
|
103
|
+
npx @aicopycoders/exodus brand list
|
|
104
|
+
|
|
105
|
+
# 2. Switch into it (creates its subfolder + pulls its profile on multi-brand installs)
|
|
106
|
+
npx @aicopycoders/exodus brand use my-new-brand
|
|
107
|
+
|
|
108
|
+
# 3. Walk through foundation
|
|
109
|
+
npx @aicopycoders/exodus foundation
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`npx @aicopycoders/exodus@latest init` does the folder syncing in bulk — it creates a subfolder for EVERY brand the user owns and refreshes all their profiles, and prints the brand summary at the end. Either path works; `brand use` is the targeted one.
|
|
113
|
+
|
|
114
|
+
## Not the Right Skill For
|
|
115
|
+
|
|
116
|
+
- Creating, editing, or deleting brands themselves — those happen on the dashboard at Settings → Brands.
|
|
117
|
+
- Editing a brand's foundation content — use the `exodus-foundation` skill.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: exodus-browse
|
|
3
|
+
description: View past Exodus pipeline runs and pull outputs from previous sessions. This skill should not just dump the run table back at the user — it should filter, name the most relevant entry, and offer the next move (open the doc, re-run with a sharper brief, rerun with tweaks). Only invoke when the user has explicitly invoked Exodus: they said "exodus" in the request ("exodus, what did we run today", "show me my exodus runs", "did the exodus genesis run from earlier finish"), named this skill or /exodus-browse, ran an `npx exodus` command, or the `exodus` hub skill routed here. Never claim generic history questions ("what did we run today", "show me past runs") — in shared folders those may belong to the user's other tools; if the user did not say exodus, this skill is not for them.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
```operator-guide
|
|
7
|
+
Inputs:
|
|
8
|
+
none required — defaults to recent runs across all pipelines
|
|
9
|
+
Flags:
|
|
10
|
+
--limit (default: 20) — max runs to list
|
|
11
|
+
--agent — filter by agent: genesis | creative | template | meme
|
|
12
|
+
Returns: terminal table of recent runs with timestamps, agents, statuses, and Doc URLs
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
# Browse — View History and Surface the Right Run
|
|
16
|
+
|
|
17
|
+
## Strategic Context
|
|
18
|
+
|
|
19
|
+
`exodus-browse` (the `npx @aicopycoders/exodus browse` command) is the cheap, fast read on what's happened recently in Exodus. Almost every exodus-invoked "where did that go?" / "what did we run?" question routes here. The mistake to avoid is treating it as a dumb proxy — pasting the full table back to the user is more noise than signal. Your job is to find the run they actually mean and queue up the next move on it.
|
|
20
|
+
|
|
21
|
+
## When to Use
|
|
22
|
+
|
|
23
|
+
- "What did we run today / this week?"
|
|
24
|
+
- "Find that Genesis run about cortisol from this morning."
|
|
25
|
+
- "Did the Creative run finish yet?"
|
|
26
|
+
- "Show me all our Template runs."
|
|
27
|
+
- "Where's the doc from earlier?"
|
|
28
|
+
|
|
29
|
+
## Workflow
|
|
30
|
+
|
|
31
|
+
### 1. Run the query that matches the user's intent
|
|
32
|
+
|
|
33
|
+
If they named a pipeline, filter by it — don't make them re-ask:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx @aicopycoders/exodus browse --agent genesis --limit 20
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If they didn't name one, list across all:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx @aicopycoders/exodus browse --limit 30
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Bump `--limit` higher when they say "this week" or "all our runs" — the default 20 will miss things on a busy day.
|
|
46
|
+
|
|
47
|
+
### 2. Parse the output, then surface the relevant entry
|
|
48
|
+
|
|
49
|
+
Don't paste the whole table. Read it, find the run that matches what the user asked for (by topic keyword, time, status), and call it out by name. Examples:
|
|
50
|
+
|
|
51
|
+
> "The cortisol Genesis run from this morning is `gen_xyz123` — finished at 9:42am, doc here: <url>."
|
|
52
|
+
|
|
53
|
+
> "Three Creative runs this week. The most recent (`run_abc789`) is the only one that completed — the other two failed mid-render."
|
|
54
|
+
|
|
55
|
+
If multiple runs match, list 2-3 with one-line context each, then ask which one. If nothing matches, say so directly and suggest the closest neighbor ("nothing today, but here's yesterday's Genesis run on a similar angle").
|
|
56
|
+
|
|
57
|
+
### 3. Anticipate the next move
|
|
58
|
+
|
|
59
|
+
The user almost never wants `exodus-browse` for its own sake. They want to do something with what they find. Offer the obvious next step inline:
|
|
60
|
+
|
|
61
|
+
- "Want me to read the doc for `gen_xyz123` and pull the top hooks?"
|
|
62
|
+
- "Should I re-run that with a sharper brief and a new awareness level?"
|
|
63
|
+
- "Want me to check the run that just finished?"
|
|
64
|
+
- "Ready to rerun the failed one with the fix?"
|
|
65
|
+
|
|
66
|
+
Pick the one that fits their pattern, don't list all four.
|
|
67
|
+
|
|
68
|
+
### 4. For "is it done yet?" questions
|
|
69
|
+
|
|
70
|
+
Use `status` directly with the run ID — it's faster than re-listing:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npx @aicopycoders/exodus status --id <runId> --type genesis
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`--type` is required and pipeline-specific. Get it wrong and you get a 400. For standalone Genesis runs, use `--type genesis`. Creative-suite runs (native / copy-derived / ref-match / meme) use `--type creative`; Template runs use `--type template`.
|
|
77
|
+
|
|
78
|
+
## Reading a Run's Doc
|
|
79
|
+
|
|
80
|
+
Once you've identified the run, prefer `read-doc` over the Drive MCP — it walks every tab. The MCP only sees tab 1 and will misreport the run as empty:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
npx @aicopycoders/exodus read-doc <runId>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Falls back to the Drive MCP only if `read-doc` exits with code 2 (`unavailable`).
|
|
87
|
+
|
|
88
|
+
## Run Types Reference
|
|
89
|
+
|
|
90
|
+
| Type | Used For |
|
|
91
|
+
|------|----------|
|
|
92
|
+
| `genesis` | Standalone Genesis runs |
|
|
93
|
+
| `creative` | Creative-suite runs — native, copy-derived, ref-match, and meme |
|
|
94
|
+
| `template` | Template (ad-type format) runs |
|
|
95
|
+
|
|
96
|
+
All of them also render live in the creative-suite library / dashboard if you'd rather watch there.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: exodus-creative
|
|
3
|
+
description: Run a SPECIFIC Exodus creative-suite engine when the user has already chosen one — native (render image ads straight from ad copy), copy-derived (renders derived from copy variations), or ref-match (match the look of reference images already in the brand library). Only invoke when the user has explicitly invoked Exodus AND names the engine or asks precisely for it: they said "exodus" in the request ("exodus native creative", "exodus, ref-match this library image", "exodus copy-derived images"), named this skill or /exodus-creative, ran an `npx @aicopycoders/exodus creative` command, or the `exodus` hub skill routed here. Never claim generic creative requests ("creative suite", "make ads that look like this image") — in shared folders those may belong to the user's other tools; if the user did not say exodus, this skill is not for them. For an unsure "exodus, just make me some images / statics" ask, start at the `exodus-image` front door — it reads the request and routes here. For a spread across structured ad-type formats use `exodus-template`; for meme formats use `exodus-meme`.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
```operator-guide
|
|
7
|
+
Subcommands:
|
|
8
|
+
exodus creative native --ad "<text>" [options] Render image ads from ad copy
|
|
9
|
+
exodus creative copy-derived --ad "<text>" [options] Renders derived from copy variations
|
|
10
|
+
exodus creative ref-match --refs <id,id,...> [options] Match the look of reference image(s)
|
|
11
|
+
exodus creative status --id <runId> Poll a run
|
|
12
|
+
|
|
13
|
+
Shared options (kickoffs):
|
|
14
|
+
--variations N Renders to generate (default: engine-specific)
|
|
15
|
+
--aspect 1:1|4:5|9:16 Image aspect ratio (default: 1:1)
|
|
16
|
+
--name "<label>" Custom run name (otherwise auto-generated)
|
|
17
|
+
--ad-group <id> Attach to an existing ad-group
|
|
18
|
+
|
|
19
|
+
ref-match additional options:
|
|
20
|
+
--refs <id,id,...> REQUIRED. Comma-separated creativeSuiteImages ids
|
|
21
|
+
(the images must already be in the dashboard library)
|
|
22
|
+
--subject "<text>" Optional subject hint
|
|
23
|
+
--objects <id,id,...> Optional object-overlay image ids
|
|
24
|
+
|
|
25
|
+
Returns: runId + dashboard URL (/creative-suite/runs/<runId>).
|
|
26
|
+
Status: `exodus creative status --id <runId>` → engine, status, completed/total, isTerminal.
|
|
27
|
+
Auth: Bearer (kickoff via Convex HTTP; status via dashboard route).
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
# Creative — Creative-Suite Engines (Max's pipeline)
|
|
31
|
+
|
|
32
|
+
Three engines that turn copy (or a reference image) into static renders, without the SCRAWLS concept-mining pass:
|
|
33
|
+
|
|
34
|
+
- **`native`** — render image ads straight from the ad copy you pass in `--ad`.
|
|
35
|
+
- **`copy-derived`** — renders derived from variations of that copy.
|
|
36
|
+
- **`ref-match`** — match the visual style of one or more **reference images already in the brand's library** (`--refs <imageIds>`), optionally with a subject hint and object overlays.
|
|
37
|
+
|
|
38
|
+
Unlike `exodus-template` (structured ad-type formats), `exodus-creative` is the engine-direct path — fastest when the user already knows the copy or has a reference look to match.
|
|
39
|
+
|
|
40
|
+
## When to reach for `exodus-creative` vs the other image tools
|
|
41
|
+
|
|
42
|
+
| Situation | Use |
|
|
43
|
+
|---|---|
|
|
44
|
+
| "Render images from this ad copy" / "native creative" | `creative native` |
|
|
45
|
+
| "Give me variations derived off this copy" | `creative copy-derived` |
|
|
46
|
+
| "Make ads that look like this image" (ref already uploaded) | `creative ref-match --refs <ids>` |
|
|
47
|
+
| Spread across ad-type formats (testimonial, hero, UGC…) | the `exodus-template` skill |
|
|
48
|
+
|
|
49
|
+
## Workflow
|
|
50
|
+
|
|
51
|
+
### 1. Pick the engine, state your read, run
|
|
52
|
+
|
|
53
|
+
**Native / copy-derived** (copy in `--ad`, min 3 chars):
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
./node_modules/.bin/exodus creative native --ad "<finished ad copy>" --variations 10
|
|
57
|
+
./node_modules/.bin/exodus creative copy-derived --ad "<finished ad copy>" --aspect 9:16
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Ref-match** (reference image ids must already exist in the library):
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
./node_modules/.bin/exodus creative ref-match --refs k57abc123,k57def456 --subject "morning routine"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
To get reference image ids, the user uploads to the dashboard library first (Settings → library) — there's **no Bearer upload route**, so the CLI can't upload for them. If they hand you a local file, tell them to upload it in the dashboard and give you the resulting id.
|
|
67
|
+
|
|
68
|
+
### 2. Poll status (only if asked)
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
./node_modules/.bin/exodus creative status --id <runId>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Returns engine, status (with `(terminal)` when done), `completed / total` render counts, and any error. The dashboard renders the same data live, so prefer linking it over polling in a loop.
|
|
75
|
+
|
|
76
|
+
### 3. Report
|
|
77
|
+
|
|
78
|
+
Surface the dashboard URL (`/creative-suite/runs/<runId>`) + a 2-line take per the **Default Post-Run Reporting** rule. Don't claim renders are finished off the kickoff line — the kickoff only confirms the run started. Check `status` (or the dashboard) before calling it done.
|
|
79
|
+
|
|
80
|
+
## Failure Handling
|
|
81
|
+
|
|
82
|
+
- **`native`/`copy-derived` without `--ad`** (or under 3 chars) errors — supply the copy.
|
|
83
|
+
- **`ref-match` without `--refs`** errors — supply at least one library image id.
|
|
84
|
+
- **Bad/aspect value** — `--aspect` must be `1:1`, `4:5`, or `9:16`.
|
|
85
|
+
- **whoami/auth failure** — run `npx @aicopycoders/exodus doctor`; confirm `EXODUS_API_KEY`.
|
|
86
|
+
- **Reference id not found** — the id must be a real `creativeSuiteImages` id from the brand's library; re-upload via the dashboard and use the returned id.
|
|
87
|
+
- **"variance" (L1–L5) is NOT an engine here** — only `native | copy-derived | ref-match` are valid. Don't invent a variance engine.
|
|
88
|
+
|
|
89
|
+
## Admin
|
|
90
|
+
|
|
91
|
+
- Backend: Convex HTTP `POST /api/creative-suite/run` (Bearer-auth) with engine-specific Trigger.dev fanout; status via dashboard `GET /api/creative-suite/runs/[id]` (Bearer, Max QA #34).
|
|
92
|
+
- Reference images live in `creativeSuiteImages`; upload is dashboard-only for now.
|
|
93
|
+
- Runs appear in the creative-suite library alongside template + meme output.
|
|
94
|
+
- Don't echo render prompts or bot system prompts in your reply.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: exodus-drive
|
|
3
|
+
description: Read and write Google Drive / Docs / Sheets via the Exodus dashboard's existing OAuth, using `npx @aicopycoders/exodus drive` subcommands — open a Google Doc URL the user references, inspect a spreadsheet, search Drive for a file, or create new Drive artifacts outside the pipeline flow. For Exodus pipeline-run docs (genesis, creative, template), use `npx @aicopycoders/exodus read-doc <runId>` instead — the Drive MCP only sees tab 1 and will misreport multi-tab pipeline output as empty. Only invoke when the user has explicitly invoked Exodus: they said "exodus" in the request ("exodus, read the doc from that run", "exodus drive, find that file"), named this skill or /exodus-drive, ran an `npx @aicopycoders/exodus drive` command, or the `exodus` hub skill routed here. Never claim generic Drive/Docs/Sheets requests ("read this Google Doc", "pull the data from this sheet") — in shared folders those usually belong to the user's other tools (e.g. a Drive MCP); if the user did not say exodus, this skill is not for them.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
```operator-guide
|
|
7
|
+
Subcommands (use the one that matches intent):
|
|
8
|
+
get-doc <docId> Read a Google Doc by ID
|
|
9
|
+
get-sheet <sheetId> Read a spreadsheet range
|
|
10
|
+
list-files Search/list Drive files
|
|
11
|
+
create-doc <title> Create a new Google Doc
|
|
12
|
+
batch-update <docId> Apply Docs API requests (insertText, etc.)
|
|
13
|
+
For pipeline-run docs, use:
|
|
14
|
+
npx @aicopycoders/exodus read-doc <runId> — walks every tab, renders to markdown
|
|
15
|
+
Returns: structured JSON forwarded from Google's APIs (or markdown for read-doc)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
# Drive — Google Drive, Docs, Sheets via the Dashboard's OAuth
|
|
19
|
+
|
|
20
|
+
## Strategic Context
|
|
21
|
+
|
|
22
|
+
There is no separate Google CLI to install, no keyring to configure, no `gws` env vars to export. The dashboard holds a single OAuth refresh token at Settings → Google Drive, auto-refreshes it, and `npx @aicopycoders/exodus drive` proxies through with the workspace API key the user already has. One connect, every command works.
|
|
23
|
+
|
|
24
|
+
If anything's wrong, run `npx @aicopycoders/exodus doctor` first — it probes the dashboard's Drive connection (label: "Google Drive (dashboard)") and tells the user exactly what to click.
|
|
25
|
+
|
|
26
|
+
## Pipeline Docs Get a Different Command
|
|
27
|
+
|
|
28
|
+
`npx @aicopycoders/exodus drive get-doc` reads tab 1 of a Doc. Pipeline runs (Genesis, and the creative-suite engines) write **multi-tab** Docs — one tab per variant, segment, or phase. Reading tab 1 of those gives you a fragment and looks like an empty/broken run.
|
|
29
|
+
|
|
30
|
+
For any pipeline run, use `read-doc` with the run ID:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx @aicopycoders/exodus read-doc <runId>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
It walks every tab and gives you the full output as markdown. This is the default for "read the doc from that run" — reach for `drive get-doc` only when the doc isn't a pipeline output.
|
|
37
|
+
|
|
38
|
+
## Pick the Subcommand from Intent
|
|
39
|
+
|
|
40
|
+
| User says... | Run |
|
|
41
|
+
|---|---|
|
|
42
|
+
| "Read this Google Doc URL: …" (not a pipeline) | `get-doc <docId>` |
|
|
43
|
+
| "Read the doc from yesterday's genesis run" | `read-doc <runId>` (NOT `drive`) |
|
|
44
|
+
| "Find that Drive file about cortisol" | `list-files --q "name contains 'cortisol'"` |
|
|
45
|
+
| "Pull the data from this sheet" | `get-sheet <sheetId> --range 'Sheet1!A1:Z100'` |
|
|
46
|
+
| "Write up these notes as a new Doc" | `create-doc` then `batch-update` |
|
|
47
|
+
| "Append this to the doc you just made" | `batch-update <docId>` with `insertText` |
|
|
48
|
+
|
|
49
|
+
Don't ask "which subcommand?" — pick from intent.
|
|
50
|
+
|
|
51
|
+
## Common Commands
|
|
52
|
+
|
|
53
|
+
### Get a Google Doc by ID
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npx @aicopycoders/exodus drive get-doc DOC_ID
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Extract `DOC_ID` from `docs.google.com/document/d/DOC_ID/edit`. Returns the Docs API `documents.get` shape; parse `.body.content` for text.
|
|
60
|
+
|
|
61
|
+
### Search Drive
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx @aicopycoders/exodus drive list-files --q "name contains 'genesis'" --page-size 10
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Then pass the matching ID into `get-doc`.
|
|
68
|
+
|
|
69
|
+
### Read a Spreadsheet range
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx @aicopycoders/exodus drive get-sheet SPREADSHEET_ID --range "Sheet1!A1:Z100"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Create a new Doc
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npx @aicopycoders/exodus drive create-doc "Draft — [topic]" --folder FOLDER_ID
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Returns `{id, name, webViewLink}` — share `webViewLink` back to the user.
|
|
82
|
+
|
|
83
|
+
### Append content to a Doc
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npx @aicopycoders/exodus drive batch-update DOC_ID --requests '[{"insertText":{"location":{"index":1},"text":"Hello, world.\n"}}]'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Batch all `insertText` requests in a single call rather than one per paragraph.
|
|
90
|
+
|
|
91
|
+
## Workflow: "Read this Doc and help me revise it"
|
|
92
|
+
|
|
93
|
+
1. Extract the doc ID (or use `read-doc` if it's a pipeline run).
|
|
94
|
+
2. Fetch the contents.
|
|
95
|
+
3. Quote back the relevant section so the user knows you're looking at the right thing.
|
|
96
|
+
4. Offer revisions inline in chat — don't mutate the Doc unless they explicitly say "update the doc".
|
|
97
|
+
|
|
98
|
+
## Anticipate the Next Move
|
|
99
|
+
|
|
100
|
+
- After `get-doc` / `read-doc` — "Want me to walk through the hooks one by one?" / "Should I draft revisions inline, or push edits straight back to the doc?"
|
|
101
|
+
- After `create-doc` — "Want me to share this with [team email]?" / "Ready to drop the draft content in?"
|
|
102
|
+
- After `list-files` finds the wrong thing — "Nothing for that exact name. Want me to broaden the query, or check by date instead?"
|
|
103
|
+
|
|
104
|
+
## Errors & Recovery
|
|
105
|
+
|
|
106
|
+
`npx @aicopycoders/exodus drive` exit codes:
|
|
107
|
+
|
|
108
|
+
- **Exit 2 / `drive_not_connected`** — user hasn't connected Drive on the dashboard. Tell them to visit Settings → Google Drive → Connect, then retry.
|
|
109
|
+
- **Exit 1 / `insufficient_scope`** — they connected before a needed scope was added. Reconnect at Settings → Google Drive.
|
|
110
|
+
- **Exit 1 / `token_refresh_failed`** — refresh token was revoked. Reconnect.
|
|
111
|
+
- **Permission denied on a specific file** — Google account doesn't have access. Ask them to share the file with the email shown at Settings → Google Drive.
|
|
112
|
+
|
|
113
|
+
When in doubt, `npx @aicopycoders/exodus doctor` surfaces the same problems with concrete remediations.
|
|
114
|
+
|
|
115
|
+
## Not the Right Skill For
|
|
116
|
+
|
|
117
|
+
- Reading pipeline-run output — use `npx @aicopycoders/exodus read-doc <runId>`.
|
|
118
|
+
- Running pipelines — Genesis and the creative-suite engines write their own Drive/dashboard output and return the URL.
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: exodus-foundation
|
|
3
|
+
description: Manage an Exodus brand's Genesis foundation (audience concerns, 2 primers — cold and warm — brand voice); everything it sets lives in the Exodus dashboard, NOT in the user's local files. THREE PATHS, choose by what the user gave you. (1) If the user provided already-structured content with section headers like "## Audience Concerns" / "## Primer (Cold)" / "## Primer (Warm)" — pipe it straight in: `npx @aicopycoders/exodus foundation save -` (reads stdin) — NO interactive walkthrough, NO bot extraction. (2) If the user wants to update one field — `npx @aicopycoders/exodus foundation set <field> --stdin` and pipe content. (3) If the user gave a raw source (Doc URL, web page, brief notes that need extracting), use the interactive walkthrough. Run `npx @aicopycoders/exodus foundation status` first to see what's missing — don't ask the user "where do you want to start", figure it out. Only invoke when the user has explicitly invoked Exodus — they said "exodus" in the request ("exodus, fill in the foundation", "set the exodus brand voice", "refresh the exodus primers"), named this skill or /exodus-foundation, ran an `npx exodus` command, or the exodus hub or `exodus-primer` skill routed here. "Primer" and "foundation" are overloaded words — other toolkits build their own local primers, and a "primer" in the user's local files belongs to their other system; never claim generic asks ("update my primer file", "write a brand voice doc") without Exodus context. The bare word "Genesis" without "exodus" refers to the member's own Genesis API key and personal bot recipes, NOT to Exodus.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
```operator-guide
|
|
7
|
+
Three paths — pick by what you have:
|
|
8
|
+
|
|
9
|
+
1. STRUCTURED markdown (already has "## Audience Concerns" / "## Primer ..." headers):
|
|
10
|
+
echo "<markdown>" | npx @aicopycoders/exodus foundation save -
|
|
11
|
+
# or, if it's already in a file:
|
|
12
|
+
npx @aicopycoders/exodus foundation save path/to/file.md
|
|
13
|
+
|
|
14
|
+
2. ONE field at a time:
|
|
15
|
+
echo "<content>" | npx @aicopycoders/exodus foundation set <fieldKey> --stdin
|
|
16
|
+
npx @aicopycoders/exodus foundation set <fieldKey> --value "<inline string>"
|
|
17
|
+
npx @aicopycoders/exodus foundation set <fieldKey> --file path/to/section.md
|
|
18
|
+
fieldKey ∈ { audienceConcerns, brandVoice,
|
|
19
|
+
primerUnawareProblemAware, primerSolutionProductAware }
|
|
20
|
+
(Legacy primerUnaware / primerProblemAware / primerSolutionAware /
|
|
21
|
+
primerProductAware still accepted — they collapse server-side into
|
|
22
|
+
the 2-track shape.)
|
|
23
|
+
|
|
24
|
+
3. RAW source needs extracting (Doc URL, web page, raw notes):
|
|
25
|
+
npx @aicopycoders/exodus foundation # interactive walkthrough
|
|
26
|
+
npx @aicopycoders/exodus foundation --doc <url> # skip the source picker
|
|
27
|
+
npx @aicopycoders/exodus foundation --url <url>
|
|
28
|
+
npx @aicopycoders/exodus foundation --file path/to/raw-source.md
|
|
29
|
+
|
|
30
|
+
Status check (always cheap, run first):
|
|
31
|
+
npx @aicopycoders/exodus foundation status
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
# Foundation — Set Up a Brand's Genesis Foundation
|
|
35
|
+
|
|
36
|
+
> **New brand with winning ads?** Prefer the `exodus-primer` skill — one pass over the brand's winners builds the single document that unlocks every pipeline. This `foundation` command is the **legacy 2-track path** and the **no-ads fallback**: use it for field-level edits, for brands that arrive with finished primer text, or when there are no winning ads to paste and you need to extract a foundation from a brand doc / URL / notes.
|
|
37
|
+
|
|
38
|
+
## Strategic Context
|
|
39
|
+
|
|
40
|
+
Genesis routes every variant through a brand's foundation — audience concerns + two awareness-keyed primers (cold = unaware/problem-aware; warm = solution-aware/product-aware) + an optional brand voice. If foundation is incomplete, Genesis falls back to defaults, and the output sounds wrong for the brand. This skill is how you fix that without hand-pasting JSON into the dashboard.
|
|
41
|
+
|
|
42
|
+
The biggest mistake is running the interactive walkthrough on already-finished content. The walkthrough re-extracts via a bot — slower, costs tokens, and may rewrite content the user already finalized. Read what they gave you first, then pick the path.
|
|
43
|
+
|
|
44
|
+
## The Primer Prompt (Winning Examples) — the highest-leverage input
|
|
45
|
+
|
|
46
|
+
The two primers are collections of *winning ads* that teach the Genesis bots what "good" looks like for this market. The better the examples, the sharper every hook and body-copy variant. A brand often arrives onboarding with a **primer prompt** already prepared — a packaged set of winning ads + examples (produced by the separate onboarding/primer step). When the user has one, drop it straight into the matching primer field — no walkthrough, no re-extraction:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# cold primer — unaware / problem-aware winning ads:
|
|
50
|
+
pbpaste | npx @aicopycoders/exodus foundation set primerUnawareProblemAware --stdin
|
|
51
|
+
# warm primer — solution / product-aware winning ads:
|
|
52
|
+
pbpaste | npx @aicopycoders/exodus foundation set primerSolutionProductAware --stdin
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
If the primer prompt is one structured document covering both awareness bands (headers like `## Primer (Cold)` / `## Primer (Warm)`), pipe the whole thing through `foundation save -` — the router splits it into the right fields.
|
|
56
|
+
|
|
57
|
+
**Works without it.** No primer prompt yet? Don't block. Genesis falls back to sensible defaults and still produces copy — the output just isn't yet calibrated to this brand's winners. Set foundation up to whatever degree you can, run, and tell the user plainly: "output gets noticeably sharper once you add winning examples." Adding the primer later and re-running is cheap. See `references/hook-quality-checklist.md` for what makes an ad primer-worthy.
|
|
58
|
+
|
|
59
|
+
## Picking the Right Path
|
|
60
|
+
|
|
61
|
+
| Situation | Command | Why |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| User pasted structured markdown with `## Audience Concerns`, `## Primer (Cold)` / `## Primer (Warm)` (or legacy `## Primer (Unaware)` etc.), etc. | `foundation save -` and pipe the content | They already wrote it. Don't re-extract. Legacy single-level headers still parse and collapse into the 2-track shape. |
|
|
64
|
+
| User wants to overwrite ONE field | `foundation set <fieldKey> --stdin` | Surgical, no walkthrough loop |
|
|
65
|
+
| User handed you a Google Doc URL / web page / raw brief | `foundation` (interactive walkthrough) | Bot extracts each field from the source |
|
|
66
|
+
|
|
67
|
+
## Workflow
|
|
68
|
+
|
|
69
|
+
### 1. Check status first — always
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx @aicopycoders/exodus foundation status
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Cheap, one query. Tells you which fields are populated, which are missing, and shows the first 80 chars of each. **Use the result to decide what to do next, don't re-ask the user.**
|
|
76
|
+
|
|
77
|
+
If status shows ✓ Ready — surface that and ask whether they want to refresh anything specific or move on to a Genesis run.
|
|
78
|
+
|
|
79
|
+
If status shows missing fields — start with those. Don't loop the user through populated fields they didn't ask to touch.
|
|
80
|
+
|
|
81
|
+
### 2. Recommend a path based on what they gave you
|
|
82
|
+
|
|
83
|
+
Don't list all three options. State your read:
|
|
84
|
+
|
|
85
|
+
> "You've got structured markdown with the right headers — piping it straight in. No walkthrough needed."
|
|
86
|
+
|
|
87
|
+
> "This is a Google Doc with raw brand brief — running the interactive walkthrough so each field gets extracted cleanly."
|
|
88
|
+
|
|
89
|
+
### 3. For the interactive walkthrough — propose drafts, don't make them type from blank
|
|
90
|
+
|
|
91
|
+
When you do run the walkthrough, the bot drafts each field from the source. Your job is to surface that draft, evaluate it against what you know about the brand (read the active brand's `state/brand-profile.md` — inside its brand subfolder on multi-brand installs — plus recent runs, the dashboard config), and tell the user "this looks right" or "this is missing X — let me regenerate" instead of just dumping the bot output and asking them to decide blind.
|
|
92
|
+
|
|
93
|
+
For each field, the walkthrough offers:
|
|
94
|
+
- **a** — accept and save
|
|
95
|
+
- **e** — open in `$EDITOR` and tweak
|
|
96
|
+
- **r** — regenerate with the same source
|
|
97
|
+
- **s** — skip (keep what's there)
|
|
98
|
+
|
|
99
|
+
Drive the choice. If the draft clearly fits the brand voice, recommend `a`. If a phrase is off, recommend `e` and tell them what to change. If the bot misread the source entirely, recommend `r`.
|
|
100
|
+
|
|
101
|
+
### 4. After foundation is ready — verify with a real run
|
|
102
|
+
|
|
103
|
+
Don't declare victory on the status badge alone. Foundation only matters insofar as it changes Genesis output. Verify with a Genesis run:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npx @aicopycoders/exodus genesis run --brief "<a known angle for this brand>" --awareness problem-aware
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Then read the resulting Doc with `npx @aicopycoders/exodus read-doc <runId>` and check whether the voice and primer landed. If it sounds wrong, come back and `set` the drifted field.
|
|
110
|
+
|
|
111
|
+
## Anticipate the Next Move
|
|
112
|
+
|
|
113
|
+
- After `status` shows ✓ Ready — "Want me to verify with a Genesis run at problem-aware level?"
|
|
114
|
+
- After `save -` of structured markdown — "Saved. Ready to test it with a real run?"
|
|
115
|
+
- After `set <field>` — "Updated. Want me to spot-check with a quick Genesis run, or move on?"
|
|
116
|
+
- After interactive walkthrough completes — "Foundation reads clean. Should I update the active brand's `state/brand-profile.md` (inside its brand subfolder on multi-brand installs) to match the new primers, or run a verification Genesis pass?"
|
|
117
|
+
- If a primer drifted on the test run — "The Genesis output is leaning too generic on [field]. Let me regenerate that field with a tighter source."
|
|
118
|
+
|
|
119
|
+
## Common Commands
|
|
120
|
+
|
|
121
|
+
### Status only
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npx @aicopycoders/exodus foundation status
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Interactive walkthrough — let the command pick a source
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npx @aicopycoders/exodus foundation
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Prompts for source type (Google Doc / web URL / local file / paste).
|
|
134
|
+
|
|
135
|
+
### Skip the source picker
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
npx @aicopycoders/exodus foundation --doc https://docs.google.com/document/d/DOC_ID/edit
|
|
139
|
+
npx @aicopycoders/exodus foundation --url https://example.com/about
|
|
140
|
+
npx @aicopycoders/exodus foundation --file ./brand-brief.md
|
|
141
|
+
npx @aicopycoders/exodus foundation --text "Brand X sells silver-threaded grounding sheets..."
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Iterate on a single field via walkthrough
|
|
145
|
+
|
|
146
|
+
Run `npx @aicopycoders/exodus foundation`, pick a source, then answer **n** to "Regenerate?" on every populated field except the one you want to redo. That field hits the accept/edit/regenerate/skip loop alone.
|
|
147
|
+
|
|
148
|
+
## Source Picking Guidance
|
|
149
|
+
|
|
150
|
+
| Source | Best for |
|
|
151
|
+
|---|---|
|
|
152
|
+
| Google Doc | Customer hands you a brief — fastest, preserves structure across tabs |
|
|
153
|
+
| Web URL | Brand has a live About / Mission / Press page worth scraping |
|
|
154
|
+
| Local file | You've already pulled notes into the workspace as `brand-brief.md` |
|
|
155
|
+
| Paste | Quick experiments or ad-hoc text you don't want to save |
|
|
156
|
+
|
|
157
|
+
Source quality > source length. Pick something that talks like a customer, not corporate marketing copy. Voice and primer extraction are only as good as the source. The command caps at 30K chars server-side, so length isn't a real constraint.
|
|
158
|
+
|
|
159
|
+
## Prerequisites
|
|
160
|
+
|
|
161
|
+
- Workspace API key minted for the target brand (`EXODUS_API_KEY` in `.env`).
|
|
162
|
+
- User is admin OR a member whose `currentWorkspaceId` matches the brand. Otherwise `forbidden`.
|
|
163
|
+
- For Google Doc sources: Drive connected at Settings → Google Drive (same connection used by `npx @aicopycoders/exodus drive`).
|
|
164
|
+
|
|
165
|
+
If anything's off, `npx @aicopycoders/exodus doctor` is the one-shot diagnosis.
|
|
166
|
+
|
|
167
|
+
## Not the Right Skill For
|
|
168
|
+
|
|
169
|
+
- Editing brand metadata (name, slug, ad account) — those live on the dashboard at Settings → Brands.
|
|
170
|
+
- Running pipelines — once foundation is ✓ Ready, switch to `exodus-genesis`.
|