@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,223 @@
|
|
|
1
|
+
import { apiGet, apiPost, getDashboardUrl } from "../lib/client.js";
|
|
2
|
+
import { formatError } from "../lib/format.js";
|
|
3
|
+
export const helpText = `
|
|
4
|
+
exodus creative — Creative-suite engines (native, copy-derived, ref-match)
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
exodus creative native --ad "<text>" [options]
|
|
8
|
+
exodus creative copy-derived --ad "<text>" [options]
|
|
9
|
+
exodus creative ref-match --refs <id,id,...> [--subject "<text>"] [--objects <id,id>] [options]
|
|
10
|
+
exodus creative status --id <runId>
|
|
11
|
+
|
|
12
|
+
Shared options (kickoffs):
|
|
13
|
+
--variations N Renders to generate (default: engine-specific)
|
|
14
|
+
--aspect 1:1|4:5|9:16 Image aspect ratio (default: 1:1)
|
|
15
|
+
--name "<label>" Custom run name (otherwise auto-generated)
|
|
16
|
+
--ad-group <id> Attach to an existing ad-group
|
|
17
|
+
|
|
18
|
+
ref-match additional options:
|
|
19
|
+
--refs <id,id,...> Required: comma-separated creativeSuiteImages ids
|
|
20
|
+
--subject "<text>" Optional subject hint
|
|
21
|
+
--objects <id,id,...> Optional object overlay image ids
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
exodus creative native --ad "grounding sheets reduce inflammation" --variations 10
|
|
25
|
+
exodus creative copy-derived --ad "..." --aspect 9:16
|
|
26
|
+
exodus creative ref-match --refs k57abc123,k57def456 --subject "morning routine"
|
|
27
|
+
exodus creative status --id rd72e9ybakhwj0v8qkk39yntd586thbw
|
|
28
|
+
|
|
29
|
+
Note: status polling reads /api/creative-suite/runs/[id] and returns the live
|
|
30
|
+
run row including imageCount + isTerminal. The dashboard renders the same
|
|
31
|
+
data realtime via Convex subscriptions if you'd rather watch there.
|
|
32
|
+
`.trim();
|
|
33
|
+
function flagString(flags, name) {
|
|
34
|
+
const v = flags[name];
|
|
35
|
+
return typeof v === "string" ? v : undefined;
|
|
36
|
+
}
|
|
37
|
+
function flagInt(flags, name) {
|
|
38
|
+
const v = flags[name];
|
|
39
|
+
if (typeof v !== "string")
|
|
40
|
+
return undefined;
|
|
41
|
+
const n = parseInt(v, 10);
|
|
42
|
+
return Number.isFinite(n) ? n : undefined;
|
|
43
|
+
}
|
|
44
|
+
async function resolveWorkspace() {
|
|
45
|
+
const who = await apiGet("/api/v2/whoami");
|
|
46
|
+
if (!who.ok || !who.data.workspaceId) {
|
|
47
|
+
console.error("Error: whoami failed. Check EXODUS_API_KEY and EXODUS_API_URL/CONVEX_SITE_URL.");
|
|
48
|
+
console.error(formatError(who));
|
|
49
|
+
process.exit(1);
|
|
50
|
+
throw new Error("unreachable");
|
|
51
|
+
}
|
|
52
|
+
return { workspaceId: who.data.workspaceId, slug: who.data.workspaceSlug ?? who.data.workspaceId };
|
|
53
|
+
}
|
|
54
|
+
function validateAspect(value) {
|
|
55
|
+
const aspect = value ?? "1:1";
|
|
56
|
+
if (aspect !== "1:1" && aspect !== "4:5" && aspect !== "9:16") {
|
|
57
|
+
console.error(`Error: --aspect must be 1:1 | 4:5 | 9:16 (got "${aspect}").`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
throw new Error("unreachable");
|
|
60
|
+
}
|
|
61
|
+
return aspect;
|
|
62
|
+
}
|
|
63
|
+
async function runTextEngine(engine, flags) {
|
|
64
|
+
const adText = flagString(flags, "ad");
|
|
65
|
+
if (!adText || adText.trim().length < 3) {
|
|
66
|
+
console.error(`Error: creative ${engine} requires --ad "<text>" (min 3 chars).`);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const aspect = validateAspect(flagString(flags, "aspect"));
|
|
71
|
+
const variations = flagInt(flags, "variations");
|
|
72
|
+
const name = flagString(flags, "name");
|
|
73
|
+
const adGroupId = flagString(flags, "ad-group");
|
|
74
|
+
const ws = await resolveWorkspace();
|
|
75
|
+
const body = {
|
|
76
|
+
workspaceId: ws.workspaceId,
|
|
77
|
+
engine,
|
|
78
|
+
adText,
|
|
79
|
+
aspectRatio: aspect,
|
|
80
|
+
...(variations !== undefined ? { variations } : {}),
|
|
81
|
+
...(name ? { name } : {}),
|
|
82
|
+
...(adGroupId ? { adGroupId } : {}),
|
|
83
|
+
};
|
|
84
|
+
console.log(`Creative run: brand=${ws.slug}, engine=${engine}, aspect=${aspect}`);
|
|
85
|
+
const res = await apiPost("/api/creative-suite/run", body);
|
|
86
|
+
if (!res.ok) {
|
|
87
|
+
console.error(formatError(res));
|
|
88
|
+
process.exit(1);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
console.log("");
|
|
92
|
+
console.log(`✓ Creative ${engine} run started`);
|
|
93
|
+
console.log(` runId: ${res.data.runId}`);
|
|
94
|
+
if (res.data.triggerRunId)
|
|
95
|
+
console.log(` triggerRunId: ${res.data.triggerRunId}`);
|
|
96
|
+
console.log(` dashboard: ${getDashboardUrl()}/creative-suite/runs/${res.data.runId}`);
|
|
97
|
+
console.log("");
|
|
98
|
+
console.log(`Poll: exodus creative status --id ${res.data.runId}`);
|
|
99
|
+
}
|
|
100
|
+
async function runRefMatch(flags) {
|
|
101
|
+
const refsRaw = flagString(flags, "refs");
|
|
102
|
+
if (!refsRaw) {
|
|
103
|
+
console.error("Error: creative ref-match requires --refs <id,id,...>.");
|
|
104
|
+
process.exit(1);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const referenceImageIds = refsRaw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
108
|
+
if (referenceImageIds.length === 0) {
|
|
109
|
+
console.error("Error: --refs must contain at least one non-empty id.");
|
|
110
|
+
process.exit(1);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const aspect = validateAspect(flagString(flags, "aspect"));
|
|
114
|
+
const variations = flagInt(flags, "variations");
|
|
115
|
+
const subject = flagString(flags, "subject");
|
|
116
|
+
const objectsRaw = flagString(flags, "objects");
|
|
117
|
+
const objectImageIds = objectsRaw
|
|
118
|
+
? objectsRaw.split(",").map((s) => s.trim()).filter(Boolean)
|
|
119
|
+
: undefined;
|
|
120
|
+
const name = flagString(flags, "name");
|
|
121
|
+
const adGroupId = flagString(flags, "ad-group");
|
|
122
|
+
const ws = await resolveWorkspace();
|
|
123
|
+
const body = {
|
|
124
|
+
workspaceId: ws.workspaceId,
|
|
125
|
+
engine: "ref-match",
|
|
126
|
+
referenceImageIds,
|
|
127
|
+
aspectRatio: aspect,
|
|
128
|
+
...(variations !== undefined ? { variations } : {}),
|
|
129
|
+
...(subject ? { subject } : {}),
|
|
130
|
+
...(objectImageIds && objectImageIds.length > 0 ? { objectImageIds } : {}),
|
|
131
|
+
...(name ? { name } : {}),
|
|
132
|
+
...(adGroupId ? { adGroupId } : {}),
|
|
133
|
+
};
|
|
134
|
+
console.log(`Creative run: brand=${ws.slug}, engine=ref-match, aspect=${aspect}, refs=${referenceImageIds.length}`);
|
|
135
|
+
const res = await apiPost("/api/creative-suite/run", body);
|
|
136
|
+
if (!res.ok) {
|
|
137
|
+
console.error(formatError(res));
|
|
138
|
+
process.exit(1);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
console.log("");
|
|
142
|
+
console.log(`✓ Creative ref-match run started`);
|
|
143
|
+
console.log(` runId: ${res.data.runId}`);
|
|
144
|
+
if (res.data.triggerRunId)
|
|
145
|
+
console.log(` triggerRunId: ${res.data.triggerRunId}`);
|
|
146
|
+
console.log(` dashboard: ${getDashboardUrl()}/creative-suite/runs/${res.data.runId}`);
|
|
147
|
+
}
|
|
148
|
+
async function runStatus(flags) {
|
|
149
|
+
const runId = flagString(flags, "id");
|
|
150
|
+
if (!runId) {
|
|
151
|
+
console.error("Error: creative status requires --id <runId>.");
|
|
152
|
+
process.exit(1);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const dashUrl = `${getDashboardUrl()}/api/creative-suite/runs/${encodeURIComponent(runId)}`;
|
|
156
|
+
const apiKey = process.env["EXODUS_API_KEY"] ??
|
|
157
|
+
process.env["VAD_API_KEY"] ??
|
|
158
|
+
"";
|
|
159
|
+
const headers = { "Content-Type": "application/json" };
|
|
160
|
+
if (apiKey)
|
|
161
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
162
|
+
const fetchRes = await fetch(dashUrl, { method: "GET", headers });
|
|
163
|
+
const text = await fetchRes.text();
|
|
164
|
+
let data;
|
|
165
|
+
try {
|
|
166
|
+
data = JSON.parse(text);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
console.error(`Non-JSON ${fetchRes.status} from /api/creative-suite/runs/${runId}: ${text.slice(0, 300)}`);
|
|
170
|
+
process.exit(1);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (!fetchRes.ok) {
|
|
174
|
+
const errMsg = data.error ?? `HTTP ${fetchRes.status}`;
|
|
175
|
+
console.error(`Error: ${errMsg}`);
|
|
176
|
+
process.exit(1);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const d = data;
|
|
180
|
+
console.log(`runId: ${d._id}`);
|
|
181
|
+
if (d.name)
|
|
182
|
+
console.log(`name: ${d.name}`);
|
|
183
|
+
if (d.engine)
|
|
184
|
+
console.log(`engine: ${d.engine}`);
|
|
185
|
+
console.log(`status: ${d.status ?? "—"}${d.isTerminal ? " (terminal)" : ""}`);
|
|
186
|
+
if (d.completedImages !== undefined || d.totalImages !== undefined) {
|
|
187
|
+
console.log(`progress: ${d.completedImages ?? 0} / ${d.totalImages ?? "?"} completed${d.failedImages ? `, ${d.failedImages} failed` : ""}`);
|
|
188
|
+
}
|
|
189
|
+
else if (d.imageCount !== undefined) {
|
|
190
|
+
console.log(`images: ${d.imageCount}`);
|
|
191
|
+
}
|
|
192
|
+
if (d.errorMessage)
|
|
193
|
+
console.log(`error: ${d.errorMessage}`);
|
|
194
|
+
console.log(`dashboard: ${getDashboardUrl()}/creative-suite/runs/${runId}`);
|
|
195
|
+
}
|
|
196
|
+
export async function run(flags) {
|
|
197
|
+
const sub = process.argv[3] ?? "";
|
|
198
|
+
if (sub === "native") {
|
|
199
|
+
await runTextEngine("native", flags);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (sub === "copy-derived") {
|
|
203
|
+
await runTextEngine("copy-derived", flags);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (sub === "ref-match") {
|
|
207
|
+
await runRefMatch(flags);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (sub === "status") {
|
|
211
|
+
await runStatus(flags);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (sub && !sub.startsWith("--")) {
|
|
215
|
+
console.error(`Error: unknown creative subcommand "${sub}".`);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
console.error("Error: creative requires a subcommand (native | copy-derived | ref-match | status).");
|
|
219
|
+
}
|
|
220
|
+
console.error("");
|
|
221
|
+
console.error(helpText);
|
|
222
|
+
process.exit(1);
|
|
223
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const helpText: string;
|
|
2
|
+
export interface CheckResult {
|
|
3
|
+
ok: boolean;
|
|
4
|
+
warn?: boolean;
|
|
5
|
+
todo?: boolean;
|
|
6
|
+
label: string;
|
|
7
|
+
detail?: string;
|
|
8
|
+
fix?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function checkNodeVersion(): CheckResult;
|
|
11
|
+
export declare function checkClaudeCli(): CheckResult;
|
|
12
|
+
export declare function checkEnvFile(): CheckResult;
|
|
13
|
+
export declare function checkWhoami(): Promise<CheckResult>;
|
|
14
|
+
export declare function checkActiveBrandMatch(): Promise<CheckResult>;
|
|
15
|
+
export declare function checkExodusDistFreshness(pkgRootOverride?: string): CheckResult;
|
|
16
|
+
export declare function checkVersionCurrency(pkgRootOverride?: string, fetchImpl?: typeof fetch): Promise<CheckResult>;
|
|
17
|
+
export declare function checkApiAndDrive(): Promise<CheckResult[]>;
|
|
18
|
+
export declare function checkDashboardAuth(): Promise<CheckResult>;
|
|
19
|
+
export declare function checkLayout(): CheckResult;
|
|
20
|
+
export declare function checkBrandProfileGenesisDepth(): CheckResult;
|
|
21
|
+
export declare function run(_flags: Record<string, string | boolean>): Promise<void>;
|