Ctrl K
ComunidadGuías…

scripts/preview.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { randomBytes } from "node:crypto";
import { join } from "node:path";
import { fileURLToPath } from "node:url";

import { attachBrowserReopenOnEnter, openBrowser } from "../src/browser.js";
import { ensureLocalDashboardBrowserLaunchRoot } from "../src/services/local-dashboard-control.js";
import { startWizardServer } from "../src/web/server.js";

const SESSION_TOKEN_PATTERN = /^[A-Za-z0-9_-]{43}$/u;

const previewRegistrationId = "preview_registration_1";
const previewAccount = Object.freeze({
  registrationId: previewRegistrationId, label: "Preview account",
  email: "preview@example.test", identity: "verified", session: "connected",
  planPermission: "granted", planEnabled: true, ownership: "owned",
  generation: "68f572d8-2b56-4ef2-a6c2-7791078a1161",
  ownerHostId: "urn:uuid:38031c97-8e16-402b-85f8-6c7eb17e72bb",
  ownerRuntimeId: "local", needsPlanWelcome: false,
});

// Select sanitized UI state: RELMIO_PREVIEW_FIXTURE=signed-out|connected|reauthorize|
// plan-not-granted|usage-limit|handoff-pending|staged node scripts/preview.js.
export const PREVIEW_FIXTURES = Object.freeze([
  "signed-out", "connected", "reauthorize", "plan-not-granted", "usage-limit", "handoff-pending", "staged",
]);

export function createPreviewServices(fixture = "connected") {
  if (!PREVIEW_FIXTURES.includes(fixture)) throw new TypeError("Unknown sanitized preview fixture.");
  const account = { ...previewAccount,
    session: ["signed-out", "reauthorize"].includes(fixture) ? fixture : "connected",
    planPermission: fixture === "plan-not-granted" ? "not-granted" : "granted",
    planEnabled: !["signed-out", "reauthorize", "plan-not-granted"].includes(fixture),
    ownership: fixture === "handoff-pending" ? "handoff-pending" : "owned",
  };
  // The guide choice lives in memory for this preview run; preview never writes the preference file.
  const preferences = {};
  return {
  async readUiPreferences() { return { ...preferences }; },
  async writeUiPreferences({ preferences: { guide } }) { preferences.guide = guide; },
  async listAuthRegistrations() { return [account]; },
  async getSelectedRegistration() { return previewRegistrationId; },
  async getAuthStatus({ registrationId }) {
    return { ...account, exists: registrationId === previewRegistrationId && account.session === "connected" };
  },
  async readRegistration({ registrationId }) {
    if (registrationId !== previewRegistrationId) throw new Error("Unknown preview account.");
    return { registrationId, clientId: "preview-client", generation: account.generation };
  },
  async listSiwcModels() { return []; },
  async getProjectMeta() {
    return { version: "preview", stars: null, checkedAt: new Date().toISOString() };
  },
  async getSshCapabilities() { return { agent: { status: "unavailable", transport: null } }; },
  async reviewVpsSiwcTarget() { return { n8nContainerId: "a".repeat(64), networkId: "b".repeat(64) }; },
  async getVpsSiwcInstallationStatus() {
    return fixture === "staged" ? { state: "staged", staging: {
      installId: "preview_installation_1", registrationId: previewRegistrationId, stage: "prepared",
    } } : { state: "absent" };
  },
  async scanHostFingerprint() {
    return "SHA256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
  },
  async connectVerified(request) {
    return {
      close() {},
      identity: Object.freeze({
        host: request.host, port: Number(request.port), fingerprint: request.expectedFingerprint,
        username: request.username, authentication: request.useAgent ? "agent" : "password",
        privilege: request.privilege, loginUid: request.privilege === "root" ? 0 : 1000, effectiveUid: 0,
      }),
      scope: request.privilege === "root" ? "vps" : "local-model-only",
    };
  },
  async discoverN8n() {
    return {
      dockerVersion: "28.3.2",
      composeVersion: "2.38.2",
      containers: [
        {
          id: "a".repeat(64),
          image: "docker.n8n.io/n8nio/n8n",
          name: "n8n-n8n-1",
          state: "running",
        },
      ],
    };
  },
  async discoverNetworks() {
    return { networks: ["proxy"], recommended: "proxy" };
  },
  async installSidecar() {
    throw new Error("Sanitized preview cannot install a ChatGPT sidecar.");
  },
  };
}

export async function runPreview({
  env = process.env,
  log = console.log,
  open = openBrowser,
  attachReopen = attachBrowserReopenOnEnter,
  startServer = startWizardServer,
  ensureBrowserLaunchRoot = ensureLocalDashboardBrowserLaunchRoot,
  createSessionToken = () => randomBytes(32).toString("base64url"),
  signalTarget = process,
} = {}) {
  if (
    typeof log !== "function" || typeof open !== "function" ||
    typeof attachReopen !== "function" || typeof startServer !== "function" ||
    typeof ensureBrowserLaunchRoot !== "function" ||
    typeof createSessionToken !== "function" ||
    !signalTarget || typeof signalTarget.once !== "function" ||
    typeof signalTarget.removeListener !== "function"
  ) {
    throw new TypeError("The Relmio preview launcher adapter is invalid.");
  }

  const sessionToken = createSessionToken();
  if (!SESSION_TOKEN_PATTERN.test(sessionToken)) {
    throw new Error("Relmio could not create a strong preview session.");
  }
  const fixture = env.RELMIO_PREVIEW_FIXTURE ?? "connected";
  const services = createPreviewServices(fixture);
  const browserHandoffRoot = await ensureBrowserLaunchRoot({ env });
  let wizard;
  let detachReopen = () => {};
  let closePromise;

  function onSignal() {
    void close().catch(() => {});
  }

  function close() {
    if (closePromise) return closePromise;
    closePromise = (async () => {
      signalTarget.removeListener("SIGINT", onSignal);
      signalTarget.removeListener("SIGTERM", onSignal);
      detachReopen();
      await wizard?.close();
    })();
    return closePromise;
  }

  try {
    wizard = await startServer({
      sessionToken,
      storageRoot: join(browserHandoffRoot, "siwc-preview"),
      services,
      previewMode: true,
      previewFixture: fixture,
      browserHandoffRoot,
    });
    const prepareLaunch = async () => await wizard.prepareBrowserLaunch("/");
    await open(await prepareLaunch());
    detachReopen = attachReopen({ prepareLaunch, open, write: log });
    if (typeof detachReopen !== "function") {
      throw new TypeError("The Relmio preview reopen adapter is invalid.");
    }
    signalTarget.once("SIGINT", onSignal);
    signalTarget.once("SIGTERM", onSignal);
    log(
      "Sanitized preview opened through a private browser handoff. Live ChatGPT sign-in is disabled. Press Control+C to stop.",
    );
    return Object.freeze({ close });
  } catch (error) {
    await close();
    throw error;
  }
}

if (process.argv[1] === fileURLToPath(import.meta.url)) {
  try {
    await runPreview();
  } catch (error) {
    console.error(error.message);
    process.exitCode = 1;
  }
}