@wix/himalaya-cli 0.1113.0 → 0.1114.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 +126 -12
- package/guides/himi-mcp.md +8 -5
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -24718,7 +24718,6 @@ function shouldRevealError(args) {
|
|
|
24718
24718
|
var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
|
|
24719
24719
|
var init_validation = __esm({
|
|
24720
24720
|
"../../core/ts/src/validation.ts"() {
|
|
24721
|
-
"use strict";
|
|
24722
24721
|
EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
|
|
24723
24722
|
URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
|
|
24724
24723
|
INTEGER_RE = /^[+-]?[0-9]+$/;
|
|
@@ -29119,7 +29118,6 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
|
|
|
29119
29118
|
var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
|
|
29120
29119
|
var init_worker_subtree = __esm({
|
|
29121
29120
|
"../../core/ts/src/worker-subtree.ts"() {
|
|
29122
|
-
"use strict";
|
|
29123
29121
|
init_worker_subtree_safe_types_generated();
|
|
29124
29122
|
WORKER_SUBTREE_CEILINGS = Object.freeze({
|
|
29125
29123
|
maxEncodedBytes: 65536,
|
|
@@ -53871,8 +53869,25 @@ async function appDir2(args, deps) {
|
|
|
53871
53869
|
const base = await deps.defaultDir();
|
|
53872
53870
|
return typeof args.dir === "string" && args.dir ? resolve45(base, args.dir) : base;
|
|
53873
53871
|
}
|
|
53872
|
+
function loginResult(s) {
|
|
53873
|
+
switch (s.state) {
|
|
53874
|
+
case "pending":
|
|
53875
|
+
return json3({
|
|
53876
|
+
ok: true,
|
|
53877
|
+
state: "pending",
|
|
53878
|
+
...s.loginUrl ? { loginUrl: s.loginUrl } : {},
|
|
53879
|
+
message: "A browser window opened for the user to sign in to Wix. If it did not open, give them `loginUrl`. Once they have signed in, call himi_login again to confirm, or just retry the push."
|
|
53880
|
+
});
|
|
53881
|
+
case "signed_in":
|
|
53882
|
+
return json3({ ok: true, state: "signed_in", account: s.account, scope: s.scope, expiresAt: s.expiresAt });
|
|
53883
|
+
case "failed":
|
|
53884
|
+
return { ...json3({ ok: false, state: "failed", error: s.error, hint: "Call himi_login again to retry, or ask the user to run `himi login --browser` in a terminal." }), isError: true };
|
|
53885
|
+
default:
|
|
53886
|
+
return json3({ ok: true, state: "idle" });
|
|
53887
|
+
}
|
|
53888
|
+
}
|
|
53874
53889
|
async function requireLogin(deps) {
|
|
53875
|
-
const who = await deps.runCli(["whoami"]);
|
|
53890
|
+
const who = await deps.runCli(["whoami", ...opt("--target", deps.login.target())]);
|
|
53876
53891
|
if (who.code === 0) return null;
|
|
53877
53892
|
return { content: [{ type: "text", text: LOGIN_HINT }, ...who.stderr.trim() ? [{ type: "text", text: who.stderr.trim() }] : []], isError: true };
|
|
53878
53893
|
}
|
|
@@ -54068,12 +54083,34 @@ ${log}` : ""}`, true);
|
|
|
54068
54083
|
description: "The identity the stored serve-plane credential carries (account, scope, expiry). Local \u2014 decodes the stored token, no network.",
|
|
54069
54084
|
annotations: LEARN,
|
|
54070
54085
|
inputSchema: z.object({ target: z.string().optional().describe("Serve target. Default: the CLI's default.") }),
|
|
54071
|
-
handler: async (a, d) => fromCli(await d.runCli(["whoami", ...opt("--target", a.target)]))
|
|
54086
|
+
handler: async (a, d) => fromCli(await d.runCli(["whoami", ...opt("--target", a.target ?? d.login.target())]))
|
|
54087
|
+
},
|
|
54088
|
+
{
|
|
54089
|
+
name: "himi_login",
|
|
54090
|
+
title: "Sign in to Wix",
|
|
54091
|
+
description: "Open a browser window where the USER signs in to Wix, so himi_push and himi_share can publish. Returns at once with the sign-in link; call again to see whether the sign-in finished. Already signed in: says who, and opens nothing unless `switchAccount` is true. This server never sees the credential \u2014 the sign-in stores a scoped token on this machine.",
|
|
54092
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
54093
|
+
inputSchema: z.object({
|
|
54094
|
+
target: z.string().optional().describe("Serve target. Default: the CLI's default."),
|
|
54095
|
+
switchAccount: z.boolean().optional().describe("Sign in again even though a credential is stored (e.g. to use another Wix account).")
|
|
54096
|
+
}),
|
|
54097
|
+
handler: async (a, d) => {
|
|
54098
|
+
const s = d.login.status();
|
|
54099
|
+
if (s.state === "pending") return loginResult(s);
|
|
54100
|
+
if (!a.switchAccount) {
|
|
54101
|
+
const who = await d.runCli(["whoami", ...opt("--target", a.target)]);
|
|
54102
|
+
if (who.code === 0) {
|
|
54103
|
+
d.login.adopt(typeof a.target === "string" && a.target ? a.target : void 0);
|
|
54104
|
+
return json3({ ok: true, state: "signed_in", ...who.json && typeof who.json === "object" ? who.json : {} });
|
|
54105
|
+
}
|
|
54106
|
+
}
|
|
54107
|
+
return loginResult(await d.login.start(typeof a.target === "string" && a.target ? a.target : void 0));
|
|
54108
|
+
}
|
|
54072
54109
|
},
|
|
54073
54110
|
{
|
|
54074
54111
|
name: "himi_push",
|
|
54075
54112
|
title: "Publish a draft",
|
|
54076
|
-
description: "Lint, build and publish the app as a DRAFT release: owner-private, servable by preview link and in Himi Player, NOT live. Returns the preview links and the universal link that opens it in Himi Player. Never promotes \u2014 going live is a human command. Refuses on any validation error. Needs
|
|
54113
|
+
description: "Lint, build and publish the app as a DRAFT release: owner-private, servable by preview link and in Himi Player, NOT live. Returns the preview links and the universal link that opens it in Himi Player. Never promotes \u2014 going live is a human command. Refuses on any validation error. Needs a sign-in first (himi_login).",
|
|
54077
54114
|
annotations: PUBLISH,
|
|
54078
54115
|
inputSchema: z.object({
|
|
54079
54116
|
dir: DIR,
|
|
@@ -54083,13 +54120,13 @@ ${log}` : ""}`, true);
|
|
|
54083
54120
|
handler: async (a, d) => {
|
|
54084
54121
|
const gate = await requireLogin(d);
|
|
54085
54122
|
if (gate) return gate;
|
|
54086
|
-
return fromCli(await d.runCli(["push", "--content", await appDir2(a, d), "--draft", ...opt("--label", a.label), ...opt("--notes", a.notes)]));
|
|
54123
|
+
return fromCli(await d.runCli(["push", "--content", await appDir2(a, d), "--draft", ...opt("--label", a.label), ...opt("--notes", a.notes), ...opt("--target", d.login.target())]));
|
|
54087
54124
|
}
|
|
54088
54125
|
},
|
|
54089
54126
|
{
|
|
54090
54127
|
name: "himi_share",
|
|
54091
54128
|
title: "Share a .himi package link",
|
|
54092
|
-
description: "Publish a content-addressed share link for a validated `.himi` package of an already-published release. Needs
|
|
54129
|
+
description: "Publish a content-addressed share link for a validated `.himi` package of an already-published release. Needs a sign-in first (himi_login).",
|
|
54093
54130
|
annotations: PUBLISH,
|
|
54094
54131
|
inputSchema: z.object({
|
|
54095
54132
|
file: z.string().min(1).describe("Path to the .himi package (see `himi pack`)."),
|
|
@@ -54098,7 +54135,7 @@ ${log}` : ""}`, true);
|
|
|
54098
54135
|
handler: async (a, d) => {
|
|
54099
54136
|
const gate = await requireLogin(d);
|
|
54100
54137
|
if (gate) return gate;
|
|
54101
|
-
return fromCli(await d.runCli(["share", "--file", resolve45(await d.defaultDir(), String(a.file)), ...opt("--expires-at", a.expiresAt)]));
|
|
54138
|
+
return fromCli(await d.runCli(["share", "--file", resolve45(await d.defaultDir(), String(a.file)), ...opt("--expires-at", a.expiresAt), ...opt("--target", d.login.target())]));
|
|
54102
54139
|
}
|
|
54103
54140
|
},
|
|
54104
54141
|
{
|
|
@@ -54114,7 +54151,7 @@ ${log}` : ""}`, true);
|
|
|
54114
54151
|
screen: z.string().optional(),
|
|
54115
54152
|
surface: z.string().optional()
|
|
54116
54153
|
}),
|
|
54117
|
-
handler: async (a, d) => fromCli(await d.runCli(["preview", "--app", String(a.app), "--release", String(a.release), ...opt("--screen", a.screen), ...opt("--surface", a.surface)]))
|
|
54154
|
+
handler: async (a, d) => fromCli(await d.runCli(["preview", "--app", String(a.app), "--release", String(a.release), ...opt("--screen", a.screen), ...opt("--surface", a.surface), ...opt("--target", d.login.target())]))
|
|
54118
54155
|
}
|
|
54119
54156
|
];
|
|
54120
54157
|
}
|
|
@@ -54134,7 +54171,82 @@ var init_tools = __esm({
|
|
|
54134
54171
|
LOCAL_WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false };
|
|
54135
54172
|
PUBLISH = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true };
|
|
54136
54173
|
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.";
|
|
54137
|
-
LOGIN_HINT = "Not signed in to the himi serve plane.
|
|
54174
|
+
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.";
|
|
54175
|
+
}
|
|
54176
|
+
});
|
|
54177
|
+
|
|
54178
|
+
// src/mcp/login.ts
|
|
54179
|
+
import { spawn as nodeSpawn2 } from "node:child_process";
|
|
54180
|
+
function createLoginSession(deps) {
|
|
54181
|
+
let current = { state: "idle" };
|
|
54182
|
+
let signedInTarget;
|
|
54183
|
+
return {
|
|
54184
|
+
status: () => current,
|
|
54185
|
+
target: () => signedInTarget,
|
|
54186
|
+
adopt: (target) => {
|
|
54187
|
+
signedInTarget = target;
|
|
54188
|
+
},
|
|
54189
|
+
start(target) {
|
|
54190
|
+
if (current.state === "pending") return Promise.resolve(current);
|
|
54191
|
+
const self = deps.selfCommand();
|
|
54192
|
+
const args = [...self.args, "login", "--browser", "--skip-version-check", ...target ? ["--target", target] : []];
|
|
54193
|
+
const pending = { state: "pending", startedAt: deps.now() };
|
|
54194
|
+
current = pending;
|
|
54195
|
+
const out2 = [];
|
|
54196
|
+
const err = [];
|
|
54197
|
+
return new Promise((resolve53) => {
|
|
54198
|
+
let answered = false;
|
|
54199
|
+
const answer = () => {
|
|
54200
|
+
if (answered) return;
|
|
54201
|
+
answered = true;
|
|
54202
|
+
resolve53(current);
|
|
54203
|
+
};
|
|
54204
|
+
let child;
|
|
54205
|
+
try {
|
|
54206
|
+
child = deps.spawn(self.cmd, args, { stdio: ["ignore", "pipe", "pipe"], env: { ...process.env, HIMI_NO_UPDATE_CHECK: "1" } });
|
|
54207
|
+
} catch (e) {
|
|
54208
|
+
current = { state: "failed", error: `could not start himi login: ${e.message}` };
|
|
54209
|
+
answer();
|
|
54210
|
+
return;
|
|
54211
|
+
}
|
|
54212
|
+
child.stdout?.on("data", (c) => out2.push(String(c)));
|
|
54213
|
+
child.stderr?.on("data", (c) => {
|
|
54214
|
+
err.push(String(c));
|
|
54215
|
+
const link = LINK2.exec(err.join(""))?.[0];
|
|
54216
|
+
if (link && !pending.loginUrl && current === pending) {
|
|
54217
|
+
pending.loginUrl = link;
|
|
54218
|
+
answer();
|
|
54219
|
+
}
|
|
54220
|
+
});
|
|
54221
|
+
child.once("error", (e) => {
|
|
54222
|
+
current = { state: "failed", error: `could not start himi login: ${e.message}` };
|
|
54223
|
+
answer();
|
|
54224
|
+
});
|
|
54225
|
+
child.once("exit", (code) => {
|
|
54226
|
+
if (code === 0) {
|
|
54227
|
+
const r = lastJson([out2.join("")]) ?? {};
|
|
54228
|
+
current = { state: "signed_in", account: r.sub, scope: r.scope, expiresAt: r.exp };
|
|
54229
|
+
signedInTarget = target;
|
|
54230
|
+
} else {
|
|
54231
|
+
const e = lastJson(err.join("").split("\n"));
|
|
54232
|
+
current = { state: "failed", error: e?.error ?? (err.join("").trim().slice(-500) || `himi login exited ${code}`) };
|
|
54233
|
+
}
|
|
54234
|
+
answer();
|
|
54235
|
+
});
|
|
54236
|
+
setTimeout(answer, deps.linkWaitMs ?? 5e3).unref?.();
|
|
54237
|
+
});
|
|
54238
|
+
}
|
|
54239
|
+
};
|
|
54240
|
+
}
|
|
54241
|
+
var defaultLoginDeps, LINK2;
|
|
54242
|
+
var init_login = __esm({
|
|
54243
|
+
"src/mcp/login.ts"() {
|
|
54244
|
+
init_cli_bridge();
|
|
54245
|
+
defaultLoginDeps = {
|
|
54246
|
+
spawn: (cmd, args, opts) => nodeSpawn2(cmd, args, opts),
|
|
54247
|
+
now: () => Date.now()
|
|
54248
|
+
};
|
|
54249
|
+
LINK2 = /https?:\/\/[^\s)]+/;
|
|
54138
54250
|
}
|
|
54139
54251
|
});
|
|
54140
54252
|
|
|
@@ -54199,7 +54311,8 @@ async function startMcpServer(opts) {
|
|
|
54199
54311
|
status: (dir) => previewStatus(dir, previewDeps),
|
|
54200
54312
|
stop: (dir) => stopPreview(dir, previewDeps)
|
|
54201
54313
|
},
|
|
54202
|
-
readFile: (p) => readFileSync59(p)
|
|
54314
|
+
readFile: (p) => readFileSync59(p),
|
|
54315
|
+
login: createLoginSession({ ...defaultLoginDeps, selfCommand: previewDeps.selfCommand, ...opts.login })
|
|
54203
54316
|
};
|
|
54204
54317
|
const closed = new Promise((resolve53) => {
|
|
54205
54318
|
stdin.once("end", resolve53);
|
|
@@ -54221,6 +54334,7 @@ var init_server = __esm({
|
|
|
54221
54334
|
init_cli_bridge();
|
|
54222
54335
|
init_tools();
|
|
54223
54336
|
init_preview();
|
|
54337
|
+
init_login();
|
|
54224
54338
|
SERVER_INSTRUCTIONS = "himi builds native mobile apps (iOS + Android + web) from a content package: SDUI descriptors plus Tier-5 JS workers. The loop: himi_docs (read `headless-loop` first) \u2192 edit files \u2192 himi_validate \u2192 himi_test \u2192 himi_render (show the owner the PNG) \u2192 himi_preview_start (live preview in your IDE's browser) \u2192 himi_push (a DRAFT the owner opens in Himi Player; never live). Tools act on the workspace root unless given `dir`.";
|
|
54225
54339
|
}
|
|
54226
54340
|
});
|
|
@@ -71944,7 +72058,7 @@ var COMMANDS = [
|
|
|
71944
72058
|
{ name: "pull", summary: "restore an app's SOURCE from the serve plane into an editable content package \u2014 the other half of `himi push`, which archives the content package on every publish. Owner or editor only: a viewer may download the RUNNING app (`/v1/owner/package`), not the codebase it was built from. A PAST release is restorable, not only the live one \u2014 the archive is content-addressed per release, so it has none of the live-single-slot problem that makes `himi pack` current-release-only. Two limits: pruning keeps the current release plus the newest ~20 ledger entries, and a release id identifies OTA content rather than source, so a source-only change republishes under the same id and replaces that id's archive. A release published before source archiving shipped, or pushed with `--no-source`, answers `app_source_not_found` and says to push again. `--name` re-substitutes the app identity through the same machinery `himi init --template` uses, so the restored tree is a NEW app rather than a second copy of the same one, and a name that also appears inside a screen id (`feed` in `feed_home`) is left alone. A NON-EMPTY destination is refused unless you say which you mean: `--force` merges and reports \u2014 it writes the archive over what is there, keeps files the release does not carry, and NAMES every one of them as `left: [...]` so a tree that matches no release is never silent (#2437); `--replace` restores exactly what was archived, removing those files first (`removed: [...]`) and implying `--force`. `--replace` refuses a directory holding no `himalaya.content.json`, so a mistyped `--out` cannot clear an unrelated tree, and the only paths it can remove are the ones a push would have archived \u2014 `.git/`, `node_modules/`, `dist/`, `.env*` and key material are out of its reach by construction.", required: "<app> [--release <id>] [--out <dir>] [--name <new>] [--force|--replace] [--target <t>]" },
|
|
71945
72059
|
{ name: "share", summary: "publish or revoke a content-addressed `.himi` share link. The package must be a validated archive for an already-published release; the resulting https URL is safe to QR, copy, or open in Himi Player.", required: "--file <package.himi> [--expires-at <ISO>] | revoke --app <app> <shareId>" },
|
|
71946
72060
|
{ name: "run", summary: "serve a .himi package on localhost and open it in a browser \u2014 no serve plane, no dev-server, no setup. Given no argument it builds the current content package first, so `himi run` is the inner loop: edit, run, look at it. The SPA and /v1 are served from ONE origin because Tier-5 bundle fetches on web are same-origin-only. --chrome preview frames the app in a device chassis; --chrome app serves it as a plain web app. Blocks until Ctrl-C, like any dev server. --browser runs the whole plane INSIDE the tab (service worker + in-memory store) so no app code executes in this process or on any pod. --lan also serves it to the local network and prints a QR, so a phone on the same Wi-Fi opens it as the real app, full screen. --watch keeps the preview LIVE: every save in the content package rebuilds it and repaints the open tab with only what changed (the dev-server's hot-reload events); a build that fails keeps the last good preview on screen and says why. --idle-exit <min> (with --watch only) stops the watch once that many minutes pass with no source save, printing `{\"watch\":\"idle_exit\"}` and removing its .himi/run.json on the way out \u2014 the watch `himi init` starts passes 30; one started by hand runs until Ctrl-C. Stopping (Ctrl-C, SIGTERM, SIGHUP or the idle exit) removes the run's own .himi/run.json. Any `himi run` of a content package (plain, --watch or --browser) frames its preview on the build board (`himi studio`) while it serves, and all but --browser also serve that board at /__himi/studio/ on the preview's own origin. Its .himi/run.json (pid, watching) is also how `himi render` and `himi test` tell a live --watch is running: while none is, they add a `reminder` naming `himi run --watch --content <dir> &`, and while one is (the one `himi init` started, usually, whose .himi/watch.json vouches for it until it serves) the reminder names its url and board instead (either at most once every ten minutes per app) \u2014 first in `next[]` and again as the envelope's LAST key (the last line of `himi test`'s plain report), so an output read with `tail` still carries it.", required: "[<package.himi|dir|url>] [--browser] [--watch] [--idle-exit <min>] [--lan] [--content <dir>] [--port <n>] [--chrome preview|app] [--screen <id>] [--surface <id>] [--no-open] [--spa <url>]" },
|
|
71947
|
-
{ name: "mcp", summary: "run the himi tools as a local Model Context Protocol server over stdio, for coding agents \u2014 Claude Code, Cursor, Codex, VS Code. Tools: docs/components/sdk/icons, init, build, validate, test (hermetic), render (returns the PNG), progress, a live preview (start/status/stop a `himi run --watch`), whoami, and DRAFT-only push/share/preview links \u2014 never promote,
|
|
72061
|
+
{ name: "mcp", summary: "run the himi tools as a local Model Context Protocol server over stdio, for coding agents \u2014 Claude Code, Cursor, Codex, VS Code. Tools: docs/components/sdk/icons, init, build, validate, test (hermetic), render (returns the PNG), progress, a live preview (start/status/stop a `himi run --watch`), whoami, login (opens the browser sign-in for the user; the credential goes to a child `himi login` and onto disk, never through the server), and DRAFT-only push/share/preview links \u2014 never promote, dist or secrets. A sign-in's target is the one push/share then use. Each tool runs the same command in-process on the content package on disk (default: the host's workspace root). `himi init` and `himi agent-init` write the config for every host (.mcp.json, .cursor/mcp.json, .vscode/mcp.json, .codex/config.toml when absent) plus a `himi-preview` launch configuration (.claude/launch.json) that opens the live preview in Claude Code desktop's browser pane. Never self-updates (npx already runs the current CLI). Blocks until the host closes stdin. `himi mcp plugin --out <dir>` writes the Claude Code plugin (the customer skill + this server) as a folder \u2014 the same plugin the serve plane's marketplace hands out at /.claude-plugin/marketplace.json.", required: "[plugin --out <dir>]" },
|
|
71948
72062
|
{ name: "preview", summary: "print the shareable web URL + himi:// deep link + agent /v1/preview JSON URLs for an app+release; --surface frames the web preview as any catalog surface (?surface=)", required: "--app --release [--screen] [--surface]" },
|
|
71949
72063
|
{ name: "surfaces", summary: "the surface catalog vs this app's envelope (platforms.json): targeted surfaces, the opt-in key for the rest, per-surface preview links with --app --release, and which widget families the package produces with --measure-widgets (which runs its built bundles)", required: "[--content <dir>] [--app --release] [--measure-widgets]" },
|
|
71950
72064
|
{ name: "context", summary: "fetch the agent preview envelope (GET /v1/preview/a/<app>) \u2014 ok/issues/screens/links; exit 1 if ok:false", required: "--app --release [--screen] [--include telemetry]" },
|
package/guides/himi-mcp.md
CHANGED
|
@@ -74,16 +74,19 @@ runs a session with it.
|
|
|
74
74
|
| `himi_progress` | Read or add to the build journal the owner follows. |
|
|
75
75
|
| `himi_preview_start` / `_status` / `_stop` | The live preview — see below. |
|
|
76
76
|
| `himi_whoami` | Which account the stored sign-in belongs to. |
|
|
77
|
+
| `himi_login` | Open a browser window where the user signs in to Wix, so publishing works with no terminal. It returns the sign-in link at once; call it again to see whether the sign-in finished. |
|
|
77
78
|
| `himi_push` | Publish a **draft**: private to the owner, viewable by preview link and in Himi Player, not live. |
|
|
78
79
|
| `himi_share`, `himi_preview_links` | Share links for a published release. |
|
|
79
80
|
|
|
80
81
|
Each tool acts on the agent's workspace folder unless it is given a `dir`.
|
|
81
82
|
|
|
82
|
-
**What the tools will not do:**
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
`himi login --browser` in a terminal
|
|
86
|
-
|
|
83
|
+
**What the tools will not do:** make a release live, build store binaries, touch secrets, write to a
|
|
84
|
+
site's CMS, or create a Wix site. Those spend money, handle credentials, or change what real users
|
|
85
|
+
see, so they stay commands a person runs. Publishing needs a sign-in first: `himi_login` opens the
|
|
86
|
+
browser sign-in for the user, or run `himi login --browser` in a terminal. Either way the server
|
|
87
|
+
never asks for or sees a credential — the browser hands a scoped token to a separate `himi login`
|
|
88
|
+
process, which stores it on this machine. A tool input that starts with `-` is refused, so nothing
|
|
89
|
+
can be passed through to a flag no tool offers.
|
|
87
90
|
|
|
88
91
|
## See the app inside your IDE
|
|
89
92
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1114.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": "0577b42d47b1e8019d8e91a63ef760878990ad8500fc4c7deec84f83"
|
|
71
71
|
}
|