@wix/himalaya-cli 0.1506.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 +172 -123
- 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"] },
|
|
@@ -22191,8 +22216,9 @@ var init_idiom_controls = __esm({
|
|
|
22191
22216
|
// The web's own bar, exactly as web-host drew it before #3222.
|
|
22192
22217
|
tabBar: { height: null, itemPadding: "7px 4px 6px", itemGap: 3, iconSize: 22, labelSize: 11, labelWeight: 600, indicator: null, roles: { background: "surfacePrimary", selected: "accentPrimary", selectedLabel: "accentPrimary", unselected: "textSecondary", indicator: null }, topHairline: true, translucent: false, badgeColor: "#E62214" }
|
|
22193
22218
|
},
|
|
22194
|
-
// iOS: the stock UIKit / SwiftUI controls. The switch is
|
|
22195
|
-
//
|
|
22219
|
+
// iOS: the stock UIKit / SwiftUI controls. The switch is the pre-26 UISwitch (51×31, 27pt thumb,
|
|
22220
|
+
// 2pt inset), once measured against HimalayaDemoAppSnapshotTests' gallery_inputs golden. That
|
|
22221
|
+
// golden is iOS 26.2 now and draws no thumb, so this row is NOT golden-verified until #4919.
|
|
22196
22222
|
ios: {
|
|
22197
22223
|
// SF Pro reaches a page only as the Apple system font (`-apple-system`); it is not
|
|
22198
22224
|
// redistributable as a webfont, so elsewhere this frame falls back and says so.
|
|
@@ -27548,7 +27574,7 @@ function redactBodyString(body) {
|
|
|
27548
27574
|
} catch {
|
|
27549
27575
|
}
|
|
27550
27576
|
}
|
|
27551
|
-
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}`);
|
|
27552
27578
|
}
|
|
27553
27579
|
function createWixGatewayState() {
|
|
27554
27580
|
return { mode: "record", rules: [], traffic: [], clients: /* @__PURE__ */ new Set(), seq: 0, ruleSeq: 0 };
|
|
@@ -32007,10 +32033,10 @@ async function runRicosImageUpload(o2) {
|
|
|
32007
32033
|
} catch {
|
|
32008
32034
|
return fail6("read");
|
|
32009
32035
|
}
|
|
32010
|
-
const
|
|
32036
|
+
const sep22 = entry.uploadUrl.includes("?") ? "&" : "?";
|
|
32011
32037
|
let res;
|
|
32012
32038
|
try {
|
|
32013
|
-
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 });
|
|
32014
32040
|
} catch {
|
|
32015
32041
|
return fail6("put");
|
|
32016
32042
|
}
|
|
@@ -32648,10 +32674,10 @@ async function runMediaFieldUpload(o2) {
|
|
|
32648
32674
|
} catch (e2) {
|
|
32649
32675
|
return { ok: false, reason: e2 instanceof Deadline ? "timeout" : "read" };
|
|
32650
32676
|
}
|
|
32651
|
-
const
|
|
32677
|
+
const sep22 = uploadUrl.includes("?") ? "&" : "?";
|
|
32652
32678
|
let res;
|
|
32653
32679
|
try {
|
|
32654
|
-
res = await bounded2(deps.fetch(`${uploadUrl}${
|
|
32680
|
+
res = await bounded2(deps.fetch(`${uploadUrl}${sep22}filename=${encodeURIComponent(file2.fileName)}`, {
|
|
32655
32681
|
method: "PUT",
|
|
32656
32682
|
headers: { "Content-Type": file2.mimeType },
|
|
32657
32683
|
body,
|
|
@@ -115773,8 +115799,8 @@ function ensureCountUpRuntime() {
|
|
|
115773
115799
|
const neg = fixed.startsWith("-");
|
|
115774
115800
|
const body = neg ? fixed.slice(1) : fixed;
|
|
115775
115801
|
const [int2, frac] = body.split(".");
|
|
115776
|
-
const
|
|
115777
|
-
return (neg ? "-" : "") +
|
|
115802
|
+
const sep22 = int2.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
115803
|
+
return (neg ? "-" : "") + sep22 + (frac ? "." + frac : "");
|
|
115778
115804
|
};
|
|
115779
115805
|
const animateEl = (el2) => {
|
|
115780
115806
|
const node = el2;
|
|
@@ -126440,7 +126466,7 @@ var init_widgets = __esm({
|
|
|
126440
126466
|
import { createServer as createServer2 } from "node:http";
|
|
126441
126467
|
import { readFile, stat } from "node:fs/promises";
|
|
126442
126468
|
import { readFileSync as readFileSync32, existsSync as existsSync28, watch, mkdirSync as mkdirSync15, rmSync as rmSync7 } from "node:fs";
|
|
126443
|
-
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";
|
|
126444
126470
|
import { createHash as createHash16, randomUUID as randomUUID4 } from "node:crypto";
|
|
126445
126471
|
import { fileURLToPath as fileURLToPath19, pathToFileURL as pathToFileURL5 } from "node:url";
|
|
126446
126472
|
function readLogicBundle(read, tier5Dir, name) {
|
|
@@ -127309,7 +127335,7 @@ function startBundleSourceWatcher(state) {
|
|
|
127309
127335
|
try {
|
|
127310
127336
|
const watcher2 = watch(TIER5_SRC_ROOT, { persistent: false, recursive: true }, (_event, filename) => {
|
|
127311
127337
|
if (!filename || !/\.(ts|tsx)$/.test(filename)) return;
|
|
127312
|
-
const name = filename.split(
|
|
127338
|
+
const name = filename.split(sep9)[0];
|
|
127313
127339
|
if (!name || name.startsWith(".")) return;
|
|
127314
127340
|
pending.add(name);
|
|
127315
127341
|
if (timer) clearTimeout(timer);
|
|
@@ -127457,12 +127483,12 @@ function servedTokensHash(app) {
|
|
|
127457
127483
|
}
|
|
127458
127484
|
}
|
|
127459
127485
|
function appDependencyFiles(inputs, appDir3) {
|
|
127460
|
-
const inside2 = (root, p2) => p2 === root || p2.startsWith(root +
|
|
127486
|
+
const inside2 = (root, p2) => p2 === root || p2.startsWith(root + sep9);
|
|
127461
127487
|
const out2 = /* @__PURE__ */ new Set();
|
|
127462
127488
|
for (const raw of inputs) {
|
|
127463
127489
|
const p2 = resolve28(raw);
|
|
127464
127490
|
if (!inside2(ROOT6, p2) || inside2(resolve28(appDir3), p2) || inside2(HMR_TMP_DIR, p2)) continue;
|
|
127465
|
-
if (p2.split(
|
|
127491
|
+
if (p2.split(sep9).includes("node_modules")) continue;
|
|
127466
127492
|
out2.add(p2);
|
|
127467
127493
|
}
|
|
127468
127494
|
return [...out2].sort();
|
|
@@ -127580,7 +127606,7 @@ function startAppSourceWatcher(state) {
|
|
|
127580
127606
|
try {
|
|
127581
127607
|
const watcher2 = watch(appDir3, { persistent: false, recursive: true }, (_event, filename) => {
|
|
127582
127608
|
if (!filename) return;
|
|
127583
|
-
const rel = String(filename).split(
|
|
127609
|
+
const rel = String(filename).split(sep9).join("/");
|
|
127584
127610
|
if (!classifyAppPath(rel)) return;
|
|
127585
127611
|
pending.add(rel);
|
|
127586
127612
|
if (timer) clearTimeout(timer);
|
|
@@ -129924,7 +129950,7 @@ var init_src5 = __esm({
|
|
|
129924
129950
|
|
|
129925
129951
|
// ../../core/serve-storage/src/file-store.ts
|
|
129926
129952
|
import { mkdirSync as mkdirSync16, readFileSync as readFileSync33, rmSync as rmSync8, writeFileSync as writeFileSync10, readdirSync as readdirSync16, existsSync as existsSync29 } from "node:fs";
|
|
129927
|
-
import { join as join25, resolve as resolve29, sep as
|
|
129953
|
+
import { join as join25, resolve as resolve29, sep as sep10 } from "node:path";
|
|
129928
129954
|
var FileReleaseStore;
|
|
129929
129955
|
var init_file_store = __esm({
|
|
129930
129956
|
"../../core/serve-storage/src/file-store.ts"() {
|
|
@@ -129961,7 +129987,7 @@ var init_file_store = __esm({
|
|
|
129961
129987
|
*/
|
|
129962
129988
|
appDir(app) {
|
|
129963
129989
|
const dir = resolve29(this.root, this.safe(app));
|
|
129964
|
-
if (!dir.startsWith(this.root +
|
|
129990
|
+
if (!dir.startsWith(this.root + sep10)) {
|
|
129965
129991
|
throw new Error(`unsafe app id ${JSON.stringify(app)}: ${dir} is not inside the store root`);
|
|
129966
129992
|
}
|
|
129967
129993
|
return dir;
|
|
@@ -133737,8 +133763,8 @@ async function crawlScreenInner(opts) {
|
|
|
133737
133763
|
if (linkable.has(target)) return true;
|
|
133738
133764
|
for (const base of linkable) {
|
|
133739
133765
|
if (target.length > base.length + 1 && target.startsWith(base)) {
|
|
133740
|
-
const
|
|
133741
|
-
if (
|
|
133766
|
+
const sep22 = target[base.length];
|
|
133767
|
+
if (sep22 === "_" || sep22 === "/") return true;
|
|
133742
133768
|
}
|
|
133743
133769
|
}
|
|
133744
133770
|
return false;
|
|
@@ -137603,13 +137629,13 @@ __export(studio_exports, {
|
|
|
137603
137629
|
});
|
|
137604
137630
|
import { createHash as createHash21 } from "node:crypto";
|
|
137605
137631
|
import { existsSync as existsSync33, readdirSync as readdirSync19, readFileSync as readFileSync37, realpathSync as realpathSync6, statSync as statSync7 } from "node:fs";
|
|
137606
|
-
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";
|
|
137607
137633
|
import { pathToFileURL as pathToFileURL6 } from "node:url";
|
|
137608
137634
|
function realInside(dir, abs) {
|
|
137609
137635
|
try {
|
|
137610
137636
|
const root = realpathSync6(dir);
|
|
137611
137637
|
const real = realpathSync6(abs);
|
|
137612
|
-
return real.startsWith(root +
|
|
137638
|
+
return real.startsWith(root + sep11) ? real : null;
|
|
137613
137639
|
} catch {
|
|
137614
137640
|
return null;
|
|
137615
137641
|
}
|
|
@@ -141906,21 +141932,21 @@ var init_Matcher = __esm({
|
|
|
141906
141932
|
* @returns {string}
|
|
141907
141933
|
*/
|
|
141908
141934
|
toString(separator, includeNamespace = true) {
|
|
141909
|
-
const
|
|
141910
|
-
const isDefault =
|
|
141935
|
+
const sep22 = separator || this.separator;
|
|
141936
|
+
const isDefault = sep22 === this.separator && includeNamespace === true;
|
|
141911
141937
|
if (isDefault) {
|
|
141912
141938
|
if (this._pathStringCache !== null) {
|
|
141913
141939
|
return this._pathStringCache;
|
|
141914
141940
|
}
|
|
141915
141941
|
const result = this.path.map(
|
|
141916
141942
|
(n2) => n2.namespace ? `${n2.namespace}:${n2.tag}` : n2.tag
|
|
141917
|
-
).join(
|
|
141943
|
+
).join(sep22);
|
|
141918
141944
|
this._pathStringCache = result;
|
|
141919
141945
|
return result;
|
|
141920
141946
|
}
|
|
141921
141947
|
return this.path.map(
|
|
141922
141948
|
(n2) => includeNamespace && n2.namespace ? `${n2.namespace}:${n2.tag}` : n2.tag
|
|
141923
|
-
).join(
|
|
141949
|
+
).join(sep22);
|
|
141924
141950
|
}
|
|
141925
141951
|
/**
|
|
141926
141952
|
* Get path as array of tag names.
|
|
@@ -142622,76 +142648,76 @@ var init_redos = __esm({
|
|
|
142622
142648
|
});
|
|
142623
142649
|
|
|
142624
142650
|
// ../../node_modules/is-unsafe/src/contexts/nosql.js
|
|
142625
|
-
var
|
|
142651
|
+
var sep12, NOSQL_PATTERNS, nosql_default;
|
|
142626
142652
|
var init_nosql = __esm({
|
|
142627
142653
|
"../../node_modules/is-unsafe/src/contexts/nosql.js"() {
|
|
142628
|
-
|
|
142654
|
+
sep12 = `["'\\s]*:`;
|
|
142629
142655
|
NOSQL_PATTERNS = [
|
|
142630
142656
|
// ─── MongoDB $ operator injection ────────────────────────────────────────
|
|
142631
142657
|
{
|
|
142632
142658
|
id: "nosql-where-operator",
|
|
142633
142659
|
description: "$where \u2014 executes arbitrary JavaScript server-side in MongoDB",
|
|
142634
|
-
pattern: new RegExp(`\\$where${
|
|
142660
|
+
pattern: new RegExp(`\\$where${sep12}`, "i")
|
|
142635
142661
|
},
|
|
142636
142662
|
{
|
|
142637
142663
|
id: "nosql-ne-operator",
|
|
142638
142664
|
description: '$ne \u2014 "not equal" operator used to bypass equality checks',
|
|
142639
|
-
pattern: new RegExp(`\\$ne${
|
|
142665
|
+
pattern: new RegExp(`\\$ne${sep12}`, "i")
|
|
142640
142666
|
},
|
|
142641
142667
|
{
|
|
142642
142668
|
id: "nosql-gt-operator",
|
|
142643
142669
|
description: '$gt \u2014 "greater than" used to bypass password/value checks',
|
|
142644
|
-
pattern: new RegExp(`\\$gte?${
|
|
142670
|
+
pattern: new RegExp(`\\$gte?${sep12}`, "i")
|
|
142645
142671
|
},
|
|
142646
142672
|
{
|
|
142647
142673
|
id: "nosql-lt-operator",
|
|
142648
142674
|
description: '$lt / $lte \u2014 "less than" bypass variants',
|
|
142649
|
-
pattern: new RegExp(`\\$lte?${
|
|
142675
|
+
pattern: new RegExp(`\\$lte?${sep12}`, "i")
|
|
142650
142676
|
},
|
|
142651
142677
|
{
|
|
142652
142678
|
id: "nosql-regex-operator",
|
|
142653
142679
|
description: "$regex \u2014 can be used to extract data character by character (blind injection)",
|
|
142654
|
-
pattern: new RegExp(`\\$regex${
|
|
142680
|
+
pattern: new RegExp(`\\$regex${sep12}`, "i")
|
|
142655
142681
|
},
|
|
142656
142682
|
{
|
|
142657
142683
|
id: "nosql-or-operator",
|
|
142658
142684
|
description: "$or \u2014 logical OR; used to create always-true conditions",
|
|
142659
|
-
pattern: new RegExp(`\\$or${
|
|
142685
|
+
pattern: new RegExp(`\\$or${sep12}\\s*\\[`, "i")
|
|
142660
142686
|
},
|
|
142661
142687
|
{
|
|
142662
142688
|
id: "nosql-and-operator",
|
|
142663
142689
|
description: "$and \u2014 logical AND operator injection",
|
|
142664
|
-
pattern: new RegExp(`\\$and${
|
|
142690
|
+
pattern: new RegExp(`\\$and${sep12}\\s*\\[`, "i")
|
|
142665
142691
|
},
|
|
142666
142692
|
{
|
|
142667
142693
|
id: "nosql-nor-operator",
|
|
142668
142694
|
description: "$nor \u2014 logical NOR operator injection",
|
|
142669
|
-
pattern: new RegExp(`\\$nor${
|
|
142695
|
+
pattern: new RegExp(`\\$nor${sep12}\\s*\\[`, "i")
|
|
142670
142696
|
},
|
|
142671
142697
|
{
|
|
142672
142698
|
id: "nosql-exists-operator",
|
|
142673
142699
|
description: "$exists \u2014 can enumerate fields to determine schema",
|
|
142674
|
-
pattern: new RegExp(`\\$exists${
|
|
142700
|
+
pattern: new RegExp(`\\$exists${sep12}`, "i")
|
|
142675
142701
|
},
|
|
142676
142702
|
{
|
|
142677
142703
|
id: "nosql-in-operator",
|
|
142678
142704
|
description: "$in \u2014 matches any value in a list; can enumerate values",
|
|
142679
|
-
pattern: new RegExp(`\\$in${
|
|
142705
|
+
pattern: new RegExp(`\\$in${sep12}\\s*\\[`, "i")
|
|
142680
142706
|
},
|
|
142681
142707
|
{
|
|
142682
142708
|
id: "nosql-expr-operator",
|
|
142683
142709
|
description: "$expr \u2014 allows aggregation expressions in queries (MongoDB 3.6+)",
|
|
142684
|
-
pattern: new RegExp(`\\$expr${
|
|
142710
|
+
pattern: new RegExp(`\\$expr${sep12}`, "i")
|
|
142685
142711
|
},
|
|
142686
142712
|
{
|
|
142687
142713
|
id: "nosql-function-operator",
|
|
142688
142714
|
description: "$function \u2014 executes arbitrary JavaScript in MongoDB 4.4+",
|
|
142689
|
-
pattern: new RegExp(`\\$function${
|
|
142715
|
+
pattern: new RegExp(`\\$function${sep12}`, "i")
|
|
142690
142716
|
},
|
|
142691
142717
|
{
|
|
142692
142718
|
id: "nosql-accumulator-operator",
|
|
142693
142719
|
description: "$accumulator \u2014 custom aggregation with arbitrary JS execution",
|
|
142694
|
-
pattern: new RegExp(`\\$accumulator${
|
|
142720
|
+
pattern: new RegExp(`\\$accumulator${sep12}`, "i")
|
|
142695
142721
|
},
|
|
142696
142722
|
// ─── Prototype pollution ─────────────────────────────────────────────────
|
|
142697
142723
|
{
|
|
@@ -148535,7 +148561,7 @@ __export(app_source_exports, {
|
|
|
148535
148561
|
});
|
|
148536
148562
|
import { createHash as createHash25 } from "node:crypto";
|
|
148537
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";
|
|
148538
|
-
import { join as join38, resolve as resolve40, sep as
|
|
148564
|
+
import { join as join38, resolve as resolve40, sep as sep13 } from "node:path";
|
|
148539
148565
|
import { createRequire as createRequire3 } from "node:module";
|
|
148540
148566
|
import { deflateRawSync as deflateRawSync2 } from "node:zlib";
|
|
148541
148567
|
function walkSourceTree(dir, file2, skip, enter = () => {
|
|
@@ -148558,7 +148584,7 @@ function walkSourceTree(dir, file2, skip, enter = () => {
|
|
|
148558
148584
|
skip(rel);
|
|
148559
148585
|
continue;
|
|
148560
148586
|
}
|
|
148561
|
-
file2(rel.split(
|
|
148587
|
+
file2(rel.split(sep13).join("/"), rel);
|
|
148562
148588
|
}
|
|
148563
148589
|
};
|
|
148564
148590
|
walk2("");
|
|
@@ -148618,8 +148644,8 @@ function renderInputRootDirs(dir) {
|
|
|
148618
148644
|
}
|
|
148619
148645
|
function newestSourceChangeMs(dir) {
|
|
148620
148646
|
const roots2 = renderInputRootDirs(dir);
|
|
148621
|
-
const inRead = (hostRel) => !roots2 || roots2.has(hostRel.split(
|
|
148622
|
-
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);
|
|
148623
148649
|
let newest = 0;
|
|
148624
148650
|
walkSourceTree(
|
|
148625
148651
|
dir,
|
|
@@ -148781,7 +148807,7 @@ function pruneEmptyDirs(root, rel, needed, removed) {
|
|
|
148781
148807
|
let empty2 = true;
|
|
148782
148808
|
for (const name of readdirSync24(rel ? join38(root, rel) : root)) {
|
|
148783
148809
|
const childRel = rel ? join38(rel, name) : name;
|
|
148784
|
-
const posix5 = childRel.split(
|
|
148810
|
+
const posix5 = childRel.split(sep13).join("/");
|
|
148785
148811
|
const kind = lstatSync13(join38(root, childRel));
|
|
148786
148812
|
if (kind.isSymbolicLink() || !kind.isDirectory() || isDeniedSourceDir(name, rel)) {
|
|
148787
148813
|
empty2 = false;
|
|
@@ -148865,7 +148891,7 @@ __export(run_watch_exports, {
|
|
|
148865
148891
|
});
|
|
148866
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";
|
|
148867
148893
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
148868
|
-
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";
|
|
148869
148895
|
function diffReleases(prev, next) {
|
|
148870
148896
|
const bundles = Object.keys(next.bundles).filter((b2) => prev.bundles[b2]?.sha256 !== next.bundles[b2].sha256).sort();
|
|
148871
148897
|
const changedBundles = new Set(bundles);
|
|
@@ -148893,7 +148919,7 @@ function reloadEvents(d2) {
|
|
|
148893
148919
|
function hhpRasterDir(dir) {
|
|
148894
148920
|
const assets = findAssetsDir(dir);
|
|
148895
148921
|
if (!assets) return null;
|
|
148896
|
-
const rel = relative8(dir, assets).split(
|
|
148922
|
+
const rel = relative8(dir, assets).split(sep14).join("/");
|
|
148897
148923
|
return rel ? `${rel}/hhp-raster` : "hhp-raster";
|
|
148898
148924
|
}
|
|
148899
148925
|
function ignoredChange(relPath, isDirectory = () => false, rasterDir = "assets/hhp-raster") {
|
|
@@ -149120,7 +149146,7 @@ function boardFile(dir, pathname) {
|
|
|
149120
149146
|
function readConfined(root, rel) {
|
|
149121
149147
|
try {
|
|
149122
149148
|
if (!lstatSync14(root).isDirectory()) return null;
|
|
149123
|
-
const parts = rel.split(
|
|
149149
|
+
const parts = rel.split(sep14);
|
|
149124
149150
|
let at2 = root;
|
|
149125
149151
|
for (let i2 = 0; i2 < parts.length; i2++) {
|
|
149126
149152
|
at2 = join39(at2, parts[i2]);
|
|
@@ -149128,7 +149154,7 @@ function readConfined(root, rel) {
|
|
|
149128
149154
|
if (st2.isSymbolicLink() || !(i2 === parts.length - 1 ? st2.isFile() : st2.isDirectory())) return null;
|
|
149129
149155
|
}
|
|
149130
149156
|
const canonicalRoot = realpathSync8(root);
|
|
149131
|
-
if (!realpathSync8(at2).startsWith(canonicalRoot +
|
|
149157
|
+
if (!realpathSync8(at2).startsWith(canonicalRoot + sep14)) return null;
|
|
149132
149158
|
const fd = openSync4(at2, constants3.O_RDONLY | (constants3.O_NOFOLLOW ?? 0));
|
|
149133
149159
|
try {
|
|
149134
149160
|
if (!fstatSync(fd).isFile()) return null;
|
|
@@ -149639,13 +149665,13 @@ import { createHash as createHash28, randomUUID as randomUUID8 } from "node:cryp
|
|
|
149639
149665
|
import { spawn as spawn4 } from "node:child_process";
|
|
149640
149666
|
import { closeSync as closeSync5, existsSync as existsSync44, lstatSync as lstatSync17, readFileSync as readFileSync54, statSync as statSync15 } from "node:fs";
|
|
149641
149667
|
import { createServer as createServer3 } from "node:net";
|
|
149642
|
-
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";
|
|
149643
149669
|
function homeShotPath(dir, home) {
|
|
149644
149670
|
const root = resolve42(dir);
|
|
149645
149671
|
const base = resolve42(root, ".himi", "shots");
|
|
149646
149672
|
const shot = resolve42(base, `${home}.png`);
|
|
149647
|
-
if (!shot.startsWith(base +
|
|
149648
|
-
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)) {
|
|
149649
149675
|
try {
|
|
149650
149676
|
if (lstatSync17(p2).isSymbolicLink()) return null;
|
|
149651
149677
|
} catch {
|
|
@@ -155068,7 +155094,7 @@ __export(eject_exports, {
|
|
|
155068
155094
|
ejectModule: () => ejectModule
|
|
155069
155095
|
});
|
|
155070
155096
|
import { existsSync as existsSync58, mkdirSync as mkdirSync27, readFileSync as readFileSync68, writeFileSync as writeFileSync23 } from "node:fs";
|
|
155071
|
-
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";
|
|
155072
155098
|
function locate(repoRootOrCwd, mod) {
|
|
155073
155099
|
const inRepo = resolve47(repoRootOrCwd, `stdlib/flows/${mod}/src/index.ts`);
|
|
155074
155100
|
if (existsSync58(inRepo)) return { path: inRepo, form: "source" };
|
|
@@ -155121,7 +155147,7 @@ function ejectModule(opts) {
|
|
|
155121
155147
|
if (!existsSync58(f2)) continue;
|
|
155122
155148
|
const before = readFileSync68(f2, "utf8");
|
|
155123
155149
|
let after = before;
|
|
155124
|
-
let rel = relative10(dirname33(f2), target).split(
|
|
155150
|
+
let rel = relative10(dirname33(f2), target).split(sep16).join("/").replace(/\.tsx?$/, ".js");
|
|
155125
155151
|
if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
155126
155152
|
for (const spec of specifiersFor(mod)) {
|
|
155127
155153
|
const q2 = spec.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -155298,7 +155324,7 @@ __export(icon_exports, {
|
|
|
155298
155324
|
});
|
|
155299
155325
|
import { createHash as createHash31 } from "node:crypto";
|
|
155300
155326
|
import { existsSync as existsSync59, mkdirSync as mkdirSync28, readFileSync as readFileSync69, statSync as statSync18, writeFileSync as writeFileSync24 } from "node:fs";
|
|
155301
|
-
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";
|
|
155302
155328
|
function readManifest(dir) {
|
|
155303
155329
|
try {
|
|
155304
155330
|
return JSON.parse(readFileSync69(join59(dir, MANIFEST), "utf8"));
|
|
@@ -155315,7 +155341,7 @@ function declaredIconName(dir) {
|
|
|
155315
155341
|
function iconDest(dir, name) {
|
|
155316
155342
|
const base = resolve48(dir);
|
|
155317
155343
|
const abs = resolve48(base, name);
|
|
155318
|
-
if (!abs.startsWith(base +
|
|
155344
|
+
if (!abs.startsWith(base + sep17)) {
|
|
155319
155345
|
throw new Error(
|
|
155320
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}".`
|
|
155321
155347
|
);
|
|
@@ -155662,8 +155688,8 @@ function baseOf(target, linkable, known) {
|
|
|
155662
155688
|
let best = null;
|
|
155663
155689
|
for (const base of linkable ?? []) {
|
|
155664
155690
|
if (!known.has(base) || target.length <= base.length + 1 || !target.startsWith(base)) continue;
|
|
155665
|
-
const
|
|
155666
|
-
if ((
|
|
155691
|
+
const sep22 = target[base.length];
|
|
155692
|
+
if ((sep22 === "_" || sep22 === "/") && (!best || base.length > best.length)) best = base;
|
|
155667
155693
|
}
|
|
155668
155694
|
return best;
|
|
155669
155695
|
}
|
|
@@ -159653,10 +159679,10 @@ var init_cli_bridge = __esm({
|
|
|
159653
159679
|
// src/mcp/file-tools.ts
|
|
159654
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";
|
|
159655
159681
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
159656
|
-
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";
|
|
159657
159683
|
import * as z2 from "zod";
|
|
159658
159684
|
function within(root, p2) {
|
|
159659
|
-
return p2 === root || p2.startsWith(root.endsWith(
|
|
159685
|
+
return p2 === root || p2.startsWith(root.endsWith(sep18) ? root : root + sep18);
|
|
159660
159686
|
}
|
|
159661
159687
|
function realish(p2) {
|
|
159662
159688
|
let cur = p2;
|
|
@@ -159664,14 +159690,14 @@ function realish(p2) {
|
|
|
159664
159690
|
while (!existsSync69(cur)) {
|
|
159665
159691
|
const up = dirname39(cur);
|
|
159666
159692
|
if (up === cur) break;
|
|
159667
|
-
tail.unshift(cur.slice(up.length + (up.endsWith(
|
|
159693
|
+
tail.unshift(cur.slice(up.length + (up.endsWith(sep18) ? 0 : 1)));
|
|
159668
159694
|
cur = up;
|
|
159669
159695
|
}
|
|
159670
159696
|
return join72(realpathSync10(cur), ...tail);
|
|
159671
159697
|
}
|
|
159672
159698
|
function symlinkComponent(base, abs) {
|
|
159673
159699
|
let cur = base;
|
|
159674
|
-
for (const part3 of relative13(base, abs).split(
|
|
159700
|
+
for (const part3 of relative13(base, abs).split(sep18).filter(Boolean)) {
|
|
159675
159701
|
cur = join72(cur, part3);
|
|
159676
159702
|
try {
|
|
159677
159703
|
if (lstatSync21(cur).isSymbolicLink()) return relative13(base, cur);
|
|
@@ -159710,7 +159736,7 @@ function onDiskSpelling(abs) {
|
|
|
159710
159736
|
while (!existsSync69(cur)) {
|
|
159711
159737
|
const up = dirname39(cur);
|
|
159712
159738
|
if (up === cur) break;
|
|
159713
|
-
tail.unshift(cur.slice(up.length + (up.endsWith(
|
|
159739
|
+
tail.unshift(cur.slice(up.length + (up.endsWith(sep18) ? 0 : 1)));
|
|
159714
159740
|
cur = up;
|
|
159715
159741
|
}
|
|
159716
159742
|
return join72(realpathSync10.native(cur), ...tail);
|
|
@@ -159770,7 +159796,7 @@ function listFiles(appDir3) {
|
|
|
159770
159796
|
const rel = relative13(appDir3, p2);
|
|
159771
159797
|
if (isDeniedSourcePath(rel) || isDeniedSourcePath(rel.toLowerCase())) continue;
|
|
159772
159798
|
if (files.length >= MAX_LISTED) return false;
|
|
159773
|
-
files.push({ path: rel.split(
|
|
159799
|
+
files.push({ path: rel.split(sep18).join("/"), bytes: statSync19(p2).size });
|
|
159774
159800
|
}
|
|
159775
159801
|
}
|
|
159776
159802
|
return true;
|
|
@@ -160570,7 +160596,7 @@ __export(native_decode_exports, {
|
|
|
160570
160596
|
runAndroidNativeDecode: () => runAndroidNativeDecode,
|
|
160571
160597
|
runNativeDecode: () => runNativeDecode
|
|
160572
160598
|
});
|
|
160573
|
-
import { execFileSync as execFileSync6, spawnSync as
|
|
160599
|
+
import { execFileSync as execFileSync6, spawnSync as spawnSync4 } from "node:child_process";
|
|
160574
160600
|
import { existsSync as existsSync73, mkdirSync as mkdirSync37, mkdtempSync as mkdtempSync5, readFileSync as readFileSync84, rmSync as rmSync20, writeFileSync as writeFileSync31 } from "node:fs";
|
|
160575
160601
|
import { homedir as homedir10, tmpdir as tmpdir6 } from "node:os";
|
|
160576
160602
|
import { join as join78 } from "node:path";
|
|
@@ -160590,7 +160616,7 @@ function nativeOracleShipped() {
|
|
|
160590
160616
|
function detectNativeDecode(options = {}) {
|
|
160591
160617
|
const hostPlatform = options.hostPlatform ?? process.platform;
|
|
160592
160618
|
const packageDir = options.packageDir ?? nativeDecodePackageDir();
|
|
160593
|
-
const swiftAvailable = options.swiftAvailable ??
|
|
160619
|
+
const swiftAvailable = options.swiftAvailable ?? spawnSync4("swift", ["--version"], { stdio: "ignore" }).status === 0;
|
|
160594
160620
|
if (hostPlatform !== "darwin") {
|
|
160595
160621
|
return { platform: "ios", available: false, reason: `the iOS decoder oracle requires macOS (darwin); this host is ${hostPlatform}` };
|
|
160596
160622
|
}
|
|
@@ -160892,7 +160918,7 @@ __export(browser_authoring_exports, {
|
|
|
160892
160918
|
import { createServer as createServer4 } from "node:http";
|
|
160893
160919
|
import { createHash as createHash38, randomBytes as randomBytes4 } from "node:crypto";
|
|
160894
160920
|
import { existsSync as existsSync74, readdirSync as readdirSync33, readFileSync as readFileSync85, realpathSync as realpathSync11, statSync as statSync20 } from "node:fs";
|
|
160895
|
-
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";
|
|
160896
160922
|
function humanMs(ms2) {
|
|
160897
160923
|
return ms2 < 1e3 ? `${ms2}ms` : `${Math.round(ms2 / 1e3)}s`;
|
|
160898
160924
|
}
|
|
@@ -160942,7 +160968,7 @@ function collectRelativeSiblings(files, tier5SrcDir) {
|
|
|
160942
160968
|
];
|
|
160943
160969
|
for (const abs of candidates) {
|
|
160944
160970
|
if (!existsSync74(abs) || statSync20(abs).isDirectory()) continue;
|
|
160945
|
-
const key3 = `/tier5-src/${relative15(tier5SrcDir, abs).split(
|
|
160971
|
+
const key3 = `/tier5-src/${relative15(tier5SrcDir, abs).split(sep19).join(posix3.sep)}`;
|
|
160946
160972
|
if (key3 in files) break;
|
|
160947
160973
|
files[key3] = readFileSync85(abs, "utf8");
|
|
160948
160974
|
queue.push(key3);
|
|
@@ -164279,6 +164305,11 @@ ${releaseId}`;
|
|
|
164279
164305
|
...m2.templateMeta.accent ? { accent: m2.templateMeta.accent } : {},
|
|
164280
164306
|
...m2.templateMeta.palette?.length ? { palette: m2.templateMeta.palette } : {},
|
|
164281
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 } : {},
|
|
164282
164313
|
minBinaryVersion: m2.minBinaryVersion,
|
|
164283
164314
|
...iconUrl ? { iconUrl } : {}
|
|
164284
164315
|
});
|
|
@@ -165386,7 +165417,7 @@ __export(run_browser_exports, {
|
|
|
165386
165417
|
});
|
|
165387
165418
|
import { createServer as createServer6 } from "node:http";
|
|
165388
165419
|
import { existsSync as existsSync84, readFileSync as readFileSync94 } from "node:fs";
|
|
165389
|
-
import { spawnSync as
|
|
165420
|
+
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
165390
165421
|
import { dirname as dirname44, resolve as resolve68 } from "node:path";
|
|
165391
165422
|
import { fileURLToPath as fileURLToPath30 } from "node:url";
|
|
165392
165423
|
function stagedDir() {
|
|
@@ -165397,7 +165428,7 @@ function missingStaged() {
|
|
|
165397
165428
|
}
|
|
165398
165429
|
function ensureBrowserPlaneStaged() {
|
|
165399
165430
|
if (missingStaged().length === 0) return { ok: true, detail: "already staged" };
|
|
165400
|
-
const r3 =
|
|
165431
|
+
const r3 = spawnSync5(process.execPath, [resolve68(REPO2, "core/serve/scripts/stage-browser-plane.mjs")], {
|
|
165401
165432
|
cwd: REPO2,
|
|
165402
165433
|
encoding: "utf8"
|
|
165403
165434
|
});
|
|
@@ -177493,7 +177524,7 @@ var init_analyze = __esm({
|
|
|
177493
177524
|
|
|
177494
177525
|
// src/base44-analyze/write-artifacts.ts
|
|
177495
177526
|
import { existsSync as existsSync101, mkdirSync as mkdirSync45, readFileSync as readFileSync119, rmSync as rmSync29, writeFileSync as writeFileSync44 } from "node:fs";
|
|
177496
|
-
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";
|
|
177497
177528
|
function isBookFolder(dir) {
|
|
177498
177529
|
try {
|
|
177499
177530
|
return JSON.parse(readFileSync119(join111(dir, "book.json"), "utf8")).kind === "base44-app-book";
|
|
@@ -177601,7 +177632,7 @@ function writeBase44Book(result, outDir, opts = {}) {
|
|
|
177601
177632
|
for (const f2 of result.sourceFiles) {
|
|
177602
177633
|
if (!safeRel(f2.path)) continue;
|
|
177603
177634
|
const dest = join111(sourceRoot, ...f2.path.split("/"));
|
|
177604
|
-
if (!dest.startsWith(sourceRoot +
|
|
177635
|
+
if (!dest.startsWith(sourceRoot + sep20)) continue;
|
|
177605
177636
|
mkdirSync45(dirname52(dest), { recursive: true });
|
|
177606
177637
|
writeFileSync44(dest, f2.bytes);
|
|
177607
177638
|
}
|
|
@@ -184116,8 +184147,8 @@ var init_customer_build = __esm({
|
|
|
184116
184147
|
|
|
184117
184148
|
// src/site-analyze/apply.ts
|
|
184118
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";
|
|
184119
|
-
import { dirname as dirname54, isAbsolute as isAbsolute9, join as join115, resolve as resolve78, sep as
|
|
184120
|
-
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";
|
|
184121
184152
|
function unpairedRedirectNote(overlay) {
|
|
184122
184153
|
if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
|
|
184123
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)`;
|
|
@@ -184246,7 +184277,7 @@ function buildMergedContract(options) {
|
|
|
184246
184277
|
const contained = (root, rel) => {
|
|
184247
184278
|
if (isAbsolute9(rel)) return void 0;
|
|
184248
184279
|
const full = resolve78(root, rel);
|
|
184249
|
-
return full.startsWith(resolve78(root) +
|
|
184280
|
+
return full.startsWith(resolve78(root) + sep21) ? full : void 0;
|
|
184250
184281
|
};
|
|
184251
184282
|
const stage = (fromRel, toRel) => {
|
|
184252
184283
|
const from = contained(packageDir, fromRel);
|
|
@@ -184260,7 +184291,7 @@ function buildMergedContract(options) {
|
|
|
184260
184291
|
} catch {
|
|
184261
184292
|
return void 0;
|
|
184262
184293
|
}
|
|
184263
|
-
if (!real.startsWith(realRoot +
|
|
184294
|
+
if (!real.startsWith(realRoot + sep21)) return void 0;
|
|
184264
184295
|
try {
|
|
184265
184296
|
if (!statSync27(real).isFile()) return void 0;
|
|
184266
184297
|
mkdirSync48(dirname54(to2), { recursive: true });
|
|
@@ -184396,7 +184427,7 @@ async function applyOverlays(input) {
|
|
|
184396
184427
|
const packageDir = dirname54(resolve78(input.overlayPath));
|
|
184397
184428
|
const { path: contract, staged } = buildMergedContract({ appDir: appDir3, packageDir, overlay });
|
|
184398
184429
|
wrote.push(...staged);
|
|
184399
|
-
const r3 =
|
|
184430
|
+
const r3 = spawnSync6("npm", ["run", "prepare:customer", "--", "--contract", contract], {
|
|
184400
184431
|
cwd: appDir3,
|
|
184401
184432
|
encoding: "utf8"
|
|
184402
184433
|
});
|
|
@@ -187470,7 +187501,8 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
187470
187501
|
"refresh-wix",
|
|
187471
187502
|
"empty-app-ok",
|
|
187472
187503
|
"aab",
|
|
187473
|
-
"managed"
|
|
187504
|
+
"managed",
|
|
187505
|
+
"source-hash"
|
|
187474
187506
|
]);
|
|
187475
187507
|
var SWITCH_FLAGS = new Set([...BOOLEAN_FLAGS].filter((name) => name !== "deep"));
|
|
187476
187508
|
var SWITCH_CONSEQUENCE = {
|
|
@@ -187480,6 +187512,7 @@ var SWITCH_CONSEQUENCE = {
|
|
|
187480
187512
|
record: "silently ignored, it would leave you believing the fixture was refreshed",
|
|
187481
187513
|
"no-oauth-app": "silently ignored, it would mint an OAuth client you asked to skip",
|
|
187482
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",
|
|
187483
187516
|
"allow-destructive": "silently ignored, it would refuse the destructive step you opted into",
|
|
187484
187517
|
static: "silently ignored, it would render HYDRATED when you asked for static",
|
|
187485
187518
|
// `--wait=false` is the one spelling where "pass it bare" is the WRONG advice: bare `--wait`
|
|
@@ -188243,7 +188276,7 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
188243
188276
|
else skips it: outside CI it starts, and watch.note says why
|
|
188244
188277
|
himi template list [--remote] list starter templates + metadata (title/description/tags) + each one's start prompt
|
|
188245
188278
|
himi template prompt <name> print the prompt that starts an app from that template
|
|
188246
|
-
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]
|
|
188247
188280
|
publish an app AS a himi init --template on the serve plane
|
|
188248
188281
|
himi template trim --keep <id,id,\u2026> | --from-spec [SPEC.md] [--content <dir>] [--links follow|drop] [--dry-run] [--force]
|
|
188249
188282
|
cut a scaffolded template to the screens you keep (the home and
|
|
@@ -188991,7 +189024,7 @@ var COMMANDS = [
|
|
|
188991
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]" },
|
|
188992
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>]" },
|
|
188993
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" },
|
|
188994
|
-
{ 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]" },
|
|
188995
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]" },
|
|
188996
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>]" },
|
|
188997
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>]" },
|
|
@@ -189071,7 +189104,7 @@ function helpJson() {
|
|
|
189071
189104
|
|
|
189072
189105
|
// src/self-update.ts
|
|
189073
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";
|
|
189074
|
-
import { execFile, execFileSync as execFileSync3, spawnSync } from "node:child_process";
|
|
189107
|
+
import { execFile, execFileSync as execFileSync3, spawnSync as spawnSync2 } from "node:child_process";
|
|
189075
189108
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
189076
189109
|
import { homedir as homedir8, hostname } from "node:os";
|
|
189077
189110
|
import { join as join31, resolve as resolve33, dirname as dirname23 } from "node:path";
|
|
@@ -189316,7 +189349,7 @@ function npmInstallArgs(registry2, version5) {
|
|
|
189316
189349
|
return ["i", "-g", `${CLI_PACKAGE}@${version5}`, `--registry=${pinned}`, `--@wix:registry=${pinned}`];
|
|
189317
189350
|
}
|
|
189318
189351
|
var INSTALLABLE_SPEC = /^(?:latest|\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)$/;
|
|
189319
|
-
function createUpdateRunner(spawn8 =
|
|
189352
|
+
function createUpdateRunner(spawn8 = spawnSync2) {
|
|
189320
189353
|
return {
|
|
189321
189354
|
install: async (registry2, version5) => {
|
|
189322
189355
|
if (!isTrustedRegistry(registry2)) return { ok: false, detail: `refusing untrusted registry ${registry2}` };
|
|
@@ -189340,7 +189373,7 @@ function createUpdateRunner(spawn8 = spawnSync) {
|
|
|
189340
189373
|
const root = globalNodeModulesRoot();
|
|
189341
189374
|
const entry = root ? join31(root, "@wix", "himalaya-cli", "dist", "cli.mjs") : void 0;
|
|
189342
189375
|
if (!entry || !existsSync35(entry)) return void 0;
|
|
189343
|
-
const result =
|
|
189376
|
+
const result = spawnSync2(process.execPath, [entry, ...argv], {
|
|
189344
189377
|
// inherit keeps PIPED STDIN working — commands that read stdin must survive a re-exec.
|
|
189345
189378
|
stdio: "inherit",
|
|
189346
189379
|
env: { ...process.env, [UPDATE_REEXEC_ENV]: "1" }
|
|
@@ -190344,6 +190377,7 @@ async function templateCommand(ctx) {
|
|
|
190344
190377
|
}
|
|
190345
190378
|
const appDir3 = resolve46(str3(flags.dir) ?? process.cwd());
|
|
190346
190379
|
const sourceDir = resolve46(str3(flags["source-dir"]) ?? appDir3);
|
|
190380
|
+
ensureTemplatesFor(appDir3, sourceDir);
|
|
190347
190381
|
let meta;
|
|
190348
190382
|
try {
|
|
190349
190383
|
meta = JSON.parse(readFileSync67(join57(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
@@ -190374,6 +190408,28 @@ async function templateCommand(ctx) {
|
|
|
190374
190408
|
const buildDir = materializeForPreview(appDir3, name, meta.title);
|
|
190375
190409
|
if (buildDir !== appDir3) publishScratch.push(buildDir);
|
|
190376
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
|
+
}
|
|
190377
190433
|
const strict = flags.strict === true;
|
|
190378
190434
|
const force = flags.force === true;
|
|
190379
190435
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
@@ -190436,25 +190492,18 @@ async function templateCommand(ctx) {
|
|
|
190436
190492
|
}));
|
|
190437
190493
|
return 1;
|
|
190438
190494
|
}
|
|
190439
|
-
const
|
|
190440
|
-
|
|
190441
|
-
if (
|
|
190442
|
-
try {
|
|
190443
|
-
const bytes2 = readFileSync67(iconPath);
|
|
190444
|
-
payload.icon = bytes2.toString("base64");
|
|
190445
|
-
iconHash = createHash30("sha256").update(bytes2).digest("hex");
|
|
190446
|
-
} catch {
|
|
190447
|
-
}
|
|
190448
|
-
}
|
|
190495
|
+
const icon = launcherIcon();
|
|
190496
|
+
const iconHash = icon?.hash;
|
|
190497
|
+
if (icon) payload.icon = icon.bytes.toString("base64");
|
|
190449
190498
|
payload.app = templateAppId;
|
|
190450
190499
|
const { rebindReleaseId: rebindReleaseId2 } = await Promise.resolve().then(() => (init_build3(), build_exports2));
|
|
190451
190500
|
payload.manifest = rebindReleaseId2({ ...payload.manifest, app: templateAppId, ...iconHash ? { iconHash } : {} });
|
|
190452
|
-
const
|
|
190453
|
-
if (Object.keys(files).length === 0) {
|
|
190501
|
+
const source = catalogView();
|
|
190502
|
+
if (Object.keys(source.files).length === 0) {
|
|
190454
190503
|
io2.error(JSON.stringify({ error: `no source files collected from ${sourceDir}` }));
|
|
190455
190504
|
return 1;
|
|
190456
190505
|
}
|
|
190457
|
-
payload.source =
|
|
190506
|
+
payload.source = source;
|
|
190458
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));
|
|
190459
190508
|
const templateArchive = collectAppSource2(sourceDir);
|
|
190460
190509
|
const templateSecrets = secretFindings2(templateArchive.entries);
|
|
@@ -190610,7 +190659,7 @@ async function templateCommand(ctx) {
|
|
|
190610
190659
|
icon: Boolean(iconHash),
|
|
190611
190660
|
...meta.accent ? { accent: meta.accent } : {},
|
|
190612
190661
|
...meta.palette ? { palette: meta.palette } : {},
|
|
190613
|
-
sourceFiles: Object.keys(files).length,
|
|
190662
|
+
sourceFiles: Object.keys(source.files).length,
|
|
190614
190663
|
...hasErrors && force ? { forcedPastErrors: true } : {},
|
|
190615
190664
|
initWith: `himi init <new-app-name> --template ${name} --remote${targetFlag}`
|
|
190616
190665
|
});
|
|
@@ -190625,7 +190674,7 @@ async function templateCommand(ctx) {
|
|
|
190625
190674
|
}
|
|
190626
190675
|
}
|
|
190627
190676
|
}
|
|
190628
|
-
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>" }));
|
|
190629
190678
|
return 2;
|
|
190630
190679
|
}
|
|
190631
190680
|
|
|
@@ -190843,7 +190892,7 @@ async function validateCommand(ctx) {
|
|
|
190843
190892
|
import { readFileSync as readFileSync80 } from "node:fs";
|
|
190844
190893
|
|
|
190845
190894
|
// src/dpx.ts
|
|
190846
|
-
import { spawnSync as
|
|
190895
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
190847
190896
|
import { existsSync as existsSync67, readFileSync as readFileSync78 } from "node:fs";
|
|
190848
190897
|
import { homedir as homedir9 } from "node:os";
|
|
190849
190898
|
import { join as join70 } from "node:path";
|
|
@@ -190888,7 +190937,7 @@ function parseDpxAuthStatusIdentity(stdout) {
|
|
|
190888
190937
|
return stdout.split("\n").map((l2) => l2.trim()).find(Boolean) || void 0;
|
|
190889
190938
|
}
|
|
190890
190939
|
var defaultRunner2 = (cmd, args) => {
|
|
190891
|
-
const r3 =
|
|
190940
|
+
const r3 = spawnSync3(cmd, args, { encoding: "utf8" });
|
|
190892
190941
|
return { status: r3.status, stdout: r3.stdout ?? "", stderr: r3.stderr ?? "", error: r3.error };
|
|
190893
190942
|
};
|
|
190894
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
|
}
|