@zalify/cli 0.24.1 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/cli.js +135 -49
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,6 +58,14 @@ API keys — list and revoke them in **Settings → Developer**. One login
|
|
|
58
58
|
covers every workspace; `zalify workspace set` switches between them
|
|
59
59
|
locally, no re-login.
|
|
60
60
|
|
|
61
|
+
**Inside a brand checkout, the folder decides.** `ads` commands read the
|
|
62
|
+
checkout's own workspace (its `.zalify/brand-repo.json` stamp, or
|
|
63
|
+
`identity.yaml` for folders AdsBuddy downloaded) and act as that
|
|
64
|
+
workspace — no `workspace set` first, and no risk of pulling one
|
|
65
|
+
brand's campaigns into another's folder. `workspace set` still matters
|
|
66
|
+
for commands run outside any checkout, and for `ads create`, which
|
|
67
|
+
provisions a NEW brand into the workspace you chose.
|
|
68
|
+
|
|
61
69
|
## Command reference
|
|
62
70
|
|
|
63
71
|
### Auth & workspace
|
package/dist/cli.js
CHANGED
|
@@ -18259,7 +18259,7 @@ function updateNotifier(options) {
|
|
|
18259
18259
|
|
|
18260
18260
|
// src/cli.ts
|
|
18261
18261
|
import { createRequire as createRequire2 } from "node:module";
|
|
18262
|
-
import { dirname as
|
|
18262
|
+
import { dirname as dirname4, join as join14 } from "node:path";
|
|
18263
18263
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
18264
18264
|
|
|
18265
18265
|
// src/auth.ts
|
|
@@ -18271,7 +18271,7 @@ import { spawn as spawn2 } from "node:child_process";
|
|
|
18271
18271
|
// src/config.ts
|
|
18272
18272
|
import { readFileSync, writeFileSync as writeFileSync2, mkdirSync, rmSync, existsSync } from "node:fs";
|
|
18273
18273
|
import { homedir } from "node:os";
|
|
18274
|
-
import { join } from "node:path";
|
|
18274
|
+
import { dirname, join, resolve } from "node:path";
|
|
18275
18275
|
var dir = join(homedir(), ".zalify");
|
|
18276
18276
|
var file = join(dir, "config.json");
|
|
18277
18277
|
function migrate(raw) {
|
|
@@ -18316,12 +18316,83 @@ function writeConfig(config) {
|
|
|
18316
18316
|
function deleteConfig() {
|
|
18317
18317
|
rmSync(file, { force: true });
|
|
18318
18318
|
}
|
|
18319
|
-
function
|
|
18319
|
+
function enforceWorkspaceLink(root, auth) {
|
|
18320
|
+
const linkPath = join(root, ".zalify", "brand-repo.json");
|
|
18321
|
+
if (!existsSync(linkPath))
|
|
18322
|
+
return;
|
|
18323
|
+
let link;
|
|
18324
|
+
try {
|
|
18325
|
+
link = JSON.parse(readFileSync(linkPath, "utf8"));
|
|
18326
|
+
} catch {
|
|
18327
|
+
return;
|
|
18328
|
+
}
|
|
18329
|
+
const ws = link.workspace;
|
|
18330
|
+
if (!ws?.id) {
|
|
18331
|
+
link.workspace = {
|
|
18332
|
+
id: auth.workspaceId,
|
|
18333
|
+
name: auth.workspaceName,
|
|
18334
|
+
slug: auth.workspaceSlug
|
|
18335
|
+
};
|
|
18336
|
+
writeFileSync2(linkPath, `${JSON.stringify(link, null, 2)}
|
|
18337
|
+
`);
|
|
18338
|
+
console.log(`stamped workspace "${auth.workspaceSlug}" into .zalify/brand-repo.json — commit it.`);
|
|
18339
|
+
return;
|
|
18340
|
+
}
|
|
18341
|
+
if (ws.id !== auth.workspaceId) {
|
|
18342
|
+
throw new Error(`This checkout belongs to workspace "${ws.name ?? ws.slug ?? ws.id}" ` + `but the command is running as "${auth.workspaceName}" (${auth.workspaceSlug}).`);
|
|
18343
|
+
}
|
|
18344
|
+
}
|
|
18345
|
+
function checkoutWorkspace(startDir) {
|
|
18346
|
+
let cur = resolve(startDir ?? process.cwd());
|
|
18347
|
+
for (let up = 0;up < 12; up += 1) {
|
|
18348
|
+
const stamp = join(cur, ".zalify", "brand-repo.json");
|
|
18349
|
+
if (existsSync(stamp)) {
|
|
18350
|
+
try {
|
|
18351
|
+
const link = JSON.parse(readFileSync(stamp, "utf8"));
|
|
18352
|
+
const ws = link.workspace;
|
|
18353
|
+
if (ws?.id) {
|
|
18354
|
+
return {
|
|
18355
|
+
root: cur,
|
|
18356
|
+
id: ws.id,
|
|
18357
|
+
name: ws.name ?? ws.slug ?? ws.id,
|
|
18358
|
+
slug: ws.slug ?? ws.id
|
|
18359
|
+
};
|
|
18360
|
+
}
|
|
18361
|
+
} catch {}
|
|
18362
|
+
}
|
|
18363
|
+
const identity = join(cur, "identity.yaml");
|
|
18364
|
+
if (existsSync(identity)) {
|
|
18365
|
+
const text = readFileSync(identity, "utf8");
|
|
18366
|
+
const id = /^workspace_id:\s*(\S+)\s*$/m.exec(text)?.[1];
|
|
18367
|
+
const slug = /^brand_slug:\s*(\S+)\s*$/m.exec(text)?.[1];
|
|
18368
|
+
if (id)
|
|
18369
|
+
return { root: cur, id, name: slug ?? id, slug: slug ?? id };
|
|
18370
|
+
}
|
|
18371
|
+
const parent = dirname(cur);
|
|
18372
|
+
if (parent === cur)
|
|
18373
|
+
break;
|
|
18374
|
+
cur = parent;
|
|
18375
|
+
}
|
|
18376
|
+
return null;
|
|
18377
|
+
}
|
|
18378
|
+
function requireActive(opts) {
|
|
18320
18379
|
const config = readConfig();
|
|
18321
18380
|
if (!config) {
|
|
18322
18381
|
throw new Error("Not logged in. Run `zalify login` first.");
|
|
18323
18382
|
}
|
|
18383
|
+
const here = opts?.global ? null : checkoutWorkspace();
|
|
18324
18384
|
if (config.version === 3) {
|
|
18385
|
+
if (here) {
|
|
18386
|
+
const known = config.workspacesCache?.find((w) => w.id === here.id) ?? null;
|
|
18387
|
+
return {
|
|
18388
|
+
appUrl: config.appUrl,
|
|
18389
|
+
key: config.userKey,
|
|
18390
|
+
workspaceId: here.id,
|
|
18391
|
+
workspaceName: known?.name ?? here.name,
|
|
18392
|
+
workspaceSlug: known?.slug ?? here.slug,
|
|
18393
|
+
config
|
|
18394
|
+
};
|
|
18395
|
+
}
|
|
18325
18396
|
if (!config.active) {
|
|
18326
18397
|
throw new Error("No active workspace. Run `zalify workspace list` then `zalify workspace set <slug>`.");
|
|
18327
18398
|
}
|
|
@@ -18338,7 +18409,10 @@ function requireActive() {
|
|
|
18338
18409
|
if (ids.length === 0) {
|
|
18339
18410
|
throw new Error("Not logged in. Run `zalify login` first.");
|
|
18340
18411
|
}
|
|
18341
|
-
|
|
18412
|
+
if (here && !config.workspaces[here.id]) {
|
|
18413
|
+
throw new Error(`This folder belongs to workspace "${here.slug}" but your login has no key for it. ` + "Run `zalify login` again to refresh your credentials.");
|
|
18414
|
+
}
|
|
18415
|
+
const workspaceId = here?.id ?? (config.activeWorkspaceId && config.workspaces[config.activeWorkspaceId] ? config.activeWorkspaceId : ids[0]);
|
|
18342
18416
|
const entry = config.workspaces[workspaceId];
|
|
18343
18417
|
return {
|
|
18344
18418
|
appUrl: config.appUrl,
|
|
@@ -18583,10 +18657,10 @@ async function whoami() {
|
|
|
18583
18657
|
// src/assets.ts
|
|
18584
18658
|
init_hash();
|
|
18585
18659
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync3, existsSync as existsSync2, readdirSync } from "node:fs";
|
|
18586
|
-
import { join as join2, resolve } from "node:path";
|
|
18660
|
+
import { join as join2, resolve as resolve2 } from "node:path";
|
|
18587
18661
|
var BATCH = 10;
|
|
18588
18662
|
function imagesDirFor(storeDir) {
|
|
18589
|
-
const dir2 = join2(
|
|
18663
|
+
const dir2 = join2(resolve2(storeDir), "images");
|
|
18590
18664
|
if (!existsSync2(dir2))
|
|
18591
18665
|
throw new Error(`No images/ directory in ${storeDir}`);
|
|
18592
18666
|
return dir2;
|
|
@@ -18920,7 +18994,7 @@ async function workspaceSet(slugOrId) {
|
|
|
18920
18994
|
// src/images.ts
|
|
18921
18995
|
init_hash();
|
|
18922
18996
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync4, existsSync as existsSync4, rmSync as rmSync2 } from "node:fs";
|
|
18923
|
-
import { join as join4, resolve as
|
|
18997
|
+
import { join as join4, resolve as resolve3 } from "node:path";
|
|
18924
18998
|
var MAX_JOBS_PER_REQUEST = 40;
|
|
18925
18999
|
var POLL_INTERVAL_MS = 5000;
|
|
18926
19000
|
var POLL_TIMEOUT_MS = 30 * 60 * 1000;
|
|
@@ -19085,7 +19159,7 @@ async function streamingGenerate(auth, manifest, missing, imagesDir, indexPath,
|
|
|
19085
19159
|
}
|
|
19086
19160
|
async function imagesGenerate(storeDir) {
|
|
19087
19161
|
const auth = requireActive();
|
|
19088
|
-
const imagesDir = join4(
|
|
19162
|
+
const imagesDir = join4(resolve3(storeDir), "images");
|
|
19089
19163
|
const manifestPath = join4(imagesDir, "manifest.json");
|
|
19090
19164
|
if (!existsSync4(manifestPath)) {
|
|
19091
19165
|
throw new Error(`No images/manifest.json in ${storeDir}`);
|
|
@@ -19128,12 +19202,12 @@ async function imagesGenerate(storeDir) {
|
|
|
19128
19202
|
|
|
19129
19203
|
// src/shopify.ts
|
|
19130
19204
|
import { readFileSync as readFileSync6, existsSync as existsSync7 } from "node:fs";
|
|
19131
|
-
import { basename as basename3, join as join7, resolve as
|
|
19205
|
+
import { basename as basename3, join as join7, resolve as resolve6 } from "node:path";
|
|
19132
19206
|
|
|
19133
19207
|
// src/shop.ts
|
|
19134
19208
|
import { spawn as spawn3, spawnSync as spawnSync3 } from "node:child_process";
|
|
19135
19209
|
import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync6 } from "node:fs";
|
|
19136
|
-
import { basename as basename2, join as join6, resolve as
|
|
19210
|
+
import { basename as basename2, join as join6, resolve as resolve5 } from "node:path";
|
|
19137
19211
|
|
|
19138
19212
|
// src/theme.ts
|
|
19139
19213
|
init_hash();
|
|
@@ -19153,7 +19227,7 @@ import {
|
|
|
19153
19227
|
writeFileSync as writeFileSync5
|
|
19154
19228
|
} from "node:fs";
|
|
19155
19229
|
import { tmpdir } from "node:os";
|
|
19156
|
-
import { basename, dirname, join as join5, resolve as
|
|
19230
|
+
import { basename, dirname as dirname2, join as join5, resolve as resolve4 } from "node:path";
|
|
19157
19231
|
var TEMPLATES_PKG = "@zalify/theme-templates";
|
|
19158
19232
|
var REGISTRY = "https://registry.npmjs.org";
|
|
19159
19233
|
var MANIFEST_PATH = ".zalify/theme.json";
|
|
@@ -19185,7 +19259,7 @@ async function downloadTarball(url) {
|
|
|
19185
19259
|
}
|
|
19186
19260
|
function extractTarball(file2) {
|
|
19187
19261
|
const dir2 = mkdtempSync(join5(tmpdir(), "zalify-theme-x-"));
|
|
19188
|
-
const result = spawnSync2("tar", ["-xzf",
|
|
19262
|
+
const result = spawnSync2("tar", ["-xzf", resolve4(file2), "-C", dir2], {
|
|
19189
19263
|
encoding: "utf8"
|
|
19190
19264
|
});
|
|
19191
19265
|
if (result.error || result.status !== 0) {
|
|
@@ -19253,7 +19327,7 @@ function writeJson(path9, value) {
|
|
|
19253
19327
|
`);
|
|
19254
19328
|
}
|
|
19255
19329
|
async function themeCreate(dir2, opts) {
|
|
19256
|
-
const targetDir =
|
|
19330
|
+
const targetDir = resolve4(dir2);
|
|
19257
19331
|
if (existsSync5(targetDir) && readdirSync2(targetDir).length > 0) {
|
|
19258
19332
|
throw new Error(`${dir2} already exists and is not empty`);
|
|
19259
19333
|
}
|
|
@@ -19337,7 +19411,7 @@ Runs on mock.shop demo data out of the box — edit .env to connect your store.`
|
|
|
19337
19411
|
console.log("Your theme customizations live in theme/ — see theme/README.md.");
|
|
19338
19412
|
}
|
|
19339
19413
|
function themeStatus(dir2 = ".") {
|
|
19340
|
-
const projectDir =
|
|
19414
|
+
const projectDir = resolve4(dir2);
|
|
19341
19415
|
const manifest = readProjectManifest(projectDir);
|
|
19342
19416
|
console.log(`${manifest.template} theme, ${TEMPLATES_PKG}@${manifest.version}` + (manifest.variant === "editor" ? " (editor variant)" : ""));
|
|
19343
19417
|
let clean = 0;
|
|
@@ -19365,7 +19439,7 @@ function looksBinary(...buffers) {
|
|
|
19365
19439
|
return buffers.some((b) => b.subarray(0, 8000).includes(0));
|
|
19366
19440
|
}
|
|
19367
19441
|
async function themeUpgrade(dir2 = ".", opts = {}) {
|
|
19368
|
-
const projectDir =
|
|
19442
|
+
const projectDir = resolve4(dir2);
|
|
19369
19443
|
const local = readProjectManifest(projectDir);
|
|
19370
19444
|
const variant = local.variant ?? "default";
|
|
19371
19445
|
const target = await acquireTemplatePkg(opts.tarball, opts.to);
|
|
@@ -19405,7 +19479,7 @@ async function themeUpgrade(dir2 = ".", opts = {}) {
|
|
|
19405
19479
|
const write = (bytes) => {
|
|
19406
19480
|
if (opts.dryRun)
|
|
19407
19481
|
return;
|
|
19408
|
-
mkdirSync2(
|
|
19482
|
+
mkdirSync2(dirname2(localPath), { recursive: true });
|
|
19409
19483
|
writeFileSync5(localPath, bytes);
|
|
19410
19484
|
};
|
|
19411
19485
|
if (oldHash && newHash) {
|
|
@@ -19629,7 +19703,7 @@ async function pollUntilReady(auth, id) {
|
|
|
19629
19703
|
}
|
|
19630
19704
|
async function shopCreate(dir2, opts) {
|
|
19631
19705
|
const auth = requireActive();
|
|
19632
|
-
const slug = basename2(
|
|
19706
|
+
const slug = basename2(resolve5(dir2)).toLowerCase().replaceAll(/[^a-z0-9-]+/g, "-").replaceAll(/^-+|-+$/g, "") || "site";
|
|
19633
19707
|
console.log(`Provisioning shop "${slug}" (workspace "${auth.workspaceName}")`);
|
|
19634
19708
|
const created = await request(auth, "POST", "/api/sites", {
|
|
19635
19709
|
slug,
|
|
@@ -19650,17 +19724,17 @@ async function shopCreate(dir2, opts) {
|
|
|
19650
19724
|
install: opts.install,
|
|
19651
19725
|
git: opts.git
|
|
19652
19726
|
});
|
|
19653
|
-
writeFileSync6(join6(
|
|
19727
|
+
writeFileSync6(join6(resolve5(dir2), ".zalify", "site.json"), JSON.stringify({ id: siteId, slug: view.slug, domain: view.domain, repo: view.githubRepo }, null, 2) + `
|
|
19654
19728
|
`);
|
|
19655
|
-
writeFileSync6(join6(
|
|
19729
|
+
writeFileSync6(join6(resolve5(dir2), "theme", "pixel.json"), JSON.stringify({ workspaceId: auth.workspaceId }, null, 2) + `
|
|
19656
19730
|
`);
|
|
19657
19731
|
if (opts.git !== false && view.githubRepo) {
|
|
19658
19732
|
const { token, repo } = await request(auth, "POST", `/api/sites/${siteId}/push-token`, {});
|
|
19659
|
-
const run = (args) => spawnSync3("git", args, { cwd:
|
|
19733
|
+
const run = (args) => spawnSync3("git", args, { cwd: resolve5(dir2), stdio: "ignore" });
|
|
19660
19734
|
run(["add", ".zalify/site.json", "theme/pixel.json"]);
|
|
19661
19735
|
run(["commit", "-m", "Link site record", "--no-verify"]);
|
|
19662
19736
|
run(["remote", "add", "origin", `https://github.com/${repo}.git`]);
|
|
19663
|
-
const push = spawnSync3("git", ["push", `https://x-access-token:${token}@github.com/${repo}.git`, "main"], { cwd:
|
|
19737
|
+
const push = spawnSync3("git", ["push", `https://x-access-token:${token}@github.com/${repo}.git`, "main"], { cwd: resolve5(dir2), stdio: "inherit" });
|
|
19664
19738
|
if (push.status !== 0) {
|
|
19665
19739
|
throw new Error(`git push to ${repo} failed — resolve and push manually.`);
|
|
19666
19740
|
}
|
|
@@ -19708,8 +19782,8 @@ async function resolveSite(auth, slugOrDir) {
|
|
|
19708
19782
|
return null;
|
|
19709
19783
|
};
|
|
19710
19784
|
let slug = null;
|
|
19711
|
-
if (slugOrDir && existsSync6(
|
|
19712
|
-
slug = fromDir(
|
|
19785
|
+
if (slugOrDir && existsSync6(resolve5(slugOrDir)))
|
|
19786
|
+
slug = fromDir(resolve5(slugOrDir));
|
|
19713
19787
|
if (!slug && slugOrDir)
|
|
19714
19788
|
slug = slugOrDir;
|
|
19715
19789
|
if (!slug)
|
|
@@ -19769,7 +19843,7 @@ async function maybeRefreshShops(auth, brandDir, siteSlugOverride) {
|
|
|
19769
19843
|
try {
|
|
19770
19844
|
let slug = siteSlugOverride ?? null;
|
|
19771
19845
|
if (!slug) {
|
|
19772
|
-
const storeJson = join6(
|
|
19846
|
+
const storeJson = join6(resolve5(brandDir), "store.json");
|
|
19773
19847
|
if (existsSync6(storeJson)) {
|
|
19774
19848
|
slug = JSON.parse(readFileSync5(storeJson, "utf8")).slug ?? null;
|
|
19775
19849
|
}
|
|
@@ -19854,7 +19928,7 @@ async function findProductId(auth, handle) {
|
|
|
19854
19928
|
}
|
|
19855
19929
|
async function shopifyImport(storeDir, options = {}) {
|
|
19856
19930
|
const auth = requireActive();
|
|
19857
|
-
const dir2 =
|
|
19931
|
+
const dir2 = resolve6(storeDir);
|
|
19858
19932
|
const catalog = readJson(join7(dir2, "catalog.json"), "catalog.json");
|
|
19859
19933
|
const { locations } = await gql(auth, `{ locations(first: 1) { nodes { id name } } }`);
|
|
19860
19934
|
const locationId = locations.nodes[0]?.id;
|
|
@@ -20063,7 +20137,7 @@ async function shopifyImport(storeDir, options = {}) {
|
|
|
20063
20137
|
}
|
|
20064
20138
|
async function shopifyUploadImages(storeDir, options = {}) {
|
|
20065
20139
|
const auth = requireActive();
|
|
20066
|
-
const dir2 =
|
|
20140
|
+
const dir2 = resolve6(storeDir);
|
|
20067
20141
|
const manifest = readJson(join7(dir2, "images", "manifest.json"), "images/manifest.json");
|
|
20068
20142
|
console.log(`Uploading images to the Shopify store connected to workspace "${auth.workspaceName}"`);
|
|
20069
20143
|
for (const entry of manifest.images) {
|
|
@@ -20145,7 +20219,7 @@ async function shopifyUploadImages(storeDir, options = {}) {
|
|
|
20145
20219
|
// src/ads.ts
|
|
20146
20220
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
20147
20221
|
import { existsSync as existsSync8, mkdirSync as mkdirSync3, readdirSync as readdirSync3, writeFileSync as writeFileSync7 } from "node:fs";
|
|
20148
|
-
import { basename as basename4, join as join8, relative, resolve as
|
|
20222
|
+
import { basename as basename4, join as join8, relative, resolve as resolve7 } from "node:path";
|
|
20149
20223
|
import { createInterface } from "node:readline/promises";
|
|
20150
20224
|
function apiError3(status, json) {
|
|
20151
20225
|
if (json.code === "SLUG_TAKEN") {
|
|
@@ -20197,7 +20271,7 @@ async function pollUntilReady2(auth, id) {
|
|
|
20197
20271
|
throw new Error("Provisioning timed out after 5 minutes — check the Temporal UI.");
|
|
20198
20272
|
}
|
|
20199
20273
|
function scaffoldStarter(dir2, slug, workspaceId) {
|
|
20200
|
-
const root =
|
|
20274
|
+
const root = resolve7(dir2);
|
|
20201
20275
|
const write = (rel, content) => {
|
|
20202
20276
|
const abs = join8(root, rel);
|
|
20203
20277
|
mkdirSync3(join8(abs, ".."), { recursive: true });
|
|
@@ -20250,24 +20324,33 @@ mirrors decisions into \`decisions/\` and daily signal digests into
|
|
|
20250
20324
|
`);
|
|
20251
20325
|
}
|
|
20252
20326
|
async function adsCreate(dir2) {
|
|
20253
|
-
const auth = requireActive();
|
|
20254
|
-
const slug = basename4(
|
|
20327
|
+
const auth = requireActive({ global: true });
|
|
20328
|
+
const slug = basename4(resolve7(dir2)).toLowerCase().replaceAll(/[^a-z0-9-]+/g, "-").replaceAll(/^-+|-+$/g, "") || "brand";
|
|
20255
20329
|
console.log(`Provisioning brand instance "${slug}" (workspace "${auth.workspaceName}")`);
|
|
20256
20330
|
const created = await request2(auth, "POST", "/api/repos", { slug });
|
|
20257
20331
|
const view = await pollUntilReady2(auth, created.repoId);
|
|
20258
20332
|
console.log(` ✓ provisioned: ${view.githubRepo}`);
|
|
20259
20333
|
scaffoldStarter(dir2, slug, auth.workspaceId);
|
|
20260
|
-
mkdirSync3(join8(
|
|
20261
|
-
writeFileSync7(join8(
|
|
20334
|
+
mkdirSync3(join8(resolve7(dir2), ".zalify"), { recursive: true });
|
|
20335
|
+
writeFileSync7(join8(resolve7(dir2), ".zalify", "brand-repo.json"), JSON.stringify({
|
|
20336
|
+
id: created.repoId,
|
|
20337
|
+
slug: view.slug,
|
|
20338
|
+
repo: view.githubRepo,
|
|
20339
|
+
workspace: {
|
|
20340
|
+
id: auth.workspaceId,
|
|
20341
|
+
name: auth.workspaceName,
|
|
20342
|
+
slug: auth.workspaceSlug
|
|
20343
|
+
}
|
|
20344
|
+
}, null, 2) + `
|
|
20262
20345
|
`);
|
|
20263
20346
|
if (view.githubRepo) {
|
|
20264
20347
|
const { token, repo } = await request2(auth, "POST", `/api/repos/${created.repoId}/push-token`, {});
|
|
20265
|
-
const run = (args) => spawnSync4("git", args, { cwd:
|
|
20348
|
+
const run = (args) => spawnSync4("git", args, { cwd: resolve7(dir2), stdio: "ignore" });
|
|
20266
20349
|
run(["init", "-b", "main"]);
|
|
20267
20350
|
run(["add", "-A"]);
|
|
20268
20351
|
run(["commit", "-m", "Scaffold brand instance", "--no-verify"]);
|
|
20269
20352
|
run(["remote", "add", "origin", `https://github.com/${repo}.git`]);
|
|
20270
|
-
const push = spawnSync4("git", ["push", `https://x-access-token:${token}@github.com/${repo}.git`, "main"], { cwd:
|
|
20353
|
+
const push = spawnSync4("git", ["push", `https://x-access-token:${token}@github.com/${repo}.git`, "main"], { cwd: resolve7(dir2), stdio: "inherit" });
|
|
20271
20354
|
if (push.status !== 0) {
|
|
20272
20355
|
throw new Error(`git push to ${repo} failed — resolve and push manually.`);
|
|
20273
20356
|
}
|
|
@@ -20284,7 +20367,7 @@ Next steps:
|
|
|
20284
20367
|
}
|
|
20285
20368
|
var CAMPAIGN_NAME_RE = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
20286
20369
|
function campaignParent(account) {
|
|
20287
|
-
const cwd =
|
|
20370
|
+
const cwd = resolve7(".");
|
|
20288
20371
|
const inCheckout = existsSync8(join8(cwd, ".zalify", "brand-repo.json")) || existsSync8(join8(cwd, "accounts"));
|
|
20289
20372
|
if (!inCheckout) {
|
|
20290
20373
|
throw new Error("Not inside a brand-instance checkout — run from the repo `zalify ads create` made.");
|
|
@@ -20342,7 +20425,7 @@ ad_sets:
|
|
|
20342
20425
|
age: 18-65
|
|
20343
20426
|
advantage: true
|
|
20344
20427
|
`);
|
|
20345
|
-
console.log(`✓ ${relative(
|
|
20428
|
+
console.log(`✓ ${relative(resolve7("."), dir2)}/ is ready`);
|
|
20346
20429
|
console.log(" 1. drag images into creatives/");
|
|
20347
20430
|
console.log(" 2. fill primary_text and link in campaign.yaml");
|
|
20348
20431
|
console.log(" 3. `zalify ads sync` when it lands — validate, diff, apply");
|
|
@@ -20381,7 +20464,7 @@ import {
|
|
|
20381
20464
|
readFileSync as readFileSync8,
|
|
20382
20465
|
writeFileSync as writeFileSync9
|
|
20383
20466
|
} from "node:fs";
|
|
20384
|
-
import { join as join10, resolve as
|
|
20467
|
+
import { join as join10, resolve as resolve8 } from "node:path";
|
|
20385
20468
|
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
20386
20469
|
|
|
20387
20470
|
// node_modules/yaml/dist/index.js
|
|
@@ -20543,7 +20626,7 @@ async function adsCreativeGenerate(opts) {
|
|
|
20543
20626
|
|
|
20544
20627
|
// src/ads-diff.ts
|
|
20545
20628
|
function root() {
|
|
20546
|
-
const cwd =
|
|
20629
|
+
const cwd = resolve8(".");
|
|
20547
20630
|
if (existsSync10(join10(cwd, ".zalify", "brand-repo.json")) || existsSync10(join10(cwd, "campaigns"))) {
|
|
20548
20631
|
return cwd;
|
|
20549
20632
|
}
|
|
@@ -20630,6 +20713,7 @@ ${s.creates} to create, ${s.updates} to update, ${s.unchanged} unchanged` + `${r
|
|
|
20630
20713
|
async function adsDiff() {
|
|
20631
20714
|
const auth = requireActive();
|
|
20632
20715
|
const base = root();
|
|
20716
|
+
enforceWorkspaceLink(base, auth);
|
|
20633
20717
|
const { files } = await collect(base);
|
|
20634
20718
|
if (files.length === 0) {
|
|
20635
20719
|
console.log("No campaign files — `zalify ads pull` or `zalify ads new` first.");
|
|
@@ -20647,6 +20731,7 @@ async function adsDiff() {
|
|
|
20647
20731
|
async function adsApply(opts) {
|
|
20648
20732
|
const auth = requireActive();
|
|
20649
20733
|
const base = root();
|
|
20734
|
+
enforceWorkspaceLink(base, auth);
|
|
20650
20735
|
const { files } = await collect(base);
|
|
20651
20736
|
if (files.length === 0) {
|
|
20652
20737
|
console.log("No campaign files — `zalify ads pull` or `zalify ads new` first.");
|
|
@@ -20710,10 +20795,10 @@ import {
|
|
|
20710
20795
|
readFileSync as readFileSync9,
|
|
20711
20796
|
writeFileSync as writeFileSync10
|
|
20712
20797
|
} from "node:fs";
|
|
20713
|
-
import { dirname as
|
|
20798
|
+
import { dirname as dirname3, join as join11, resolve as resolve9 } from "node:path";
|
|
20714
20799
|
var sha = (s) => createHash2("sha256").update(s).digest("hex");
|
|
20715
20800
|
function checkoutRoot() {
|
|
20716
|
-
const cwd =
|
|
20801
|
+
const cwd = resolve9(".");
|
|
20717
20802
|
if (existsSync11(join11(cwd, ".zalify", "brand-repo.json")) || existsSync11(join11(cwd, "accounts")) || existsSync11(join11(cwd, "campaigns"))) {
|
|
20718
20803
|
return cwd;
|
|
20719
20804
|
}
|
|
@@ -20734,6 +20819,7 @@ function readBindings(root2) {
|
|
|
20734
20819
|
async function adsPull(opts) {
|
|
20735
20820
|
const auth = requireActive();
|
|
20736
20821
|
const root2 = checkoutRoot();
|
|
20822
|
+
enforceWorkspaceLink(root2, auth);
|
|
20737
20823
|
const params = new URLSearchParams;
|
|
20738
20824
|
if (opts.account)
|
|
20739
20825
|
params.set("account", opts.account);
|
|
@@ -20784,7 +20870,7 @@ async function adsPull(opts) {
|
|
|
20784
20870
|
continue;
|
|
20785
20871
|
}
|
|
20786
20872
|
}
|
|
20787
|
-
mkdirSync5(
|
|
20873
|
+
mkdirSync5(dirname3(abs), { recursive: true });
|
|
20788
20874
|
writeFileSync10(abs, f.yaml);
|
|
20789
20875
|
bindings.pulled[f.path] = nextHash;
|
|
20790
20876
|
written += 1;
|
|
@@ -20798,7 +20884,7 @@ async function adsPull(opts) {
|
|
|
20798
20884
|
bindings.nodes[key] = v;
|
|
20799
20885
|
}
|
|
20800
20886
|
const bindingsPath = join11(root2, "accounts", ".bindings.json");
|
|
20801
|
-
mkdirSync5(
|
|
20887
|
+
mkdirSync5(dirname3(bindingsPath), { recursive: true });
|
|
20802
20888
|
writeFileSync10(bindingsPath, `${JSON.stringify(bindings, null, 2)}
|
|
20803
20889
|
`);
|
|
20804
20890
|
const exported = new Set(result.files.map((f) => f.path));
|
|
@@ -20824,7 +20910,7 @@ Review with git diff; commit when it reads right.`);
|
|
|
20824
20910
|
// src/ads-read.ts
|
|
20825
20911
|
import { spawn as spawn4 } from "node:child_process";
|
|
20826
20912
|
import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node:fs";
|
|
20827
|
-
import { join as join12, resolve as
|
|
20913
|
+
import { join as join12, resolve as resolve10 } from "node:path";
|
|
20828
20914
|
async function serviceGet(auth, path9) {
|
|
20829
20915
|
const res = await fetch(`${auth.appUrl}/api/autopilot/${path9}`, {
|
|
20830
20916
|
headers: {
|
|
@@ -20912,7 +20998,7 @@ account changes: not tracked for this platform yet` : `
|
|
|
20912
20998
|
account changes: ${a.byPerson} by people, ${a.byMeta} automated`);
|
|
20913
20999
|
}
|
|
20914
21000
|
function adsDigest(dir2) {
|
|
20915
|
-
const root2 =
|
|
21001
|
+
const root2 = resolve10(dir2 ?? ".");
|
|
20916
21002
|
const path9 = join12(root2, "signals", "latest.json");
|
|
20917
21003
|
if (!existsSync12(path9)) {
|
|
20918
21004
|
throw new Error("signals/latest.json not found — run from a brand-instance checkout " + "(and pull: the service commits a digest daily).");
|
|
@@ -20956,7 +21042,7 @@ function adsOpen() {
|
|
|
20956
21042
|
}
|
|
20957
21043
|
async function adsDoctor(dir2) {
|
|
20958
21044
|
const auth = requireActive();
|
|
20959
|
-
const root2 =
|
|
21045
|
+
const root2 = resolve10(dir2 ?? ".");
|
|
20960
21046
|
let failed = 0;
|
|
20961
21047
|
const ok = (msg) => console.log(` ✓ ${msg}`);
|
|
20962
21048
|
const bad = (msg) => {
|
|
@@ -21042,7 +21128,7 @@ ${failed} problem${failed > 1 ? "s" : ""}.`);
|
|
|
21042
21128
|
|
|
21043
21129
|
// src/brand.ts
|
|
21044
21130
|
import { existsSync as existsSync13, mkdirSync as mkdirSync6, readdirSync as readdirSync6, readFileSync as readFileSync11, writeFileSync as writeFileSync11 } from "node:fs";
|
|
21045
|
-
import { basename as basename5, join as join13, resolve as
|
|
21131
|
+
import { basename as basename5, join as join13, resolve as resolve11 } from "node:path";
|
|
21046
21132
|
var AUTHORING_MD = `# Brand authoring guide
|
|
21047
21133
|
|
|
21048
21134
|
The rules for filling in this folder. An author — human or AI agent —
|
|
@@ -21343,7 +21429,7 @@ var MANIFEST_JSON = JSON.stringify({
|
|
|
21343
21429
|
}, null, 2) + `
|
|
21344
21430
|
`;
|
|
21345
21431
|
function brandInit(dir2 = ".", opts = {}) {
|
|
21346
|
-
const target =
|
|
21432
|
+
const target = resolve11(dir2);
|
|
21347
21433
|
const slug = basename5(target).toLowerCase().replaceAll(/[^a-z0-9-]+/g, "-").replaceAll(/^-+|-+$/g, "");
|
|
21348
21434
|
if (existsSync13(target) && readdirSync6(target).length > 0) {
|
|
21349
21435
|
throw new Error(`${dir2} already exists and is not empty`);
|
|
@@ -21366,7 +21452,7 @@ Author in this order: brand.md → catalog.json → images/manifest.json` + `
|
|
|
21366
21452
|
}
|
|
21367
21453
|
var MANIFEST_SIZES = new Set(["1024x1024", "1536x1024", "1024x1536"]);
|
|
21368
21454
|
function brandValidate(dir2 = ".") {
|
|
21369
|
-
const target =
|
|
21455
|
+
const target = resolve11(dir2);
|
|
21370
21456
|
const problems = [];
|
|
21371
21457
|
const warnings = [];
|
|
21372
21458
|
const readJson2 = (rel) => {
|
|
@@ -21556,7 +21642,7 @@ function brandValidate(dir2 = ".") {
|
|
|
21556
21642
|
}
|
|
21557
21643
|
|
|
21558
21644
|
// src/cli.ts
|
|
21559
|
-
var __dirname4 =
|
|
21645
|
+
var __dirname4 = dirname4(fileURLToPath3(import.meta.url));
|
|
21560
21646
|
var require2 = createRequire2(import.meta.url);
|
|
21561
21647
|
var pkg = require2(join14(__dirname4, "..", "package.json"));
|
|
21562
21648
|
try {
|