@mmapp/react-compiler 0.1.0-alpha.11 → 0.1.0-alpha.13

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/index.js CHANGED
@@ -10805,6 +10805,10 @@ async function build(options = {}) {
10805
10805
  definitions: [],
10806
10806
  errorDetails: typeErrors
10807
10807
  };
10808
+ } else if (output.includes("not the tsc command") || output.includes("Cannot find module") || output.includes("ERR_MODULE_NOT_FOUND") || output.includes("command not found")) {
10809
+ console.warn(`[mindmatrix-react] TypeScript not installed \u2014 skipping type check.`);
10810
+ console.warn(` Run \`npm install\` to enable type checking, or use --skip-type-check.
10811
+ `);
10808
10812
  } else {
10809
10813
  console.error(`
10810
10814
  [mindmatrix-react] Type check failed:
@@ -14230,8 +14234,8 @@ function saveCredentials(apiUrl, token) {
14230
14234
  creds[apiUrl] = { token, savedAt: (/* @__PURE__ */ new Date()).toISOString() };
14231
14235
  (0, import_fs5.writeFileSync)(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), "utf-8");
14232
14236
  try {
14233
- const { chmodSync } = require("fs");
14234
- chmodSync(CREDENTIALS_PATH, 384);
14237
+ const { chmodSync: chmodSync2 } = require("fs");
14238
+ chmodSync2(CREDENTIALS_PATH, 384);
14235
14239
  } catch {
14236
14240
  }
14237
14241
  }
@@ -14259,7 +14263,7 @@ function resolveToken(apiUrl, explicitToken) {
14259
14263
  return null;
14260
14264
  }
14261
14265
  function prompt(question, hidden = false) {
14262
- return new Promise((resolve6) => {
14266
+ return new Promise((resolve7) => {
14263
14267
  const rl = (0, import_readline.createInterface)({
14264
14268
  input: process.stdin,
14265
14269
  output: process.stdout
@@ -14279,12 +14283,12 @@ function prompt(question, hidden = false) {
14279
14283
  process.stdout.write = origWrite;
14280
14284
  console.log();
14281
14285
  rl.close();
14282
- resolve6(answer.trim());
14286
+ resolve7(answer.trim());
14283
14287
  });
14284
14288
  } else {
14285
14289
  rl.question(question, (answer) => {
14286
14290
  rl.close();
14287
- resolve6(answer.trim());
14291
+ resolve7(answer.trim());
14288
14292
  });
14289
14293
  }
14290
14294
  });
@@ -14370,6 +14374,465 @@ var init_auth = __esm({
14370
14374
  }
14371
14375
  });
14372
14376
 
14377
+ // src/cli/engine-binary.ts
14378
+ var engine_binary_exports = {};
14379
+ __export(engine_binary_exports, {
14380
+ GITHUB_RELEASE_BASE: () => GITHUB_RELEASE_BASE,
14381
+ MANAGED_BINARY_PATH: () => MANAGED_BINARY_PATH,
14382
+ METADATA_PATH: () => METADATA_PATH,
14383
+ VERSION_FILE_PATH: () => VERSION_FILE_PATH,
14384
+ askUser: () => askUser,
14385
+ buildDownloadUrl: () => buildDownloadUrl,
14386
+ buildFromSource: () => buildFromSource,
14387
+ detectPlatform: () => detectPlatform,
14388
+ downloadBinary: () => downloadBinary,
14389
+ ensureEngineBinary: () => ensureEngineBinary,
14390
+ findEngineBinary: () => findEngineBinary,
14391
+ getCachedVersion: () => getCachedVersion,
14392
+ getEngineStatus: () => getEngineStatus,
14393
+ hasCargoInstalled: () => hasCargoInstalled,
14394
+ healthCheck: () => healthCheck,
14395
+ installEngine: () => installEngine,
14396
+ printInstallGuide: () => printInstallGuide,
14397
+ readMetadata: () => readMetadata,
14398
+ requireEngineBinary: () => requireEngineBinary,
14399
+ setCachedVersion: () => setCachedVersion,
14400
+ verifyBinary: () => verifyBinary,
14401
+ writeMetadata: () => writeMetadata
14402
+ });
14403
+ function detectPlatform() {
14404
+ const os = (0, import_os2.platform)();
14405
+ const a = (0, import_os2.arch)();
14406
+ let triple;
14407
+ let releasePlatform = null;
14408
+ if (os === "linux" && a === "x64") {
14409
+ triple = "x86_64-unknown-linux-gnu";
14410
+ releasePlatform = "linux-x64";
14411
+ } else if (os === "linux" && a === "arm64") {
14412
+ triple = "aarch64-unknown-linux-gnu";
14413
+ releasePlatform = "linux-arm64";
14414
+ } else if (os === "darwin" && a === "x64") {
14415
+ triple = "x86_64-apple-darwin";
14416
+ releasePlatform = "darwin-x64";
14417
+ } else if (os === "darwin" && a === "arm64") {
14418
+ triple = "aarch64-apple-darwin";
14419
+ releasePlatform = "darwin-arm64";
14420
+ } else if (os === "win32" && a === "x64") {
14421
+ triple = "x86_64-pc-windows-msvc";
14422
+ releasePlatform = "windows-x64";
14423
+ } else {
14424
+ triple = `${a}-unknown-${os}`;
14425
+ }
14426
+ return { os, arch: a, triple, releasePlatform };
14427
+ }
14428
+ function getCachedVersion() {
14429
+ try {
14430
+ if ((0, import_fs6.existsSync)(VERSION_FILE_PATH)) {
14431
+ return (0, import_fs6.readFileSync)(VERSION_FILE_PATH, "utf-8").trim();
14432
+ }
14433
+ } catch {
14434
+ }
14435
+ return null;
14436
+ }
14437
+ function setCachedVersion(version) {
14438
+ (0, import_fs6.mkdirSync)(MMRC_BIN_DIR, { recursive: true });
14439
+ (0, import_fs6.writeFileSync)(VERSION_FILE_PATH, version, "utf-8");
14440
+ }
14441
+ function readMetadata() {
14442
+ try {
14443
+ if (!(0, import_fs6.existsSync)(METADATA_PATH)) return null;
14444
+ return JSON.parse((0, import_fs6.readFileSync)(METADATA_PATH, "utf-8"));
14445
+ } catch {
14446
+ return null;
14447
+ }
14448
+ }
14449
+ function writeMetadata(meta) {
14450
+ (0, import_fs6.mkdirSync)(MMRC_BIN_DIR, { recursive: true });
14451
+ (0, import_fs6.writeFileSync)(METADATA_PATH, JSON.stringify(meta, null, 2), "utf-8");
14452
+ }
14453
+ async function verifyBinary(binaryPath) {
14454
+ if (!(0, import_fs6.existsSync)(binaryPath)) {
14455
+ return { ok: false, error: `Binary not found at ${binaryPath}` };
14456
+ }
14457
+ return new Promise((resolve7) => {
14458
+ try {
14459
+ const proc = (0, import_child_process2.spawn)(binaryPath, ["--version"], {
14460
+ stdio: ["ignore", "pipe", "pipe"],
14461
+ timeout: 1e4
14462
+ });
14463
+ let stdout = "";
14464
+ let stderr = "";
14465
+ proc.stdout?.on("data", (d) => {
14466
+ stdout += d.toString();
14467
+ });
14468
+ proc.stderr?.on("data", (d) => {
14469
+ stderr += d.toString();
14470
+ });
14471
+ proc.on("error", (err) => {
14472
+ resolve7({ ok: false, error: `Failed to execute: ${err.message}` });
14473
+ });
14474
+ proc.on("close", (code) => {
14475
+ if (code === 0) {
14476
+ const output = stdout.trim() || stderr.trim();
14477
+ const version = output.replace(/^mm[-_](?:server|api)\s*/i, "").trim() || "unknown";
14478
+ resolve7({ ok: true, version });
14479
+ } else {
14480
+ resolve7({ ok: false, error: `Exited with code ${code}. ${stderr.trim()}` });
14481
+ }
14482
+ });
14483
+ } catch (e) {
14484
+ resolve7({ ok: false, error: `Spawn failed: ${e instanceof Error ? e.message : String(e)}` });
14485
+ }
14486
+ });
14487
+ }
14488
+ async function healthCheck(url, timeoutMs = 5e3) {
14489
+ try {
14490
+ const resp = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) });
14491
+ if (resp.ok) {
14492
+ const data = await resp.json();
14493
+ return { ok: true, version: data.version, db: data.database };
14494
+ }
14495
+ return { ok: resp.status < 500 };
14496
+ } catch {
14497
+ return { ok: false };
14498
+ }
14499
+ }
14500
+ async function getEngineStatus(explicitPath) {
14501
+ const plat = detectPlatform();
14502
+ const resolution = findEngineBinary(explicitPath);
14503
+ const meta = readMetadata();
14504
+ let version = null;
14505
+ let verified = false;
14506
+ if (resolution.path) {
14507
+ const verify2 = await verifyBinary(resolution.path);
14508
+ if (verify2.ok) {
14509
+ version = verify2.version ?? null;
14510
+ verified = true;
14511
+ }
14512
+ }
14513
+ return {
14514
+ installed: resolution.path !== null,
14515
+ path: resolution.path,
14516
+ source: resolution.source,
14517
+ version,
14518
+ platform: plat,
14519
+ metadata: meta,
14520
+ verified
14521
+ };
14522
+ }
14523
+ async function installEngine(options) {
14524
+ const { force = false, preferBuild = false, version = "latest", cwd, prompt: prompt2, fetch: fetchFn } = options ?? {};
14525
+ const plat = detectPlatform();
14526
+ if (!force && (0, import_fs6.existsSync)(MANAGED_BINARY_PATH)) {
14527
+ const meta = readMetadata();
14528
+ if (meta?.verified) {
14529
+ console.error(`[mmrc] Found cached binary (${meta.version}, ${meta.platform})`);
14530
+ }
14531
+ const verify2 = await verifyBinary(MANAGED_BINARY_PATH);
14532
+ if (verify2.ok) {
14533
+ console.error(`[mmrc] Cached binary verified: ${verify2.version}`);
14534
+ return { path: MANAGED_BINARY_PATH, source: "managed" };
14535
+ }
14536
+ console.error("[mmrc] Cached binary failed verification \u2014 reinstalling.");
14537
+ }
14538
+ if (preferBuild) {
14539
+ return await installViaBuild(plat, version, cwd, prompt2);
14540
+ }
14541
+ if (plat.releasePlatform) {
14542
+ const dl = await downloadBinary({ version, platform: plat.releasePlatform, fetch: fetchFn });
14543
+ if (dl.success) {
14544
+ console.error("[mmrc] Verifying downloaded binary...");
14545
+ const verify2 = await verifyBinary(dl.path);
14546
+ if (verify2.ok) {
14547
+ console.error(`[mmrc] Verification passed: ${verify2.version}`);
14548
+ writeMetadata({
14549
+ version: verify2.version ?? version,
14550
+ platform: plat.releasePlatform,
14551
+ triple: plat.triple,
14552
+ downloadedAt: (/* @__PURE__ */ new Date()).toISOString(),
14553
+ verified: true,
14554
+ source: "download",
14555
+ path: dl.path
14556
+ });
14557
+ return { path: dl.path, source: "downloaded" };
14558
+ }
14559
+ console.error(`[mmrc] Binary verification FAILED: ${verify2.error}`);
14560
+ console.error("");
14561
+ console.error(` Platform: ${plat.releasePlatform} (${plat.triple})`);
14562
+ console.error(" This usually means:");
14563
+ console.error(" - Wrong architecture (e.g., ARM binary on x86)");
14564
+ console.error(" - Missing shared libraries (try: ldd " + dl.path + ")");
14565
+ console.error(" - Glibc version mismatch");
14566
+ console.error("");
14567
+ console.error("[mmrc] Falling back to build from source...\n");
14568
+ } else {
14569
+ console.error(`[mmrc] Download failed: ${dl.error}`);
14570
+ }
14571
+ } else {
14572
+ console.error(`[mmrc] No pre-built binary for ${plat.os}/${plat.arch}.`);
14573
+ }
14574
+ return await installViaBuild(plat, version, cwd, prompt2);
14575
+ }
14576
+ async function installViaBuild(plat, version, cwd, prompt2) {
14577
+ if (!hasCargoInstalled()) {
14578
+ console.error("[mmrc] Rust toolchain not found (cargo not in PATH).");
14579
+ console.error("");
14580
+ if ((0, import_os2.platform)() === "win32") {
14581
+ console.error(" Install Rust from https://rustup.rs");
14582
+ } else {
14583
+ console.error(" Install Rust:");
14584
+ console.error(' curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh');
14585
+ }
14586
+ console.error("");
14587
+ console.error(" Then restart your shell and run: mmrc engine build");
14588
+ return { path: null, source: "not-found" };
14589
+ }
14590
+ const built = await buildFromSource({ cwd, prompt: prompt2 });
14591
+ if (!built) return { path: null, source: "not-found" };
14592
+ console.error("[mmrc] Verifying built binary...");
14593
+ const verify2 = await verifyBinary(built);
14594
+ if (verify2.ok) {
14595
+ console.error(`[mmrc] Build verified: ${verify2.version}`);
14596
+ writeMetadata({
14597
+ version: verify2.version ?? version,
14598
+ platform: plat.releasePlatform ?? `${plat.os}-${plat.arch}`,
14599
+ triple: plat.triple,
14600
+ downloadedAt: (/* @__PURE__ */ new Date()).toISOString(),
14601
+ verified: true,
14602
+ source: "build",
14603
+ path: built
14604
+ });
14605
+ return { path: built, source: "built" };
14606
+ }
14607
+ console.error(`[mmrc] Built binary also failed verification: ${verify2.error}`);
14608
+ return { path: null, source: "not-found" };
14609
+ }
14610
+ function buildDownloadUrl(version, releasePlatform) {
14611
+ const tag = version.startsWith("v") ? version : `v${version}`;
14612
+ return `${GITHUB_RELEASE_BASE}/${tag}/mm-api-${releasePlatform}`;
14613
+ }
14614
+ async function downloadBinary(options) {
14615
+ const plat = options.platform ?? detectPlatform().releasePlatform;
14616
+ const dest = options.dest ?? MANAGED_BINARY_PATH;
14617
+ const fetchFn = options.fetch ?? globalThis.fetch;
14618
+ if (!plat) {
14619
+ return { success: false, path: dest, error: "Unsupported platform for pre-built binaries" };
14620
+ }
14621
+ const url = buildDownloadUrl(options.version, plat);
14622
+ console.error(`[mmrc] Downloading mm-api ${options.version} for ${plat}...`);
14623
+ console.error(`[mmrc] ${url}`);
14624
+ try {
14625
+ const response = await fetchFn(url, { redirect: "follow" });
14626
+ if (!response.ok) {
14627
+ return {
14628
+ success: false,
14629
+ path: dest,
14630
+ error: `HTTP ${response.status}: ${response.statusText} (${url})`
14631
+ };
14632
+ }
14633
+ (0, import_fs6.mkdirSync)(MMRC_BIN_DIR, { recursive: true });
14634
+ const body = response.body;
14635
+ if (!body) {
14636
+ return { success: false, path: dest, error: "Empty response body" };
14637
+ }
14638
+ const fileStream = (0, import_fs6.createWriteStream)(dest);
14639
+ await (0, import_promises.pipeline)(body, fileStream);
14640
+ (0, import_fs6.chmodSync)(dest, 493);
14641
+ setCachedVersion(options.version);
14642
+ console.error(`[mmrc] Downloaded to ${dest}`);
14643
+ return { success: true, path: dest };
14644
+ } catch (err) {
14645
+ const message = err instanceof Error ? err.message : String(err);
14646
+ return { success: false, path: dest, error: message };
14647
+ }
14648
+ }
14649
+ function hasCargoInstalled() {
14650
+ try {
14651
+ (0, import_child_process2.execSync)("cargo --version", { encoding: "utf-8", timeout: 5e3, stdio: "pipe" });
14652
+ return true;
14653
+ } catch {
14654
+ return false;
14655
+ }
14656
+ }
14657
+ async function askUser(question) {
14658
+ const readline = require("readline");
14659
+ const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
14660
+ return new Promise((resolve7) => {
14661
+ rl.question(question, (answer) => {
14662
+ rl.close();
14663
+ resolve7(answer.trim().toLowerCase());
14664
+ });
14665
+ });
14666
+ }
14667
+ async function buildFromSource(options) {
14668
+ const promptFn = options?.prompt ?? askUser;
14669
+ const cwd = options?.cwd ?? process.cwd();
14670
+ if (hasCargoInstalled()) {
14671
+ const answer = await promptFn("[mmrc] No pre-built binary available. Build from source? (y/n) ");
14672
+ if (answer !== "y" && answer !== "yes") return null;
14673
+ } else {
14674
+ const answer = await promptFn(
14675
+ "[mmrc] No pre-built binary available and Rust is not installed.\n Install Rust and build from source? (y/n) "
14676
+ );
14677
+ if (answer !== "y" && answer !== "yes") return null;
14678
+ console.error("[mmrc] Installing Rust via rustup...");
14679
+ try {
14680
+ (0, import_child_process2.execSync)('curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y', {
14681
+ stdio: "inherit",
14682
+ cwd,
14683
+ timeout: 3e5
14684
+ });
14685
+ const cargoEnv = (0, import_path5.join)((0, import_os2.homedir)(), ".cargo", "env");
14686
+ if ((0, import_fs6.existsSync)(cargoEnv)) {
14687
+ (0, import_child_process2.execSync)(`. ${cargoEnv}`, { stdio: "pipe" });
14688
+ }
14689
+ } catch (err) {
14690
+ console.error("[mmrc] Failed to install Rust:", err instanceof Error ? err.message : err);
14691
+ return null;
14692
+ }
14693
+ }
14694
+ console.error("[mmrc] Building mm-api from source (this may take a few minutes)...");
14695
+ try {
14696
+ (0, import_child_process2.execSync)("cargo build --release -p mm-api", {
14697
+ stdio: "inherit",
14698
+ cwd,
14699
+ timeout: 6e5
14700
+ });
14701
+ } catch (err) {
14702
+ console.error("[mmrc] Build failed:", err instanceof Error ? err.message : err);
14703
+ return null;
14704
+ }
14705
+ const candidates = [
14706
+ (0, import_path5.join)(cwd, "mm-core", "target", "release", "mm-server"),
14707
+ (0, import_path5.join)(cwd, "target", "release", "mm-server")
14708
+ ];
14709
+ for (const p of candidates) {
14710
+ if ((0, import_fs6.existsSync)(p)) {
14711
+ (0, import_fs6.mkdirSync)(MMRC_BIN_DIR, { recursive: true });
14712
+ (0, import_fs6.copyFileSync)(p, MANAGED_BINARY_PATH);
14713
+ (0, import_fs6.chmodSync)(MANAGED_BINARY_PATH, 493);
14714
+ console.error(`[mmrc] Installed to ${MANAGED_BINARY_PATH}`);
14715
+ return MANAGED_BINARY_PATH;
14716
+ }
14717
+ }
14718
+ console.error("[mmrc] Build completed but binary not found in expected locations.");
14719
+ return null;
14720
+ }
14721
+ function findEngineBinary(explicitPath, cwd) {
14722
+ const workDir = cwd ?? process.cwd();
14723
+ if (explicitPath) {
14724
+ if ((0, import_fs6.existsSync)(explicitPath)) {
14725
+ return { path: explicitPath, source: "explicit" };
14726
+ }
14727
+ return { path: null, source: "not-found" };
14728
+ }
14729
+ if ((0, import_fs6.existsSync)(MANAGED_BINARY_PATH)) {
14730
+ return { path: MANAGED_BINARY_PATH, source: "managed" };
14731
+ }
14732
+ for (const rel of PROJECT_SEARCH_PATHS) {
14733
+ const abs = (0, import_path5.resolve)(workDir, rel);
14734
+ if ((0, import_fs6.existsSync)(abs)) {
14735
+ return { path: abs, source: "project" };
14736
+ }
14737
+ }
14738
+ try {
14739
+ const cmd = (0, import_os2.platform)() === "win32" ? "where mm-server 2>nul || where mm-api 2>nul" : "which mm-server 2>/dev/null || which mm-api 2>/dev/null";
14740
+ const result = (0, import_child_process2.execSync)(cmd, { encoding: "utf-8", timeout: 5e3 }).trim();
14741
+ if (result) {
14742
+ return { path: result.split("\n")[0], source: "path" };
14743
+ }
14744
+ } catch {
14745
+ }
14746
+ return { path: null, source: "not-found" };
14747
+ }
14748
+ async function ensureEngineBinary(options) {
14749
+ const found = findEngineBinary(options?.explicitPath, options?.cwd);
14750
+ if (found.path) return found;
14751
+ const plat = detectPlatform();
14752
+ const version = options?.version ?? "latest";
14753
+ if (plat.releasePlatform) {
14754
+ const result = await downloadBinary({
14755
+ version,
14756
+ platform: plat.releasePlatform,
14757
+ fetch: options?.fetch
14758
+ });
14759
+ if (result.success) {
14760
+ return { path: result.path, source: "downloaded" };
14761
+ }
14762
+ console.error(`[mmrc] Download failed: ${result.error}`);
14763
+ } else {
14764
+ console.error(`[mmrc] No pre-built binary for ${plat.os}/${plat.arch}`);
14765
+ }
14766
+ if (!options?.nonInteractive) {
14767
+ const built = await buildFromSource({
14768
+ prompt: options?.prompt,
14769
+ cwd: options?.cwd
14770
+ });
14771
+ if (built) {
14772
+ return { path: built, source: "built" };
14773
+ }
14774
+ }
14775
+ return { path: null, source: "not-found" };
14776
+ }
14777
+ function printInstallGuide() {
14778
+ const plat = detectPlatform();
14779
+ console.error("[mmrc] MindMatrix engine binary not found.\n");
14780
+ console.error("The engine binary (mm-api) is required for local development.");
14781
+ console.error("Choose one of the following options:\n");
14782
+ console.error(" 1. Auto-download (recommended):");
14783
+ console.error(" mmrc dev # auto-downloads the binary");
14784
+ console.error("");
14785
+ console.error(" 2. Build from source (requires Rust toolchain):");
14786
+ console.error(' curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh');
14787
+ console.error(" cargo build --release -p mm-api");
14788
+ console.error("");
14789
+ console.error(" 3. Download manually:");
14790
+ if (plat.releasePlatform) {
14791
+ console.error(` curl -L -o ~/.mmrc/bin/mm-api \\`);
14792
+ console.error(` ${GITHUB_RELEASE_BASE}/v0.1.0/mm-api-${plat.releasePlatform}`);
14793
+ console.error(` chmod +x ~/.mmrc/bin/mm-api`);
14794
+ } else {
14795
+ console.error(` # No pre-built binary for ${plat.triple} \u2014 build from source`);
14796
+ }
14797
+ console.error("");
14798
+ console.error(" 4. Use a remote backend instead of local:");
14799
+ console.error(" mmrc dev --api-url https://dev.mindmatrix.club/api/v1");
14800
+ console.error("");
14801
+ }
14802
+ function requireEngineBinary(explicitPath) {
14803
+ const result = findEngineBinary(explicitPath);
14804
+ if (!result.path) {
14805
+ printInstallGuide();
14806
+ process.exit(1);
14807
+ }
14808
+ return result.path;
14809
+ }
14810
+ var import_fs6, import_path5, import_os2, import_promises, import_child_process2, MMRC_BIN_DIR, BINARY_NAME, MANAGED_BINARY_PATH, VERSION_FILE_PATH, METADATA_PATH, GITHUB_RELEASE_BASE, PROJECT_SEARCH_PATHS;
14811
+ var init_engine_binary = __esm({
14812
+ "src/cli/engine-binary.ts"() {
14813
+ "use strict";
14814
+ import_fs6 = require("fs");
14815
+ import_path5 = require("path");
14816
+ import_os2 = require("os");
14817
+ import_promises = require("stream/promises");
14818
+ import_child_process2 = require("child_process");
14819
+ MMRC_BIN_DIR = (0, import_path5.join)((0, import_os2.homedir)(), ".mmrc", "bin");
14820
+ BINARY_NAME = (0, import_os2.platform)() === "win32" ? "mm-api.exe" : "mm-api";
14821
+ MANAGED_BINARY_PATH = (0, import_path5.join)(MMRC_BIN_DIR, BINARY_NAME);
14822
+ VERSION_FILE_PATH = (0, import_path5.join)(MMRC_BIN_DIR, "mm-api.version");
14823
+ METADATA_PATH = (0, import_path5.join)(MMRC_BIN_DIR, "mm-api.json");
14824
+ GITHUB_RELEASE_BASE = "https://github.com/dev-nested/mm-app/releases/download";
14825
+ PROJECT_SEARCH_PATHS = [
14826
+ "engine/target/release/mm-server",
14827
+ "engine/target/debug/mm-server",
14828
+ "mm-core/target/release/mm-server",
14829
+ "mm-core/target/debug/mm-server",
14830
+ "target/release/mm-server",
14831
+ "target/debug/mm-server"
14832
+ ];
14833
+ }
14834
+ });
14835
+
14373
14836
  // src/vite/index.ts
