@wix/himalaya-cli 0.1118.0 → 0.1119.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 +73 -6
- package/guides/himi-mcp.md +3 -1
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -24719,7 +24719,6 @@ function shouldRevealError(args) {
|
|
|
24719
24719
|
var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
|
|
24720
24720
|
var init_validation = __esm({
|
|
24721
24721
|
"../../core/ts/src/validation.ts"() {
|
|
24722
|
-
"use strict";
|
|
24723
24722
|
EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
|
|
24724
24723
|
URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
|
|
24725
24724
|
INTEGER_RE = /^[+-]?[0-9]+$/;
|
|
@@ -29120,7 +29119,6 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
|
|
|
29120
29119
|
var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
|
|
29121
29120
|
var init_worker_subtree = __esm({
|
|
29122
29121
|
"../../core/ts/src/worker-subtree.ts"() {
|
|
29123
|
-
"use strict";
|
|
29124
29122
|
init_worker_subtree_safe_types_generated();
|
|
29125
29123
|
WORKER_SUBTREE_CEILINGS = Object.freeze({
|
|
29126
29124
|
maxEncodedBytes: 65536,
|
|
@@ -49227,6 +49225,7 @@ function readInitWatch(dir) {
|
|
|
49227
49225
|
const r = JSON.parse(readFileSync52(file, "utf8"));
|
|
49228
49226
|
if (r.v !== 1 || typeof r.pid !== "number" || !Number.isInteger(r.pid) || r.pid < 1) return null;
|
|
49229
49227
|
if (typeof r.url !== "string" || !/^http:\/\/127\.0\.0\.1:\d+\//.test(r.url) || typeof r.board !== "string" || typeof r.log !== "string" || typeof r.startedAt !== "string") return null;
|
|
49228
|
+
if (r.root !== runRootId(dir)) return null;
|
|
49230
49229
|
return r;
|
|
49231
49230
|
} catch {
|
|
49232
49231
|
return null;
|
|
@@ -49324,7 +49323,7 @@ async function startWatchAtInit(dir, opts) {
|
|
|
49324
49323
|
});
|
|
49325
49324
|
child.unref();
|
|
49326
49325
|
if (!child.pid) return { skipped: "the live preview did not start (no process) \u2014 start it yourself: `himi run --watch --content <dir> &`" };
|
|
49327
|
-
const record2 = { v: 1, pid: child.pid, url, board, log: WATCH_LOG, startedAt: now.toISOString() };
|
|
49326
|
+
const record2 = { v: 1, pid: child.pid, root: runRootId(dir), url, board, log: WATCH_LOG, startedAt: now.toISOString() };
|
|
49328
49327
|
if (realDirIn(dir, ".himi")) writeFileAtomic(join46(dir, INIT_WATCH_FILE), `${JSON.stringify(record2, null, 2)}
|
|
49329
49328
|
`);
|
|
49330
49329
|
return { started: true, pid: child.pid, url, board, log: WATCH_LOG };
|
|
@@ -49384,6 +49383,7 @@ var init_milestones = __esm({
|
|
|
49384
49383
|
"src/milestones.ts"() {
|
|
49385
49384
|
init_app_source();
|
|
49386
49385
|
init_preview();
|
|
49386
|
+
init_run_identity();
|
|
49387
49387
|
init_progress();
|
|
49388
49388
|
init_shell_quote();
|
|
49389
49389
|
init_studio_reel();
|
|
@@ -54035,6 +54035,15 @@ function symlinkComponent(base, abs) {
|
|
|
54035
54035
|
}
|
|
54036
54036
|
return void 0;
|
|
54037
54037
|
}
|
|
54038
|
+
function workspaceRefusal(root, target) {
|
|
54039
|
+
const r = resolve45(root);
|
|
54040
|
+
const t = resolve45(r, target);
|
|
54041
|
+
if (!existsSync54(r)) return `the workspace folder ${r} does not exist`;
|
|
54042
|
+
if (!within(r, t) || !within(realpathSync7(r), realish(t))) return `"${target}" is outside the workspace folder ${r}`;
|
|
54043
|
+
const link = symlinkComponent(r, t);
|
|
54044
|
+
if (link) return `"${link}" is a symlink \u2014 paths must stay in real folders inside the workspace`;
|
|
54045
|
+
return null;
|
|
54046
|
+
}
|
|
54038
54047
|
async function confinedAppDir(args, deps) {
|
|
54039
54048
|
const root = resolve45(await deps.defaultDir());
|
|
54040
54049
|
const dir = typeof args.dir === "string" && args.dir ? resolve45(root, args.dir) : root;
|
|
@@ -54305,6 +54314,15 @@ function guarded(h) {
|
|
|
54305
54314
|
return async (args, deps) => {
|
|
54306
54315
|
const bad2 = flagShapedInputs(args);
|
|
54307
54316
|
if (bad2.length) return text6(`refused: ${bad2.join(", ")} may not start with "-" (it would be read as a himi flag)`, true);
|
|
54317
|
+
if (deps.workspaceBoundary) {
|
|
54318
|
+
const base = await deps.defaultDir();
|
|
54319
|
+
for (const k of PATH_ARGS) {
|
|
54320
|
+
const v = args[k];
|
|
54321
|
+
if (typeof v !== "string" || !v) continue;
|
|
54322
|
+
const why = workspaceRefusal(deps.workspaceBoundary, resolve46(base, v));
|
|
54323
|
+
if (why) return text6(`refused: ${k} ${why}`, true);
|
|
54324
|
+
}
|
|
54325
|
+
}
|
|
54308
54326
|
return h(args, deps);
|
|
54309
54327
|
};
|
|
54310
54328
|
}
|
|
@@ -54557,7 +54575,7 @@ ${log}` : ""}`, true);
|
|
|
54557
54575
|
}
|
|
54558
54576
|
];
|
|
54559
54577
|
}
|
|
54560
|
-
var MAX_TEXT2, clip, text6, json3, opt, sw, DIR2, LEARN, CHECK, LOCAL_WRITE, PUBLISH, PREVIEW_HINT, LOGIN_HINT;
|
|
54578
|
+
var MAX_TEXT2, clip, text6, json3, opt, sw, DIR2, LEARN, CHECK, LOCAL_WRITE, PUBLISH, PREVIEW_HINT, LOGIN_HINT, PATH_ARGS;
|
|
54561
54579
|
var init_tools = __esm({
|
|
54562
54580
|
"src/mcp/tools.ts"() {
|
|
54563
54581
|
init_file_tools();
|
|
@@ -54575,6 +54593,7 @@ var init_tools = __esm({
|
|
|
54575
54593
|
PUBLISH = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true };
|
|
54576
54594
|
PREVIEW_HINT = "The preview is already running: open `url` in your built-in browser \u2014 Claude Code desktop's browser pane, Cursor's Browser tool, the Browser in Codex inside the ChatGPT desktop app, VS Code's integrated browser. Do not also start the `himi-preview` launch configuration: it serves the same port, and is the way to start a preview only when none is running. A terminal-only agent should show the owner `himi_render` PNGs instead. `board` (when present) is the build board on the same origin.";
|
|
54577
54595
|
LOGIN_HINT = "Not signed in to the himi serve plane. Call himi_login: it opens a browser window where the user signs in to Wix (this server never sees the credential). A user with a terminal can run `himi login --browser` instead. Then retry.";
|
|
54596
|
+
PATH_ARGS = ["dir", "parentDir", "file"];
|
|
54578
54597
|
}
|
|
54579
54598
|
});
|
|
54580
54599
|
|
|
@@ -54715,7 +54734,8 @@ async function startMcpServer(opts) {
|
|
|
54715
54734
|
stop: (dir) => stopPreview(dir, previewDeps)
|
|
54716
54735
|
},
|
|
54717
54736
|
readFile: (p) => readFileSync60(p),
|
|
54718
|
-
login: createLoginSession({ ...defaultLoginDeps, selfCommand: previewDeps.selfCommand, ...opts.login })
|
|
54737
|
+
login: createLoginSession({ ...defaultLoginDeps, selfCommand: previewDeps.selfCommand, ...opts.login }),
|
|
54738
|
+
...opts.workspace ? { workspaceBoundary: opts.workspace } : {}
|
|
54719
54739
|
};
|
|
54720
54740
|
const closed = new Promise((resolve54) => {
|
|
54721
54741
|
stdin.once("end", resolve54);
|
|
@@ -57667,6 +57687,7 @@ __export(run_watch_exports, {
|
|
|
57667
57687
|
isEmptyDiff: () => isEmptyDiff,
|
|
57668
57688
|
rebuildBlocker: () => rebuildBlocker,
|
|
57669
57689
|
reloadEvents: () => reloadEvents,
|
|
57690
|
+
removeInitWatchRecord: () => removeInitWatchRecord,
|
|
57670
57691
|
removeRunRecord: () => removeRunRecord,
|
|
57671
57692
|
serialize: () => serialize,
|
|
57672
57693
|
watchContent: () => watchContent,
|
|
@@ -57836,6 +57857,24 @@ function removeRunRecord(dir, owner) {
|
|
|
57836
57857
|
}
|
|
57837
57858
|
rmSync15(join59(root, "run.json"), { force: true });
|
|
57838
57859
|
}
|
|
57860
|
+
function removeInitWatchRecord(dir, owner) {
|
|
57861
|
+
const root = join59(dir, ".himi");
|
|
57862
|
+
try {
|
|
57863
|
+
if (!lstatSync13(root).isDirectory()) return;
|
|
57864
|
+
} catch {
|
|
57865
|
+
return;
|
|
57866
|
+
}
|
|
57867
|
+
const bytes2 = readConfined(root, "watch.json");
|
|
57868
|
+
if (!bytes2) return;
|
|
57869
|
+
let pid;
|
|
57870
|
+
try {
|
|
57871
|
+
pid = JSON.parse(bytes2.toString("utf8")).pid;
|
|
57872
|
+
} catch {
|
|
57873
|
+
return;
|
|
57874
|
+
}
|
|
57875
|
+
if (pid !== owner) return;
|
|
57876
|
+
rmSync15(join59(root, "watch.json"), { force: true });
|
|
57877
|
+
}
|
|
57839
57878
|
function boardFile(dir, pathname) {
|
|
57840
57879
|
if (pathname === RUN_IDENTITY_PATH) {
|
|
57841
57880
|
return new Response(JSON.stringify(runIdentity(dir)), { status: 200, headers: { "content-type": "application/json", "cache-control": "no-store" } });
|
|
@@ -77537,9 +77576,30 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
77537
77576
|
let browserCopy = null;
|
|
77538
77577
|
let servedMissing = [];
|
|
77539
77578
|
const fromContent = !source;
|
|
77579
|
+
let dropEarlySignals;
|
|
77580
|
+
let dropInitRecord;
|
|
77540
77581
|
try {
|
|
77541
77582
|
if (!source) {
|
|
77542
77583
|
const dir2 = contentDir(flags);
|
|
77584
|
+
if (watch2) {
|
|
77585
|
+
const { removeInitWatchRecord: removeInitWatchRecord2 } = await Promise.resolve().then(() => (init_run_watch(), run_watch_exports));
|
|
77586
|
+
dropInitRecord = () => removeInitWatchRecord2(dir2, process.pid);
|
|
77587
|
+
const onExit = () => dropInitRecord?.();
|
|
77588
|
+
process.once("exit", onExit);
|
|
77589
|
+
const early = [["SIGINT", 130], ["SIGTERM", 143], ["SIGHUP", 129]].map(([sig, code]) => {
|
|
77590
|
+
const onEarly = () => {
|
|
77591
|
+
dropInitRecord?.();
|
|
77592
|
+
process.exit(code);
|
|
77593
|
+
};
|
|
77594
|
+
process.once(sig, onEarly);
|
|
77595
|
+
return [sig, onEarly];
|
|
77596
|
+
});
|
|
77597
|
+
dropEarlySignals = () => {
|
|
77598
|
+
for (const [sig, onEarly] of early) process.removeListener(sig, onEarly);
|
|
77599
|
+
process.removeListener("exit", onExit);
|
|
77600
|
+
dropEarlySignals = void 0;
|
|
77601
|
+
};
|
|
77602
|
+
}
|
|
77543
77603
|
const app = await appId(dir2);
|
|
77544
77604
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
77545
77605
|
const bres = await buildContentBundles2(dir2, { resolution: resolutionFlag(flags) });
|
|
@@ -77573,7 +77633,10 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
77573
77633
|
let startedAt = "";
|
|
77574
77634
|
const record2 = (served2, build2) => {
|
|
77575
77635
|
try {
|
|
77576
|
-
if (recordKit?.writeRunRecord(dir, { url: served2.url, port: served2.port, ...served2.lanUrl ? { lanUrl: served2.lanUrl } : {}, pid: process.pid, startedAt, watching: watch2, build: build2 }))
|
|
77636
|
+
if (recordKit?.writeRunRecord(dir, { url: served2.url, port: served2.port, ...served2.lanUrl ? { lanUrl: served2.lanUrl } : {}, pid: process.pid, startedAt, watching: watch2, build: build2 })) {
|
|
77637
|
+
recorded = true;
|
|
77638
|
+
if (watch2) recordKit.removeInitWatchRecord(dir, process.pid);
|
|
77639
|
+
}
|
|
77577
77640
|
return null;
|
|
77578
77641
|
} catch (e) {
|
|
77579
77642
|
return e.message;
|
|
@@ -77610,6 +77673,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
77610
77673
|
const stop = () => {
|
|
77611
77674
|
void retract().catch((e) => io.error(JSON.stringify({ run: "stop_cleanup_failed", message: e.message }))).finally(() => run2.close().finally(() => resolve54()));
|
|
77612
77675
|
};
|
|
77676
|
+
dropEarlySignals?.();
|
|
77613
77677
|
process.once("SIGINT", stop);
|
|
77614
77678
|
process.once("SIGTERM", stop);
|
|
77615
77679
|
});
|
|
@@ -77755,6 +77819,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
77755
77819
|
}
|
|
77756
77820
|
};
|
|
77757
77821
|
const onSignal = () => void stop();
|
|
77822
|
+
dropEarlySignals?.();
|
|
77758
77823
|
for (const sig of ["SIGINT", "SIGTERM", "SIGHUP"]) process.once(sig, onSignal);
|
|
77759
77824
|
stopNow = (why) => void stop(why);
|
|
77760
77825
|
armIdle();
|
|
@@ -77764,6 +77829,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
77764
77829
|
io.error(JSON.stringify({ error: e.message }));
|
|
77765
77830
|
return 1;
|
|
77766
77831
|
} finally {
|
|
77832
|
+
dropEarlySignals?.();
|
|
77833
|
+
dropInitRecord?.();
|
|
77767
77834
|
if (temp) rmSync16(temp, { recursive: true, force: true });
|
|
77768
77835
|
if (served) rmSync16(served, { recursive: true, force: true });
|
|
77769
77836
|
if (browserCopy) rmSync16(browserCopy, { recursive: true, force: true });
|
package/guides/himi-mcp.md
CHANGED
|
@@ -90,7 +90,9 @@ without following links. They judge the deny-list in every spelling, because mac
|
|
|
90
90
|
write or delete anything the source deny-list keeps off the machine: `.env` files, the `.himi/`
|
|
91
91
|
secret store, MCP host configs with their keys, key files, and `node_modules`, `dist` and `.git`
|
|
92
92
|
at any depth. When the host names
|
|
93
|
-
no workspace, `HIMI_WORKSPACE` sets the folder.
|
|
93
|
+
no workspace, `HIMI_WORKSPACE` sets the folder. It is then a hard boundary for EVERY tool: a
|
|
94
|
+
`dir`, `parentDir` or `file` argument outside it, or through a symlink, is refused. That covers the
|
|
95
|
+
publish and share tools, not only the file tools. Coding agents edit files themselves, so the flag is
|
|
94
96
|
off by default.
|
|
95
97
|
|
|
96
98
|
**What the tools will not do:** make a release live, build store binaries, touch secrets, write to a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1119.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": [
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"artifactId": "himalaya-cli"
|
|
68
68
|
}
|
|
69
69
|
},
|
|
70
|
-
"falconPackageHash": "
|
|
70
|
+
"falconPackageHash": "095801b2c05f44cecb7cf7c8b66b69b17736a05e43bf01dd8c72dde5"
|
|
71
71
|
}
|