@wix/himalaya-cli 0.1507.0 → 0.1508.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.mjs +169 -121
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -1013,7 +1013,8 @@ var init_compiler_options = __esm({
|
|
|
1013
1013
|
|
|
1014
1014
|
// src/scaffold.ts
|
|
1015
1015
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, existsSync, readdirSync, readFileSync as readFileSync2, statSync, lstatSync, copyFileSync } from "node:fs";
|
|
1016
|
-
import {
|
|
1016
|
+
import { spawnSync } from "node:child_process";
|
|
1017
|
+
import { resolve, join as join2, dirname as dirname2, sep as sep2 } from "node:path";
|
|
1017
1018
|
import { fileURLToPath } from "node:url";
|
|
1018
1019
|
function keptPlanNote(kept) {
|
|
1019
1020
|
if (!kept?.length) return void 0;
|
|
@@ -1056,6 +1057,20 @@ function defaultWorkerTsconfig() {
|
|
|
1056
1057
|
function offRepoImports(body) {
|
|
1057
1058
|
return body.replace(/(["'])@himalaya\/([^"']+)\1/g, "$1@wix/himalaya/$2$1");
|
|
1058
1059
|
}
|
|
1060
|
+
function checkoutHead() {
|
|
1061
|
+
const r3 = spawnSync("git", ["rev-parse", "HEAD"], { cwd: dirname2(TEMPLATES_DIR), encoding: "utf8" });
|
|
1062
|
+
return r3.status === 0 ? r3.stdout.trim() : "";
|
|
1063
|
+
}
|
|
1064
|
+
function ensureCheckoutTemplates(run2 = spawnSync, headOf = checkoutHead) {
|
|
1065
|
+
if (process.env.HIMI_TEMPLATES_FRESH || !existsSync(resolve(ENSURE_TEMPLATES, "../gen-templates.mts"))) return;
|
|
1066
|
+
const head = headOf();
|
|
1067
|
+
if (templatesEnsuredAt !== null && templatesEnsuredAt === head) return;
|
|
1068
|
+
const r3 = run2(process.execPath, [ENSURE_TEMPLATES], { stdio: ["ignore", 2, 2] });
|
|
1069
|
+
if (r3.status !== 0) {
|
|
1070
|
+
throw new Error(`could not generate the starter templates (node ${ENSURE_TEMPLATES} exited ${r3.status ?? r3.signal})`);
|
|
1071
|
+
}
|
|
1072
|
+
templatesEnsuredAt = head;
|
|
1073
|
+
}
|
|
1059
1074
|
function templateTakesBase44AppId(template) {
|
|
1060
1075
|
if (!availableTemplates().includes(template)) return void 0;
|
|
1061
1076
|
const config = join2(templateSourceDir(template), "config.ts");
|
|
@@ -1106,13 +1121,22 @@ function extractTemplateAppearance(tokens2) {
|
|
|
1106
1121
|
const palette2 = [...new Set(slots.map((c2) => c2.toUpperCase()))].map((u2) => slots.find((c2) => c2.toUpperCase() === u2));
|
|
1107
1122
|
return { ...accent ? { accent } : {}, ...slots.length >= 3 && palette2.length >= 2 ? { palette: palette2 } : {} };
|
|
1108
1123
|
}
|
|
1124
|
+
function ensureTemplatesFor(...dirs) {
|
|
1125
|
+
if (dirs.some((d2) => resolve(d2) === TEMPLATES_DIR || resolve(d2).startsWith(TEMPLATES_DIR + sep2))) ensureCheckoutTemplates();
|
|
1126
|
+
}
|
|
1127
|
+
function canonicalCatalogFiles(files, separator = sep2) {
|
|
1128
|
+
const posix5 = (rel) => separator === "/" ? rel : rel.split(separator).join("/");
|
|
1129
|
+
return Object.fromEntries(Object.entries(files).map(([rel, body]) => [posix5(rel), body]).sort(([a2], [b2]) => a2 < b2 ? -1 : a2 > b2 ? 1 : 0));
|
|
1130
|
+
}
|
|
1109
1131
|
function availableTemplates() {
|
|
1132
|
+
ensureCheckoutTemplates();
|
|
1110
1133
|
const generated = existsSync(TEMPLATES_DIR) ? readdirSync(TEMPLATES_DIR).filter((d2) => !d2.includes(".build-") && statSync(join2(TEMPLATES_DIR, d2)).isDirectory()).filter((d2) => existsSync(join2(TEMPLATES_DIR, d2, "himalaya.content.json"))) : [];
|
|
1111
1134
|
const showcase = SHOWCASE_TEMPLATE_NAMES.filter((name) => existsSync(join2(SHOWCASE_TEMPLATES_DIR, name, "himalaya.content.json")));
|
|
1112
1135
|
return [.../* @__PURE__ */ new Set([...generated, ...showcase])].sort();
|
|
1113
1136
|
}
|
|
1114
1137
|
function templateSourceDir(template) {
|
|
1115
1138
|
if (SHOWCASE_TEMPLATE_NAMES.includes(template)) return join2(SHOWCASE_TEMPLATES_DIR, template);
|
|
1139
|
+
ensureCheckoutTemplates();
|
|
1116
1140
|
return join2(TEMPLATES_DIR, template);
|
|
1117
1141
|
}
|
|
1118
1142
|
function idSegOf(name) {
|
|
@@ -1154,7 +1178,7 @@ function sentinelizeIdentity(body, identity) {
|
|
|
1154
1178
|
}
|
|
1155
1179
|
if (identity.name) {
|
|
1156
1180
|
const re2 = new RegExp(`\\b(${NAME_FIELDS.join("|")})(["']?\\s*[:=]\\s*)(["'])${escapeRe(identity.name)}\\3`, "g");
|
|
1157
|
-
out2 = out2.replace(re2, (_m, key3,
|
|
1181
|
+
out2 = out2.replace(re2, (_m, key3, sep22, q2) => `${key3}${sep22}${q2}__HIMI_APP_NAME__${q2}`);
|
|
1158
1182
|
}
|
|
1159
1183
|
return out2;
|
|
1160
1184
|
}
|
|
@@ -1481,7 +1505,7 @@ A per-app \`npm i @wix/himalaya\` is optional and only buys your editor local ty
|
|
|
1481
1505
|
);
|
|
1482
1506
|
return finishScaffold({ dir, files, ...kept.length ? { kept: kept.sort() } : {} });
|
|
1483
1507
|
}
|
|
1484
|
-
var PLAN_FILES, PACKAGE_GITIGNORE, MODULE_SOURCE_FILE, TEMPLATES_DIR, SHOWCASE_TEMPLATES_DIR, SHOWCASE_TEMPLATE_NAMES, BASE44_APP_ID_PLACEHOLDER, BASE44_APP_ID_RE, TEMPLATE_META_FILE, TEMPLATE_ICONS_DIR, HEX_COLOR, PALETTE_KEYS, IDENTITY_SENTINELS, SENTINEL_RE, escapeRe, NAME_FIELDS, IDENTITY_FILES, DOTID_RE, BINARY_EXTENSIONS, extOf;
|
|
1508
|
+
var PLAN_FILES, PACKAGE_GITIGNORE, MODULE_SOURCE_FILE, TEMPLATES_DIR, ENSURE_TEMPLATES, templatesEnsuredAt, SHOWCASE_TEMPLATES_DIR, SHOWCASE_TEMPLATE_NAMES, BASE44_APP_ID_PLACEHOLDER, BASE44_APP_ID_RE, TEMPLATE_META_FILE, TEMPLATE_ICONS_DIR, HEX_COLOR, PALETTE_KEYS, IDENTITY_SENTINELS, SENTINEL_RE, escapeRe, NAME_FIELDS, IDENTITY_FILES, DOTID_RE, BINARY_EXTENSIONS, extOf;
|
|
1485
1509
|
var init_scaffold = __esm({
|
|
1486
1510
|
"src/scaffold.ts"() {
|
|
1487
1511
|
init_source_deny();
|
|
@@ -1491,6 +1515,8 @@ var init_scaffold = __esm({
|
|
|
1491
1515
|
PACKAGE_GITIGNORE = [".himi/", "dist/", "node_modules/"];
|
|
1492
1516
|
MODULE_SOURCE_FILE = /\.(?:[cm]?[jt]sx?)$/i;
|
|
1493
1517
|
TEMPLATES_DIR = resolve(dirname2(fileURLToPath(import.meta.url)), "../templates");
|
|
1518
|
+
ENSURE_TEMPLATES = resolve(TEMPLATES_DIR, "../../authoring-kit/ensure-templates.mjs");
|
|
1519
|
+
templatesEnsuredAt = null;
|
|
1494
1520
|
SHOWCASE_TEMPLATES_DIR = resolve(dirname2(fileURLToPath(import.meta.url)), "../showcase-apps");
|
|
1495
1521
|
SHOWCASE_TEMPLATE_NAMES = ["video-courses", "base44-starter", "base44-booking", "base44-inspections", "base44-fitness", "base44-podcast"];
|
|
1496
1522
|
BASE44_APP_ID_PLACEHOLDER = "ReplaceWithYourBase44AppId";
|
|
@@ -5910,7 +5936,7 @@ import { spawn } from "node:child_process";
|
|
|
5910
5936
|
import { createHash as createHash4 } from "node:crypto";
|
|
5911
5937
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
5912
5938
|
import { appendFileSync, closeSync, existsSync as existsSync6, lstatSync as lstatSync4, mkdirSync as mkdirSync5, openSync, readdirSync as readdirSync5, readFileSync as readFileSync7, readSync, renameSync as renameSync3, rmSync as rmSync2, statSync as statSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
5913
|
-
import { isAbsolute, join as join8, relative, resolve as resolve5, sep as
|
|
5939
|
+
import { isAbsolute, join as join8, relative, resolve as resolve5, sep as sep3 } from "node:path";
|
|
5914
5940
|
function agentCovers(agent, cli) {
|
|
5915
5941
|
if (isCliEntry(agent)) return false;
|
|
5916
5942
|
const agentShas = shasOf(agent.images);
|
|
@@ -6223,7 +6249,7 @@ function formatBrief(input) {
|
|
|
6223
6249
|
const who = `himi \u2014 ${input.appName ?? "this folder"}`;
|
|
6224
6250
|
const lines = [];
|
|
6225
6251
|
if (!summary2.count) {
|
|
6226
|
-
lines.push(`${who}: no journey journal yet (${PROGRESS_FILE.split(
|
|
6252
|
+
lines.push(`${who}: no journey journal yet (${PROGRESS_FILE.split(sep3).join("/")}).`);
|
|
6227
6253
|
lines.push(
|
|
6228
6254
|
'A new app starts with discovery (step 1). An app built before journaling existed continues from its current state instead: confirm with the customer that its SPEC.md was approved rather than re-running discovery. Either way, journal each milestone with `himi progress "<what changed>" --step <n>` so the next session can pick up from it.'
|
|
6229
6255
|
);
|
|
@@ -6338,7 +6364,7 @@ var init_progress = __esm({
|
|
|
6338
6364
|
this.code = code;
|
|
6339
6365
|
}
|
|
6340
6366
|
};
|
|
6341
|
-
toPosix = (p2) => p2.split(
|
|
6367
|
+
toPosix = (p2) => p2.split(sep3).join("/");
|
|
6342
6368
|
UnsafeHimiDirError = class extends Error {
|
|
6343
6369
|
constructor(rel) {
|
|
6344
6370
|
super(`${rel} is not a real directory inside the content package (a symlink?) \u2014 refusing to write through it`);
|
|
@@ -7245,7 +7271,7 @@ var init_preview = __esm({
|
|
|
7245
7271
|
});
|
|
7246
7272
|
|
|
7247
7273
|
// src/mcp/client-configs.ts
|
|
7248
|
-
import { dirname as dirname7, relative as relative2, resolve as resolve7, sep as
|
|
7274
|
+
import { dirname as dirname7, relative as relative2, resolve as resolve7, sep as sep4 } from "node:path";
|
|
7249
7275
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
7250
7276
|
function sourceCheckout(moduleUrl = import.meta.url) {
|
|
7251
7277
|
if (!moduleUrl.endsWith(".ts")) return null;
|
|
@@ -7343,7 +7369,7 @@ var init_client_configs = __esm({
|
|
|
7343
7369
|
HERE = dirname7(fileURLToPath4(import.meta.url));
|
|
7344
7370
|
inside = (child, parent) => {
|
|
7345
7371
|
const rel = relative2(parent, child);
|
|
7346
|
-
return rel === "" || !rel.startsWith("..") && !rel.startsWith(
|
|
7372
|
+
return rel === "" || !rel.startsWith("..") && !rel.startsWith(sep4) && !/^[A-Za-z]:/.test(rel);
|
|
7347
7373
|
};
|
|
7348
7374
|
same = (a2, b2) => JSON.stringify(a2) === JSON.stringify(b2);
|
|
7349
7375
|
out = (o2) => `${JSON.stringify(o2, null, 2)}
|
|
@@ -7721,7 +7747,7 @@ __export(build_lib_exports, {
|
|
|
7721
7747
|
umbrellaRewritePlugin: () => umbrellaRewritePlugin
|
|
7722
7748
|
});
|
|
7723
7749
|
import { fileURLToPath as fileURLToPath5, pathToFileURL } from "node:url";
|
|
7724
|
-
import { basename as basename3, dirname as dirname9, join as join11, resolve as resolve8, sep as
|
|
7750
|
+
import { basename as basename3, dirname as dirname9, join as join11, resolve as resolve8, sep as sep5 } from "node:path";
|
|
7725
7751
|
import { readdirSync as readdirSync6, existsSync as existsSync9, readFileSync as readFileSync10, realpathSync as realpathSync3, statSync as statSync3 } from "node:fs";
|
|
7726
7752
|
async function loadCompiler() {
|
|
7727
7753
|
try {
|
|
@@ -7769,7 +7795,7 @@ function realpathOrSelf(p2) {
|
|
|
7769
7795
|
}
|
|
7770
7796
|
}
|
|
7771
7797
|
function isUnder(p2, root) {
|
|
7772
|
-
return p2 === root || p2.startsWith(root +
|
|
7798
|
+
return p2 === root || p2.startsWith(root + sep5);
|
|
7773
7799
|
}
|
|
7774
7800
|
function confinementRoots(contentRoot2) {
|
|
7775
7801
|
const roots2 = /* @__PURE__ */ new Set();
|
|
@@ -8059,7 +8085,7 @@ function tsExtResolvePlugin() {
|
|
|
8059
8085
|
}
|
|
8060
8086
|
function importMetaUrlPlugin({ scope: scope2 } = {}) {
|
|
8061
8087
|
const scopes = scope2 ? [.../* @__PURE__ */ new Set([realpathOrSelf(scope2), resolve8(scope2)])] : [];
|
|
8062
|
-
const inScope = (p2) => scopes.some((r3) => p2 === r3 || p2.startsWith(r3 +
|
|
8088
|
+
const inScope = (p2) => scopes.some((r3) => p2 === r3 || p2.startsWith(r3 + sep5));
|
|
8063
8089
|
return {
|
|
8064
8090
|
name: "himalaya-import-meta-url",
|
|
8065
8091
|
setup(b2) {
|
|
@@ -8747,7 +8773,7 @@ var init_tier5_dir = __esm({
|
|
|
8747
8773
|
|
|
8748
8774
|
// src/tier5-typecheck.ts
|
|
8749
8775
|
import { existsSync as existsSync10, readFileSync as readFileSync11 } from "node:fs";
|
|
8750
|
-
import { relative as relative3, resolve as resolve10, sep as
|
|
8776
|
+
import { relative as relative3, resolve as resolve10, sep as sep6 } from "node:path";
|
|
8751
8777
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
8752
8778
|
async function loadTypeScript() {
|
|
8753
8779
|
const runtime = process.env.HIMI_AUTHORING_RUNTIME_DIR;
|
|
@@ -8786,7 +8812,7 @@ function pathsFor(options) {
|
|
|
8786
8812
|
return declarationPaths(options.umbrellaDir);
|
|
8787
8813
|
}
|
|
8788
8814
|
function relativeFile(contentDir2, fileName) {
|
|
8789
|
-
return relative3(contentDir2, fileName).split(
|
|
8815
|
+
return relative3(contentDir2, fileName).split(sep6).join("/");
|
|
8790
8816
|
}
|
|
8791
8817
|
function belongsToContentWorkers(contentDir2, diagnostic) {
|
|
8792
8818
|
if (!diagnostic.file) return true;
|
|
@@ -8964,7 +8990,7 @@ var init_provisioning_facts = __esm({
|
|
|
8964
8990
|
// ../../core/dev-server/src/app-assets.ts
|
|
8965
8991
|
import { createHash as createHash6 } from "node:crypto";
|
|
8966
8992
|
import { existsSync as existsSync11, lstatSync as lstatSync7, readFileSync as readFileSync13, readdirSync as readdirSync8, realpathSync as realpathSync4, statSync as statSync4 } from "node:fs";
|
|
8967
|
-
import { join as join12, resolve as resolve12, sep as
|
|
8993
|
+
import { join as join12, resolve as resolve12, sep as sep7 } from "node:path";
|
|
8968
8994
|
function contentTypeFor(name) {
|
|
8969
8995
|
const ext = name.includes(".") ? name.slice(name.lastIndexOf(".") + 1).toLowerCase() : "";
|
|
8970
8996
|
return CONTENT_TYPES[ext] ?? "application/octet-stream";
|
|
@@ -8985,7 +9011,7 @@ function findAssetsDir(appDir3) {
|
|
|
8985
9011
|
const rel = typeof declared === "string" && declared ? declared : "assets";
|
|
8986
9012
|
const abs = resolve12(appDir3, rel);
|
|
8987
9013
|
const base = resolve12(appDir3);
|
|
8988
|
-
if (abs !== base && !abs.startsWith(base +
|
|
9014
|
+
if (abs !== base && !abs.startsWith(base + sep7)) return null;
|
|
8989
9015
|
return existsSync11(abs) && statSync4(abs).isDirectory() ? abs : null;
|
|
8990
9016
|
}
|
|
8991
9017
|
function readOtaOnlyPatterns(appDir3) {
|
|
@@ -9043,7 +9069,7 @@ function collectBrandFonts(appDir3) {
|
|
|
9043
9069
|
try {
|
|
9044
9070
|
if (!lstatSync7(path2).isFile()) continue;
|
|
9045
9071
|
const root = realpathSync4(appDir3);
|
|
9046
|
-
if (!realpathSync4(path2).startsWith(root +
|
|
9072
|
+
if (!realpathSync4(path2).startsWith(root + sep7)) continue;
|
|
9047
9073
|
} catch {
|
|
9048
9074
|
continue;
|
|
9049
9075
|
}
|
|
@@ -12521,8 +12547,8 @@ function textOf(node) {
|
|
|
12521
12547
|
function plainText(node) {
|
|
12522
12548
|
if (typeOf2(node) === "TEXT") return str(at(node, "textData", "text"));
|
|
12523
12549
|
const children = kids(node).filter(isObj);
|
|
12524
|
-
const
|
|
12525
|
-
return children.map(plainText).join(
|
|
12550
|
+
const sep22 = children.every((c2) => typeOf2(c2) === "TEXT") ? "" : "\n";
|
|
12551
|
+
return children.map(plainText).join(sep22);
|
|
12526
12552
|
}
|
|
12527
12553
|
function alignOf(v2) {
|
|
12528
12554
|
switch (v2) {
|
|
@@ -17908,14 +17934,14 @@ var init_hhp_command = __esm({
|
|
|
17908
17934
|
|
|
17909
17935
|
// src/hhp.ts
|
|
17910
17936
|
import { existsSync as existsSync16, readFileSync as readFileSync17, writeFileSync as writeFileSync8, mkdirSync as mkdirSync10, renameSync as renameSync4, rmSync as rmSync5, lstatSync as lstatSync8, readdirSync as readdirSync12 } from "node:fs";
|
|
17911
|
-
import { basename as basename6, dirname as dirname13, resolve as resolve18, relative as relative4, sep as
|
|
17937
|
+
import { basename as basename6, dirname as dirname13, resolve as resolve18, relative as relative4, sep as sep8, join as join15 } from "node:path";
|
|
17912
17938
|
import { createHash as createHash7, randomUUID as randomUUID3 } from "node:crypto";
|
|
17913
17939
|
import ts3 from "typescript";
|
|
17914
17940
|
function localPath(root, path2, from = join15(root, "hhp.json")) {
|
|
17915
17941
|
if (/^[a-z]+:|^\/\//i.test(path2)) throw new Error("HHP source dependencies must be local files.");
|
|
17916
17942
|
const target = resolve18(dirname13(from), path2), rel = relative4(resolve18(root), target);
|
|
17917
|
-
if (rel.startsWith(`..${
|
|
17918
|
-
const components2 = rel.split(
|
|
17943
|
+
if (rel.startsWith(`..${sep8}`) || rel === ".." || !rel || target === resolve18(root)) throw new Error("HHP source path escapes the app.");
|
|
17944
|
+
const components2 = rel.split(sep8);
|
|
17919
17945
|
let current = resolve18(root);
|
|
17920
17946
|
for (const component of components2) {
|
|
17921
17947
|
current = join15(current, component);
|
|
@@ -18038,13 +18064,13 @@ async function compileContentHhp(root, opts = {}) {
|
|
|
18038
18064
|
for (const dependency of result2.dependencies.filter((f2) => /\.tsx?$/.test(f2))) inspect2(dependency);
|
|
18039
18065
|
result2.manifest.requiredCapabilities = [...requiredCapabilities2].sort();
|
|
18040
18066
|
outputs.set(`dev/hhp/${id}.descriptor.json`, JSON.stringify(result2.descriptor, null, 2) + "\n");
|
|
18041
|
-
outputs.set(`dev/hhp/${id}.map.json`, JSON.stringify({ ...result2.manifest, nodes: Object.fromEntries(Object.entries(result2.sourceMap).map(([key3, node]) => [key3, { ...node, file: relative4(root, node.file).split(
|
|
18067
|
+
outputs.set(`dev/hhp/${id}.map.json`, JSON.stringify({ ...result2.manifest, nodes: Object.fromEntries(Object.entries(result2.sourceMap).map(([key3, node]) => [key3, { ...node, file: relative4(root, node.file).split(sep8).join("/") }])) }, null, 2) + "\n");
|
|
18042
18068
|
if (result2.worker && result2.bundleName) {
|
|
18043
18069
|
if (results.some((r3) => r3 !== result2 && r3.bundleName === result2.bundleName)) diagnostics.push({ code: "HHP-BUNDLE-ID", severity: "error", file: file2, line: 1, column: 1, message: "Screen ids normalize to the same bundle name." });
|
|
18044
18070
|
const workerRel = `tier5-src/${result2.bundleName}/index.ts`;
|
|
18045
18071
|
let worker = result2.worker;
|
|
18046
18072
|
for (const dependency of result2.dependencies.filter((f2) => /\.(controller|service)\.tsx?$/.test(f2)))
|
|
18047
|
-
worker = worker.replace(JSON.stringify(dependency), JSON.stringify(relative4(dirname13(join15(root, workerRel)), dependency).split(
|
|
18073
|
+
worker = worker.replace(JSON.stringify(dependency), JSON.stringify(relative4(dirname13(join15(root, workerRel)), dependency).split(sep8).join("/").replace(/\.tsx?$/, ".js")));
|
|
18048
18074
|
outputs.set(workerRel, worker);
|
|
18049
18075
|
}
|
|
18050
18076
|
}
|
|
@@ -22150,7 +22176,6 @@ function resolveIdiom(tokens2, ctx = {}) {
|
|
|
22150
22176
|
var IDIOM_CONTEXTS, UNSAFE_KEYS;
|
|
22151
22177
|
var init_idiom = __esm({
|
|
22152
22178
|
"../../core/ts/src/idiom.ts"() {
|
|
22153
|
-
"use strict";
|
|
22154
22179
|
IDIOM_CONTEXTS = {
|
|
22155
22180
|
ios: { native: ["ios"] },
|
|
22156
22181
|
android: { native: ["material"] },
|
|
@@ -27549,7 +27574,7 @@ function redactBodyString(body) {
|
|
|
27549
27574
|
} catch {
|
|
27550
27575
|
}
|
|
27551
27576
|
}
|
|
27552
|
-
return body.replace(FORM_ASSIGNMENT_RE, (m2, name) => isSensitiveBodyName(name) ? `${name}=${REDACTED}` : m2).replace(JSON_FIELD_RE, (m2, name,
|
|
27577
|
+
return body.replace(FORM_ASSIGNMENT_RE, (m2, name) => isSensitiveBodyName(name) ? `${name}=${REDACTED}` : m2).replace(JSON_FIELD_RE, (m2, name, sep22) => isSensitiveBodyName(name) ? `"${name}"${sep22}"${REDACTED}"` : m2).replace(JSON_FIELD_UNTERMINATED_RE, (m2, name, sep22) => isSensitiveBodyName(name) ? `"${name}"${sep22}"${REDACTED}` : m2).replace(BEARER_RE, (_m, s2) => `${s2} ${REDACTED}`);
|
|
27553
27578
|
}
|
|
27554
27579
|
function createWixGatewayState() {
|
|
27555
27580
|
return { mode: "record", rules: [], traffic: [], clients: /* @__PURE__ */ new Set(), seq: 0, ruleSeq: 0 };
|
|
@@ -32008,10 +32033,10 @@ async function runRicosImageUpload(o2) {
|
|
|
32008
32033
|
} catch {
|
|
32009
32034
|
return fail6("read");
|
|
32010
32035
|
}
|
|
32011
|
-
const
|
|
32036
|
+
const sep22 = entry.uploadUrl.includes("?") ? "&" : "?";
|
|
32012
32037
|
let res;
|
|
32013
32038
|
try {
|
|
32014
|
-
res = await deps.fetch(`${entry.uploadUrl}${
|
|
32039
|
+
res = await deps.fetch(`${entry.uploadUrl}${sep22}filename=${encodeURIComponent(file2.fileName)}`, { method: "PUT", headers: { "Content-Type": file2.mimeType }, body });
|
|
32015
32040
|
} catch {
|
|
32016
32041
|
return fail6("put");
|
|
32017
32042
|
}
|
|
@@ -32649,10 +32674,10 @@ async function runMediaFieldUpload(o2) {
|
|
|
32649
32674
|
} catch (e2) {
|
|
32650
32675
|
return { ok: false, reason: e2 instanceof Deadline ? "timeout" : "read" };
|
|
32651
32676
|
}
|
|
32652
|
-
const
|
|
32677
|
+
const sep22 = uploadUrl.includes("?") ? "&" : "?";
|
|
32653
32678
|
let res;
|
|
32654
32679
|
try {
|
|
32655
|
-
res = await bounded2(deps.fetch(`${uploadUrl}${
|
|
32680
|
+
res = await bounded2(deps.fetch(`${uploadUrl}${sep22}filename=${encodeURIComponent(file2.fileName)}`, {
|
|
32656
32681
|
method: "PUT",
|
|
32657
32682
|
headers: { "Content-Type": file2.mimeType },
|
|
32658
32683
|
body,
|
|
@@ -115774,8 +115799,8 @@ function ensureCountUpRuntime() {
|
|
|
115774
115799
|
const neg = fixed.startsWith("-");
|
|
115775
115800
|
const body = neg ? fixed.slice(1) : fixed;
|
|
115776
115801
|
const [int2, frac] = body.split(".");
|
|
115777
|
-
const
|
|
115778
|
-
return (neg ? "-" : "") +
|
|
115802
|
+
const sep22 = int2.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
115803
|
+
return (neg ? "-" : "") + sep22 + (frac ? "." + frac : "");
|
|
115779
115804
|
};
|
|
115780
115805
|
const animateEl = (el2) => {
|
|
115781
115806
|
const node = el2;
|
|
@@ -126441,7 +126466,7 @@ var init_widgets = __esm({
|
|
|
126441
126466
|
import { createServer as createServer2 } from "node:http";
|
|
126442
126467
|
import { readFile, stat } from "node:fs/promises";
|
|
126443
126468
|
import { readFileSync as readFileSync32, existsSync as existsSync28, watch, mkdirSync as mkdirSync15, rmSync as rmSync7 } from "node:fs";
|
|
126444
|
-
import { basename as basename8, dirname as dirname20, extname as extname2, join as join24, relative as relative5, resolve as resolve28, normalize as normalize3, sep as
|
|
126469
|
+
import { basename as basename8, dirname as dirname20, extname as extname2, join as join24, relative as relative5, resolve as resolve28, normalize as normalize3, sep as sep9 } from "node:path";
|
|
126445
126470
|
import { createHash as createHash16, randomUUID as randomUUID4 } from "node:crypto";
|
|
126446
126471
|
import { fileURLToPath as fileURLToPath19, pathToFileURL as pathToFileURL5 } from "node:url";
|
|
126447
126472
|
function readLogicBundle(read, tier5Dir, name) {
|
|
@@ -127310,7 +127335,7 @@ function startBundleSourceWatcher(state) {
|
|
|
127310
127335
|
try {
|
|
127311
127336
|
const watcher2 = watch(TIER5_SRC_ROOT, { persistent: false, recursive: true }, (_event, filename) => {
|
|
127312
127337
|
if (!filename || !/\.(ts|tsx)$/.test(filename)) return;
|
|
127313
|
-
const name = filename.split(
|
|
127338
|
+
const name = filename.split(sep9)[0];
|
|
127314
127339
|
if (!name || name.startsWith(".")) return;
|
|
127315
127340
|
pending.add(name);
|
|
127316
127341
|
if (timer) clearTimeout(timer);
|
|
@@ -127458,12 +127483,12 @@ function servedTokensHash(app) {
|
|
|
127458
127483
|
}
|
|
127459
127484
|
}
|
|
127460
127485
|
function appDependencyFiles(inputs, appDir3) {
|
|
127461
|
-
const inside2 = (root, p2) => p2 === root || p2.startsWith(root +
|
|
127486
|
+
const inside2 = (root, p2) => p2 === root || p2.startsWith(root + sep9);
|
|
127462
127487
|
const out2 = /* @__PURE__ */ new Set();
|
|
127463
127488
|
for (const raw of inputs) {
|
|
127464
127489
|
const p2 = resolve28(raw);
|
|
127465
127490
|
if (!inside2(ROOT6, p2) || inside2(resolve28(appDir3), p2) || inside2(HMR_TMP_DIR, p2)) continue;
|
|
127466
|
-
if (p2.split(
|
|
127491
|
+
if (p2.split(sep9).includes("node_modules")) continue;
|
|
127467
127492
|
out2.add(p2);
|
|
127468
127493
|
}
|
|
127469
127494
|
return [...out2].sort();
|
|
@@ -127581,7 +127606,7 @@ function startAppSourceWatcher(state) {
|
|
|
127581
127606
|
try {
|
|
127582
127607
|
const watcher2 = watch(appDir3, { persistent: false, recursive: true }, (_event, filename) => {
|
|
127583
127608
|
if (!filename) return;
|
|
127584
|
-
const rel = String(filename).split(
|
|
127609
|
+
const rel = String(filename).split(sep9).join("/");
|
|
127585
127610
|
if (!classifyAppPath(rel)) return;
|
|
127586
127611
|
pending.add(rel);
|
|
127587
127612
|
if (timer) clearTimeout(timer);
|
|
@@ -129925,7 +129950,7 @@ var init_src5 = __esm({
|
|
|
129925
129950
|
|
|
129926
129951
|
// ../../core/serve-storage/src/file-store.ts
|
|
129927
129952
|
import { mkdirSync as mkdirSync16, readFileSync as readFileSync33, rmSync as rmSync8, writeFileSync as writeFileSync10, readdirSync as readdirSync16, existsSync as existsSync29 } from "node:fs";
|
|
129928
|
-
import { join as join25, resolve as resolve29, sep as
|
|
129953
|
+
import { join as join25, resolve as resolve29, sep as sep10 } from "node:path";
|
|
129929
129954
|
var FileReleaseStore;
|
|
129930
129955
|
var init_file_store = __esm({
|
|
129931
129956
|
"../../core/serve-storage/src/file-store.ts"() {
|
|
@@ -129962,7 +129987,7 @@ var init_file_store = __esm({
|
|
|
129962
129987
|
*/
|
|
129963
129988
|
appDir(app) {
|
|
129964
129989
|
const dir = resolve29(this.root, this.safe(app));
|
|
129965
|
-
if (!dir.startsWith(this.root +
|
|
129990
|
+
if (!dir.startsWith(this.root + sep10)) {
|
|
129966
129991
|
throw new Error(`unsafe app id ${JSON.stringify(app)}: ${dir} is not inside the store root`);
|
|
129967
129992
|
}
|
|
129968
129993
|
return dir;
|
|
@@ -133738,8 +133763,8 @@ async function crawlScreenInner(opts) {
|
|
|
133738
133763
|
if (linkable.has(target)) return true;
|
|
133739
133764
|
for (const base of linkable) {
|
|
133740
133765
|
if (target.length > base.length + 1 && target.startsWith(base)) {
|
|
133741
|
-
const
|
|
133742
|
-
if (
|
|
133766
|
+
const sep22 = target[base.length];
|
|
133767
|
+
if (sep22 === "_" || sep22 === "/") return true;
|
|
133743
133768
|
}
|
|
133744
133769
|
}
|
|
133745
133770
|
return false;
|
|
@@ -137604,13 +137629,13 @@ __export(studio_exports, {
|
|
|
137604
137629
|
});
|
|
137605
137630
|
import { createHash as createHash21 } from "node:crypto";
|
|
137606
137631
|
import { existsSync as existsSync33, readdirSync as readdirSync19, readFileSync as readFileSync37, realpathSync as realpathSync6, statSync as statSync7 } from "node:fs";
|
|
137607
|
-
import { basename as basename9, extname as extname3, join as join29, relative as relative6, resolve as resolve31, sep as
|
|
137632
|
+
import { basename as basename9, extname as extname3, join as join29, relative as relative6, resolve as resolve31, sep as sep11 } from "node:path";
|
|
137608
137633
|
import { pathToFileURL as pathToFileURL6 } from "node:url";
|
|
137609
137634
|
function realInside(dir, abs) {
|
|
137610
137635
|
try {
|
|
137611
137636
|
const root = realpathSync6(dir);
|
|
137612
137637
|
const real = realpathSync6(abs);
|
|
137613
|
-
return real.startsWith(root +
|
|
137638
|
+
return real.startsWith(root + sep11) ? real : null;
|
|
137614
137639
|
} catch {
|
|
137615
137640
|
return null;
|
|
137616
137641
|
}
|
|
@@ -141907,21 +141932,21 @@ var init_Matcher = __esm({
|
|
|
141907
141932
|
* @returns {string}
|
|
141908
141933
|
*/
|
|
141909
141934
|
toString(separator, includeNamespace = true) {
|
|
141910
|
-
const
|
|
141911
|
-
const isDefault =
|
|
141935
|
+
const sep22 = separator || this.separator;
|
|
141936
|
+
const isDefault = sep22 === this.separator && includeNamespace === true;
|
|
141912
141937
|
if (isDefault) {
|
|
141913
141938
|
if (this._pathStringCache !== null) {
|
|
141914
141939
|
return this._pathStringCache;
|
|
141915
141940
|
}
|
|
141916
141941
|
const result = this.path.map(
|
|
141917
141942
|
(n2) => n2.namespace ? `${n2.namespace}:${n2.tag}` : n2.tag
|
|
141918
|
-
).join(
|
|
141943
|
+
).join(sep22);
|
|
141919
141944
|
this._pathStringCache = result;
|
|
141920
141945
|
return result;
|
|
141921
141946
|
}
|
|
141922
141947
|
return this.path.map(
|
|
141923
141948
|
(n2) => includeNamespace && n2.namespace ? `${n2.namespace}:${n2.tag}` : n2.tag
|
|
141924
|
-
).join(
|
|
141949
|
+
).join(sep22);
|
|
141925
141950
|
}
|
|
141926
141951
|
/**
|
|
141927
141952
|
* Get path as array of tag names.
|
|
@@ -142623,76 +142648,76 @@ var init_redos = __esm({
|
|
|
142623
142648
|
});
|
|
142624
142649
|
|
|
142625
142650
|
// ../../node_modules/is-unsafe/src/contexts/nosql.js
|
|
142626
|
-
var
|
|
142651
|
+
var sep12, NOSQL_PATTERNS, nosql_default;
|
|
142627
142652
|
var init_nosql = __esm({
|
|
142628
142653
|
"../../node_modules/is-unsafe/src/contexts/nosql.js"() {
|
|
142629
|
-
|
|
142654
|
+
sep12 = `["'\\s]*:`;
|
|
142630
142655
|
NOSQL_PATTERNS = [
|
|
142631
142656
|
// ─── MongoDB $ operator injection ────────────────────────────────────────
|
|
142632
142657
|
{
|
|
142633
142658
|
id: "nosql-where-operator",
|
|
142634
142659
|
description: "$where \u2014 executes arbitrary JavaScript server-side in MongoDB",
|
|
142635
|
-
pattern: new RegExp(`\\$where${
|
|
142660
|
+
pattern: new RegExp(`\\$where${sep12}`, "i")
|
|
142636
142661
|
},
|
|
142637
142662
|
{
|
|
142638
142663
|
id: "nosql-ne-operator",
|
|
142639
142664
|
description: '$ne \u2014 "not equal" operator used to bypass equality checks',
|
|
142640
|
-
pattern: new RegExp(`\\$ne${
|
|
142665
|
+
pattern: new RegExp(`\\$ne${sep12}`, "i")
|
|
142641
142666
|
},
|
|
142642
142667
|
{
|
|
142643
142668
|
id: "nosql-gt-operator",
|
|
142644
142669
|
description: '$gt \u2014 "greater than" used to bypass password/value checks',
|
|
142645
|
-
pattern: new RegExp(`\\$gte?${
|
|
142670
|
+
pattern: new RegExp(`\\$gte?${sep12}`, "i")
|
|
142646
142671
|
},
|
|
142647
142672
|
{
|
|
142648
142673
|
id: "nosql-lt-operator",
|
|
142649
142674
|
description: '$lt / $lte \u2014 "less than" bypass variants',
|
|
142650
|
-
pattern: new RegExp(`\\$lte?${
|
|
142675
|
+
pattern: new RegExp(`\\$lte?${sep12}`, "i")
|
|
142651
142676
|
},
|
|
142652
142677
|
{
|
|
142653
142678
|
id: "nosql-regex-operator",
|
|
142654
142679
|
description: "$regex \u2014 can be used to extract data character by character (blind injection)",
|
|
142655
|
-
pattern: new RegExp(`\\$regex${
|
|
142680
|
+
pattern: new RegExp(`\\$regex${sep12}`, "i")
|
|
142656
142681
|
},
|
|
142657
142682
|
{
|
|
142658
142683
|
id: "nosql-or-operator",
|
|
142659
142684
|
description: "$or \u2014 logical OR; used to create always-true conditions",
|
|
142660
|
-
pattern: new RegExp(`\\$or${
|
|
142685
|
+
pattern: new RegExp(`\\$or${sep12}\\s*\\[`, "i")
|
|
142661
142686
|
},
|
|
142662
142687
|
{
|
|
142663
142688
|
id: "nosql-and-operator",
|
|
142664
142689
|
description: "$and \u2014 logical AND operator injection",
|
|
142665
|
-
pattern: new RegExp(`\\$and${
|
|
142690
|
+
pattern: new RegExp(`\\$and${sep12}\\s*\\[`, "i")
|
|
142666
142691
|
},
|
|
142667
142692
|
{
|
|
142668
142693
|
id: "nosql-nor-operator",
|
|
142669
142694
|
description: "$nor \u2014 logical NOR operator injection",
|
|
142670
|
-
pattern: new RegExp(`\\$nor${
|
|
142695
|
+
pattern: new RegExp(`\\$nor${sep12}\\s*\\[`, "i")
|
|
142671
142696
|
},
|
|
142672
142697
|
{
|
|
142673
142698
|
id: "nosql-exists-operator",
|
|
142674
142699
|
description: "$exists \u2014 can enumerate fields to determine schema",
|
|
142675
|
-
pattern: new RegExp(`\\$exists${
|
|
142700
|
+
pattern: new RegExp(`\\$exists${sep12}`, "i")
|
|
142676
142701
|
},
|
|
142677
142702
|
{
|
|
142678
142703
|
id: "nosql-in-operator",
|
|
142679
142704
|
description: "$in \u2014 matches any value in a list; can enumerate values",
|
|
142680
|
-
pattern: new RegExp(`\\$in${
|
|
142705
|
+
pattern: new RegExp(`\\$in${sep12}\\s*\\[`, "i")
|
|
142681
142706
|
},
|
|
142682
142707
|
{
|
|
142683
142708
|
id: "nosql-expr-operator",
|
|
142684
142709
|
description: "$expr \u2014 allows aggregation expressions in queries (MongoDB 3.6+)",
|
|
142685
|
-
pattern: new RegExp(`\\$expr${
|
|
142710
|
+
pattern: new RegExp(`\\$expr${sep12}`, "i")
|
|
142686
142711
|
},
|
|
142687
142712
|
{
|
|
142688
142713
|
id: "nosql-function-operator",
|
|
142689
142714
|
description: "$function \u2014 executes arbitrary JavaScript in MongoDB 4.4+",
|
|
142690
|
-
pattern: new RegExp(`\\$function${
|
|
142715
|
+
pattern: new RegExp(`\\$function${sep12}`, "i")
|
|
142691
142716
|
},
|
|
142692
142717
|
{
|
|
142693
142718
|
id: "nosql-accumulator-operator",
|
|
142694
142719
|
description: "$accumulator \u2014 custom aggregation with arbitrary JS execution",
|
|
142695
|
-
pattern: new RegExp(`\\$accumulator${
|
|
142720
|
+
pattern: new RegExp(`\\$accumulator${sep12}`, "i")
|
|
142696
142721
|
},
|
|
142697
142722
|
// ─── Prototype pollution ─────────────────────────────────────────────────
|
|
142698
142723
|
{
|
|
@@ -148536,7 +148561,7 @@ __export(app_source_exports, {
|
|
|
148536
148561
|
});
|
|
148537
148562
|
import { createHash as createHash25 } from "node:crypto";
|
|
148538
148563
|
import { readdirSync as readdirSync24, lstatSync as lstatSync13, readFileSync as readFileSync49, mkdirSync as mkdirSync23, writeFileSync as writeFileSync18, existsSync as existsSync42, rmSync as rmSync13, rmdirSync as rmdirSync2, unlinkSync as unlinkSync3 } from "node:fs";
|
|
148539
|
-
import { join as join38, resolve as resolve40, sep as
|
|
148564
|
+
import { join as join38, resolve as resolve40, sep as sep13 } from "node:path";
|
|
148540
148565
|
import { createRequire as createRequire3 } from "node:module";
|
|
148541
148566
|
import { deflateRawSync as deflateRawSync2 } from "node:zlib";
|
|
148542
148567
|
function walkSourceTree(dir, file2, skip, enter = () => {
|
|
@@ -148559,7 +148584,7 @@ function walkSourceTree(dir, file2, skip, enter = () => {
|
|
|
148559
148584
|
skip(rel);
|
|
148560
148585
|
continue;
|
|
148561
148586
|
}
|
|
148562
|
-
file2(rel.split(
|
|
148587
|
+
file2(rel.split(sep13).join("/"), rel);
|
|
148563
148588
|
}
|
|
148564
148589
|
};
|
|
148565
148590
|
walk2("");
|
|
@@ -148619,8 +148644,8 @@ function renderInputRootDirs(dir) {
|
|
|
148619
148644
|
}
|
|
148620
148645
|
function newestSourceChangeMs(dir) {
|
|
148621
148646
|
const roots2 = renderInputRootDirs(dir);
|
|
148622
|
-
const inRead = (hostRel) => !roots2 || roots2.has(hostRel.split(
|
|
148623
|
-
const counts = (hostRel) => !hostRel.includes(
|
|
148647
|
+
const inRead = (hostRel) => !roots2 || roots2.has(hostRel.split(sep13)[0]);
|
|
148648
|
+
const counts = (hostRel) => !hostRel.includes(sep13) || inRead(hostRel);
|
|
148624
148649
|
let newest = 0;
|
|
148625
148650
|
walkSourceTree(
|
|
148626
148651
|
dir,
|
|
@@ -148782,7 +148807,7 @@ function pruneEmptyDirs(root, rel, needed, removed) {
|
|
|
148782
148807
|
let empty2 = true;
|
|
148783
148808
|
for (const name of readdirSync24(rel ? join38(root, rel) : root)) {
|
|
148784
148809
|
const childRel = rel ? join38(rel, name) : name;
|
|
148785
|
-
const posix5 = childRel.split(
|
|
148810
|
+
const posix5 = childRel.split(sep13).join("/");
|
|
148786
148811
|
const kind = lstatSync13(join38(root, childRel));
|
|
148787
148812
|
if (kind.isSymbolicLink() || !kind.isDirectory() || isDeniedSourceDir(name, rel)) {
|
|
148788
148813
|
empty2 = false;
|
|
@@ -148866,7 +148891,7 @@ __export(run_watch_exports, {
|
|
|
148866
148891
|
});
|
|
148867
148892
|
import { closeSync as closeSync4, constants as constants3, existsSync as existsSync43, fstatSync, lstatSync as lstatSync14, statSync as statSync14, readdirSync as readdirSync25, mkdirSync as mkdirSync24, openSync as openSync4, readFileSync as readFileSync50, realpathSync as realpathSync8, renameSync as renameSync10, rmSync as rmSync14, writeFileSync as writeFileSync19, watch as fsWatch } from "node:fs";
|
|
148868
148893
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
148869
|
-
import { extname as extname4, join as join39, relative as relative8, resolve as resolve41, sep as
|
|
148894
|
+
import { extname as extname4, join as join39, relative as relative8, resolve as resolve41, sep as sep14 } from "node:path";
|
|
148870
148895
|
function diffReleases(prev, next) {
|
|
148871
148896
|
const bundles = Object.keys(next.bundles).filter((b2) => prev.bundles[b2]?.sha256 !== next.bundles[b2].sha256).sort();
|
|
148872
148897
|
const changedBundles = new Set(bundles);
|
|
@@ -148894,7 +148919,7 @@ function reloadEvents(d2) {
|
|
|
148894
148919
|
function hhpRasterDir(dir) {
|
|
148895
148920
|
const assets = findAssetsDir(dir);
|
|
148896
148921
|
if (!assets) return null;
|
|
148897
|
-
const rel = relative8(dir, assets).split(
|
|
148922
|
+
const rel = relative8(dir, assets).split(sep14).join("/");
|
|
148898
148923
|
return rel ? `${rel}/hhp-raster` : "hhp-raster";
|
|
148899
148924
|
}
|
|
148900
148925
|
function ignoredChange(relPath, isDirectory = () => false, rasterDir = "assets/hhp-raster") {
|
|
@@ -149121,7 +149146,7 @@ function boardFile(dir, pathname) {
|
|
|
149121
149146
|
function readConfined(root, rel) {
|
|
149122
149147
|
try {
|
|
149123
149148
|
if (!lstatSync14(root).isDirectory()) return null;
|
|
149124
|
-
const parts = rel.split(
|
|
149149
|
+
const parts = rel.split(sep14);
|
|
149125
149150
|
let at2 = root;
|
|
149126
149151
|
for (let i2 = 0; i2 < parts.length; i2++) {
|
|
149127
149152
|
at2 = join39(at2, parts[i2]);
|
|
@@ -149129,7 +149154,7 @@ function readConfined(root, rel) {
|
|
|
149129
149154
|
if (st2.isSymbolicLink() || !(i2 === parts.length - 1 ? st2.isFile() : st2.isDirectory())) return null;
|
|
149130
149155
|
}
|
|
149131
149156
|
const canonicalRoot = realpathSync8(root);
|
|
149132
|
-
if (!realpathSync8(at2).startsWith(canonicalRoot +
|
|
149157
|
+
if (!realpathSync8(at2).startsWith(canonicalRoot + sep14)) return null;
|
|
149133
149158
|
const fd = openSync4(at2, constants3.O_RDONLY | (constants3.O_NOFOLLOW ?? 0));
|
|
149134
149159
|
try {
|
|
149135
149160
|
if (!fstatSync(fd).isFile()) return null;
|
|
@@ -149640,13 +149665,13 @@ import { createHash as createHash28, randomUUID as randomUUID8 } from "node:cryp
|
|
|
149640
149665
|
import { spawn as spawn4 } from "node:child_process";
|
|
149641
149666
|
import { closeSync as closeSync5, existsSync as existsSync44, lstatSync as lstatSync17, readFileSync as readFileSync54, statSync as statSync15 } from "node:fs";
|
|
149642
149667
|
import { createServer as createServer3 } from "node:net";
|
|
149643
|
-
import { basename as basename14, dirname as dirname28, isAbsolute as isAbsolute4, join as join43, relative as relative9, resolve as resolve42, sep as
|
|
149668
|
+
import { basename as basename14, dirname as dirname28, isAbsolute as isAbsolute4, join as join43, relative as relative9, resolve as resolve42, sep as sep15 } from "node:path";
|
|
149644
149669
|
function homeShotPath(dir, home) {
|
|
149645
149670
|
const root = resolve42(dir);
|
|
149646
149671
|
const base = resolve42(root, ".himi", "shots");
|
|
149647
149672
|
const shot = resolve42(base, `${home}.png`);
|
|
149648
|
-
if (!shot.startsWith(base +
|
|
149649
|
-
for (let p2 = shot; p2 !== root && p2.startsWith(root +
|
|
149673
|
+
if (!shot.startsWith(base + sep15)) return null;
|
|
149674
|
+
for (let p2 = shot; p2 !== root && p2.startsWith(root + sep15); p2 = dirname28(p2)) {
|
|
149650
149675
|
try {
|
|
149651
149676
|
if (lstatSync17(p2).isSymbolicLink()) return null;
|
|
149652
149677
|
} catch {
|
|
@@ -155069,7 +155094,7 @@ __export(eject_exports, {
|
|
|
155069
155094
|
ejectModule: () => ejectModule
|
|
155070
155095
|
});
|
|
155071
155096
|
import { existsSync as existsSync58, mkdirSync as mkdirSync27, readFileSync as readFileSync68, writeFileSync as writeFileSync23 } from "node:fs";
|
|
155072
|
-
import { dirname as dirname33, join as join58, relative as relative10, resolve as resolve47, sep as
|
|
155097
|
+
import { dirname as dirname33, join as join58, relative as relative10, resolve as resolve47, sep as sep16 } from "node:path";
|
|
155073
155098
|
function locate(repoRootOrCwd, mod) {
|
|
155074
155099
|
const inRepo = resolve47(repoRootOrCwd, `stdlib/flows/${mod}/src/index.ts`);
|
|
155075
155100
|
if (existsSync58(inRepo)) return { path: inRepo, form: "source" };
|
|
@@ -155122,7 +155147,7 @@ function ejectModule(opts) {
|
|
|
155122
155147
|
if (!existsSync58(f2)) continue;
|
|
155123
155148
|
const before = readFileSync68(f2, "utf8");
|
|
155124
155149
|
let after = before;
|
|
155125
|
-
let rel = relative10(dirname33(f2), target).split(
|
|
155150
|
+
let rel = relative10(dirname33(f2), target).split(sep16).join("/").replace(/\.tsx?$/, ".js");
|
|
155126
155151
|
if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
155127
155152
|
for (const spec of specifiersFor(mod)) {
|
|
155128
155153
|
const q2 = spec.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -155299,7 +155324,7 @@ __export(icon_exports, {
|
|
|
155299
155324
|
});
|
|
155300
155325
|
import { createHash as createHash31 } from "node:crypto";
|
|
155301
155326
|
import { existsSync as existsSync59, mkdirSync as mkdirSync28, readFileSync as readFileSync69, statSync as statSync18, writeFileSync as writeFileSync24 } from "node:fs";
|
|
155302
|
-
import { basename as basename16, dirname as dirname34, join as join59, resolve as resolve48, sep as
|
|
155327
|
+
import { basename as basename16, dirname as dirname34, join as join59, resolve as resolve48, sep as sep17 } from "node:path";
|
|
155303
155328
|
function readManifest(dir) {
|
|
155304
155329
|
try {
|
|
155305
155330
|
return JSON.parse(readFileSync69(join59(dir, MANIFEST), "utf8"));
|
|
@@ -155316,7 +155341,7 @@ function declaredIconName(dir) {
|
|
|
155316
155341
|
function iconDest(dir, name) {
|
|
155317
155342
|
const base = resolve48(dir);
|
|
155318
155343
|
const abs = resolve48(base, name);
|
|
155319
|
-
if (!abs.startsWith(base +
|
|
155344
|
+
if (!abs.startsWith(base + sep17)) {
|
|
155320
155345
|
throw new Error(
|
|
155321
155346
|
`himi icon: himalaya.content.json declares "icon": "${name}", which resolves outside the package (${abs}). Declare a path inside it, e.g. "${DEFAULT_CONTENT_ICON}".`
|
|
155322
155347
|
);
|
|
@@ -155663,8 +155688,8 @@ function baseOf(target, linkable, known) {
|
|
|
155663
155688
|
let best = null;
|
|
155664
155689
|
for (const base of linkable ?? []) {
|
|
155665
155690
|
if (!known.has(base) || target.length <= base.length + 1 || !target.startsWith(base)) continue;
|
|
155666
|
-
const
|
|
155667
|
-
if ((
|
|
155691
|
+
const sep22 = target[base.length];
|
|
155692
|
+
if ((sep22 === "_" || sep22 === "/") && (!best || base.length > best.length)) best = base;
|
|
155668
155693
|
}
|
|
155669
155694
|
return best;
|
|
155670
155695
|
}
|
|
@@ -159654,10 +159679,10 @@ var init_cli_bridge = __esm({
|
|
|
159654
159679
|
// src/mcp/file-tools.ts
|
|
159655
159680
|
import { closeSync as closeSync6, constants as constants4, lstatSync as lstatSync21, mkdirSync as mkdirSync33, openSync as openSync5, readdirSync as readdirSync31, readFileSync as readFileSync81, realpathSync as realpathSync10, renameSync as renameSync11, rmSync as rmSync18, statSync as statSync19, writeSync, existsSync as existsSync69 } from "node:fs";
|
|
159656
159681
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
159657
|
-
import { dirname as dirname39, isAbsolute as isAbsolute7, join as join72, relative as relative13, resolve as resolve56, sep as
|
|
159682
|
+
import { dirname as dirname39, isAbsolute as isAbsolute7, join as join72, relative as relative13, resolve as resolve56, sep as sep18 } from "node:path";
|
|
159658
159683
|
import * as z2 from "zod";
|
|
159659
159684
|
function within(root, p2) {
|
|
159660
|
-
return p2 === root || p2.startsWith(root.endsWith(
|
|
159685
|
+
return p2 === root || p2.startsWith(root.endsWith(sep18) ? root : root + sep18);
|
|
159661
159686
|
}
|
|
159662
159687
|
function realish(p2) {
|
|
159663
159688
|
let cur = p2;
|
|
@@ -159665,14 +159690,14 @@ function realish(p2) {
|
|
|
159665
159690
|
while (!existsSync69(cur)) {
|
|
159666
159691
|
const up = dirname39(cur);
|
|
159667
159692
|
if (up === cur) break;
|
|
159668
|
-
tail.unshift(cur.slice(up.length + (up.endsWith(
|
|
159693
|
+
tail.unshift(cur.slice(up.length + (up.endsWith(sep18) ? 0 : 1)));
|
|
159669
159694
|
cur = up;
|
|
159670
159695
|
}
|
|
159671
159696
|
return join72(realpathSync10(cur), ...tail);
|
|
159672
159697
|
}
|
|
159673
159698
|
function symlinkComponent(base, abs) {
|
|
159674
159699
|
let cur = base;
|
|
159675
|
-
for (const part3 of relative13(base, abs).split(
|
|
159700
|
+
for (const part3 of relative13(base, abs).split(sep18).filter(Boolean)) {
|
|
159676
159701
|
cur = join72(cur, part3);
|
|
159677
159702
|
try {
|
|
159678
159703
|
if (lstatSync21(cur).isSymbolicLink()) return relative13(base, cur);
|
|
@@ -159711,7 +159736,7 @@ function onDiskSpelling(abs) {
|
|
|
159711
159736
|
while (!existsSync69(cur)) {
|
|
159712
159737
|
const up = dirname39(cur);
|
|
159713
159738
|
if (up === cur) break;
|
|
159714
|
-
tail.unshift(cur.slice(up.length + (up.endsWith(
|
|
159739
|
+
tail.unshift(cur.slice(up.length + (up.endsWith(sep18) ? 0 : 1)));
|
|
159715
159740
|
cur = up;
|
|
159716
159741
|
}
|
|
159717
159742
|
return join72(realpathSync10.native(cur), ...tail);
|
|
@@ -159771,7 +159796,7 @@ function listFiles(appDir3) {
|
|
|
159771
159796
|
const rel = relative13(appDir3, p2);
|
|
159772
159797
|
if (isDeniedSourcePath(rel) || isDeniedSourcePath(rel.toLowerCase())) continue;
|
|
159773
159798
|
if (files.length >= MAX_LISTED) return false;
|
|
159774
|
-
files.push({ path: rel.split(
|
|
159799
|
+
files.push({ path: rel.split(sep18).join("/"), bytes: statSync19(p2).size });
|
|
159775
159800
|
}
|
|
159776
159801
|
}
|
|
159777
159802
|
return true;
|
|
@@ -160571,7 +160596,7 @@ __export(native_decode_exports, {
|
|
|
160571
160596
|
runAndroidNativeDecode: () => runAndroidNativeDecode,
|
|
160572
160597
|
runNativeDecode: () => runNativeDecode
|
|
160573
160598
|
});
|
|
160574
|
-
import { execFileSync as execFileSync6, spawnSync as
|
|
160599
|
+
import { execFileSync as execFileSync6, spawnSync as spawnSync4 } from "node:child_process";
|
|
160575
160600
|
import { existsSync as existsSync73, mkdirSync as mkdirSync37, mkdtempSync as mkdtempSync5, readFileSync as readFileSync84, rmSync as rmSync20, writeFileSync as writeFileSync31 } from "node:fs";
|
|
160576
160601
|
import { homedir as homedir10, tmpdir as tmpdir6 } from "node:os";
|
|
160577
160602
|
import { join as join78 } from "node:path";
|
|
@@ -160591,7 +160616,7 @@ function nativeOracleShipped() {
|
|
|
160591
160616
|
function detectNativeDecode(options = {}) {
|
|
160592
160617
|
const hostPlatform = options.hostPlatform ?? process.platform;
|
|
160593
160618
|
const packageDir = options.packageDir ?? nativeDecodePackageDir();
|
|
160594
|
-
const swiftAvailable = options.swiftAvailable ??
|
|
160619
|
+
const swiftAvailable = options.swiftAvailable ?? spawnSync4("swift", ["--version"], { stdio: "ignore" }).status === 0;
|
|
160595
160620
|
if (hostPlatform !== "darwin") {
|
|
160596
160621
|
return { platform: "ios", available: false, reason: `the iOS decoder oracle requires macOS (darwin); this host is ${hostPlatform}` };
|
|
160597
160622
|
}
|
|
@@ -160893,7 +160918,7 @@ __export(browser_authoring_exports, {
|
|
|
160893
160918
|
import { createServer as createServer4 } from "node:http";
|
|
160894
160919
|
import { createHash as createHash38, randomBytes as randomBytes4 } from "node:crypto";
|
|
160895
160920
|
import { existsSync as existsSync74, readdirSync as readdirSync33, readFileSync as readFileSync85, realpathSync as realpathSync11, statSync as statSync20 } from "node:fs";
|
|
160896
|
-
import { join as join79, posix as posix3, relative as relative15, sep as
|
|
160921
|
+
import { join as join79, posix as posix3, relative as relative15, sep as sep19 } from "node:path";
|
|
160897
160922
|
function humanMs(ms2) {
|
|
160898
160923
|
return ms2 < 1e3 ? `${ms2}ms` : `${Math.round(ms2 / 1e3)}s`;
|
|
160899
160924
|
}
|
|
@@ -160943,7 +160968,7 @@ function collectRelativeSiblings(files, tier5SrcDir) {
|
|
|
160943
160968
|
];
|
|
160944
160969
|
for (const abs of candidates) {
|
|
160945
160970
|
if (!existsSync74(abs) || statSync20(abs).isDirectory()) continue;
|
|
160946
|
-
const key3 = `/tier5-src/${relative15(tier5SrcDir, abs).split(
|
|
160971
|
+
const key3 = `/tier5-src/${relative15(tier5SrcDir, abs).split(sep19).join(posix3.sep)}`;
|
|
160947
160972
|
if (key3 in files) break;
|
|
160948
160973
|
files[key3] = readFileSync85(abs, "utf8");
|
|
160949
160974
|
queue.push(key3);
|
|
@@ -164280,6 +164305,11 @@ ${releaseId}`;
|
|
|
164280
164305
|
...m2.templateMeta.accent ? { accent: m2.templateMeta.accent } : {},
|
|
164281
164306
|
...m2.templateMeta.palette?.length ? { palette: m2.templateMeta.palette } : {},
|
|
164282
164307
|
releaseId: m2.releaseId,
|
|
164308
|
+
// The content address of the catalog view (`/v1/template-source`), which serve-control
|
|
164309
|
+
// stamps as sha256(JSON.stringify(source)). Public so tools/ci/check-published-templates.mjs
|
|
164310
|
+
// can tell a stale template from a current one without the source or a credential:
|
|
164311
|
+
// `himi template publish --source-hash` computes the same hash from a checkout.
|
|
164312
|
+
...m2.sourceHash ? { sourceHash: m2.sourceHash } : {},
|
|
164283
164313
|
minBinaryVersion: m2.minBinaryVersion,
|
|
164284
164314
|
...iconUrl ? { iconUrl } : {}
|
|
164285
164315
|
});
|
|
@@ -165387,7 +165417,7 @@ __export(run_browser_exports, {
|
|
|
165387
165417
|
});
|
|
165388
165418
|
import { createServer as createServer6 } from "node:http";
|
|
165389
165419
|
import { existsSync as existsSync84, readFileSync as readFileSync94 } from "node:fs";
|
|
165390
|
-
import { spawnSync as
|
|
165420
|
+
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
165391
165421
|
import { dirname as dirname44, resolve as resolve68 } from "node:path";
|
|
165392
165422
|
import { fileURLToPath as fileURLToPath30 } from "node:url";
|
|
165393
165423
|
function stagedDir() {
|
|
@@ -165398,7 +165428,7 @@ function missingStaged() {
|
|
|
165398
165428
|
}
|
|
165399
165429
|
function ensureBrowserPlaneStaged() {
|
|
165400
165430
|
if (missingStaged().length === 0) return { ok: true, detail: "already staged" };
|
|
165401
|
-
const r3 =
|
|
165431
|
+
const r3 = spawnSync5(process.execPath, [resolve68(REPO2, "core/serve/scripts/stage-browser-plane.mjs")], {
|
|
165402
165432
|
cwd: REPO2,
|
|
165403
165433
|
encoding: "utf8"
|
|
165404
165434
|
});
|
|
@@ -177494,7 +177524,7 @@ var init_analyze = __esm({
|
|
|
177494
177524
|
|
|
177495
177525
|
// src/base44-analyze/write-artifacts.ts
|
|
177496
177526
|
import { existsSync as existsSync101, mkdirSync as mkdirSync45, readFileSync as readFileSync119, rmSync as rmSync29, writeFileSync as writeFileSync44 } from "node:fs";
|
|
177497
|
-
import { dirname as dirname52, join as join111, resolve as resolve74, sep as
|
|
177527
|
+
import { dirname as dirname52, join as join111, resolve as resolve74, sep as sep20 } from "node:path";
|
|
177498
177528
|
function isBookFolder(dir) {
|
|
177499
177529
|
try {
|
|
177500
177530
|
return JSON.parse(readFileSync119(join111(dir, "book.json"), "utf8")).kind === "base44-app-book";
|
|
@@ -177602,7 +177632,7 @@ function writeBase44Book(result, outDir, opts = {}) {
|
|
|
177602
177632
|
for (const f2 of result.sourceFiles) {
|
|
177603
177633
|
if (!safeRel(f2.path)) continue;
|
|
177604
177634
|
const dest = join111(sourceRoot, ...f2.path.split("/"));
|
|
177605
|
-
if (!dest.startsWith(sourceRoot +
|
|
177635
|
+
if (!dest.startsWith(sourceRoot + sep20)) continue;
|
|
177606
177636
|
mkdirSync45(dirname52(dest), { recursive: true });
|
|
177607
177637
|
writeFileSync44(dest, f2.bytes);
|
|
177608
177638
|
}
|
|
@@ -184117,8 +184147,8 @@ var init_customer_build = __esm({
|
|
|
184117
184147
|
|
|
184118
184148
|
// src/site-analyze/apply.ts
|
|
184119
184149
|
import { existsSync as existsSync103, readFileSync as readFileSync121, writeFileSync as writeFileSync47, copyFileSync as copyFileSync2, mkdirSync as mkdirSync48, realpathSync as realpathSync15, statSync as statSync27 } from "node:fs";
|
|
184120
|
-
import { dirname as dirname54, isAbsolute as isAbsolute9, join as join115, resolve as resolve78, sep as
|
|
184121
|
-
import { spawnSync as
|
|
184150
|
+
import { dirname as dirname54, isAbsolute as isAbsolute9, join as join115, resolve as resolve78, sep as sep21 } from "node:path";
|
|
184151
|
+
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
184122
184152
|
function unpairedRedirectNote(overlay) {
|
|
184123
184153
|
if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
|
|
184124
184154
|
return `no OAuth redirect paired with client ${overlay.wix.clientId} \u2014 the app (and prepare:customer) will refuse to start until one is set. Register it with \`himi site client ensure --site ${overlay.siteId?.trim() || "<msid>"} --redirect-uri <uri> --yes\`, then re-run analyze with \`--redirect-uri <uri>\` (or export HIMI_BRANDED_LITE_WIX_REDIRECT_URI)`;
|
|
@@ -184247,7 +184277,7 @@ function buildMergedContract(options) {
|
|
|
184247
184277
|
const contained = (root, rel) => {
|
|
184248
184278
|
if (isAbsolute9(rel)) return void 0;
|
|
184249
184279
|
const full = resolve78(root, rel);
|
|
184250
|
-
return full.startsWith(resolve78(root) +
|
|
184280
|
+
return full.startsWith(resolve78(root) + sep21) ? full : void 0;
|
|
184251
184281
|
};
|
|
184252
184282
|
const stage = (fromRel, toRel) => {
|
|
184253
184283
|
const from = contained(packageDir, fromRel);
|
|
@@ -184261,7 +184291,7 @@ function buildMergedContract(options) {
|
|
|
184261
184291
|
} catch {
|
|
184262
184292
|
return void 0;
|
|
184263
184293
|
}
|
|
184264
|
-
if (!real.startsWith(realRoot +
|
|
184294
|
+
if (!real.startsWith(realRoot + sep21)) return void 0;
|
|
184265
184295
|
try {
|
|
184266
184296
|
if (!statSync27(real).isFile()) return void 0;
|
|
184267
184297
|
mkdirSync48(dirname54(to2), { recursive: true });
|
|
@@ -184397,7 +184427,7 @@ async function applyOverlays(input) {
|
|
|
184397
184427
|
const packageDir = dirname54(resolve78(input.overlayPath));
|
|
184398
184428
|
const { path: contract, staged } = buildMergedContract({ appDir: appDir3, packageDir, overlay });
|
|
184399
184429
|
wrote.push(...staged);
|
|
184400
|
-
const r3 =
|
|
184430
|
+
const r3 = spawnSync6("npm", ["run", "prepare:customer", "--", "--contract", contract], {
|
|
184401
184431
|
cwd: appDir3,
|
|
184402
184432
|
encoding: "utf8"
|
|
184403
184433
|
});
|
|
@@ -187471,7 +187501,8 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
187471
187501
|
"refresh-wix",
|
|
187472
187502
|
"empty-app-ok",
|
|
187473
187503
|
"aab",
|
|
187474
|
-
"managed"
|
|
187504
|
+
"managed",
|
|
187505
|
+
"source-hash"
|
|
187475
187506
|
]);
|
|
187476
187507
|
var SWITCH_FLAGS = new Set([...BOOLEAN_FLAGS].filter((name) => name !== "deep"));
|
|
187477
187508
|
var SWITCH_CONSEQUENCE = {
|
|
@@ -187481,6 +187512,7 @@ var SWITCH_CONSEQUENCE = {
|
|
|
187481
187512
|
record: "silently ignored, it would leave you believing the fixture was refreshed",
|
|
187482
187513
|
"no-oauth-app": "silently ignored, it would mint an OAuth client you asked to skip",
|
|
187483
187514
|
"dry-run": "silently ignored, it would perform the real writes you asked to rehearse",
|
|
187515
|
+
"source-hash": "silently ignored, it would PUBLISH the template instead of printing its source hash",
|
|
187484
187516
|
"allow-destructive": "silently ignored, it would refuse the destructive step you opted into",
|
|
187485
187517
|
static: "silently ignored, it would render HYDRATED when you asked for static",
|
|
187486
187518
|
// `--wait=false` is the one spelling where "pass it bare" is the WRONG advice: bare `--wait`
|
|
@@ -188244,7 +188276,7 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
188244
188276
|
else skips it: outside CI it starts, and watch.note says why
|
|
188245
188277
|
himi template list [--remote] list starter templates + metadata (title/description/tags) + each one's start prompt
|
|
188246
188278
|
himi template prompt <name> print the prompt that starts an app from that template
|
|
188247
|
-
himi template publish [--dir <app>] [--source-dir <dir>] [--name <n>] [--icon <png>] [--visibility public|unlisted]
|
|
188279
|
+
himi template publish [--dir <app>] [--source-dir <dir>] [--name <n>] [--icon <png>] [--visibility public|unlisted] [--source-hash]
|
|
188248
188280
|
publish an app AS a himi init --template on the serve plane
|
|
188249
188281
|
himi template trim --keep <id,id,\u2026> | --from-spec [SPEC.md] [--content <dir>] [--links follow|drop] [--dry-run] [--force]
|
|
188250
188282
|
cut a scaffolded template to the screens you keep (the home and
|
|
@@ -188992,7 +189024,7 @@ var COMMANDS = [
|
|
|
188992
189024
|
{ name: "hhp", summary: "author responsive HTML/CSS/TypeScript screens compiled to native SDUI and T5 workers; scaffold, inspect the app profile, lint or compile declared sources", required: "init <screen> | profile | lint | compile [--app <name>|--content <dir>] [--json] [--dry-run]" },
|
|
188993
189025
|
{ name: "captcha", summary: "create and store native CAPTCHA keys in Serve, or inspect setup status; customer setup verifies Wix site ownership; does not enable member CAPTCHA SDKs", required: "setup|status --app <app> [--content <dir>] [--site <msid>] [--ios-bundle-id <id>] [--android-package-name <id>] [--target <t>]" },
|
|
188994
189026
|
{ name: "init", summary: "scaffold a starter content package (OTA-only; no native shells). --template <t> starts from a full reference app (branded-lite = consumer storefront over a Wix site; owner-lite = owner CRUD/management) instead of the minimal counter; --templates lists bundled ones; --remote fetches the template off the serve plane (falls back to the bundled copy offline). The new app also gets its agent files (the same set `himi agent-init` writes: AGENTS.md, CLAUDE.md, the himalaya skill, HIMALAYA.md, a SessionStart hook) so the next session started inside it picks the work up; --no-agent skips them. It also makes the build board (.himi/studio/, exactly as `himi studio --no-open` does \u2014 it never opens a browser), so every later render, test, validate, push and progress entry refreshes it; and, for a template bundled with this CLI, it makes the FIRST PICTURE itself (never for a --remote one: that is its publisher's code, and a render runs it on this machine, so next[] leaves the render to the agent after it has read the code): exactly `himi render <homeScreenId> --png --mocks --device iphone` (offline \u2014 no request; never --live; --mocks loads the app's recorded data when it has any), run as a child it kills after a time budget, writing .himi/shots/<home>.png and journaling it (by: himi) as the STARTING POINT (\"Starting point: the <template> template, before any of your changes\") so the board and the journal hold a picture when init returns. init also records the source it wrote (.himi/init-source.json: a content fingerprint, Markdown left out), and the first home PNG render after the source diverges from it is journaled once as \"First look at your app\" \u2014 reported as `firstLook: {image}` or `{skipped: <reason>}`, never a failed init; `--no-first-look` skips it (for scripts and CI that render themselves). For a bundled template (never a --remote one \u2014 the preview would build and serve its publisher's code) init also STARTS the live preview itself: `himi run --watch --content <dir> --port <p> --no-open --idle-exit 30`, detached in its own process group with its output in .himi/watch.log, never waited for (the url is chosen before it builds), recorded in .himi/watch.json, and reported as `watch: {started, pid, url, board, log}` \u2014 or `{skipped: <reason>}` for a `CI` environment, a test runner, a watch already running, or a start that failed (never a failed init). Nothing else skips it: outside CI it is started, and `watch.note` says an opt-out was ignored. The envelope LEADS with `doNow`: three lines to run now (the consent preflight, the live preview \u2014 its url and board when init started it, else `himi run --watch --content <dir> &` with the board's path \u2014 and the postcard line), and ENDS with the same lines as `doNowAgain`, so an agent that reads only the head or only the tail (`| tail`) gets them; at a terminal they are also printed as plain text on stderr, before the JSON and again after it. Its `next[]` LEADS with the steps for THIS session, in this order for every app \u2014 the offline first render and that picture's `himi progress` postcard (only when init could not make the picture), the skill's consent preflight (authorize or mock any Wix or external startup request; with none, go straight on), and only then the live preview (the running one's url, or `himi run --watch &` when init did not start it) \u2014 ahead of the next-session guidance", required: "<name> [--dir] [--template <t>] [--remote] [--base44-app-id <id>] [--base44-app-url <https://tenant>] [--no-agent] [--no-first-look] | --templates" },
|
|
188995
|
-
{ name: "template", summary: "starter-template catalog + publishing. Every template is a SHOWCASE APP \u2014 a real published release you can open running before you start from it. `list` prints available templates with metadata (title/description/tags) plus each one's start prompt \u2014 pass --remote to include the serve-plane catalog so an agent can pick one; `prompt <name>` prints just that sentence for one template (the skill URL is the public door, or the plane named by --target/--serve-url); `publish` publishes an app AS a `himi init --template` (needs a himalaya.template.json; builds a previewable release + attaches the scaffold source; --source-dir overrides which tree becomes the source, --name sets the template name; bakes a launcher icon \u2014 --icon <png>, or the committed template-icons/<name>.png \u2014 and extracts accent/palette gallery meta from the scaffold's tokens.json; --visibility unlisted keeps it out of the /v1/templates catalog \u2014 templates default to public); `trim --keep <ids>` cuts an app scaffolded from a template down to those screens (the home, and any screen the navigation pins such as a drawer body, always stays) \u2014 it deletes the other SCREENS/TEMPLATED entries whole, prunes navigation (linkableScreens, tabBar, drawer, deep links, surfaces) and drops tier5-src workers no kept screen uses, then runs validate --strict and rolls everything back if it fails (--force keeps it, --dry-run writes nothing). A kept screen that links to a removed one is refused unless --links follow (keep those too) or --links drop (remove the taps). Adopting one: `inspect` writes the adoption inventory (.himi/adopt.json: screens, workers, which screens can call Wix/network on appear \u2014 bootsOffline \u2014 placeholder and sample copy, proposed Data access rows, typed-journey stubs); `screens` lists, shows, rewrites or adds ONE dev/index.ts entry; `sweep` replaces sample identity/copy inside string literals; `recommend` ranks the catalog for a business description or a site's verticals; `trim --from-spec` takes the kept screens from SPEC.md's Screen catalogue", required: "list [--remote] | prompt <name> | publish [--dir <app>] [--source-dir <dir>] [--name <n>] [--icon <png>] [--visibility public|unlisted] [--target <t>] | trim --keep <id,id,\u2026>|--from-spec [SPEC.md] [--content <dir>] [--links follow|drop] [--dry-run] [--force] | inspect [--content <dir>] [--dry-run] | screens [--show <id>] [--write <id> --from <file>] [--add <id> --from <file>] | sweep --set 'Old=>New' | --map <file> [--dry-run] | recommend [--text <t>] [--verticals a,b] [--book <dir>] [--remote]" },
|
|
189027
|
+
{ name: "template", summary: "starter-template catalog + publishing. Every template is a SHOWCASE APP \u2014 a real published release you can open running before you start from it. `list` prints available templates with metadata (title/description/tags) plus each one's start prompt \u2014 pass --remote to include the serve-plane catalog so an agent can pick one; `prompt <name>` prints just that sentence for one template (the skill URL is the public door, or the plane named by --target/--serve-url); `publish` publishes an app AS a `himi init --template` (needs a himalaya.template.json; builds a previewable release + attaches the scaffold source; --source-dir overrides which tree becomes the source, --name sets the template name; bakes a launcher icon \u2014 --icon <png>, or the committed template-icons/<name>.png \u2014 and extracts accent/palette gallery meta from the scaffold's tokens.json; --visibility unlisted keeps it out of the /v1/templates catalog \u2014 templates default to public; --source-hash prints the sourceHash and iconHash a publish would be stored under, with no build or network, and exits); `trim --keep <ids>` cuts an app scaffolded from a template down to those screens (the home, and any screen the navigation pins such as a drawer body, always stays) \u2014 it deletes the other SCREENS/TEMPLATED entries whole, prunes navigation (linkableScreens, tabBar, drawer, deep links, surfaces) and drops tier5-src workers no kept screen uses, then runs validate --strict and rolls everything back if it fails (--force keeps it, --dry-run writes nothing). A kept screen that links to a removed one is refused unless --links follow (keep those too) or --links drop (remove the taps). Adopting one: `inspect` writes the adoption inventory (.himi/adopt.json: screens, workers, which screens can call Wix/network on appear \u2014 bootsOffline \u2014 placeholder and sample copy, proposed Data access rows, typed-journey stubs); `screens` lists, shows, rewrites or adds ONE dev/index.ts entry; `sweep` replaces sample identity/copy inside string literals; `recommend` ranks the catalog for a business description or a site's verticals; `trim --from-spec` takes the kept screens from SPEC.md's Screen catalogue", required: "list [--remote] | prompt <name> | publish [--dir <app>] [--source-dir <dir>] [--name <n>] [--icon <png>] [--visibility public|unlisted] [--target <t>] [--source-hash] | trim --keep <id,id,\u2026>|--from-spec [SPEC.md] [--content <dir>] [--links follow|drop] [--dry-run] [--force] | inspect [--content <dir>] [--dry-run] | screens [--show <id>] [--write <id> --from <file>] [--add <id> --from <file>] | sweep --set 'Old=>New' | --map <file> [--dry-run] | recommend [--text <t>] [--verticals a,b] [--book <dir>] [--remote]" },
|
|
188996
189028
|
{ name: "build", summary: "compile tier5-src/<name>/index.ts -> dist/bundles/<name>.bundle.js with esbuild (--binary = resolve published @himalaya/*); semantic TypeScript checking belongs to himi validate", required: "[--content <dir>] [--binary]" },
|
|
188997
189029
|
{ name: "functions", summary: "inspect/invoke server functions and operate durable jobs or schedules", required: "list|describe|openapi|invoke | jobs list|get|cancel|retry|dlq | schedule describe|invoke [--app <a>] [--environment preview|production] [--release <id>]" },
|
|
188998
189030
|
{ name: "eject", summary: "take ownership of a shared flow module (auth|checkout|screens): copies its source into tier5-src/_ejected/ and repoints this package's imports at the copy. The ladder's escape hatch \u2014 for when the factory options cannot express what you need. AFTER EJECTING, CENTRAL FIXES NO LONGER REACH THIS APP, including future corrections to the fail-closed entitlement and confirm-the-session rules. The floor is unaffected: credentials still go only through the native auth actions and money only through the cashier rail.", required: "<auth|checkout|screens> [--content <dir>]" },
|
|
@@ -189072,7 +189104,7 @@ function helpJson() {
|
|
|
189072
189104
|
|
|
189073
189105
|
// src/self-update.ts
|
|
189074
189106
|
import { readFileSync as readFileSync39, mkdirSync as mkdirSync18, writeFileSync as writeFileSync12, existsSync as existsSync35, rmSync as rmSync10, statSync as statSync8, accessSync, constants } from "node:fs";
|
|
189075
|
-
import { execFile, execFileSync as execFileSync3, spawnSync } from "node:child_process";
|
|
189107
|
+
import { execFile, execFileSync as execFileSync3, spawnSync as spawnSync2 } from "node:child_process";
|
|
189076
189108
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
189077
189109
|
import { homedir as homedir8, hostname } from "node:os";
|
|
189078
189110
|
import { join as join31, resolve as resolve33, dirname as dirname23 } from "node:path";
|
|
@@ -189317,7 +189349,7 @@ function npmInstallArgs(registry2, version5) {
|
|
|
189317
189349
|
return ["i", "-g", `${CLI_PACKAGE}@${version5}`, `--registry=${pinned}`, `--@wix:registry=${pinned}`];
|
|
189318
189350
|
}
|
|
189319
189351
|
var INSTALLABLE_SPEC = /^(?:latest|\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)$/;
|
|
189320
|
-
function createUpdateRunner(spawn8 =
|
|
189352
|
+
function createUpdateRunner(spawn8 = spawnSync2) {
|
|
189321
189353
|
return {
|
|
189322
189354
|
install: async (registry2, version5) => {
|
|
189323
189355
|
if (!isTrustedRegistry(registry2)) return { ok: false, detail: `refusing untrusted registry ${registry2}` };
|
|
@@ -189341,7 +189373,7 @@ function createUpdateRunner(spawn8 = spawnSync) {
|
|
|
189341
189373
|
const root = globalNodeModulesRoot();
|
|
189342
189374
|
const entry = root ? join31(root, "@wix", "himalaya-cli", "dist", "cli.mjs") : void 0;
|
|
189343
189375
|
if (!entry || !existsSync35(entry)) return void 0;
|
|
189344
|
-
const result =
|
|
189376
|
+
const result = spawnSync2(process.execPath, [entry, ...argv], {
|
|
189345
189377
|
// inherit keeps PIPED STDIN working — commands that read stdin must survive a re-exec.
|
|
189346
189378
|
stdio: "inherit",
|
|
189347
189379
|
env: { ...process.env, [UPDATE_REEXEC_ENV]: "1" }
|
|
@@ -190345,6 +190377,7 @@ async function templateCommand(ctx) {
|
|
|
190345
190377
|
}
|
|
190346
190378
|
const appDir3 = resolve46(str3(flags.dir) ?? process.cwd());
|
|
190347
190379
|
const sourceDir = resolve46(str3(flags["source-dir"]) ?? appDir3);
|
|
190380
|
+
ensureTemplatesFor(appDir3, sourceDir);
|
|
190348
190381
|
let meta;
|
|
190349
190382
|
try {
|
|
190350
190383
|
meta = JSON.parse(readFileSync67(join57(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
@@ -190375,6 +190408,28 @@ async function templateCommand(ctx) {
|
|
|
190375
190408
|
const buildDir = materializeForPreview(appDir3, name, meta.title);
|
|
190376
190409
|
if (buildDir !== appDir3) publishScratch.push(buildDir);
|
|
190377
190410
|
const app = await appId(buildDir);
|
|
190411
|
+
const catalogView = () => ({ files: canonicalCatalogFiles(sentinelizeArchive(readTemplateFiles(sourceDir), app)), meta });
|
|
190412
|
+
const launcherIcon = () => {
|
|
190413
|
+
const iconPath = str3(flags.icon) ? resolve46(str3(flags.icon)) : templateIconPath(name);
|
|
190414
|
+
if (!iconPath) return void 0;
|
|
190415
|
+
try {
|
|
190416
|
+
const bytes2 = readFileSync67(iconPath);
|
|
190417
|
+
return { bytes: bytes2, hash: createHash30("sha256").update(bytes2).digest("hex") };
|
|
190418
|
+
} catch {
|
|
190419
|
+
return void 0;
|
|
190420
|
+
}
|
|
190421
|
+
};
|
|
190422
|
+
if (flags["source-hash"] === true) {
|
|
190423
|
+
print({
|
|
190424
|
+
ok: true,
|
|
190425
|
+
template: name,
|
|
190426
|
+
app: templateAppId,
|
|
190427
|
+
published: false,
|
|
190428
|
+
sourceHash: createHash30("sha256").update(JSON.stringify(catalogView())).digest("hex"),
|
|
190429
|
+
iconHash: launcherIcon()?.hash ?? null
|
|
190430
|
+
});
|
|
190431
|
+
return 0;
|
|
190432
|
+
}
|
|
190378
190433
|
const strict = flags.strict === true;
|
|
190379
190434
|
const force = flags.force === true;
|
|
190380
190435
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
@@ -190437,25 +190492,18 @@ async function templateCommand(ctx) {
|
|
|
190437
190492
|
}));
|
|
190438
190493
|
return 1;
|
|
190439
190494
|
}
|
|
190440
|
-
const
|
|
190441
|
-
|
|
190442
|
-
if (
|
|
190443
|
-
try {
|
|
190444
|
-
const bytes2 = readFileSync67(iconPath);
|
|
190445
|
-
payload.icon = bytes2.toString("base64");
|
|
190446
|
-
iconHash = createHash30("sha256").update(bytes2).digest("hex");
|
|
190447
|
-
} catch {
|
|
190448
|
-
}
|
|
190449
|
-
}
|
|
190495
|
+
const icon = launcherIcon();
|
|
190496
|
+
const iconHash = icon?.hash;
|
|
190497
|
+
if (icon) payload.icon = icon.bytes.toString("base64");
|
|
190450
190498
|
payload.app = templateAppId;
|
|
190451
190499
|
const { rebindReleaseId: rebindReleaseId2 } = await Promise.resolve().then(() => (init_build3(), build_exports2));
|
|
190452
190500
|
payload.manifest = rebindReleaseId2({ ...payload.manifest, app: templateAppId, ...iconHash ? { iconHash } : {} });
|
|
190453
|
-
const
|
|
190454
|
-
if (Object.keys(files).length === 0) {
|
|
190501
|
+
const source = catalogView();
|
|
190502
|
+
if (Object.keys(source.files).length === 0) {
|
|
190455
190503
|
io2.error(JSON.stringify({ error: `no source files collected from ${sourceDir}` }));
|
|
190456
190504
|
return 1;
|
|
190457
190505
|
}
|
|
190458
|
-
payload.source =
|
|
190506
|
+
payload.source = source;
|
|
190459
190507
|
const { collectAppSource: collectAppSource2, secretFindings: secretFindings2, zipAppSource: zipAppSource2, largestEntries: largestEntries2, MAX_APP_SOURCE_BYTES: MAX_APP_SOURCE_BYTES2 } = await Promise.resolve().then(() => (init_app_source(), app_source_exports));
|
|
190460
190508
|
const templateArchive = collectAppSource2(sourceDir);
|
|
190461
190509
|
const templateSecrets = secretFindings2(templateArchive.entries);
|
|
@@ -190611,7 +190659,7 @@ async function templateCommand(ctx) {
|
|
|
190611
190659
|
icon: Boolean(iconHash),
|
|
190612
190660
|
...meta.accent ? { accent: meta.accent } : {},
|
|
190613
190661
|
...meta.palette ? { palette: meta.palette } : {},
|
|
190614
|
-
sourceFiles: Object.keys(files).length,
|
|
190662
|
+
sourceFiles: Object.keys(source.files).length,
|
|
190615
190663
|
...hasErrors && force ? { forcedPastErrors: true } : {},
|
|
190616
190664
|
initWith: `himi init <new-app-name> --template ${name} --remote${targetFlag}`
|
|
190617
190665
|
});
|
|
@@ -190626,7 +190674,7 @@ async function templateCommand(ctx) {
|
|
|
190626
190674
|
}
|
|
190627
190675
|
}
|
|
190628
190676
|
}
|
|
190629
|
-
io2.error(JSON.stringify({ error: "template needs a subcommand", usage: "himi template list [--remote] | himi template prompt <name> | himi template publish [--dir <app>] [--source-dir <dir>] [--name <n>] [--icon <png>] [--target <t>] | himi template trim --keep <id,id,\u2026>|--from-spec [SPEC.md] [--content <dir>] [--links follow|drop] [--dry-run] [--force] | himi template inspect | himi template screens [--show <id>] [--write <id> --from <file>] | himi template sweep --set 'Old=>New' | himi template recommend --text <description>" }));
|
|
190677
|
+
io2.error(JSON.stringify({ error: "template needs a subcommand", usage: "himi template list [--remote] | himi template prompt <name> | himi template publish [--dir <app>] [--source-dir <dir>] [--name <n>] [--icon <png>] [--target <t>] [--source-hash] | himi template trim --keep <id,id,\u2026>|--from-spec [SPEC.md] [--content <dir>] [--links follow|drop] [--dry-run] [--force] | himi template inspect | himi template screens [--show <id>] [--write <id> --from <file>] | himi template sweep --set 'Old=>New' | himi template recommend --text <description>" }));
|
|
190630
190678
|
return 2;
|
|
190631
190679
|
}
|
|
190632
190680
|
|
|
@@ -190844,7 +190892,7 @@ async function validateCommand(ctx) {
|
|
|
190844
190892
|
import { readFileSync as readFileSync80 } from "node:fs";
|
|
190845
190893
|
|
|
190846
190894
|
// src/dpx.ts
|
|
190847
|
-
import { spawnSync as
|
|
190895
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
190848
190896
|
import { existsSync as existsSync67, readFileSync as readFileSync78 } from "node:fs";
|
|
190849
190897
|
import { homedir as homedir9 } from "node:os";
|
|
190850
190898
|
import { join as join70 } from "node:path";
|
|
@@ -190889,7 +190937,7 @@ function parseDpxAuthStatusIdentity(stdout) {
|
|
|
190889
190937
|
return stdout.split("\n").map((l2) => l2.trim()).find(Boolean) || void 0;
|
|
190890
190938
|
}
|
|
190891
190939
|
var defaultRunner2 = (cmd, args) => {
|
|
190892
|
-
const r3 =
|
|
190940
|
+
const r3 = spawnSync3(cmd, args, { encoding: "utf8" });
|
|
190893
190941
|
return { status: r3.status, stdout: r3.stdout ?? "", stderr: r3.stderr ?? "", error: r3.error };
|
|
190894
190942
|
};
|
|
190895
190943
|
function dpxAuthStatus(opts = {}) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1508.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
|
|
6
6
|
"keywords": [
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"artifactId": "himalaya-cli"
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
|
-
"falconPackageHash": "
|
|
74
|
+
"falconPackageHash": "1dcc0a1ea79af010948564037a6ea00f3df198f1a6cf8c8b37d42e86"
|
|
75
75
|
}
|