14374
14837
  function mindmatrixReact(options) {
14375
14838
  const include = options?.include ?? ["**/*.workflow.tsx"];
@@ -14402,7 +14865,7 @@ function mindmatrixReact(options) {
14402
14865
  experience: ir.experience || {},
14403
14866
  metadata: {
14404
14867
  ...ir.metadata || {},
14405
- source_file: (0, import_path5.relative)(process.cwd(), filePath),
14868
+ source_file: (0, import_path6.relative)(process.cwd(), filePath),
14406
14869
  compiled_at: (/* @__PURE__ */ new Date()).toISOString()
14407
14870
  }
14408
14871
  };
@@ -14462,7 +14925,7 @@ function mindmatrixReact(options) {
14462
14925
  parserOpts: { plugins: ["jsx", "typescript"] },
14463
14926
  sourceMaps: wantMaps,
14464
14927
  // Embed original source in the source map so debuggers can show .workflow.tsx
14465
- ...wantMaps ? { sourceFileName: (0, import_path5.basename)(id) } : {}
14928
+ ...wantMaps ? { sourceFileName: (0, import_path6.basename)(id) } : {}
14466
14929
  });
14467
14930
  if (!result?.code) return null;
14468
14931
  const metadata = result.metadata || {};
@@ -14471,25 +14934,25 @@ function mindmatrixReact(options) {
14471
14934
  const errors = metadata.mindmatrixErrors;
14472
14935
  if (warnings?.length) {
14473
14936
  for (const w of warnings) {
14474
- console.warn(`[mindmatrix-react] ${(0, import_path5.basename)(id)}: ${w.message}`);
14937
+ console.warn(`[mindmatrix-react] ${(0, import_path6.basename)(id)}: ${w.message}`);
14475
14938
  }
14476
14939
  }
14477
14940
  if (errors?.length) {
14478
14941
  for (const e of errors) {
14479
14942
  if (mode === "strict") {
14480
- this.error(`${(0, import_path5.basename)(id)}: ${e.message}`);
14943
+ this.error(`${(0, import_path6.basename)(id)}: ${e.message}`);
14481
14944
  } else {
14482
- this.warn(`${(0, import_path5.basename)(id)}: ${e.message}`);
14945
+ this.warn(`${(0, import_path6.basename)(id)}: ${e.message}`);
14483
14946
  }
14484
14947
  }
14485
14948
  }
14486
14949
  if (ir) {
14487
14950
  compiledFiles.set(id, ir);
14488
- const outputFileName = (0, import_path5.basename)(id).replace(/\.tsx?$/, ".workflow.json");
14489
- const outputPath = (0, import_path5.join)(process.cwd(), outDir, outputFileName);
14490
- (0, import_fs6.mkdirSync)((0, import_path5.dirname)(outputPath), { recursive: true });
14491
- (0, import_fs6.writeFileSync)(outputPath, JSON.stringify(ir, null, 2), "utf-8");
14492
- console.log(`[mindmatrix-react] Compiled ${(0, import_path5.basename)(id)} \u2192 ${outputFileName}`);
14951
+ const outputFileName = (0, import_path6.basename)(id).replace(/\.tsx?$/, ".workflow.json");
14952
+ const outputPath = (0, import_path6.join)(process.cwd(), outDir, outputFileName);
14953
+ (0, import_fs7.mkdirSync)((0, import_path6.dirname)(outputPath), { recursive: true });
14954
+ (0, import_fs7.writeFileSync)(outputPath, JSON.stringify(ir, null, 2), "utf-8");
14955
+ console.log(`[mindmatrix-react] Compiled ${(0, import_path6.basename)(id)} \u2192 ${outputFileName}`);
14493
14956
  seedToApi(ir, id);
14494
14957
  }
14495
14958
  if (!enableSourceAnnotations && ir) {
@@ -14502,16 +14965,16 @@ function mindmatrixReact(options) {
14502
14965
  } catch (error) {
14503
14966
  const msg = error instanceof Error ? error.message : String(error);
14504
14967
  if (mode === "strict") {
14505
- this.error(`Failed to compile ${(0, import_path5.basename)(id)}: ${msg}`);
14968
+ this.error(`Failed to compile ${(0, import_path6.basename)(id)}: ${msg}`);
14506
14969
  } else {
14507
- console.error(`[mindmatrix-react] Error compiling ${(0, import_path5.basename)(id)}:`, msg);
14970
+ console.error(`[mindmatrix-react] Error compiling ${(0, import_path6.basename)(id)}:`, msg);
14508
14971
  }
14509
14972
  return null;
14510
14973
  }
14511
14974
  },
14512
14975
  handleHotUpdate(ctx) {
14513
14976
  if (!shouldTransform(ctx.file)) return;
14514
- console.log(`[mindmatrix-react] HMR: ${(0, import_path5.basename)(ctx.file)} changed`);
14977
+ console.log(`[mindmatrix-react] HMR: ${(0, import_path6.basename)(ctx.file)} changed`);
14515
14978
  return void 0;
14516
14979
  }
14517
14980
  };
