@zalify/cli 0.2.4 → 0.4.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/dist/cli.js +244 -38
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -11308,11 +11308,36 @@ import { homedir } from "node:os";
|
|
|
11308
11308
|
import { join } from "node:path";
|
|
11309
11309
|
var dir = join(homedir(), ".zalify");
|
|
11310
11310
|
var file = join(dir, "config.json");
|
|
11311
|
+
function migrate(raw) {
|
|
11312
|
+
if (!raw || typeof raw !== "object")
|
|
11313
|
+
return null;
|
|
11314
|
+
const obj = raw;
|
|
11315
|
+
if (obj.version === 3 && obj.userKey && obj.appUrl)
|
|
11316
|
+
return obj;
|
|
11317
|
+
if (obj.version === 2 && obj.workspaces && obj.appUrl)
|
|
11318
|
+
return obj;
|
|
11319
|
+
if (typeof obj.key === "string" && typeof obj.workspaceId === "string") {
|
|
11320
|
+
return {
|
|
11321
|
+
version: 2,
|
|
11322
|
+
appUrl: obj.appUrl ?? "https://app.zalify.com",
|
|
11323
|
+
activeWorkspaceId: obj.workspaceId,
|
|
11324
|
+
workspaces: {
|
|
11325
|
+
[obj.workspaceId]: {
|
|
11326
|
+
key: obj.key,
|
|
11327
|
+
name: obj.workspaceName ?? "",
|
|
11328
|
+
slug: obj.workspaceSlug ?? "",
|
|
11329
|
+
createdAt: obj.createdAt ?? new Date().toISOString()
|
|
11330
|
+
}
|
|
11331
|
+
}
|
|
11332
|
+
};
|
|
11333
|
+
}
|
|
11334
|
+
return null;
|
|
11335
|
+
}
|
|
11311
11336
|
function readConfig() {
|
|
11312
11337
|
if (!existsSync(file))
|
|
11313
11338
|
return null;
|
|
11314
11339
|
try {
|
|
11315
|
-
return JSON.parse(readFileSync(file, "utf8"));
|
|
11340
|
+
return migrate(JSON.parse(readFileSync(file, "utf8")));
|
|
11316
11341
|
} catch {
|
|
11317
11342
|
return null;
|
|
11318
11343
|
}
|
|
@@ -11325,12 +11350,38 @@ function writeConfig(config) {
|
|
|
11325
11350
|
function deleteConfig() {
|
|
11326
11351
|
rmSync(file, { force: true });
|
|
11327
11352
|
}
|
|
11328
|
-
function
|
|
11353
|
+
function requireActive() {
|
|
11329
11354
|
const config = readConfig();
|
|
11330
|
-
if (!config
|
|
11355
|
+
if (!config) {
|
|
11331
11356
|
throw new Error("Not logged in. Run `zalify login` first.");
|
|
11332
11357
|
}
|
|
11333
|
-
|
|
11358
|
+
if (config.version === 3) {
|
|
11359
|
+
if (!config.active) {
|
|
11360
|
+
throw new Error("No active workspace. Run `zalify workspace list` then `zalify workspace set <slug>`.");
|
|
11361
|
+
}
|
|
11362
|
+
return {
|
|
11363
|
+
appUrl: config.appUrl,
|
|
11364
|
+
key: config.userKey,
|
|
11365
|
+
workspaceId: config.active.id,
|
|
11366
|
+
workspaceName: config.active.name,
|
|
11367
|
+
workspaceSlug: config.active.slug,
|
|
11368
|
+
config
|
|
11369
|
+
};
|
|
11370
|
+
}
|
|
11371
|
+
const ids = Object.keys(config.workspaces);
|
|
11372
|
+
if (ids.length === 0) {
|
|
11373
|
+
throw new Error("Not logged in. Run `zalify login` first.");
|
|
11374
|
+
}
|
|
11375
|
+
const workspaceId = config.activeWorkspaceId && config.workspaces[config.activeWorkspaceId] ? config.activeWorkspaceId : ids[0];
|
|
11376
|
+
const entry = config.workspaces[workspaceId];
|
|
11377
|
+
return {
|
|
11378
|
+
appUrl: config.appUrl,
|
|
11379
|
+
key: entry.key,
|
|
11380
|
+
workspaceId,
|
|
11381
|
+
workspaceName: entry.name,
|
|
11382
|
+
workspaceSlug: entry.slug,
|
|
11383
|
+
config
|
|
11384
|
+
};
|
|
11334
11385
|
}
|
|
11335
11386
|
|
|
11336
11387
|
// src/auth.ts
|
|
@@ -11346,10 +11397,26 @@ function openBrowser(url) {
|
|
|
11346
11397
|
detached: true
|
|
11347
11398
|
}).unref();
|
|
11348
11399
|
}
|
|
11400
|
+
function decodePayload(encoded) {
|
|
11401
|
+
const b64 = encoded.replace(/-/g, "+").replace(/_/g, "/");
|
|
11402
|
+
return JSON.parse(Buffer.from(b64, "base64").toString("utf8"));
|
|
11403
|
+
}
|
|
11404
|
+
async function fetchWorkspaces(appUrl, userKey) {
|
|
11405
|
+
try {
|
|
11406
|
+
const res = await fetch(`${appUrl}/api/cli/workspaces`, {
|
|
11407
|
+
headers: { Authorization: `Bearer ${userKey}` }
|
|
11408
|
+
});
|
|
11409
|
+
if (!res.ok)
|
|
11410
|
+
return [];
|
|
11411
|
+
return (await res.json()).workspaces;
|
|
11412
|
+
} catch {
|
|
11413
|
+
return [];
|
|
11414
|
+
}
|
|
11415
|
+
}
|
|
11349
11416
|
async function login(options) {
|
|
11350
11417
|
const base = (options.appUrl || readConfig()?.appUrl || DEFAULT_APP_URL).replace(/\/$/, "");
|
|
11351
11418
|
const state = randomBytes(32).toString("hex");
|
|
11352
|
-
const
|
|
11419
|
+
const payload = await new Promise((resolvePromise, reject) => {
|
|
11353
11420
|
const timer = setTimeout(() => {
|
|
11354
11421
|
server.close();
|
|
11355
11422
|
server.closeAllConnections();
|
|
@@ -11387,22 +11454,38 @@ async function login(options) {
|
|
|
11387
11454
|
});
|
|
11388
11455
|
return;
|
|
11389
11456
|
}
|
|
11390
|
-
const
|
|
11391
|
-
|
|
11392
|
-
|
|
11457
|
+
const encoded = url.searchParams.get("payload");
|
|
11458
|
+
const legacyKey = url.searchParams.get("key");
|
|
11459
|
+
let parsed = null;
|
|
11460
|
+
if (encoded) {
|
|
11461
|
+
try {
|
|
11462
|
+
parsed = decodePayload(encoded);
|
|
11463
|
+
} catch {
|
|
11464
|
+
parsed = null;
|
|
11465
|
+
}
|
|
11466
|
+
} else if (legacyKey) {
|
|
11467
|
+
parsed = {
|
|
11468
|
+
keys: [
|
|
11469
|
+
{
|
|
11470
|
+
workspaceId: url.searchParams.get("workspace_id") ?? "",
|
|
11471
|
+
workspaceName: url.searchParams.get("workspace_name") ?? "",
|
|
11472
|
+
workspaceSlug: url.searchParams.get("workspace_slug") ?? "",
|
|
11473
|
+
key: legacyKey
|
|
11474
|
+
}
|
|
11475
|
+
]
|
|
11476
|
+
};
|
|
11477
|
+
}
|
|
11478
|
+
if (!parsed || !parsed.userKey && !parsed.keys?.length) {
|
|
11479
|
+
done("Login failed: no credentials in callback.", () => {
|
|
11393
11480
|
teardown();
|
|
11394
|
-
reject(new Error("Callback did not include
|
|
11481
|
+
reject(new Error("Callback did not include credentials."));
|
|
11395
11482
|
});
|
|
11396
11483
|
return;
|
|
11397
11484
|
}
|
|
11485
|
+
const result = parsed;
|
|
11398
11486
|
done("Logged in!", () => {
|
|
11399
11487
|
teardown();
|
|
11400
|
-
resolvePromise(
|
|
11401
|
-
key,
|
|
11402
|
-
workspaceId: url.searchParams.get("workspace_id") ?? "",
|
|
11403
|
-
workspaceName: url.searchParams.get("workspace_name") ?? "",
|
|
11404
|
-
workspaceSlug: url.searchParams.get("workspace_slug") ?? ""
|
|
11405
|
-
});
|
|
11488
|
+
resolvePromise(result);
|
|
11406
11489
|
});
|
|
11407
11490
|
});
|
|
11408
11491
|
server.listen(0, "127.0.0.1", () => {
|
|
@@ -11416,13 +11499,57 @@ async function login(options) {
|
|
|
11416
11499
|
});
|
|
11417
11500
|
server.on("error", reject);
|
|
11418
11501
|
});
|
|
11419
|
-
|
|
11420
|
-
|
|
11502
|
+
if (payload.userKey && payload.user) {
|
|
11503
|
+
const previous = readConfig();
|
|
11504
|
+
const previousActive = previous?.version === 3 ? previous.active : previous?.version === 2 && previous.activeWorkspaceId ? {
|
|
11505
|
+
id: previous.activeWorkspaceId,
|
|
11506
|
+
name: previous.workspaces[previous.activeWorkspaceId]?.name ?? "",
|
|
11507
|
+
slug: previous.workspaces[previous.activeWorkspaceId]?.slug ?? ""
|
|
11508
|
+
} : null;
|
|
11509
|
+
const workspaces = await fetchWorkspaces(base, payload.userKey);
|
|
11510
|
+
const active = previousActive && workspaces.find((w) => w.id === previousActive.id) || workspaces[0] || previousActive || null;
|
|
11511
|
+
writeConfig({
|
|
11512
|
+
version: 3,
|
|
11513
|
+
appUrl: base,
|
|
11514
|
+
userKey: payload.userKey,
|
|
11515
|
+
user: payload.user,
|
|
11516
|
+
active,
|
|
11517
|
+
workspacesCache: workspaces
|
|
11518
|
+
});
|
|
11519
|
+
console.log(`✓ Logged in as ${payload.user.name ?? payload.user.email ?? payload.user.id} — key covers ${workspaces.length || "your"} workspace(s), expires in 90 days.`);
|
|
11520
|
+
if (active)
|
|
11521
|
+
console.log(` Active workspace: ${active.name} (${active.slug})`);
|
|
11522
|
+
console.log(" Switch with `zalify workspace set <slug>`.");
|
|
11523
|
+
return;
|
|
11524
|
+
}
|
|
11525
|
+
const existing = readConfig();
|
|
11526
|
+
const config = {
|
|
11527
|
+
version: 2,
|
|
11528
|
+
appUrl: base,
|
|
11529
|
+
activeWorkspaceId: existing?.version === 2 ? existing.activeWorkspaceId : null,
|
|
11530
|
+
workspaces: {
|
|
11531
|
+
...existing?.version === 2 && existing.appUrl === base ? existing.workspaces : {}
|
|
11532
|
+
}
|
|
11533
|
+
};
|
|
11534
|
+
const now = new Date().toISOString();
|
|
11535
|
+
for (const k of payload.keys ?? []) {
|
|
11536
|
+
config.workspaces[k.workspaceId] = {
|
|
11537
|
+
key: k.key,
|
|
11538
|
+
name: k.workspaceName,
|
|
11539
|
+
slug: k.workspaceSlug,
|
|
11540
|
+
createdAt: now
|
|
11541
|
+
};
|
|
11542
|
+
}
|
|
11543
|
+
if (!config.activeWorkspaceId || !config.workspaces[config.activeWorkspaceId]) {
|
|
11544
|
+
config.activeWorkspaceId = payload.keys?.[0]?.workspaceId ?? null;
|
|
11545
|
+
}
|
|
11546
|
+
writeConfig(config);
|
|
11547
|
+
console.log(`✓ Authorized ${payload.keys?.length ?? 0} workspace(s) (legacy keys).`);
|
|
11421
11548
|
}
|
|
11422
11549
|
function logout() {
|
|
11423
11550
|
deleteConfig();
|
|
11424
11551
|
console.log("✓ Logged out (local credentials deleted).");
|
|
11425
|
-
console.log("
|
|
11552
|
+
console.log(" CLI keys expire after 90 days; revoke sooner via app.zalify.com if needed.");
|
|
11426
11553
|
}
|
|
11427
11554
|
function ago(iso) {
|
|
11428
11555
|
if (!iso)
|
|
@@ -11439,17 +11566,15 @@ function ago(iso) {
|
|
|
11439
11566
|
return `${Math.round(hours / 24)}d ago`;
|
|
11440
11567
|
}
|
|
11441
11568
|
async function whoami() {
|
|
11442
|
-
const
|
|
11569
|
+
const auth = requireActive();
|
|
11443
11570
|
let live = null;
|
|
11444
11571
|
let liveError = null;
|
|
11445
11572
|
try {
|
|
11446
|
-
const res = await fetch(`${
|
|
11447
|
-
headers: { Authorization: `Bearer ${config.key}` }
|
|
11448
|
-
});
|
|
11573
|
+
const res = await fetch(`${auth.appUrl}/api/cli/whoami?workspaceId=${encodeURIComponent(auth.workspaceId)}`, { headers: { Authorization: `Bearer ${auth.key}` } });
|
|
11449
11574
|
if (res.ok) {
|
|
11450
11575
|
live = await res.json();
|
|
11451
11576
|
} else if (res.status === 401) {
|
|
11452
|
-
liveError = "key is invalid or
|
|
11577
|
+
liveError = "key is invalid, expired, or revoked — run `zalify login`";
|
|
11453
11578
|
} else {
|
|
11454
11579
|
liveError = `server returned ${res.status}`;
|
|
11455
11580
|
}
|
|
@@ -11457,18 +11582,21 @@ async function whoami() {
|
|
|
11457
11582
|
liveError = "could not reach the server (offline?)";
|
|
11458
11583
|
}
|
|
11459
11584
|
const ws = live?.workspace;
|
|
11460
|
-
|
|
11585
|
+
const keyKind = auth.key.startsWith("zalify_cli_") ? "user key" : "workspace key";
|
|
11586
|
+
console.log(`workspace ${ws?.name ?? auth.workspaceName ?? "(unknown)"} (${ws?.slug ?? auth.workspaceSlug ?? "?"}) [${ws?.id ?? auth.workspaceId}]`);
|
|
11587
|
+
if (auth.config.version === 3) {
|
|
11588
|
+
console.log(`user ${auth.config.user.name ?? auth.config.user.email ?? auth.config.user.id}`);
|
|
11589
|
+
} else if (live?.key.createdByName) {
|
|
11590
|
+
console.log(`user ${live.key.createdByName}`);
|
|
11591
|
+
}
|
|
11461
11592
|
if (live) {
|
|
11462
11593
|
console.log(`plan ${live.plan.name} (${live.plan.type})`);
|
|
11463
|
-
|
|
11464
|
-
console.log(`user ${live.key.createdByName}`);
|
|
11465
|
-
}
|
|
11466
|
-
console.log(`key ${live.key.name ?? config.key.slice(0, 16) + "…"} — created ${live.key.createdAt ? new Date(live.key.createdAt).toISOString().slice(0, 10) : "?"}, last used ${ago(live.key.lastRequest)}`);
|
|
11594
|
+
console.log(`key ${live.key.name ?? auth.key.slice(0, 16) + "…"} (${keyKind}) — created ${live.key.createdAt ? new Date(live.key.createdAt).toISOString().slice(0, 10) : "?"}, last used ${ago(live.key.lastRequest)}`);
|
|
11467
11595
|
} else {
|
|
11468
|
-
console.log(`key ${
|
|
11596
|
+
console.log(`key ${auth.key.slice(0, 16)}… (${keyKind})`);
|
|
11469
11597
|
}
|
|
11470
|
-
const slug = ws?.slug ??
|
|
11471
|
-
console.log(`app ${slug ? `${
|
|
11598
|
+
const slug = ws?.slug ?? auth.workspaceSlug;
|
|
11599
|
+
console.log(`app ${slug ? `${auth.appUrl}/store/${slug}` : auth.appUrl}`);
|
|
11472
11600
|
console.log(live ? "status ✓ key verified" : `status ! not verified — ${liveError}`);
|
|
11473
11601
|
}
|
|
11474
11602
|
|
|
@@ -11513,23 +11641,23 @@ async function assetsPull(storeDir) {
|
|
|
11513
11641
|
console.log(`Done: ${pulled} downloaded, ${Object.keys(index).length - pulled} already local.`);
|
|
11514
11642
|
}
|
|
11515
11643
|
async function assetsPush(storeDir) {
|
|
11516
|
-
const
|
|
11644
|
+
const { appUrl, workspaceId, key, workspaceName, workspaceSlug } = requireActive();
|
|
11517
11645
|
const imagesDir = imagesDirFor(storeDir);
|
|
11518
11646
|
const indexPath = join2(imagesDir, "assets.json");
|
|
11519
11647
|
const index = readIndex(imagesDir);
|
|
11520
11648
|
async function api(path9, body) {
|
|
11521
|
-
const res = await fetch(`${
|
|
11649
|
+
const res = await fetch(`${appUrl}${path9}`, {
|
|
11522
11650
|
method: "POST",
|
|
11523
11651
|
headers: {
|
|
11524
11652
|
"Content-Type": "application/json",
|
|
11525
|
-
Authorization: `Bearer ${
|
|
11653
|
+
Authorization: `Bearer ${key}`
|
|
11526
11654
|
},
|
|
11527
11655
|
body: JSON.stringify(body)
|
|
11528
11656
|
});
|
|
11529
11657
|
const json = await res.json().catch(() => ({}));
|
|
11530
11658
|
if (!res.ok) {
|
|
11531
11659
|
if (json.code === "UPGRADE_REQUIRED") {
|
|
11532
|
-
const billingUrl =
|
|
11660
|
+
const billingUrl = workspaceSlug ? `${appUrl}/store/${workspaceSlug}/settings/billing` : `${appUrl} (Settings → Billing)`;
|
|
11533
11661
|
throw new Error(`${json.error ?? "This feature requires a paid plan."}
|
|
11534
11662
|
` + ` Upgrade this workspace: ${billingUrl}`);
|
|
11535
11663
|
}
|
|
@@ -11545,11 +11673,11 @@ async function assetsPush(storeDir) {
|
|
|
11545
11673
|
console.log("Everything already pushed.");
|
|
11546
11674
|
return;
|
|
11547
11675
|
}
|
|
11548
|
-
console.log(`Pushing ${files.length} file(s) to "${
|
|
11676
|
+
console.log(`Pushing ${files.length} file(s) to "${workspaceName || workspaceId}"`);
|
|
11549
11677
|
for (let i = 0;i < files.length; i += BATCH) {
|
|
11550
11678
|
const batch = files.slice(i, i + BATCH);
|
|
11551
11679
|
const { uploads } = await api("/api/assets/presign", {
|
|
11552
|
-
workspaceId
|
|
11680
|
+
workspaceId,
|
|
11553
11681
|
folderId: process.env.ZALIFY_FOLDER_ID ?? null,
|
|
11554
11682
|
files: batch.map((f) => ({
|
|
11555
11683
|
id: f.name,
|
|
@@ -11589,7 +11717,7 @@ async function assetsPush(storeDir) {
|
|
|
11589
11717
|
}
|
|
11590
11718
|
if (toFinalize.length) {
|
|
11591
11719
|
const { assets, pending } = await api("/api/assets/finalize", {
|
|
11592
|
-
workspaceId
|
|
11720
|
+
workspaceId,
|
|
11593
11721
|
items: toFinalize.map(({ file: file2, up }) => ({
|
|
11594
11722
|
assetId: up.assetId,
|
|
11595
11723
|
checksum: file2.checksum,
|
|
@@ -11648,6 +11776,77 @@ Try manually: ${cmd} ${args.join(" ")}`);
|
|
|
11648
11776
|
✓ Done${updated ? ` (version: ${updated})` : ""}`);
|
|
11649
11777
|
}
|
|
11650
11778
|
|
|
11779
|
+
// src/workspace.ts
|
|
11780
|
+
async function fetchWorkspaces2(appUrl, userKey) {
|
|
11781
|
+
try {
|
|
11782
|
+
const res = await fetch(`${appUrl}/api/cli/workspaces`, {
|
|
11783
|
+
headers: { Authorization: `Bearer ${userKey}` }
|
|
11784
|
+
});
|
|
11785
|
+
if (!res.ok)
|
|
11786
|
+
return null;
|
|
11787
|
+
const json = await res.json();
|
|
11788
|
+
return json.workspaces;
|
|
11789
|
+
} catch {
|
|
11790
|
+
return null;
|
|
11791
|
+
}
|
|
11792
|
+
}
|
|
11793
|
+
async function workspaceList() {
|
|
11794
|
+
const config = readConfig();
|
|
11795
|
+
if (!config)
|
|
11796
|
+
throw new Error("Not logged in. Run `zalify login` first.");
|
|
11797
|
+
if (config.version === 3) {
|
|
11798
|
+
const live = await fetchWorkspaces2(config.appUrl, config.userKey);
|
|
11799
|
+
const list = live ?? config.workspacesCache;
|
|
11800
|
+
if (live) {
|
|
11801
|
+
config.workspacesCache = live;
|
|
11802
|
+
writeConfig(config);
|
|
11803
|
+
} else {
|
|
11804
|
+
console.log(`! could not fetch live list — showing cached workspaces
|
|
11805
|
+
`);
|
|
11806
|
+
}
|
|
11807
|
+
for (const w of list) {
|
|
11808
|
+
const marker = w.id === config.active?.id ? "* " : " ";
|
|
11809
|
+
console.log(`${marker}${w.slug.padEnd(36)} ${w.name} [${w.id}]`);
|
|
11810
|
+
}
|
|
11811
|
+
return;
|
|
11812
|
+
}
|
|
11813
|
+
const entries = Object.entries(config.workspaces);
|
|
11814
|
+
if (entries.length === 0)
|
|
11815
|
+
throw new Error("Not logged in. Run `zalify login` first.");
|
|
11816
|
+
for (const [id, w] of entries) {
|
|
11817
|
+
const marker = id === config.activeWorkspaceId ? "* " : " ";
|
|
11818
|
+
console.log(`${marker}${w.slug.padEnd(36)} ${w.name} [${id}]`);
|
|
11819
|
+
}
|
|
11820
|
+
}
|
|
11821
|
+
async function workspaceSet(slugOrId) {
|
|
11822
|
+
const config = readConfig();
|
|
11823
|
+
if (!config)
|
|
11824
|
+
throw new Error("Not logged in. Run `zalify login` first.");
|
|
11825
|
+
if (config.version === 3) {
|
|
11826
|
+
const live = await fetchWorkspaces2(config.appUrl, config.userKey);
|
|
11827
|
+
const list = live ?? config.workspacesCache;
|
|
11828
|
+
if (live)
|
|
11829
|
+
config.workspacesCache = live;
|
|
11830
|
+
const match = list.find((w) => w.id === slugOrId || w.slug === slugOrId || w.name === slugOrId);
|
|
11831
|
+
if (!match) {
|
|
11832
|
+
throw new Error(`No workspace matches "${slugOrId}". Known: ${list.map((w) => w.slug).join(", ")}.`);
|
|
11833
|
+
}
|
|
11834
|
+
config.active = match;
|
|
11835
|
+
writeConfig(config);
|
|
11836
|
+
console.log(`✓ Active workspace: ${match.name} (${match.slug})`);
|
|
11837
|
+
return;
|
|
11838
|
+
}
|
|
11839
|
+
const found = Object.entries(config.workspaces).find(([id, w]) => id === slugOrId || w.slug === slugOrId || w.name === slugOrId);
|
|
11840
|
+
if (!found) {
|
|
11841
|
+
const known = Object.values(config.workspaces).map((w) => w.slug).join(", ");
|
|
11842
|
+
throw new Error(`No authorized workspace matches "${slugOrId}". Known: ${known}.
|
|
11843
|
+
` + "Run `zalify login` to authorize more workspaces.");
|
|
11844
|
+
}
|
|
11845
|
+
config.activeWorkspaceId = found[0];
|
|
11846
|
+
writeConfig(config);
|
|
11847
|
+
console.log(`✓ Active workspace: ${found[1].name} (${found[1].slug})`);
|
|
11848
|
+
}
|
|
11849
|
+
|
|
11651
11850
|
// src/cli.ts
|
|
11652
11851
|
var __dirname4 = dirname(fileURLToPath3(import.meta.url));
|
|
11653
11852
|
var require2 = createRequire2(import.meta.url);
|
|
@@ -11688,6 +11887,13 @@ program2.command("logout").description("Delete the stored CLI credentials").acti
|
|
|
11688
11887
|
program2.command("whoami").description("Verify the stored key and show workspace, plan, and key details").action(async () => {
|
|
11689
11888
|
await whoami();
|
|
11690
11889
|
});
|
|
11890
|
+
var workspace = program2.command("workspace").description("List authorized workspaces or switch the active one");
|
|
11891
|
+
workspace.command("list", { isDefault: true }).description("List authorized workspaces (* = active)").action(async () => {
|
|
11892
|
+
await workspaceList();
|
|
11893
|
+
});
|
|
11894
|
+
workspace.command("set <slug-or-id>").description("Switch the active workspace (local, no re-login)").action(async (slugOrId) => {
|
|
11895
|
+
await workspaceSet(slugOrId);
|
|
11896
|
+
});
|
|
11691
11897
|
var assets = program2.command("assets").description("Sync images with the Zalify asset library");
|
|
11692
11898
|
assets.command("push <store-dir>").description("Upload <store-dir>/images/*.png (sha256 dedup, writes assets.json)").action(async (storeDir) => {
|
|
11693
11899
|
await assetsPush(storeDir);
|