@popcraft/cli 0.33.0 → 0.34.1
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/popcraft.mjs +76 -24
- package/package.json +2 -2
package/dist/popcraft.mjs
CHANGED
|
@@ -1196,7 +1196,7 @@ function operations(spec = openapi) {
|
|
|
1196
1196
|
}
|
|
1197
1197
|
async function call(target2, method, path, opts = {}) {
|
|
1198
1198
|
const qs = new URLSearchParams(opts.query ?? {}).toString();
|
|
1199
|
-
const headers = { "user-agent": `popcraft-cli/${"0.
|
|
1199
|
+
const headers = { "user-agent": `popcraft-cli/${"0.34.1"}`, ...opts.headers };
|
|
1200
1200
|
if (target2.token) headers.authorization = `Bearer ${target2.token}`;
|
|
1201
1201
|
if (opts.contentType) headers["content-type"] = opts.contentType;
|
|
1202
1202
|
try {
|
|
@@ -32183,6 +32183,23 @@ var init_en2 = __esm({
|
|
|
32183
32183
|
"apiTokensDialog.used": "used {date}",
|
|
32184
32184
|
"appHeader.doubleClickToRename": "Double-click to rename",
|
|
32185
32185
|
"appHeader.fileName": "File name",
|
|
32186
|
+
"appStoreOffers.buyCredits": "Buy AI credits",
|
|
32187
|
+
"appStoreOffers.creditsAdded": "{credits} AI credits added to {teamName}.",
|
|
32188
|
+
"appStoreOffers.creditsGoTo": "Credits are added to {teamName} and pay for AI. They don't expire.",
|
|
32189
|
+
"appStoreOffers.failed": "The purchase did not go through.",
|
|
32190
|
+
"appStoreOffers.loading": "Loading App Store prices\u2026",
|
|
32191
|
+
"appStoreOffers.manage": "Manage in the App Store",
|
|
32192
|
+
"appStoreOffers.pack": "{credits} credits \xB7 {price}",
|
|
32193
|
+
"appStoreOffers.pending": "Your purchase is waiting for approval. It's added as soon as it goes through.",
|
|
32194
|
+
"appStoreOffers.perMonth": " / month",
|
|
32195
|
+
"appStoreOffers.perYear": " / year",
|
|
32196
|
+
"appStoreOffers.privacy": "Privacy Policy",
|
|
32197
|
+
"appStoreOffers.renewalTerms": "Payment is charged to your Apple Account. The subscription renews automatically at the price shown for each period unless you cancel it at least 24 hours before the period ends. Manage or cancel it in your App Store account settings.",
|
|
32198
|
+
"appStoreOffers.restore": "Restore purchases",
|
|
32199
|
+
"appStoreOffers.restored": "{count, plural, =0 {No purchases to restore.} one {Restored # purchase.} other {Restored # purchases.}}",
|
|
32200
|
+
"appStoreOffers.subscribe": "Subscribe",
|
|
32201
|
+
"appStoreOffers.subscribed": "Subscribed to {plan} \xB7 {teamName}.",
|
|
32202
|
+
"appStoreOffers.terms": "Terms of Use",
|
|
32186
32203
|
"assetsPanel.components": "Components",
|
|
32187
32204
|
"assetsPanel.documentColors": "Document colors",
|
|
32188
32205
|
"assetsPanel.editComponent": "Edit component",
|
|
@@ -34946,6 +34963,7 @@ var init_en2 = __esm({
|
|
|
34946
34963
|
"planDialog.isOnThePlan": "{teamName} is on the {value} plan.",
|
|
34947
34964
|
"planDialog.largestUpload": "Largest upload",
|
|
34948
34965
|
"planDialog.loadingPlans": "Loading plans\u2026",
|
|
34966
|
+
"planDialog.managedInAppStore": "Bought in the App Store. Manage or cancel it in the App Store on your iPad or Mac.",
|
|
34949
34967
|
"planDialog.mediaStorage": "Storage (media and websites)",
|
|
34950
34968
|
"planDialog.mo": "mo",
|
|
34951
34969
|
"planDialog.namedVersionsPerFile": "Named versions per file",
|
|
@@ -261324,8 +261342,13 @@ var init_plans = __esm({
|
|
|
261324
261342
|
});
|
|
261325
261343
|
|
|
261326
261344
|
// lib/billing/purchases.ts
|
|
261345
|
+
function purchaseChannel() {
|
|
261346
|
+
const store6 = storePlatform();
|
|
261347
|
+
if (store6 === null) return "web";
|
|
261348
|
+
return store6 === "ios" || store6 === "macos" ? "app_store" : null;
|
|
261349
|
+
}
|
|
261327
261350
|
function purchasesAllowed() {
|
|
261328
|
-
return
|
|
261351
|
+
return purchaseChannel() === "web";
|
|
261329
261352
|
}
|
|
261330
261353
|
function limitMessageHere(d) {
|
|
261331
261354
|
return limitMessage(purchasesAllowed() ? d : { ...d, upgradeTo: null });
|
|
@@ -310330,7 +310353,6 @@ function downloadBlob(blob, filename) {
|
|
|
310330
310353
|
}
|
|
310331
310354
|
var init_download = __esm({
|
|
310332
310355
|
"lib/io/download.ts"() {
|
|
310333
|
-
"use strict";
|
|
310334
310356
|
}
|
|
310335
310357
|
});
|
|
310336
310358
|
|
|
@@ -310550,7 +310572,6 @@ function creditLine(c2) {
|
|
|
310550
310572
|
var MAX_PHOTO_PAGE, MAX_PHOTO_QUERY, UUID, isPhotoId, photoImagePath;
|
|
310551
310573
|
var init_stock = __esm({
|
|
310552
310574
|
"lib/photos/stock.ts"() {
|
|
310553
|
-
"use strict";
|
|
310554
310575
|
MAX_PHOTO_PAGE = 12;
|
|
310555
310576
|
MAX_PHOTO_QUERY = 200;
|
|
310556
310577
|
UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
@@ -316110,7 +316131,6 @@ function videoPixelSize(resolution, aspect) {
|
|
|
316110
316131
|
var VIDEO_ASPECTS, VIDEO_RESOLUTIONS, SEEDANCE_ASPECTS, range, VIDEO_MODELS, DEFAULT_VIDEO_MODEL, videoModel, VIDEO_LIMITS;
|
|
316111
316132
|
var init_video_models = __esm({
|
|
316112
316133
|
"lib/ai/video-models.ts"() {
|
|
316113
|
-
"use strict";
|
|
316114
316134
|
VIDEO_ASPECTS = ["16:9", "9:16", "1:1", "4:3", "3:4", "21:9"];
|
|
316115
316135
|
VIDEO_RESOLUTIONS = ["480p", "720p", "1080p"];
|
|
316116
316136
|
SEEDANCE_ASPECTS = ["16:9", "9:16", "1:1", "4:3", "3:4", "21:9"];
|
|
@@ -316476,7 +316496,7 @@ async function renderDocument(doc2, nodeIds, options) {
|
|
|
316476
316496
|
if (frame2) doc2 = { ...doc2, nodes: bakeMotion3(doc2.nodes, frame2.id, options.at) };
|
|
316477
316497
|
}
|
|
316478
316498
|
}
|
|
316479
|
-
return selectionReferenceImages2(doc2, [...nodeIds], { maxEdge: options?.maxEdge, max: 8, format: "
|
|
316499
|
+
return selectionReferenceImages2(doc2, [...nodeIds], { maxEdge: options?.maxEdge, max: 8, format: "JPG", ...options?.bands ? { bands: options.bands } : {} });
|
|
316480
316500
|
}
|
|
316481
316501
|
function generateCapability(ctx2) {
|
|
316482
316502
|
return async (prompt2, options = {}) => {
|
|
@@ -326462,7 +326482,7 @@ var init_package = __esm({
|
|
|
326462
326482
|
"packages/runtime/package.json"() {
|
|
326463
326483
|
package_default = {
|
|
326464
326484
|
name: "@popcraft/runtime",
|
|
326465
|
-
version: "0.
|
|
326485
|
+
version: "0.34.1",
|
|
326466
326486
|
description: "What code exported from PopCraft shares: the meaning of expressions (operators and functions) and, as it grows, the parts of a design's behaviour that are common code rather than generated React.",
|
|
326467
326487
|
license: "MIT",
|
|
326468
326488
|
homepage: "https://popcraft.app/docs/exporting/nextjs",
|
|
@@ -351128,7 +351148,6 @@ function exportsOf(source3) {
|
|
|
351128
351148
|
var CODE_LIMITS, packageOf;
|
|
351129
351149
|
var init_source2 = __esm({
|
|
351130
351150
|
"lib/code/source.ts"() {
|
|
351131
|
-
"use strict";
|
|
351132
351151
|
CODE_LIMITS = { modules: 100, sourceLength: 2e5, packages: 12 };
|
|
351133
351152
|
packageOf = (spec) => spec.split("/").slice(0, spec.startsWith("@") ? 2 : 1).join("/");
|
|
351134
351153
|
}
|
|
@@ -351171,7 +351190,6 @@ function compileModule(module2) {
|
|
|
351171
351190
|
var import_sucrase, BUILT_IN, memo4;
|
|
351172
351191
|
var init_compile2 = __esm({
|
|
351173
351192
|
"lib/code/compile.ts"() {
|
|
351174
|
-
"use strict";
|
|
351175
351193
|
import_sucrase = __toESM(require_dist2());
|
|
351176
351194
|
init_source2();
|
|
351177
351195
|
init_source2();
|
|
@@ -363345,27 +363363,35 @@ async function authHeaders2() {
|
|
|
363345
363363
|
};
|
|
363346
363364
|
}
|
|
363347
363365
|
async function streamChat(opts, handlers = {}, signal) {
|
|
363366
|
+
const body = JSON.stringify({
|
|
363367
|
+
model: opts.model,
|
|
363368
|
+
messages: opts.messages,
|
|
363369
|
+
stream: true,
|
|
363370
|
+
max_tokens: opts.maxTokens ?? (opts.tools?.length ? 16384 : 4096),
|
|
363371
|
+
...opts.temperature !== void 0 ? { temperature: opts.temperature } : {},
|
|
363372
|
+
...opts.tools?.length ? { tools: opts.tools, tool_choice: opts.toolChoice ?? "auto" } : {}
|
|
363373
|
+
});
|
|
363374
|
+
if (body.length > MAX_REQUEST_BYTES) {
|
|
363375
|
+
throw new StreamError(
|
|
363376
|
+
`This message is too large to send (${(body.length / 1e6).toFixed(1)} MB with its images). Attach fewer or smaller images.`,
|
|
363377
|
+
"too_large",
|
|
363378
|
+
413
|
|
363379
|
+
);
|
|
363380
|
+
}
|
|
363348
363381
|
const res = await fetch(`${HYPERY_GATEWAY_URL}/api/v1/chat/completions`, {
|
|
363349
363382
|
method: "POST",
|
|
363350
363383
|
headers: await authHeaders2(),
|
|
363351
363384
|
signal,
|
|
363352
|
-
body
|
|
363353
|
-
model: opts.model,
|
|
363354
|
-
messages: opts.messages,
|
|
363355
|
-
stream: true,
|
|
363356
|
-
max_tokens: opts.maxTokens ?? (opts.tools?.length ? 16384 : 4096),
|
|
363357
|
-
...opts.temperature !== void 0 ? { temperature: opts.temperature } : {},
|
|
363358
|
-
...opts.tools?.length ? { tools: opts.tools, tool_choice: opts.toolChoice ?? "auto" } : {}
|
|
363359
|
-
})
|
|
363385
|
+
body
|
|
363360
363386
|
}).catch((err2) => {
|
|
363361
363387
|
if (err2.name === "AbortError") throw err2;
|
|
363362
363388
|
throw new StreamError("Could not reach Hypery. Check your connection.", "network", 0);
|
|
363363
363389
|
});
|
|
363364
363390
|
if (!res.ok || !res.body) {
|
|
363365
|
-
const
|
|
363366
|
-
let payload =
|
|
363391
|
+
const body2 = await res.text().catch(() => "");
|
|
363392
|
+
let payload = body2;
|
|
363367
363393
|
try {
|
|
363368
|
-
payload = JSON.parse(
|
|
363394
|
+
payload = JSON.parse(body2);
|
|
363369
363395
|
} catch {
|
|
363370
363396
|
}
|
|
363371
363397
|
throw new StreamError(streamErrorMessage(payload, `The AI request failed (${res.status}).`), errorCodeFor(res.status, payload), res.status);
|
|
@@ -363414,7 +363440,7 @@ function errorCodeFor(status3, payload) {
|
|
|
363414
363440
|
if (status3 === 429) return "ai_rate_limited";
|
|
363415
363441
|
return "ai_upstream";
|
|
363416
363442
|
}
|
|
363417
|
-
var IDLE_TIMEOUT_MS;
|
|
363443
|
+
var IDLE_TIMEOUT_MS, MAX_REQUEST_BYTES;
|
|
363418
363444
|
var init_gateway = __esm({
|
|
363419
363445
|
"lib/agent/gateway.ts"() {
|
|
363420
363446
|
"use strict";
|
|
@@ -363424,6 +363450,7 @@ var init_gateway = __esm({
|
|
|
363424
363450
|
init_shared();
|
|
363425
363451
|
init_stream_parse();
|
|
363426
363452
|
IDLE_TIMEOUT_MS = 18e4;
|
|
363453
|
+
MAX_REQUEST_BYTES = 44e5;
|
|
363427
363454
|
}
|
|
363428
363455
|
});
|
|
363429
363456
|
|
|
@@ -363455,6 +363482,28 @@ function pruneOldImages(messages, keep = KEEP_IMAGE_TURNS) {
|
|
|
363455
363482
|
messages[i2] = { ...m, content: `${text} [${images === 1 ? "image" : `${images} images`} omitted: superseded by a later render \u2014 render again if you need to look.]`.trim() };
|
|
363456
363483
|
}
|
|
363457
363484
|
}
|
|
363485
|
+
function fitImagesToBudget(messages, budget) {
|
|
363486
|
+
if (sizeOf2(messages) <= budget) return;
|
|
363487
|
+
const renderTurns = messages.map((m, i2) => ({ m, i: i2 })).filter(({ m }) => m.role === "user" && Array.isArray(m.content) && m.content[0]?.type === "text" && !!m.content[0].text?.startsWith(RENDER_TURN_PREFIX)).map(({ i: i2 }) => i2);
|
|
363488
|
+
for (const i2 of renderTurns) {
|
|
363489
|
+
if (sizeOf2(messages) <= budget) return;
|
|
363490
|
+
const m = messages[i2];
|
|
363491
|
+
if (!Array.isArray(m.content)) continue;
|
|
363492
|
+
const parts = [...m.content];
|
|
363493
|
+
let dropped = 0;
|
|
363494
|
+
for (let j = parts.length - 1; j >= 0 && sizeOf2(messages) > budget; j--) {
|
|
363495
|
+
if (parts[j].type !== "image_url") continue;
|
|
363496
|
+
parts.splice(j, 1);
|
|
363497
|
+
dropped++;
|
|
363498
|
+
messages[i2] = { ...m, content: [...parts] };
|
|
363499
|
+
}
|
|
363500
|
+
if (dropped) {
|
|
363501
|
+
const note2 = `[${dropped === 1 ? "1 image" : `${dropped} images`} omitted to keep the request under the size limit \u2014 look at fewer layers at once, or pass a smaller maxEdge.]`;
|
|
363502
|
+
const rest = messages[i2].content;
|
|
363503
|
+
messages[i2] = { ...m, content: rest.some((p2) => p2.type === "image_url") ? [...rest, { type: "text", text: note2 }] : `${rest.flatMap((p2) => p2.type === "text" ? [p2.text] : []).join(" ")} ${note2}`.trim() };
|
|
363504
|
+
}
|
|
363505
|
+
}
|
|
363506
|
+
}
|
|
363458
363507
|
async function runAgentLoop(opts) {
|
|
363459
363508
|
const maxRounds = opts.maxRounds ?? DEFAULT_MAX_ROUNDS;
|
|
363460
363509
|
const maxResultChars = opts.maxResultChars ?? 8e3;
|
|
@@ -363466,6 +363515,7 @@ async function runAgentLoop(opts) {
|
|
|
363466
363515
|
if (opts.stopped?.()) return { messages, text, rounds, exhausted: false, stopped: true };
|
|
363467
363516
|
for (const note2 of opts.drainNotifications?.() ?? []) messages.push({ role: "user", content: note2 });
|
|
363468
363517
|
pruneOldImages(messages);
|
|
363518
|
+
fitImagesToBudget(messages, MAX_REQUEST_BYTES - JSON.stringify(specs).length - REQUEST_MARGIN_BYTES);
|
|
363469
363519
|
opts.hooks?.onAssistantStart?.(rounds);
|
|
363470
363520
|
const turn = await opts.callModel(messages, specs, {
|
|
363471
363521
|
onTextDelta: opts.hooks?.onTextDelta,
|
|
@@ -363524,14 +363574,17 @@ async function runAgentLoop(opts) {
|
|
|
363524
363574
|
messages.push({ role: "assistant", content: final.text });
|
|
363525
363575
|
return { messages, text: final.text, rounds, exhausted: true, stopped: false };
|
|
363526
363576
|
}
|
|
363527
|
-
var DEFAULT_MAX_ROUNDS, DEFAULT_MAX_PARALLEL, KEEP_IMAGE_TURNS, RENDER_TURN_PREFIX;
|
|
363577
|
+
var DEFAULT_MAX_ROUNDS, DEFAULT_MAX_PARALLEL, KEEP_IMAGE_TURNS, RENDER_TURN_PREFIX, REQUEST_MARGIN_BYTES, sizeOf2;
|
|
363528
363578
|
var init_loop = __esm({
|
|
363529
363579
|
"lib/agent/loop.ts"() {
|
|
363530
363580
|
"use strict";
|
|
363581
|
+
init_gateway();
|
|
363531
363582
|
DEFAULT_MAX_ROUNDS = 12;
|
|
363532
363583
|
DEFAULT_MAX_PARALLEL = 4;
|
|
363533
363584
|
KEEP_IMAGE_TURNS = 2;
|
|
363534
363585
|
RENDER_TURN_PREFIX = "Result of ";
|
|
363586
|
+
REQUEST_MARGIN_BYTES = 64e3;
|
|
363587
|
+
sizeOf2 = (messages) => JSON.stringify(messages).length;
|
|
363535
363588
|
}
|
|
363536
363589
|
});
|
|
363537
363590
|
|
|
@@ -397116,7 +397169,6 @@ function record(source, namespaces, globals, limits) {
|
|
|
397116
397169
|
var HELPER_NAMES;
|
|
397117
397170
|
var init_helper_names = __esm({
|
|
397118
397171
|
"lib/agent/design-script/helper-names.ts"() {
|
|
397119
|
-
"use strict";
|
|
397120
397172
|
HELPER_NAMES = ["draw", "marks", "fit", "motion", "captions", "overlays", "texture", "pointer", "windows", "devices", "type", "beat", "web", "social", "video", "site", "effects"];
|
|
397121
397173
|
}
|
|
397122
397174
|
});
|
|
@@ -409875,7 +409927,7 @@ init_resources();
|
|
|
409875
409927
|
init_desktop();
|
|
409876
409928
|
init_hypery();
|
|
409877
409929
|
import { createInterface } from "node:readline";
|
|
409878
|
-
var VERSION2 = "0.
|
|
409930
|
+
var VERSION2 = "0.34.1";
|
|
409879
409931
|
var HELP = `popcraft ${VERSION2} \u2014 the PopCraft command line
|
|
409880
409932
|
|
|
409881
409933
|
Files (headless, on .popcraft files):
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@popcraft/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.1",
|
|
4
4
|
"description": "The PopCraft command line: edit .popcraft files headlessly, call the REST API, publish to the marketplace and manage the desktop app's local plugins, themes, fonts, skills and agents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://popcraft.app/docs/api/cli",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"esbuild": "0.28.2"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@popcraft/kit": "0.
|
|
37
|
+
"@popcraft/kit": "0.34.1"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "node build.mjs",
|