@@ -14534,13 +14997,13 @@ function stripSourceAnnotations(ir) {
14534
14997
  strip(ir.transitions);
14535
14998
  strip(ir.experience);
14536
14999
  }
14537
- var import_core5, import_fs6, import_path5;
15000
+ var import_core5, import_fs7, import_path6;
14538
15001
  var init_vite = __esm({
14539
15002
  "src/vite/index.ts"() {
14540
15003
  "use strict";
14541
15004
  import_core5 = require("@babel/core");
14542
- import_fs6 = require("fs");
14543
- import_path5 = require("path");
15005
+ import_fs7 = require("fs");
15006
+ import_path6 = require("path");
14544
15007
  init_babel();
14545
15008
  }
14546
15009
  });
@@ -14562,10 +15025,10 @@ async function startLocalServer(options = {}) {
14562
15025
  res.end(data);
14563
15026
  }
14564
15027
  function readBody(req) {
14565
- return new Promise((resolve6, reject) => {
15028
+ return new Promise((resolve7, reject) => {
14566
15029
  const chunks = [];
14567
15030
  req.on("data", (chunk) => chunks.push(chunk));
14568
- req.on("end", () => resolve6(Buffer.concat(chunks).toString()));
15031
+ req.on("end", () => resolve7(Buffer.concat(chunks).toString()));
14569
15032
  req.on("error", reject);
14570
15033
  });
14571
15034
  }
@@ -14694,7 +15157,7 @@ async function startLocalServer(options = {}) {
14694
15157
  return json(res, 500, { error: message });
14695
15158
  }
14696
15159
  });
14697
- return new Promise((resolve6, reject) => {
15160
+ return new Promise((resolve7, reject) => {
14698
15161
  server.on("error", (err) => {
14699
15162
  if (err.code === "EADDRINUSE") {
14700
15163
  reject(new Error(`Port ${port} is already in use. Is another server running?`));
@@ -14706,7 +15169,7 @@ async function startLocalServer(options = {}) {
14706
15169
  console.log(`[mm-local] Local API server running at http://localhost:${port}`);
14707
15170
  console.log(`[mm-local] Mode: in-memory (data lost on restart)`);
14708
15171
  console.log(`[mm-local] Auth: disabled (all requests accepted)`);
14709
- resolve6({
15172
+ resolve7({
14710
15173
  server,
14711
15174
  port,
14712
15175
  store,
@@ -15075,7 +15538,7 @@ async function seedInstances(options) {
15075
15538
  for (const file2 of files) {
15076
15539
  let def;
15077
15540
  try {
15078
- def = JSON.parse((0, import_fs7.readFileSync)(file2, "utf-8"));
15541
+ def = JSON.parse((0, import_fs8.readFileSync)(file2, "utf-8"));
15079
15542
  } catch {
15080
15543
  continue;
15081
15544
  }
@@ -15115,11 +15578,11 @@ async function seedInstances(options) {
15115
15578
  }
15116
15579
  return result;
15117
15580
  }
15118
- var import_fs7, import_glob4, FIRST_NAMES, LAST_NAMES, COMPANIES, LOREM_WORDS, DOMAINS, _counter;
15581
+ var import_fs8, import_glob4, FIRST_NAMES, LAST_NAMES, COMPANIES, LOREM_WORDS, DOMAINS, _counter;
15119
15582
  var init_seed = __esm({
15120
15583
  "src/cli/seed.ts"() {
15121
15584
  "use strict";
15122
- import_fs7 = require("fs");
15585
+ import_fs8 = require("fs");
15123
15586
  import_glob4 = require("glob");
15124
15587
  FIRST_NAMES = ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank", "Grace", "Henry"];
15125
15588
  LAST_NAMES = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis"];
@@ -15269,6 +15732,33 @@ function broadcast(clients, data) {
15269
15732
  }
15270
15733
  }
15271
15734
  async function createDevServer(options = {}) {
15735
+ const { existsSync: existsSync9 } = await import("fs");
15736
+ const { resolve: resolve7 } = await import("path");
15737
+ const nodeModulesPath = resolve7(process.cwd(), "node_modules");
15738
+ if (!existsSync9(nodeModulesPath)) {
15739
+ console.error(`
15740
+ [mmrc] Error: Dependencies not installed.
15741
+ `);
15742
+ console.error(` Run one of these in your project directory first:
15743
+ `);
15744
+ console.error(` npm install`);
15745
+ console.error(` pnpm install`);
15746
+ console.error(` yarn install
15747
+ `);
15748
+ process.exit(1);
15749
+ }
15750
+ try {
15751
+ await import("vite");
15752
+ } catch {
15753
+ console.error(`
15754
+ [mmrc] Error: 'vite' is not installed.
15755
+ `);
15756
+ console.error(` Install it:
15757
+ `);
15758
+ console.error(` npm install -D vite
15759
+ `);
15760
+ process.exit(1);
15761
+ }
15272
15762
  const {
15273
15763
  port = 5199,
15274
15764
  src = "src/workflows",
@@ -15330,6 +15820,45 @@ async function createDevServer(options = {}) {
15330
15820
  }
15331
15821
  const pluginOpts = { mode, include, outDir, seedOnCompile: seed, apiUrl, authToken: token };
15332
15822
  const proxyTarget = apiUrl.replace(/\/api\/v1\/?$/, "") || apiUrl;
15823
+ const devPlayerPlugin = {
15824
+ name: "mindmatrix-dev-player",
15825
+ resolveId(id) {
15826
+ if (id === "virtual:mm-dev-player") return "\0virtual:mm-dev-player";
15827
+ return null;
15828
+ },
15829
+ load(id) {
15830
+ if (id !== "\0virtual:mm-dev-player") return null;
15831
+ return `
15832
+ import React from 'react';
15833
+ import { createRoot } from 'react-dom/client';
15834
+ import { DevPlayer } from '@mmapp/react/player';
15835
+
15836
+ const tree = window.__MM_DEV_TREE__ || { type: 'Text', props: { children: 'No tree loaded. Compile a workflow to see the preview.' } };
15837
+ const scopes = window.__MM_DEV_SCOPES__ || {};
15838
+
15839
+ function App() {
15840
+ const [currentTree, setTree] = React.useState(tree);
15841
+ const [currentScopes, setScopes] = React.useState(scopes);
15842
+
15843
+ React.useEffect(() => {
15844
+ const ws = new WebSocket('ws://' + location.host + '/__mm_dev');
15845
+ ws.onmessage = (ev) => {
15846
+ try {
15847
+ const msg = JSON.parse(ev.data);
15848
+ if (msg.type === 'workflow:compiled' && msg.tree) setTree(msg.tree);
15849
+ if (msg.type === 'workflow:compiled' && msg.scopes) setScopes(msg.scopes);
15850
+ } catch {}
15851
+ };
15852
+ return () => ws.close();
15853
+ }, []);
15854
+
15855
+ return React.createElement(DevPlayer, { tree: currentTree, scopes: currentScopes, title: document.title || 'MindMatrix Dev' });
15856
+ }
15857
+
15858
+ createRoot(document.getElementById('root')).render(React.createElement(App));
15859
+ `;
15860
+ }
15861
+ };
15333
15862
  let deployInFlight = false;
15334
15863
  const compileDeployPlugin = {
15335
15864
  name: "mindmatrix-dev-compile-deploy",
@@ -15374,6 +15903,7 @@ async function createDevServer(options = {}) {
15374
15903
  plugins: [
15375
15904
  mindmatrixReact(pluginOpts),
15376
15905
  compileDeployPlugin,
15906
+ devPlayerPlugin,
15377
15907
  { name: "mindmatrix-error-overlay", configureServer(server) {
15378
15908
  server.middlewares.use(errorOverlayMiddleware());
15379
15909
  } }
@@ -15482,20 +16012,20 @@ function deepMerge(target, source) {
15482
16012
  }
15483
16013
  function findConfigPath(startDir) {
15484
16014
  let dir = startDir ?? process.cwd();
15485
- const root = (0, import_path6.resolve)("/");
16015
+ const root = (0, import_path7.resolve)("/");
15486
16016
  while (true) {
15487
16017
  for (const name of ["mmrc.config.ts", "mmrc.config.json"]) {
15488
- const candidate = (0, import_path6.join)(dir, name);
15489
- if ((0, import_fs8.existsSync)(candidate)) return candidate;
16018
+ const candidate = (0, import_path7.join)(dir, name);
16019
+ if ((0, import_fs9.existsSync)(candidate)) return candidate;
15490
16020
  }
15491
- const parent = (0, import_path6.resolve)(dir, "..");
16021
+ const parent = (0, import_path7.resolve)(dir, "..");
15492
16022
  if (parent === dir || parent === root) break;
15493
16023
  dir = parent;
15494
16024
  }
15495
16025
  return null;
15496
16026
  }
15497
16027
  function loadConfigFromFile(configPath) {
15498
- const content = (0, import_fs8.readFileSync)(configPath, "utf-8");
16028
+ const content = (0, import_fs9.readFileSync)(configPath, "utf-8");
15499
16029
  if (configPath.endsWith(".json")) {
15500
16030
  try {
15501
16031
  return JSON.parse(content);
@@ -15576,7 +16106,7 @@ const config = ${json};
15576
16106
 
15577
16107
  export default config;
15578
16108
  `;
15579
- (0, import_fs8.writeFileSync)(configPath, content, "utf-8");
16109
+ (0, import_fs9.writeFileSync)(configPath, content, "utf-8");
15580
16110
  }
15581
16111
  function resolveTarget(targetName, config, fallbackApiUrl) {
15582
16112
  if (!config || !config.environments) {
@@ -15626,7 +16156,7 @@ const config = {
15626
16156
  dev: { apiUrl: 'https://dev.mindmatrix.club/api/v1' },
15627
16157
  },
15628
16158
 
15629
- defaultTarget: 'dev',
16159
+ defaultTarget: 'local',
15630
16160
  };
15631
16161
 
15632
16162
  export default config;
@@ -15638,19 +16168,19 @@ function loadMmrcConfig(dir) {
15638
16168
  const partial = loadConfigFromFile(path);
15639
16169
  return deepMerge(DEFAULT_CONFIG, partial);
15640
16170
  }
15641
- var import_fs8, import_path6, DEFAULT_CONFIG;
16171
+ var import_fs9, import_path7, DEFAULT_CONFIG;
15642
16172
  var init_config = __esm({
15643
16173
  "src/cli/config.ts"() {
15644
16174
  "use strict";
15645
- import_fs8 = require("fs");
15646
- import_path6 = require("path");
16175
+ import_fs9 = require("fs");
16176
+ import_path7 = require("path");
15647
16177
  DEFAULT_CONFIG = {
15648
16178
  dev: {
15649
16179
  port: 5199,
15650
16180
  apiPort: 4200,
15651
16181
  db: "sqlite://mm-dev.db",
15652
16182
  redis: "",
15653
- api: "http://localhost:4200/api/v1",
16183
+ api: "local",
15654
16184
  seed: false,
15655
16185
  open: false
15656
16186
  },
@@ -15668,7 +16198,7 @@ var init_config = __esm({
15668
16198
  local: { apiUrl: "http://localhost:4200/api/v1" },
15669
16199
  dev: { apiUrl: "https://dev.mindmatrix.club/api/v1" }
15670
16200
  },
15671
- defaultTarget: "dev"
16201
+ defaultTarget: "local"
15672
16202
  };
15673
16203
  }
15674
16204
  });
@@ -15699,12 +16229,16 @@ function generatePackageJson2(name) {
15699
16229
  deploy: "mmrc deploy --build --src ."
15700
16230
  },
15701
16231
  dependencies: {
15702
- "@mmapp/react": "^0.1.0-alpha.1"
16232
+ "@mmapp/react": "^0.1.0-alpha.1",
16233
+ "react": "^18.0.0",
16234
+ "react-dom": "^18.0.0"
15703
16235
  },
15704
16236
  devDependencies: {
15705
- typescript: "^5.5.0",
16237
+ "typescript": "^5.5.0",
15706
16238
  "@types/react": "^18.0.0",
15707
- react: "^18.0.0"
16239
+ "@types/react-dom": "^18.0.0",
16240
+ "vite": "^6.0.0",
16241
+ "@mmapp/react-compiler": "^0.1.0-alpha.1"
15708
16242
  }
15709
16243
  },
15710
16244
  null,
@@ -16010,7 +16544,7 @@ dev.db
16010
16544
  }
16011
16545
  function isInsideGitRepo(dir) {
16012
16546
  try {
16013
- (0, import_child_process2.execSync)("git rev-parse --git-dir", { cwd: dir, stdio: "pipe" });
16547
+ (0, import_child_process3.execSync)("git rev-parse --git-dir", { cwd: dir, stdio: "pipe" });
16014
16548
  return true;
16015
16549
  } catch {
16016
16550
  return false;
@@ -16021,9 +16555,9 @@ function scaffoldGit(dir) {
16021
16555
  return "Skipped git init (inside existing repo)";
16022
16556
  }
16023
16557
  try {
16024
- (0, import_child_process2.execSync)("git init", { cwd: dir, stdio: "pipe" });
16025
- (0, import_child_process2.execSync)("git add -A", { cwd: dir, stdio: "pipe" });
16026
- (0, import_child_process2.execSync)('git commit -m "Initial commit from mmrc init"', { cwd: dir, stdio: "pipe" });
16558
+ (0, import_child_process3.execSync)("git init", { cwd: dir, stdio: "pipe" });
16559
+ (0, import_child_process3.execSync)("git add -A", { cwd: dir, stdio: "pipe" });
16560
+ (0, import_child_process3.execSync)('git commit -m "Initial commit from mmrc init"', { cwd: dir, stdio: "pipe" });
16027
16561
  return "Initialized git repository";
16028
16562
  } catch (e) {
16029
16563
  return `Git init failed: ${e.message}`;
@@ -16036,16 +16570,30 @@ async function init(options) {
16036
16570
  process.exit(1);
16037
16571
  }
16038
16572
  const cwd = process.cwd();
16039
- const packagesDir = (0, import_fs9.existsSync)((0, import_path7.join)(cwd, "packages")) ? (0, import_path7.join)(cwd, "packages") : cwd;
16040
- const blueprintDir = (0, import_path7.join)(packagesDir, `blueprint-${name}`);
16041
- if ((0, import_fs9.existsSync)(blueprintDir)) {
16573
+ const packagesDir = (0, import_fs10.existsSync)((0, import_path8.join)(cwd, "packages")) ? (0, import_path8.join)(cwd, "packages") : cwd;
16574
+ const blueprintDir = (0, import_path8.join)(packagesDir, `blueprint-${name}`);
16575
+ if ((0, import_fs10.existsSync)(blueprintDir)) {
16042
16576
  console.error(`[mmrc] Error: Directory already exists: ${blueprintDir}`);
16043
16577
  process.exit(1);
16044
16578
  }
16579
+ try {
16580
+ const pkgPath = require.resolve("@mmapp/react-compiler/package.json");
16581
+ const { version } = require(pkgPath);
16582
+ console.log(`[mmrc] v${version}`);
16583
+ } catch {
16584
+ try {
16585
+ const { readFileSync: readFileSync11 } = require("fs");
16586
+ const { resolve: resolve7, dirname: dirname4 } = require("path");
16587
+ const pkg = JSON.parse(readFileSync11(resolve7(__dirname, "../../package.json"), "utf-8"));
16588
+ console.log(`[mmrc] v${pkg.version}`);
16589
+ } catch {
16590
+ console.log(`[mmrc]`);
16591
+ }
16592
+ }
16045
16593
  console.log(`[mmrc] Creating blueprint: ${name}
16046
16594
  `);
16047
- (0, import_fs9.mkdirSync)((0, import_path7.join)(blueprintDir, "models"), { recursive: true });
16048
- (0, import_fs9.mkdirSync)((0, import_path7.join)(blueprintDir, "app"), { recursive: true });
16595
+ (0, import_fs10.mkdirSync)((0, import_path8.join)(blueprintDir, "models"), { recursive: true });
16596
+ (0, import_fs10.mkdirSync)((0, import_path8.join)(blueprintDir, "app"), { recursive: true });
16049
16597
  const { generateMmrcConfig: generateMmrcConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
16050
16598
  const files = [
16051
16599
  ["package.json", generatePackageJson2(name)],
@@ -16058,31 +16606,42 @@ async function init(options) {
16058
16606
  ["app/page.tsx", generatePage(name)]
16059
16607
  ];
16060
16608
  for (const [relPath, content] of files) {
16061
- const fullPath = (0, import_path7.join)(blueprintDir, relPath);
16062
- (0, import_fs9.writeFileSync)(fullPath, content, "utf-8");
16609
+ const fullPath = (0, import_path8.join)(blueprintDir, relPath);
16610
+ (0, import_fs10.writeFileSync)(fullPath, content, "utf-8");
16063
16611
  console.log(` + ${relPath}`);
16064
16612
  }
16065
16613
  const gitMessage = scaffoldGit(blueprintDir);
16066
16614
  console.log(` ${gitMessage}`);
16615
+ console.log(`
16616
+ [mmrc] Installing dependencies...`);
16617
+ const { execSync: execSync4 } = require("child_process");
16618
+ try {
16619
+ const usesPnpm = (0, import_fs10.existsSync)((0, import_path8.join)(cwd, "pnpm-lock.yaml")) || (0, import_fs10.existsSync)((0, import_path8.join)(cwd, "pnpm-workspace.yaml"));
16620
+ const usesYarn = (0, import_fs10.existsSync)((0, import_path8.join)(cwd, "yarn.lock"));
16621
+ const pm = usesPnpm ? "pnpm" : usesYarn ? "yarn" : "npm";
16622
+ execSync4(`${pm} install`, { cwd: blueprintDir, stdio: "inherit" });
16623
+ console.log(`[mmrc] Dependencies installed with ${pm}`);
16624
+ } catch (e) {
16625
+ console.warn(`[mmrc] Warning: Could not auto-install dependencies. Run 'npm install' manually in the project directory.`);
16626
+ }
16067
16627
  const title = toTitleCase(name);
16628
+ const relDir = blueprintDir.startsWith(cwd) ? blueprintDir.slice(cwd.length + 1) : blueprintDir;
16068
16629
  console.log(`
16069
16630
  [mmrc] Blueprint "${title}" created at:
16070
16631
  ${blueprintDir}
16071
16632
 
16072
16633
  Next steps:
16073
- 1. cd ${blueprintDir.startsWith(cwd) ? blueprintDir.slice(cwd.length + 1) : blueprintDir}
16074
- 2. mmrc dev # Start dev server
16075
- 3. mmrc build # Compile to IR
16076
- 4. mmrc deploy --build # Build + deploy to backend
16634
+ 1. cd ${relDir}
16635
+ 2. mmrc dev # Start dev server with live preview
16077
16636
  `);
16078
16637
  }
16079
- var import_fs9, import_path7, import_child_process2;
16638
+ var import_fs10, import_path8, import_child_process3;
16080
16639
  var init_init = __esm({
16081
16640
  "src/cli/init.ts"() {
16082
16641
  "use strict";
16083
- import_fs9 = require("fs");
16084
- import_path7 = require("path");
16085
- import_child_process2 = require("child_process");
16642
+ import_fs10 = require("fs");
16643
+ import_path8 = require("path");
16644
+ import_child_process3 = require("child_process");
16086
16645
  }
16087
16646
  });
16088
16647
 
@@ -17862,7 +18421,7 @@ __export(verify_exports, {
17862
18421
  verifyCommand: () => verifyCommand
17863
18422
  });
17864
18423
  function compileToIR(filePath) {
17865
- const code = (0, import_fs10.readFileSync)(filePath, "utf-8");
18424
+ const code = (0, import_fs11.readFileSync)(filePath, "utf-8");
17866
18425
  const result = (0, import_core6.transformSync)(code, {
17867
18426
  filename: filePath,
17868
18427
  plugins: [[babelPlugin, { mode: "strict" }]],
@@ -17878,13 +18437,13 @@ function compileToIR(filePath) {
17878
18437
  return irDef;
17879
18438
  }
17880
18439
  async function resolveFiles(target) {
17881
- const resolved = (0, import_path8.resolve)(target);
17882
- if (!(0, import_fs10.existsSync)(resolved)) {
18440
+ const resolved = (0, import_path9.resolve)(target);
18441
+ if (!(0, import_fs11.existsSync)(resolved)) {
17883
18442
  throw new Error(`Path not found: ${resolved}`);
17884
18443
  }
17885
- const stat = (0, import_fs10.statSync)(resolved);
18444
+ const stat = (0, import_fs11.statSync)(resolved);
17886
18445
  if (stat.isFile()) {
17887
- const ext = (0, import_path8.extname)(resolved);
18446
+ const ext = (0, import_path9.extname)(resolved);
17888
18447
  if (![".ts", ".tsx", ".js", ".jsx"].includes(ext)) {
17889
18448
  throw new Error(`Unsupported file type: ${ext}. Expected .ts, .tsx, .js, or .jsx`);
17890
18449
  }
@@ -17915,12 +18474,12 @@ async function verifyCommand(options) {
17915
18474
  let filesFailed = 0;
17916
18475
  const results = [];
17917
18476
  for (const file2 of files) {
17918
- const label = (0, import_path8.basename)(file2);
18477
+ const label = (0, import_path9.basename)(file2);
17919
18478
  try {
17920
18479
  const ir = compileToIR(file2);
17921
18480
  if (options.generate) {
17922
18481
  const testCode = generateTestFile(ir);
17923
- const testFileName = (0, import_path8.basename)(file2).replace(/\.(ts|tsx|js|jsx)$/, ".verify.test.ts");
18482
+ const testFileName = (0, import_path9.basename)(file2).replace(/\.(ts|tsx|js|jsx)$/, ".verify.test.ts");
17924
18483
  console.log(`// --- ${testFileName} ---`);
17925
18484
  console.log(testCode);
17926
18485
  filesProcessed++;
@@ -17966,12 +18525,12 @@ ${"=".repeat(50)}`);
17966
18525
  }
17967
18526
  return { success, filesProcessed, filesFailed, results };
17968
18527
  }
17969
- var import_fs10, import_path8, import_glob5, import_core6;
18528
+ var import_fs11, import_path9, import_glob5, import_core6;
17970
18529
  var init_verify = __esm({
17971
18530
  "src/cli/verify.ts"() {
17972
18531
  "use strict";
17973
- import_fs10 = require("fs");
17974
- import_path8 = require("path");
18532
+ import_fs11 = require("fs");
18533
+ import_path9 = require("path");
17975
18534
  import_glob5 = require("glob");
17976
18535
  import_core6 = require("@babel/core");
17977
18536
  init_babel();
@@ -17995,12 +18554,12 @@ async function pull(options) {
17995
18554
  console.log(` Found: ${ir.name || ir.slug} (${ir.category || "workflow"}, v${ir.version || "1.0.0"})`);
17996
18555
  console.log(` Fields: ${ir.fields?.length ?? 0}, States: ${ir.states?.length ?? 0}, Transitions: ${ir.transitions?.length ?? 0}`);
17997
18556
  const result = decompileProjectEnhanced(ir);
17998
- (0, import_fs11.mkdirSync)(outDir, { recursive: true });
18557
+ (0, import_fs12.mkdirSync)(outDir, { recursive: true });
17999
18558
  const filesWritten = [];
18000
18559
  for (const file2 of result.files) {
18001
- const filePath = (0, import_path9.join)(outDir, file2.path);
18002
- (0, import_fs11.mkdirSync)((0, import_path9.dirname)(filePath), { recursive: true });
18003
- (0, import_fs11.writeFileSync)(filePath, file2.content, "utf-8");
18560
+ const filePath = (0, import_path10.join)(outDir, file2.path);
18561
+ (0, import_fs12.mkdirSync)((0, import_path10.dirname)(filePath), { recursive: true });
18562
+ (0, import_fs12.writeFileSync)(filePath, file2.content, "utf-8");
18004
18563
  filesWritten.push(file2.path);
18005
18564
  console.log(` + ${file2.path}`);
18006
18565
  }
@@ -18082,12 +18641,12 @@ function normalizeApiResponse(def) {
18082
18641
  }
18083
18642
  return ir;
18084
18643
  }
18085
- var import_fs11, import_path9;
18644
+ var import_fs12, import_path10;
18086
18645
  var init_pull = __esm({
18087
18646
  "src/cli/pull.ts"() {
18088
18647
  "use strict";
18089
- import_fs11 = require("fs");
18090
- import_path9 = require("path");
18648
+ import_fs12 = require("fs");
18649
+ import_path10 = require("path");
18091
18650
  init_project_decompiler();
18092
18651
  }
18093
18652
  });
@@ -18105,15 +18664,15 @@ __export(server_exports, {
18105
18664
  });
18106
18665
  function findServerBinary(explicitPath) {
18107
18666
  if (explicitPath) {
18108
- return (0, import_fs12.existsSync)(explicitPath) ? explicitPath : null;
18667
+ return (0, import_fs13.existsSync)(explicitPath) ? explicitPath : null;
18109
18668
  }
18110
18669
  for (const rel of BINARY_SEARCH_PATHS) {
18111
- const abs = (0, import_path10.resolve)(process.cwd(), rel);
18112
- if ((0, import_fs12.existsSync)(abs)) return abs;
18670
+ const abs = (0, import_path11.resolve)(process.cwd(), rel);
18671
+ if ((0, import_fs13.existsSync)(abs)) return abs;
18113
18672
  }
18114
18673
  try {
18115
- const { execSync: execSync3 } = require("child_process");
18116
- const result = execSync3("which mm-server 2>/dev/null || which mm-api 2>/dev/null", {
18674
+ const { execSync: execSync4 } = require("child_process");
18675
+ const result = execSync4("which mm-server 2>/dev/null || which mm-api 2>/dev/null", {
18117
18676
  encoding: "utf-8",
18118
18677
  timeout: 5e3
18119
18678
  }).trim();
@@ -18201,12 +18760,12 @@ async function serverMigrate(options) {
18201
18760
  process.exit(1);
18202
18761
  }
18203
18762
  console.log(`[mmrc] Running migrations via ${binary}...`);
18204
- const { execSync: execSync3 } = require("child_process");
18763
+ const { execSync: execSync4 } = require("child_process");
18205
18764
  try {
18206
18765
  const configPath = options.config ?? findConfigFile();
18207
18766
  const env = { ...process.env, MM_RUN_MIGRATIONS: "true" };
18208
18767
  if (configPath) env.MM_CONFIG_PATH = configPath;
18209
- execSync3(`${binary} --migrate-only`, { stdio: "inherit", env });
18768
+ execSync4(`${binary} --migrate-only`, { stdio: "inherit", env });
18210
18769
  console.log("[mmrc] Migrations complete.");
18211
18770
  } catch (e) {
18212
18771
  console.error(`[mmrc] Migration failed: ${e.message}`);
@@ -18217,12 +18776,12 @@ function serverInit(options) {
18217
18776
  const output = options.output ?? "mm-server.toml";
18218
18777
  const mode = options.mode ?? "standalone";
18219
18778
  const db = options.db ?? "$env:DATABASE_URL";
18220
- if ((0, import_fs12.existsSync)(output) && output !== "/dev/stdout") {
18779
+ if ((0, import_fs13.existsSync)(output) && output !== "/dev/stdout") {
18221
18780
  console.error(`[mmrc] Error: ${output} already exists. Use --output to specify a different path.`);
18222
18781
  process.exit(1);
18223
18782
  }
18224
18783
  const content = generateServerToml(mode, db);
18225
- (0, import_fs12.writeFileSync)(output, content, "utf-8");
18784
+ (0, import_fs13.writeFileSync)(output, content, "utf-8");
18226
18785
  console.log(`[mmrc] Generated ${output} (mode: ${mode})`);
18227
18786
  console.log(`[mmrc] Edit the file, then run: mmrc server start`);
18228
18787
  }
@@ -18337,7 +18896,7 @@ function serverConfig(options) {
18337
18896
  }
18338
18897
  console.log(`[mmrc] Config file: ${configPath}
18339
18898
  `);
18340
- const raw = (0, import_fs12.readFileSync)(configPath, "utf-8");
18899
+ const raw = (0, import_fs13.readFileSync)(configPath, "utf-8");
18341
18900
  const resolved = raw.replace(/\$env:(\w+)/g, (_match, varName) => {
18342
18901
  const val = process.env[varName];
18343
18902
  return val ? `${val} # \u2190 $env:${varName}` : `(unset) # \u2190 $env:${varName}`;
@@ -18351,17 +18910,17 @@ function findConfigFile() {
18351
18910
  "mm-core/mm-server.toml"
18352
18911
  ];
18353
18912
  for (const c of candidates) {
18354
- const abs = (0, import_path10.resolve)(process.cwd(), c);
18355
- if ((0, import_fs12.existsSync)(abs)) return abs;
18913
+ const abs = (0, import_path11.resolve)(process.cwd(), c);
18914
+ if ((0, import_fs13.existsSync)(abs)) return abs;
18356
18915
  }
18357
18916
  return null;
18358
18917
  }
18359
- var import_fs12, import_path10, BINARY_SEARCH_PATHS;
18918
+ var import_fs13, import_path11, BINARY_SEARCH_PATHS;
18360
18919
  var init_server = __esm({
18361
18920
  "src/cli/server.ts"() {
18362
18921
  "use strict";
18363
- import_fs12 = require("fs");
18364
- import_path10 = require("path");
18922
+ import_fs13 = require("fs");
18923
+ import_path11 = require("path");
18365
18924
  BINARY_SEARCH_PATHS = [
18366
18925
  "engine/target/release/mm-server",
18367
18926
  "engine/target/debug/mm-server",
@@ -18671,11 +19230,11 @@ function getPositional() {
18671
19230
  }
18672
19231
  async function loadDevConfig() {
18673
19232
  try {
18674
- const { existsSync: existsSync8, readFileSync: readFileSync10 } = await import("fs");
18675
- const { resolve: resolve6 } = await import("path");
18676
- const configPath = resolve6(process.cwd(), "mm.config.ts");
18677
- if (!existsSync8(configPath)) return {};
18678
- const content = readFileSync10(configPath, "utf-8");
19233
+ const { existsSync: existsSync9, readFileSync: readFileSync11 } = await import("fs");
19234
+ const { resolve: resolve7 } = await import("path");
19235
+ const configPath = resolve7(process.cwd(), "mm.config.ts");
19236
+ if (!existsSync9(configPath)) return {};
19237
+ const content = readFileSync11(configPath, "utf-8");
18679
19238
  const devMatch = content.match(/dev\s*:\s*\{([^}]*)\}/s);
18680
19239
  if (!devMatch) return {};
18681
19240
  const block = devMatch[1];
@@ -18703,9 +19262,89 @@ async function main() {
18703
19262
  const src = getFlag("--src") ?? devCfg.src;
18704
19263
  const mode = getFlag("--mode") ?? devCfg.mode;
18705
19264
  const seed = hasFlag("--seed") || devCfg.seed === true;
18706
- const apiUrl = hasFlag("--local") ? "local" : getFlag("--api-url") ?? devCfg.apiUrl;
19265
+ const explicitApiUrl = getFlag("--api-url") ?? devCfg.apiUrl;
19266
+ const isLocal = hasFlag("--local") || !explicitApiUrl || explicitApiUrl === "local";
18707
19267
  const authToken = getFlag("--token") ?? devCfg.token;
18708
19268
  const open = hasFlag("--open") || devCfg.open === true;
19269
+ const apiPort = getFlag("--api-port") ? parseInt(getFlag("--api-port"), 10) : 4200;
19270
+ let engineProcess = null;
19271
+ if (isLocal) {
19272
+ const { findEngineBinary: findEngineBinary2, installEngine: installEngine2, verifyBinary: verifyBinary2 } = await Promise.resolve().then(() => (init_engine_binary(), engine_binary_exports));
19273
+ let resolution = findEngineBinary2(getFlag("--binary"));
19274
+ if (resolution.path) {
19275
+ const verify2 = await verifyBinary2(resolution.path);
19276
+ if (!verify2.ok) {
19277
+ console.error(`[mmrc] Binary at ${resolution.path} failed verification: ${verify2.error}`);
19278
+ console.error("[mmrc] Attempting reinstall...\n");
19279
+ resolution = { path: null, source: "not-found" };
19280
+ }
19281
+ }
19282
+ if (!resolution.path) {
19283
+ const installed = await installEngine2({
19284
+ force: true,
19285
+ version: getFlag("--engine-version") ?? "latest"
19286
+ });
19287
+ if (installed.path) {
19288
+ resolution = installed;
19289
+ }
19290
+ }
19291
+ if (!resolution.path) {
19292
+ console.log("[mmrc] No local engine binary available.");
19293
+ console.log("[mmrc] Dev server will connect to a remote API or start in-memory mode.");
19294
+ console.log("[mmrc] (For full local mode: `mmrc engine install` or `mmrc engine build`)\n");
19295
+ } else {
19296
+ console.log(`[mmrc] Starting local engine: ${resolution.path} (${resolution.source})`);
19297
+ const { spawn: spawnProcess } = require("child_process");
19298
+ engineProcess = spawnProcess(resolution.path, [], {
19299
+ stdio: ["ignore", "pipe", "pipe"],
19300
+ env: {
19301
+ ...process.env,
19302
+ DATABASE_URL: `sqlite://${process.cwd()}/dev.db`,
19303
+ JWT_SECRET: "dev-secret-mmrc-local",
19304
+ PORT: String(apiPort),
19305
+ RUST_LOG: "mm_api=info,mm_storage=info"
19306
+ }
19307
+ });
19308
+ if (engineProcess.stdout) {
19309
+ engineProcess.stdout.on("data", (data) => {
19310
+ for (const line of data.toString().split("\n").filter(Boolean)) {
19311
+ console.log(` [engine] ${line}`);
19312
+ }
19313
+ });
19314
+ }
19315
+ if (engineProcess.stderr) {
19316
+ engineProcess.stderr.on("data", (data) => {
19317
+ for (const line of data.toString().split("\n").filter(Boolean)) {
19318
+ console.error(` [engine] ${line}`);
19319
+ }
19320
+ });
19321
+ }
19322
+ engineProcess.on("error", (err) => {
19323
+ console.error(`[mmrc] Engine failed to start: ${err.message}`);
19324
+ process.exit(1);
19325
+ });
19326
+ const healthUrl = `http://localhost:${apiPort}/health`;
19327
+ let healthy = false;
19328
+ for (let i = 0; i < 30; i++) {
19329
+ try {
19330
+ const res = await fetch(healthUrl, { signal: AbortSignal.timeout(500) });
19331
+ if (res.ok) {
19332
+ healthy = true;
19333
+ break;
19334
+ }
19335
+ } catch {
19336
+ }
19337
+ await new Promise((r) => setTimeout(r, 500));
19338
+ }
19339
+ if (!healthy) {
19340
+ console.error("[mmrc] Engine failed to become healthy within 15s.");
19341
+ engineProcess.kill();
19342
+ process.exit(1);
19343
+ }
19344
+ console.log(`[mmrc] Engine healthy at http://localhost:${apiPort}`);
19345
+ }
19346
+ }
19347
+ const apiUrl = engineProcess ? `http://localhost:${apiPort}/api/v1` : explicitApiUrl || "auto";
18709
19348
  const { createDevServer: createDevServer2 } = await Promise.resolve().then(() => (init_dev_server(), dev_server_exports));
18710
19349
  const server = await createDevServer2({
18711
19350
  port,
@@ -18717,6 +19356,10 @@ async function main() {
18717
19356
  open
18718
19357
  });
18719
19358
  const shutdown = async () => {
19359
+ if (engineProcess) {
19360
+ console.log("[mmrc] Stopping engine...");
19361
+ engineProcess.kill("SIGTERM");
19362
+ }
18720
19363
  await server.close();
18721
19364
  process.exit(0);
18722
19365
  };
@@ -18774,11 +19417,11 @@ async function main() {
18774
19417
  const srcDir = src ?? ".";
18775
19418
  const outDir = dir ?? "dist/workflows";
18776
19419
  console.log("[mmrc] Building before deploy...\n");
18777
- const { existsSync: existsSync8, readFileSync: readFileSync10, writeFileSync: writeFileSync9, mkdirSync: mkdirSync6 } = await import("fs");
18778
- const { resolve: resolve6, join: join7 } = await import("path");
19420
+ const { existsSync: existsSync9, readFileSync: readFileSync11, writeFileSync: writeFileSync10, mkdirSync: mkdirSync7 } = await import("fs");
19421
+ const { resolve: resolve7, join: join8 } = await import("path");
18779
19422
  const { glob: glob6 } = await import("glob");
18780
- const configPath = resolve6(srcDir, "mm.config.ts");
18781
- if (existsSync8(configPath)) {
19423
+ const configPath = resolve7(srcDir, "mm.config.ts");
19424
+ if (existsSync9(configPath)) {
18782
19425
  const { compileProject: compileProject2 } = await Promise.resolve().then(() => (init_project_compiler(), project_compiler_exports));
18783
19426
  const allFiles = await glob6(`${srcDir}/**/*.{ts,tsx}`, {
18784
19427
  ignore: ["**/node_modules/**", "**/dist/**", "**/__tests__/**", "**/*.test.*"]
@@ -18786,7 +19429,7 @@ async function main() {
18786
19429
  const fileMap = {};
18787
19430
  for (const f of allFiles) {
18788
19431
  const rel = f.startsWith(srcDir + "/") ? f.slice(srcDir.length + 1) : f;
18789
- fileMap[rel] = readFileSync10(f, "utf-8");
19432
+ fileMap[rel] = readFileSync11(f, "utf-8");
18790
19433
  }
18791
19434
  console.log(` Compiling project (${Object.keys(fileMap).length} files)...`);
18792
19435
  const result = compileProject2(fileMap);
@@ -18799,16 +19442,16 @@ async function main() {
18799
19442
  [mmrc] Build failed with ${errors.length} errors \u2014 aborting deploy.`);
18800
19443
  process.exit(1);
18801
19444
  }
18802
- mkdirSync6(outDir, { recursive: true });
18803
- const irPath = join7(outDir, `${result.ir.slug}.workflow.json`);
18804
- writeFileSync9(irPath, JSON.stringify(result.ir, null, 2), "utf-8");
19445
+ mkdirSync7(outDir, { recursive: true });
19446
+ const irPath = join8(outDir, `${result.ir.slug}.workflow.json`);
19447
+ writeFileSync10(irPath, JSON.stringify(result.ir, null, 2), "utf-8");
18805
19448
  console.log(` + ${result.ir.slug}.workflow.json`);
18806
19449
  const seenSlugs = /* @__PURE__ */ new Set([result.ir.slug]);
18807
19450
  for (const child of result.childDefinitions) {
18808
19451
  if (seenSlugs.has(child.slug)) continue;
18809
19452
  seenSlugs.add(child.slug);
18810
- const childPath = join7(outDir, `${child.slug}.workflow.json`);
18811
- writeFileSync9(childPath, JSON.stringify(child, null, 2), "utf-8");
19453
+ const childPath = join8(outDir, `${child.slug}.workflow.json`);
19454
+ writeFileSync10(childPath, JSON.stringify(child, null, 2), "utf-8");
18812
19455
  console.log(` + ${child.slug}.workflow.json`);
18813
19456
  }
18814
19457
  console.log(` Compiled ${1 + result.childDefinitions.length} definitions.
@@ -18971,17 +19614,132 @@ async function main() {
18971
19614
  console.error(" Usage: mmrc server [start|migrate|init|status|config]");
18972
19615
  process.exit(1);
18973
19616
  }
19617
+ } else if (command === "engine") {
19618
+ const subcommand = args[1];
19619
+ const {
19620
+ detectPlatform: detectPlatform2,
19621
+ findEngineBinary: findEngineBinary2,
19622
+ getEngineStatus: getEngineStatus2,
19623
+ installEngine: installEngine2,
19624
+ buildFromSource: _buildFromSource,
19625
+ verifyBinary: verifyBinary2,
19626
+ healthCheck: healthCheck2,
19627
+ readMetadata: readMetadata2,
19628
+ MANAGED_BINARY_PATH: _MANAGED_BINARY_PATH
19629
+ } = await Promise.resolve().then(() => (init_engine_binary(), engine_binary_exports));
19630
+ if (subcommand === "status") {
19631
+ const status = await getEngineStatus2(getFlag("--binary"));
19632
+ const plat = detectPlatform2();
19633
+ console.log("\n MindMatrix Engine Status");
19634
+ console.log(" " + "-".repeat(48));
19635
+ console.log(` Platform: ${plat.releasePlatform ?? `${plat.os}-${plat.arch}`} (${plat.triple})`);
19636
+ console.log(` Installed: ${status.installed ? "yes" : "no"}`);
19637
+ if (status.path) {
19638
+ console.log(` Path: ${status.path}`);
19639
+ console.log(` Source: ${status.source}`);
19640
+ }
19641
+ console.log(` Verified: ${status.verified ? "yes" : "no"}`);
19642
+ if (status.version) {
19643
+ console.log(` Version: ${status.version}`);
19644
+ }
19645
+ const meta = readMetadata2();
19646
+ if (meta) {
19647
+ console.log(` Downloaded: ${meta.downloadedAt}`);
19648
+ console.log(` Built via: ${meta.source}`);
19649
+ }
19650
+ console.log("");
19651
+ } else if (subcommand === "install") {
19652
+ const force = hasFlag("--force");
19653
+ const version = getFlag("--version") ?? "latest";
19654
+ const result = await installEngine2({ force, version });
19655
+ if (!result.path) {
19656
+ console.error("[mmrc] Engine installation failed.");
19657
+ process.exit(1);
19658
+ }
19659
+ console.log(`
19660
+ [mmrc] Engine installed: ${result.path} (${result.source})`);
19661
+ } else if (subcommand === "build") {
19662
+ const result = await installEngine2({ preferBuild: true, force: true });
19663
+ if (!result.path) {
19664
+ console.error("[mmrc] Engine build failed.");
19665
+ process.exit(1);
19666
+ }
19667
+ console.log(`
19668
+ [mmrc] Engine built and cached: ${result.path}`);
19669
+ } else if (subcommand === "update") {
19670
+ const version = getFlag("--version") ?? "latest";
19671
+ console.log("[mmrc] Checking for engine updates...");
19672
+ const result = await installEngine2({ force: true, version });
19673
+ if (!result.path) {
19674
+ console.error("[mmrc] Engine update failed.");
19675
+ process.exit(1);
19676
+ }
19677
+ console.log(`
19678
+ [mmrc] Engine updated: ${result.path} (${result.source})`);
19679
+ } else if (subcommand === "verify") {
19680
+ const resolution = findEngineBinary2(getFlag("--binary"));
19681
+ if (!resolution.path) {
19682
+ console.error("[mmrc] No engine binary found. Run `mmrc engine install` first.");
19683
+ process.exit(1);
19684
+ }
19685
+ console.log(`[mmrc] Verifying binary: ${resolution.path}`);
19686
+ const verify2 = await verifyBinary2(resolution.path);
19687
+ if (!verify2.ok) {
19688
+ console.error(`[mmrc] --version check FAILED: ${verify2.error}`);
19689
+ process.exit(1);
19690
+ }
19691
+ console.log(`[mmrc] --version check passed: ${verify2.version}`);
19692
+ const apiPort = getFlag("--port") ? parseInt(getFlag("--port"), 10) : 14200;
19693
+ console.log(`[mmrc] Starting engine on port ${apiPort} for health check...`);
19694
+ const { spawn } = await import("child_process");
19695
+ const proc = spawn(resolution.path, [], {
19696
+ stdio: ["ignore", "pipe", "pipe"],
19697
+ env: {
19698
+ ...process.env,
19699
+ DATABASE_URL: "sqlite://:memory:",
19700
+ JWT_SECRET: "verify-test",
19701
+ PORT: String(apiPort),
19702
+ RUST_LOG: "error"
19703
+ }
19704
+ });
19705
+ let healthy = false;
19706
+ for (let i = 0; i < 20; i++) {
19707
+ const h = await healthCheck2(`http://localhost:${apiPort}/health`, 1e3);
19708
+ if (h.ok) {
19709
+ healthy = true;
19710
+ console.log(`[mmrc] /health check passed${h.version ? ` (v${h.version})` : ""}${h.db ? ` [${h.db}]` : ""}`);
19711
+ break;
19712
+ }
19713
+ await new Promise((r) => setTimeout(r, 500));
19714
+ }
19715
+ proc.kill("SIGTERM");
19716
+ if (!healthy) {
19717
+ console.error("[mmrc] /health check FAILED: engine did not become healthy within 10s.");
19718
+ process.exit(1);
19719
+ }
19720
+ console.log("\n[mmrc] All verification checks passed.");
19721
+ } else {
19722
+ console.error(`[mmrc] Unknown engine subcommand: ${subcommand ?? "(none)"}`);
19723
+ console.error(" Usage: mmrc engine [status|install|build|update|verify]");
19724
+ console.error("");
19725
+ console.error(" status Show installed binary path, version, platform");
19726
+ console.error(" install Download or build mm-api binary");
19727
+ console.error(" build Explicitly build from source (cargo build --release -p mm-api)");
19728
+ console.error(" update Check for newer version and download/build");
19729
+ console.error(" verify Run --version and /health check against the binary");
19730
+ process.exit(1);
19731
+ }
18974
19732
  } else if (command === "version" || command === "-v" || command === "--version" || hasFlag("--version") || hasFlag("-v")) {
18975
- const { readFileSync: readFileSync10 } = await import("fs");
18976
- const { resolve: resolve6, dirname: dirname4 } = await import("path");
19733
+ const { readFileSync: readFileSync11 } = await import("fs");
19734
+ const { resolve: resolve7, dirname: dirname4 } = await import("path");
18977
19735
  try {
18978
- const pkgPath = resolve6(dirname4(new URL(import_meta.url).pathname), "../../package.json");
18979
- const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
19736
+ const pkgPath = resolve7(dirname4(new URL(import_meta.url).pathname), "../../package.json");
19737
+ const pkg = JSON.parse(readFileSync11(pkgPath, "utf-8"));
18980
19738
  console.log(`mmrc ${pkg.version}`);
18981
19739
  } catch {
18982
19740
  try {
18983
- const pkgPath = resolve6(__dirname, "../../package.json");
18984
- const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
19741
+ const pkgPath = resolve7(__dirname, "../../package.json");
19742
+ const pkg = JSON.parse(readFileSync11(pkgPath, "utf-8"));
18985
19743
  console.log(`mmrc ${pkg.version}`);
18986
19744
  } catch {
18987
19745
  console.log("mmrc (version unknown)");
@@ -18990,10 +19748,10 @@ async function main() {
18990
19748
  } else {
18991
19749
  let version = "";
18992
19750
  try {
18993
- const { readFileSync: readFileSync10 } = await import("fs");
18994
- const { resolve: resolve6 } = await import("path");
18995
- const pkgPath = resolve6(__dirname, "../../package.json");
18996
- const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
19751
+ const { readFileSync: readFileSync11 } = await import("fs");
19752
+ const { resolve: resolve7 } = await import("path");
19753
+ const pkgPath = resolve7(__dirname, "../../package.json");
19754
+ const pkg = JSON.parse(readFileSync11(pkgPath, "utf-8"));
18997
19755
  version = ` v${pkg.version}`;
18998
19756
  } catch {
18999
19757
  }
@@ -19012,6 +19770,7 @@ Commands:
19012
19770
  verify Compile + run verification layers (structural, reachability, safety, liveness, etc.)
19013
19771
  deploy Compile + upload workflows to backend DB
19014
19772
  pull Fetch a definition from DB and scaffold local project
19773
+ engine Manage the mm-api engine binary (install, build, verify, update)
19015
19774
 
19016
19775
  Usage:
19017
19776
  mmrc init <name> [options]
@@ -19074,6 +19833,17 @@ Usage:
19074
19833
  --token Auth token (or use mmrc login / MMRC_TOKEN env var)
19075
19834
  --out Output directory (default: <slug>/)
19076
19835
 
19836
+ mmrc engine <subcommand> [options]
19837
+ status Show installed binary path, version, platform
19838
+ install Download or build mm-api binary (--force to reinstall, --version VER)
19839
+ build Explicitly build from source (cargo build --release -p mm-api)
19840
+ update Check for newer version and download/build (--version VER)
19841
+ verify Run --version and /health check (--binary PATH, --port PORT)
19842
+
19843
+ Platforms: darwin-arm64, darwin-x64, linux-x64, linux-arm64, windows-x64
19844
+ Binary location: ~/.mmrc/bin/mm-api
19845
+ Metadata: ~/.mmrc/bin/mm-api.json
19846
+
19077
19847
  Token resolution (for deploy/pull):
19078
19848
  1. --token flag (highest priority)
19079
19849
  2. MMRC_TOKEN environment variable
@@ -19097,6 +19867,10 @@ Examples:
19097
19867
  mmrc build --src src/workflows
19098
19868
  mmrc deploy --build --src . --api-url http://localhost:4200/api/v1
19099
19869
  mmrc pull my-blueprint --out ./my-project
19870
+ mmrc engine status
19871
+ mmrc engine install
19872
+ mmrc engine build
19873
+ mmrc engine verify
19100
19874
  `);
19101
19875
  }
19102
19876
  }