UNPKG

@bonginkan/maria

Version:

MARIA OS v5.9.5 – Self-Evolving Organizational Intelligence OS | Speed Improvement Phase 3: LLM Optimization + Command Refactoring | Performance Measurement + Run Evidence System | Zero ESLint/TypeScript Errors | 人とAIが役割を持ち、学び、進化し続けるための仕事のOS | GraphRAG ×

1,421 lines (1,411 loc) 23 MB
#!/usr/bin/env node 'use strict'; var util$1 = require('util'); var chalk73 = require('chalk'); var fs87 = require('fs'); var path258 = require('path'); var dotenv = require('dotenv'); var crypto3 = require('crypto'); var http2 = require('http'); var Url = require('url'); var os29 = require('os'); var child_process = require('child_process'); var fs231 = require('fs/promises'); var secretManager = require('@google-cloud/secret-manager'); var module$1 = require('module'); var zod = require('zod'); var async_hooks = require('async_hooks'); var promises = require('timers/promises'); var events = require('events'); var Stream4 = require('stream'); var string_decoder = require('string_decoder'); var perf_hooks = require('perf_hooks'); var process2 = require('process'); var readline6 = require('readline'); var buffer = require('buffer'); var net = require('net'); var https = require('https'); var zlib2 = require('zlib'); var promises$1 = require('stream/promises'); var yaml61 = require('js-yaml'); var Ajv = require('ajv'); var addFormats = require('ajv-formats'); var micromatch = require('micromatch'); var toml = require('toml'); var winston = require('winston'); var firestore = require('@google-cloud/firestore'); var Ajv2020 = require('ajv/dist/2020'); var semver = require('semver'); var querystring = require('querystring'); var googleAuthLibrary = require('google-auth-library'); var pLimit = require('p-limit'); var neo4j = require('neo4j-driver'); var prompts = require('prompts'); var Ajv20203 = require('ajv/dist/2020.js'); var commander = require('commander'); var readlinePromises = require('readline/promises'); var axios = require('axios'); var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null; function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var chalk73__namespace = /*#__PURE__*/_interopNamespace(chalk73); var fs87__namespace = /*#__PURE__*/_interopNamespace(fs87); var path258__namespace = /*#__PURE__*/_interopNamespace(path258); var dotenv__namespace = /*#__PURE__*/_interopNamespace(dotenv); var crypto3__namespace = /*#__PURE__*/_interopNamespace(crypto3); var http2__namespace = /*#__PURE__*/_interopNamespace(http2); var Url__namespace = /*#__PURE__*/_interopNamespace(Url); var os29__namespace = /*#__PURE__*/_interopNamespace(os29); var fs231__namespace = /*#__PURE__*/_interopNamespace(fs231); var Stream4__default = /*#__PURE__*/_interopDefault(Stream4); var process2__namespace = /*#__PURE__*/_interopNamespace(process2); var readline6__namespace = /*#__PURE__*/_interopNamespace(readline6); var https__default = /*#__PURE__*/_interopDefault(https); var zlib2__namespace = /*#__PURE__*/_interopNamespace(zlib2); var yaml61__namespace = /*#__PURE__*/_interopNamespace(yaml61); var Ajv__default = /*#__PURE__*/_interopDefault(Ajv); var addFormats__default = /*#__PURE__*/_interopDefault(addFormats); var micromatch__default = /*#__PURE__*/_interopDefault(micromatch); var winston__default = /*#__PURE__*/_interopDefault(winston); var Ajv2020__default = /*#__PURE__*/_interopDefault(Ajv2020); var semver__default = /*#__PURE__*/_interopDefault(semver); var querystring__namespace = /*#__PURE__*/_interopNamespace(querystring); var pLimit__default = /*#__PURE__*/_interopDefault(pLimit); var neo4j__default = /*#__PURE__*/_interopDefault(neo4j); var prompts__default = /*#__PURE__*/_interopDefault(prompts); var Ajv20203__default = /*#__PURE__*/_interopDefault(Ajv20203); var readlinePromises__namespace = /*#__PURE__*/_interopNamespace(readlinePromises); var axios__default = /*#__PURE__*/_interopDefault(axios); var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __require = /* @__PURE__ */ ((x2) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x2, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x2)(function(x2) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error('Dynamic require of "' + x2 + '" is not supported'); }); var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __commonJS = (cb, mod) => function __require2() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. __defProp(target, "default", { value: mod, enumerable: true }) , mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); function isTestEnv() { return process.env.NODE_ENV === "test" || process.env.VITEST === "true" || process.env.VITEST_WORKER_ID != null || process.env.JEST_WORKER_ID != null; } function isMockFn(fn) { if (!fn || typeof fn !== "function") return false; const meta72 = fn; return Array.isArray(meta72.mock?.calls); } function stdoutLine(...args) { const text = format(...args); if (isTestEnv()) { process.stdout.write(`${text} `); if (isMockFn(console.log)) console.log(text); return; } process.stdout.write(`${text} `); } function stderrLine(...args) { const text = format(...args); if (isTestEnv()) { process.stderr.write(`${text} `); if (isMockFn(console.error)) console.error(text); return; } process.stderr.write(`${text} `); } var format; var init_tty = __esm({ "src/shared/utils/tty.ts"() { format = util$1.format; } }); var LogLevel, Logger, ChildCapableConsoleLogger, logger, envLogLevel, envLogFormat; var init_logger = __esm({ "src/utils/logger.ts"() { init_tty(); LogLevel = /* @__PURE__ */ ((LogLevel2) => { LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG"; LogLevel2[LogLevel2["INFO"] = 1] = "INFO"; LogLevel2[LogLevel2["WARN"] = 2] = "WARN"; LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR"; LogLevel2[LogLevel2["NONE"] = 4] = "NONE"; return LogLevel2; })(LogLevel || {}); Logger = class _Logger { level = 2 /* WARN */; // Default to WARN to reduce noise prefix; format = "pretty"; constructor(context) { this.prefix = context ? `[MARIA CODE][${context}]` : "[MARIA CODE]"; } setLevel(level) { this.level = level; } setFormat(format2) { this.format = format2; } out(level, tag, args) { const consoleFn = console[level]; if (this.format === "json") { const payload = { ts: (/* @__PURE__ */ new Date()).toISOString(), level: tag.replace(/\[|\]/g, "").toLowerCase(), msg: args.map(String).join(" ") }; consoleFn(JSON.stringify(payload)); return; } const debugMode = process.env.MARIA_DEBUG === "1"; const isError = tag.includes("[ERROR]"); let outArgs = args; if (isError && !debugMode) { const filtered = []; for (const a of args) { const t2 = typeof a; if (a == null || t2 === "string" || t2 === "number" || t2 === "boolean") { filtered.push(a); } } outArgs = filtered; } if (tag) { consoleFn(tag, ...outArgs); } else { consoleFn(...outArgs); } } debug(message, fields) { if (this.level <= 0 /* DEBUG */) { const args = fields ? [message, fields] : [message]; this.out("log", chalk73__namespace.default.magenta(`${this.prefix} [DEBUG]`), args); } } info(message, fields) { if (this.level <= 1 /* INFO */) { const args = fields ? [message, fields] : [message]; this.out("log", chalk73__namespace.default.bold.magenta(`${this.prefix} [INFO]`), args); } } warn(message, fields) { if (this.level <= 2 /* WARN */) { const args = fields ? [message, fields] : [message]; this.out("warn", chalk73__namespace.default.bold.magenta(`${this.prefix} [WARN]`), args); } } error(message, fields) { if (this.level <= 3 /* ERROR */) { const args = fields ? [message, fields] : [message]; this.out("error", chalk73__namespace.default.bold.magenta(`${this.prefix} [ERROR]`), args); } } success(...args) { if (this.level <= 1 /* INFO */) { this.out("log", chalk73__namespace.default.bold.magenta(`${this.prefix} [SUCCESS]`), args); } } task(taskName, status, message) { if (process.env.MARIA_BENCH_MODE === "1") return; if (this.level > 1 /* INFO */) { return; } const statusIcons = { start: "\u{1F680}", progress: "\u23F3", complete: "\u2705", error: "\u274C" }; const statusColors = { start: chalk73__namespace.default.bold.magenta, progress: chalk73__namespace.default.magenta, complete: chalk73__namespace.default.bold.magenta, error: chalk73__namespace.default.bold.magenta }; const icon = statusIcons[status]; const color = statusColors[status]; const formattedMessage = message ? `: ${message}` : ""; stdoutLine(color(`${this.prefix} ${icon} ${taskName}${formattedMessage}`)); } table(data) { if (this.level > 1 /* INFO */) { return; } stdoutLine(data); } json(obj, pretty = true) { if (this.level > 0 /* DEBUG */) { return; } if (this.format === "json") { this.out("log", "", [JSON.stringify(obj)]); } else { stdoutLine(chalk73__namespace.default.magenta(`${this.prefix} [JSON]`)); stdoutLine(pretty ? JSON.stringify(obj, null, 2) : JSON.stringify(obj)); } } divider() { if (this.level > 1 /* INFO */) { return; } stdoutLine(chalk73__namespace.default.magenta("\u2500".repeat(60))); } /** * Create a child logger with additional context. * * For compatibility with existing code, supports a pino-like signature: * `logger.child({ module: "name" })`. * - If context is a string, use it directly as the prefix context. * - If context is an object, prefer the `module` field; otherwise join `key=value` pairs. */ child(context) { let ctx; if (typeof context === "string") { ctx = context; } else if (context && typeof context === "object") { const obj = context; if (typeof obj.module === "string" && obj.module.length > 0) { ctx = obj.module; } else { const entries = Object.entries(obj).filter(([_, v]) => v != null).map(([k, v]) => `${k}=${String(v)}`); ctx = entries.join(","); } } const childLogger = new _Logger(ctx); childLogger.setLevel(this.level); childLogger.setFormat(this.format); return childLogger; } clear() { console.clear(); } /** * Render a progress bar. */ progress(current, total, label) { if (process.env.MARIA_BENCH_MODE === "1") return; if (this.level > 1 /* INFO */) { return; } const percentage = Math.round(current / total * 100); const barLength = 30; const filled = Math.round(percentage / 100 * barLength); const empty = barLength - filled; const bar = "\u2588".repeat(filled) + "\u2591".repeat(empty); const progressText = `${current}/${total}`; const labelText = label ? ` ${label}` : ""; process.stdout.write( `\r${chalk73__namespace.default.bold.magenta(bar)} ${percentage}% ${progressText}${labelText}` ); if (current === total) { process.stdout.write("\n"); } } }; ChildCapableConsoleLogger = class _ChildCapableConsoleLogger extends Logger { constructor(context) { super(context); } child(fields) { const moduleName = fields && typeof fields.module === "string" && fields.module || void 0; const ctx = moduleName ? moduleName : void 0; return new _ChildCapableConsoleLogger(ctx); } }; logger = new ChildCapableConsoleLogger(); envLogLevel = process.env["MARIA_LOG_LEVEL"]?.toUpperCase(); if (envLogLevel && LogLevel[envLogLevel] !== void 0) { logger.setLevel(LogLevel[envLogLevel]); } envLogFormat = process.env["MARIA_LOG_FORMAT"]?.toLowerCase(); if (envLogFormat === "json" || envLogFormat === "pretty") { logger.setFormat(envLogFormat); } } }); // src/adapters/logging/default.ts var defaultLogger; var init_default = __esm({ "src/adapters/logging/default.ts"() { init_logger(); defaultLogger = logger; } }); function isLocalMode() { return String(process.env.LOCAL_MODE || "").trim() === "1" || String(process.env.MARIA_AUTH_MODE || "").trim().toLowerCase() === "local" || String(process.env.MARIA_LOCAL_ONLY || "").trim() === "1"; } function findEnvRoot(startDir) { const explicit = String(process.env.MARIA_ENV_ROOT || "").trim(); if (explicit) return explicit; let cur = startDir; for (let i2 = 0; i2 < 25; i2 += 1) { const envLocal = path258__namespace.join(cur, ".env.local"); const env = path258__namespace.join(cur, ".env"); const lmstudio = path258__namespace.join(cur, ".env.lmstudio"); if (fs87__namespace.existsSync(envLocal) || fs87__namespace.existsSync(env) || fs87__namespace.existsSync(lmstudio)) return cur; const parent = path258__namespace.dirname(cur); if (parent === cur) break; cur = parent; } return startDir; } function loadEnvironmentVariables(options) { if (environmentLoaded && true) return; environmentLoaded = true; const cwd2 = process.cwd(); const envRoot = findEnvRoot(cwd2); const _envPath = path258__namespace.join(envRoot, ".env"); if (fs87__namespace.existsSync(_envPath)) { const _result = dotenv__namespace.config({ path: _envPath }); if (_result.error) { defaultLogger.warn("Error loading .env", { error: _result.error }); } } const _envLocalPath = path258__namespace.join(envRoot, ".env.local"); const hasEnvLocal = fs87__namespace.existsSync(_envLocalPath); if (hasEnvLocal) { const _result = dotenv__namespace.config({ path: _envLocalPath, override: true }); if (_result.error) { defaultLogger.warn("Error loading .env.local", { error: _result.error }); } } else if (isLocalMode()) { defaultLogger.warn("LOCAL_MODE: .env.local not found", { envRoot, message: "Create .env.local to configure local LLM (ollama/lmstudio/vllm)." }); } const _lmstudioEnvPath = path258__namespace.join(envRoot, ".env.lmstudio"); if (fs87__namespace.existsSync(_lmstudioEnvPath)) { const _result = dotenv__namespace.config({ path: _lmstudioEnvPath, override: false }); if (_result.error) { defaultLogger.warn("Error loading .env.lmstudio", { error: _result.error }); } } if (!process.env.MARIA_API_BASE) process.env.MARIA_API_BASE = "https://api.maria-code.ai"; if (!process.env.MARIA_USE_API) process.env.MARIA_USE_API = "1"; if (!process.env.MARIA_USE_REMOTE_MEDIA) process.env.MARIA_USE_REMOTE_MEDIA = "1"; if (isLocalMode()) { if (!process.env.MARIA_PLAN_ID) process.env.MARIA_PLAN_ID = "pro"; if (!process.env.MARIA_LOCAL_LLM_PROVIDER) process.env.MARIA_LOCAL_LLM_PROVIDER = "ollama"; const provider = String(process.env.MARIA_LOCAL_LLM_PROVIDER || "").trim().toLowerCase(); if (!process.env.MARIA_LOCAL_LLM_MODEL) { if (provider === "ollama") process.env.MARIA_LOCAL_LLM_MODEL = "gpt-oss:latest"; else if (provider === "lmstudio") process.env.MARIA_LOCAL_LLM_MODEL = "openai/gpt-oss-120b"; else process.env.MARIA_LOCAL_LLM_MODEL = "vllm-model"; } if (provider === "lmstudio") { if (!process.env.LMSTUDIO_BASE_URL) process.env.LMSTUDIO_BASE_URL = "http://127.0.0.1:1234/v1"; if (!process.env.MARIA_LMSTUDIO_AUTO_START) process.env.MARIA_LMSTUDIO_AUTO_START = "1"; } else if (provider === "ollama") { if (!process.env.OLLAMA_API_BASE) process.env.OLLAMA_API_BASE = "http://localhost:11434"; } else if (provider === "vllm") { if (!process.env.VLLM_API_BASE) process.env.VLLM_API_BASE = "http://localhost:8000/v1"; } } } var environmentLoaded; var init_env_loader = __esm({ "src/utils/env-loader.ts"() { init_default(); environmentLoaded = false; } }); function getVersion() { if (_cachedVersion) { return _cachedVersion; } try { const packageJson4 = getPackageJson(); _cachedVersion = packageJson4.version; return _cachedVersion; } catch (_error) { _cachedVersion = "latest"; return _cachedVersion; } } function getPackageJson() { if (_cachedPackageJson) { return _cachedPackageJson; } try { const possiblePaths = [ // When running from built dist/ path258.join(__dirname, "../../package.json"), // When running from source path258.join(__dirname, "../../../package.json"), // Current working directory path258.join(process.cwd(), "package.json"), // One level up from current working directory path258.join(process.cwd(), "../package.json"), // For globally installed packages path258.join(__dirname, "../../../../package.json"), path258.join(__dirname, "../../../../../package.json"), // npm global install locations "/usr/local/lib/node_modules/@bonginkan/maria/package.json", "/usr/lib/node_modules/@bonginkan/maria/package.json", // User home npm global path258.join( process.env.HOME || "", ".npm-global/lib/node_modules/@bonginkan/maria/package.json" ), path258.join( process.env.HOME || "", ".nvm/versions/node", process.version, "lib/node_modules/@bonginkan/maria/package.json" ) ]; let packageJsonPath = null; for (const path410 of possiblePaths) { if (fs87.existsSync(path410)) { try { const content = fs87.readFileSync(path410, "utf-8"); const parsed = JSON.parse(content); if (parsed.name === "@bonginkan/maria") { packageJsonPath = path410; break; } } catch { continue; } } } if (!packageJsonPath) { throw new Error("package.json not found in any expected location"); } const packageJsonContent = fs87.readFileSync(packageJsonPath, "utf-8"); _cachedPackageJson = JSON.parse(packageJsonContent); return _cachedPackageJson; } catch (_error) { throw new Error(`Failed to read package.json: ${_error}`); } } var _cachedVersion, _cachedPackageJson; var init_version = __esm({ "src/utils/version.ts"() { _cachedVersion = null; _cachedPackageJson = null; getVersion(); } }); // src/utils/ora-shim.ts function createSpinner(initialText) { let active = false; let text = initialText || ""; const writeLine2 = (prefix, lineText) => { if (process.stderr.isTTY) { process.stderr.write(`\r${prefix} ${lineText} `); } else { process.stdout.write(`${prefix} ${lineText} `); } }; const api = { start(t2) { if (typeof t2 === "string") text = t2; active = true; if (process.stderr.isTTY) { process.stderr.write(`\r${text}`); } return api; }, stop() { if (active && process.stderr.isTTY) { process.stderr.write("\r\x1B[K"); } active = false; return api; }, succeed(t2) { if (typeof t2 === "string") text = t2; writeLine2("\u2705", text); active = false; return api; }, fail(t2) { if (typeof t2 === "string") text = t2; writeLine2("\u274C", text); active = false; return api; }, warn(t2) { if (typeof t2 === "string") text = t2; writeLine2("\u26A0\uFE0F", text); active = false; return api; }, info(t2) { if (typeof t2 === "string") text = t2; writeLine2("\u2139\uFE0F", text); active = false; return api; }, stopAndPersist(opts) { const symbol = opts?.symbol ?? "\u2022"; const persistedText = typeof opts?.text === "string" ? opts?.text : text; writeLine2(symbol, persistedText); active = false; return api; }, get text() { return text; }, set text(t2) { text = t2; if (active && process.stderr.isTTY) { process.stderr.write(`\r${text}`); } }, color: "cyan" }; return api; } function ora(options) { const text = typeof options === "string" ? options : options?.text; return createSpinner(text); } var init_ora_shim = __esm({ "src/utils/ora-shim.ts"() { } }); // src/services/interactive-session/display/SpinnerManager.ts var SpinnerManager; var init_SpinnerManager = __esm({ "src/services/interactive-session/display/SpinnerManager.ts"() { init_ora_shim(); SpinnerManager = class _SpinnerManager { static instance; spinners = /* @__PURE__ */ new Map(); spinnerId = 0; // Default auto-stop safety limit (ms). // NOTE: This is only a UX guard for spinners. Long-running jobs (e.g., /akashic scan) should not "timeout" at 30s. // - MARIA_SPINNER_AUTOSTOP_MS=0 disables auto-stop // - Default: 10 minutes defaultAutoStopMs; /** * Enforce "only one spinner at a time" across the entire process. * This is the key to preventing double spinners + flicker. */ activeExclusiveId = null; /** * When ora is disabled in non-TTY environments, print exactly one line so the UI doesn't look "frozen". * To prevent log spam, print only once per process. */ nonInteractiveLoggedOnce = false; constructor() { const raw = String(process.env.MARIA_SPINNER_AUTOSTOP_MS || "").trim(); const parsed = raw ? Number.parseInt(raw, 10) : NaN; const fallback = 10 * 6e4; this.defaultAutoStopMs = Number.isFinite(parsed) ? Math.max(0, parsed) : fallback; process.on("exit", () => this.clearAll()); process.on("SIGINT", () => this.clearAll()); process.on("SIGTERM", () => this.clearAll()); } /** * Get singleton instance */ static getInstance() { if (!_SpinnerManager.instance) { _SpinnerManager.instance = new _SpinnerManager(); } return _SpinnerManager.instance; } /** * Start a new spinner * @param options - Spinner configuration * @returns Spinner ID for later stopping */ start(options = {}) { const { text = "Processing...", spinner = "dots", color = "cyan", autoStopMs = this.defaultAutoStopMs } = options; this.clearAll(); const id2 = `spinner-${++this.spinnerId}`; const isTestEnv8 = process.env.NODE_ENV === "test" || process.env.VITEST_WORKER_ID != null || process.env.JEST_WORKER_ID != null; const disabled = process.env.MARIA_DISABLE_ANIMATIONS === "1" || String(process.env.MARIA_DISABLE_SPINNER || "0") === "1"; const stdinObj = process.stdin; const stdinIsTty = Boolean(stdinObj?.isTTY); const processObjForTty = process; const hasTty = Boolean( process.stdout.isTTY || processObjForTty?.stderr?.isTTY || stdinIsTty ); const canAnimate = process.env.MARIA_FORCE_ANIMATIONS === "1" || !isTestEnv8 && !disabled && hasTty; if (!canAnimate) { const activeSpinner2 = { id: id2, spinner: null, startTime: Date.now(), nonInteractive: true, text }; this.spinners.set(id2, activeSpinner2); this.activeExclusiveId = id2; if (!disabled && !this.nonInteractiveLoggedOnce) { this.nonInteractiveLoggedOnce = true; try { process.stdout.write(`${text} `); } catch { } } return id2; } const processObjForStream = process; const stream2 = process.stdout.isTTY ? process.stdout : processObjForStream?.stderr && processObjForStream.stderr.isTTY ? processObjForStream.stderr : process.stdout; const spinnerValue = spinner && (typeof spinner === "string" || typeof spinner === "object" && spinner !== null && "interval" in spinner && "frames" in spinner) ? spinner : void 0; const oraSpinner = ora({ text, spinner: spinnerValue, color, stream: stream2, // Force-enable when explicitly requested, or when stdin is a TTY but output streams // fail to report TTY (common in some wrappers). This prevents "frozen [0s]" UX. isEnabled: process.env.MARIA_FORCE_ANIMATIONS === "1" || stdinIsTty && !isTestEnv8 && !disabled }).start(); let autoStopTimer; if (autoStopMs > 0) { autoStopTimer = setTimeout(() => { this.stop(id2, "timeout"); }, autoStopMs); const timer = autoStopTimer; timer?.unref?.(); } const activeSpinner = { id: id2, spinner: oraSpinner, startTime: Date.now(), autoStopTimer }; this.spinners.set(id2, activeSpinner); this.activeExclusiveId = id2; return id2; } /** * Stop a specific spinner * @param id - Spinner ID * @param reason - Stop reason (success/fail/warn/info/timeout) */ stop(id2, reason = "success") { const activeSpinner = this.spinners.get(id2); if (!activeSpinner) return; if (activeSpinner.autoStopTimer) { clearTimeout(activeSpinner.autoStopTimer); } if (activeSpinner.nonInteractive || !activeSpinner.spinner) { this.spinners.delete(id2); if (this.activeExclusiveId === id2) { this.activeExclusiveId = null; } return; } const { spinner } = activeSpinner; const duration = Date.now() - activeSpinner.startTime; const durationText = duration > 1e3 ? ` (${(duration / 1e3).toFixed(1)}s)` : ""; const s2 = spinner; const safeCall = (method, text, fallbackSymbol) => { try { const fn = s2[method]; if (typeof fn === "function") { fn.call(spinner, text); return; } if (typeof s2.stopAndPersist === "function") { s2.stopAndPersist({ symbol: fallbackSymbol, text }); return; } s2.stop?.(); } catch { try { s2.stop?.(); } catch { } } }; switch (reason) { case "success": safeCall("succeed", spinner.text + durationText, "\u2714"); break; case "fail": safeCall("fail", spinner.text + durationText, "\u2716"); break; case "warn": safeCall("warn", spinner.text + durationText, "\u26A0"); break; case "info": safeCall("info", spinner.text + durationText, "\u2139"); break; case "timeout": safeCall( "warn", `${spinner.text} (timed out after ${duration / 1e3}s)`, "\u26A0" ); break; default: try { s2.stop?.(); } catch { } } this.spinners.delete(id2); if (this.activeExclusiveId === id2) { this.activeExclusiveId = null; } } /** * Stop a spinner silently (no succeed/fail/info line). This is important when * switching between different spinner sources to avoid "extra lines" flicker. */ clear(id2) { const activeSpinner = this.spinners.get(id2); if (!activeSpinner) return; if (activeSpinner.autoStopTimer) { clearTimeout(activeSpinner.autoStopTimer); } try { activeSpinner.spinner?.stop(); } catch { } this.spinners.delete(id2); if (this.activeExclusiveId === id2) { this.activeExclusiveId = null; } } /** * Clear all active spinners silently. */ clearAll() { for (const [id2] of this.spinners) { this.clear(id2); } this.activeExclusiveId = null; } /** * Update spinner text * @param id - Spinner ID * @param text - New text */ update(id2, text) { const activeSpinner = this.spinners.get(id2); if (activeSpinner) { activeSpinner.text = text; if (activeSpinner.spinner) { activeSpinner.spinner.text = text; } } } /** * Update spinner color (best-effort; depends on ora implementation). */ setColor(id2, color) { const activeSpinner = this.spinners.get(id2); if (activeSpinner?.spinner) { try { const spinner = activeSpinner.spinner; if (spinner) spinner.color = color; } catch { } } } /** * Stop all active spinners * @param reason - Stop reason for all spinners */ stopAll(reason = "info") { for (const [id2] of this.spinners) { this.stop(id2, reason); } } /** * Get count of active spinners */ getActiveCount() { return this.spinners.size; } /** * Check if a spinner is active * @param id - Spinner ID */ isActive(id2) { return this.spinners.has(id2); } /** * Execute a function with a spinner that auto-stops * @param fn - Function to execute * @param options - Spinner options * @returns Function result */ async withSpinner(fn, options = {}) { const spinnerId = this.start(options); try { const result = await fn(); this.stop(spinnerId, "success"); return result; } catch (error) { this.stop(spinnerId, "fail"); throw error; } } /** * Create a progress spinner that updates with percentage * @param total - Total items * @param text - Base text * @returns Object with update and stop methods */ createProgress(total, text = "Processing") { const id2 = this.start({ text: `${text} (0/${total})` }); return { id: id2, update: (current) => { const percentage = Math.round(current / total * 100); this.update(id2, `${text} (${current}/${total}) ${percentage}%`); }, stop: (reason = "success") => { this.stop(id2, reason); } }; } /** * Reset the manager (for testing) */ reset() { this.clearAll(); this.spinners.clear(); this.spinnerId = 0; this.activeExclusiveId = null; this.nonInteractiveLoggedOnce = false; } /** * Compatibility hook for callers that expect an async cleanup. */ async cleanup() { this.clearAll(); } }; } }); // src/utils/animations.ts var animations_exports = {}; __export(animations_exports, { BrainAnimation: () => BrainAnimation, CodeGenerationAnimation: () => CodeGenerationAnimation, LoadingDots: () => LoadingDots, ProcessAnimation: () => ProcessAnimation, ProgressBar: () => ProgressBar, StreamingOutput: () => StreamingOutput, ThinkingAnimation: () => ThinkingAnimation, showCodeGenerationAnimation: () => showCodeGenerationAnimation }); function showCodeGenerationAnimation() { const messages = [ "Analyzing requirements", "Designing architecture", "Writing code", "Adding documentation", "Optimizing performance", "Final review" ]; const animation = new ThinkingAnimation(messages[0]); animation.start(); let messageIndex = 0; const messageInterval = setInterval(() => { messageIndex = (messageIndex + 1) % messages.length; animation.updateMessage(messages[messageIndex]); }, 2e3); animation.messageInterval = messageInterval; const originalStop = animation.stop.bind(animation); animation.stop = () => { clearInterval(messageInterval); originalStop(); }; return animation; } var ThinkingAnimation, ProcessAnimation, CodeGenerationAnimation, LoadingDots, BrainAnimation, ProgressBar, StreamingOutput; var init_animations = __esm({ "src/utils/animations.ts"() { init_SpinnerManager(); ThinkingAnimation = class _ThinkingAnimation { static current = null; message; spinnerManager = SpinnerManager.getInstance(); spinnerId = null; nonInteractive = false; constructor(message = "Thinking") { this.message = message; } static hasActive() { return !!_ThinkingAnimation.current; } start() { const isTestEnv8 = process.env.NODE_ENV === "test" || process.env.VITEST_WORKER_ID != null || process.env.JEST_WORKER_ID != null; const disabled = process.env.MARIA_DISABLE_ANIMATIONS === "1" || String(process.env.MARIA_DISABLE_SPINNER || "0") === "1"; const hasTty = Boolean( process.stdout.isTTY || process.stderr.isTTY || process.stdin.isTTY ); const canAnimate = process.env.MARIA_FORCE_ANIMATIONS === "1" || !isTestEnv8 && !disabled && hasTty; if (_ThinkingAnimation.current && _ThinkingAnimation.current !== this) { try { _ThinkingAnimation.current.stop(); } catch { } } _ThinkingAnimation.current = this; if (!canAnimate) { this.nonInteractive = true; try { process.stderr.write(`${this.message}... `); } catch { } return; } this.nonInteractive = false; this.spinnerId = this.spinnerManager.start({ // Use default terminal foreground (with bold) for better contrast on both dark/light themes. text: `${chalk73__namespace.default.bold(this.message)}...`, spinner: { frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"], interval: 80 }, color: "cyan" }); } stop() { if (this.spinnerId) { this.spinnerManager.clear(this.spinnerId); this.spinnerId = null; } if (_ThinkingAnimation.current === this) { _ThinkingAnimation.current = null; } this.nonInteractive = false; } updateMessage(message) { this.message = message; if (this.spinnerId) { this.spinnerManager.update(this.spinnerId, `${chalk73__namespace.default.bold(this.message)}...`); } } }; ProcessAnimation = class _ProcessAnimation { static current = null; /** * In non-interactive environments (e.g. stdout.isTTY=false), * emit a single line to avoid "no output" UX. * * If multiple ProcessAnimation instances run nested within a single command, * only emit at the 0→1 depth transition to avoid log spam. */ static nonInteractiveDepth = 0; stages; stageIntervalMs; currentStage = 0; updateInterval = null; stageInterval = null; startTime = 0; spinnerManager = SpinnerManager.getInstance(); spinnerId = null; lastText = ""; nonInteractiveStarted = false; constructor(options) { const defaultStages = [ // Keep messages 1-word English to reduce noise in CLI (fast scans, high XAI). { icon: "\u{1F9E0}", message: "Parse" }, { icon: "\u{1F50D}", message: "Analyze" }, { icon: "\u{1F4AD}", message: "Reason" }, { icon: "\u2728", message: "Generate" }, { icon: "\u{1F4DD}", message: "Format" } ]; this.stages = options?.stages && options.stages.length > 0 ? options.stages : defaultStages; this.stageIntervalMs = typeof options?.stageIntervalMs === "number" ? options.stageIntervalMs : 3e3; } // Expose whether any ProcessAnimation is currently active static hasActive() { return !!_ProcessAnimation.current || _ProcessAnimation.nonInteractiveDepth > 0; } /** * Determine whether animated output should be used. * * - If not a TTY (e.g. build / docs generation environments like `@node`), * avoid spinners to keep logs stable. * - Disable when `MARIA_DISABLE_ANIMATIONS=1` is set. */ shouldUseAnimatedOutput() { if (process.env.MARIA_FORCE_ANIMATIONS === "1") { return true; } const isTestEnv8 = process.env.NODE_ENV === "test" || process.env.VITEST_WORKER_ID != null || process.env.JEST_WORKER_ID != null; if (isTestEnv8) { return false; } if (process.env.MARIA_DISABLE_ANIMATIONS === "1") { return false; } if (String(process.env.MARIA_DISABLE_SPINNER || "0") === "1") { return false; } return Boolean(process.stdout.isTTY || process.stderr.isTTY || process.stdin.isTTY); } start() { this.startTime = Date.now(); this.currentStage = 0; this.lastText = ""; this.nonInteractiveStarted = false; if (!this.shouldUseAnimatedOutput()) { _ProcessAnimation.nonInteractiveDepth += 1; if (_ProcessAnimation.nonInteractiveDepth === 1) { const stage = this.stages[this.currentStage]; const elapsed = Math.floor((Date.now() - this.startTime) / 1e3); try { process.stderr.write(`${stage.icon} ${stage.message}... [${elapsed}s] `); } catch { } this.nonInteractiveStarted = true; } return; } if (_ProcessAnimation.current && _ProcessAnimation.current !== this) { try { _ProcessAnimation.current.stop(); } catch { } } _ProcessAnimation.current = this; this.spinnerId = this.spinnerManager.start({ text: this.renderText(), spinner: { frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"], interval: 80 }, color: "cyan" }); this.lastText = this.renderText(); this.updateInterval = setInterval(() => { if (!this.spinnerId) return; const next = this.renderText(); if (next !== this.lastText) { this.spinnerManager.update(this.spinnerId, next); this.lastText = next; } }, 250); if (this.stageIntervalMs > 0 && this.stages.length > 1) { this.stageInterval = setInterval(() => { if (this.currentStage < this.stages.length - 1) { this.currentStage++; } }, this.stageIntervalMs); } } stop() { if (!this.spinnerId) { if (this.nonInteractiveStarted) { _ProcessAnimation.nonInteractiveDepth = Math.max( 0, _ProcessAnimation.nonInteractiveDepth - 1 ); this.nonInteractiveStarted = false; } else if (_ProcessAnimation.nonInteractiveDepth > 0) { _ProcessAnimation.nonInteractiveDepth = Math.max( 0, _ProcessAnimation.nonInteractiveDepth - 1 ); } return; } if (this.updateInterval) { clearInterval(this.updateInterval); this.updateInterval = null; } if (this.stageInterval) { clearInterval(this.stageInterval); this.stageInterval = null; } if (this.spinnerId) { this.spinnerManager.clear(this.spinnerId); this.spinnerId = null; } if (_ProcessAnimation.current === this) { _ProcessAnimation.current = null; } } setStage(stageIndex) { if (stageIndex >= 0 && stageIndex < this.stages.length) { this.currentStage = stageIndex; } } /** * Replace stages for this animation instance. * Useful to customize spinner text per command. */ setStages(stages) { if (!Array.isArray(stages) || stages.length === 0) return; this.stages = stages; this.currentStage = 0; } renderText() { const elapsed = Math.floor((Date.now() - this.startTime) / 1e3); const stage = this.stages[this.currentStage]; return `${stage.icon} ${chalk73__namespace.default.bold(stage.message)}... ${chalk73__namespace.default.dim(`[${elapsed}s]`)}`; } }; CodeGenerationAnimation = class { currentStage = 0; updateInterval = null; stageInterval = null; startTime = 0; isComplex = false; spinnerManager = SpinnerManager.getInstance(); spinnerId = null; lastText = ""; // Simple stages for quick generation simpleStages = [ "Generating code" ]; // Complex stages for detailed generation complexStages = [ "Understanding request", "Analyzing requirements", "Planning structure", "Designing solution", "Writing implementation", "Optimizing code", "Finalizing output" ]; constructor(isComplex = false) { this.isComplex = isComplex; } start() { this.startTime = Date.now(); this.currentStage = 0; this.lastText = ""; const stages = this.isComplex ? this.complexStages : this.simpleStages; const render = () => { const elapsed = Math.floor((Date.now() - this.startTime) / 1e3); const stage = stages[this.currentStage]; return this.isComplex ? `${chalk73__namespace.default.bold(stage)} ${chalk73__namespace.default.dim(`[${elapsed}s]`)}` : `${chalk73__namespace.default.bold(stage)}...`; }; this.spinnerId = this.spinnerManager.start({ text: render(), spinner: { frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"], interval: 80 }, color: "cyan" }); this.lastText = render(); this.updateInterval = setInterval(() => { if (!this.spinnerId) return; const next = render(); if (next !== this.lastText) { this.spinnerManager.update(this.spinnerId, next); this.lastText = next; } }, 250); if (this.isComplex) { this.stageInterval = setInterval(() => { if (this.currentStage < stages.length - 1) { this.currentStage++; } }, 2e3); } } stop() { if (this.updateInterval) { clearInterval(this.updateInterval); this.updateInterval = null; } if (this.stageInterval) { clearInterval(this.stageInterval); this.stageInterval = null; } if (this.spinnerId) { this.spinnerManager.clear(this.spinnerId); this.spinnerId = null; } } // Manually advance to next stage nextStage() { const stages = this.isComplex ? this.complexStages : this.simpleStages; if (this.currentStage < stages.length - 1) { this.currentStage++; } } }; LoadingDots = class { dots = [" ", ". ", ".. ", "..."]; currentDot = 0; interval = null; message; constructor(message = "Loading") { this.message = message; } start() { this.interval = setInterval(() => { process.stdout.write( `\r${chalk73__namespace.default.cyan(this.message)}${this.dots[this.currentDot]}` ); this.currentDot = (this.currentDot + 1) % this.dots.length; }, 300); } stop() { if (this.interval) { clearInterval(this.interval); this.interval = null; process.stdout.write("\r\x1B[K"); } } }; BrainAnimation = class { frames = ["\u{1F9E0}", "\u{1F52E}", "\u{1F4AB}", "\u2728", "\u{1F31F}"]; messages = [ "Neural processing", "Pattern recognition", "Deep thinking", "Synthesizing", "Finalizing" ]; currentFrame = 0; interval = null; start() { this.interval = setInterval(() => { const frame = this.frames[this.currentFrame]; const message = this.messages[this.currentFrame]; process.stdout.write( `\r${frame} ${chalk73__namespace.default.cyan(message)}...` ); this.currentFrame = (this.currentFrame + 1) % this.frames.length; }, 1e3); } stop() { if (this.interval) { clearInterval(this.interval); this.interval = null; process.stdout.write("\r\x1B[K"); } } }; ProgressBar = class { width; current = 0; total; label; constructor(total, width = 40, label = "Progress") { this.total = total; this.width = width; this.label = label; } update(current) { this.current = Math.min(current, this.total); const percentage = Math.floor(this.current / this.total * 100); const filled = Math.floor(this.current / this.total * this.width); const empty = this.width - filled; const bar = chalk73__namespace.default.green("\u2588").repeat(filled) + chalk73__namespace.default.dim("\u2591").repeat(empty); process.stdout.write(`\r${this.label}: [${bar}] ${percentage}%`); if (this.current >= this.total) { process.stdout.write("\n"); } } complete() { this.update(this.total); } }; StreamingOutput = class { buffer = ""; lineBuffer = ""; chunkSize; delay; constructor(chunkSize = 3, delay2 = 10) { this.chunkSize = chunkSize; this.delay = delay2; } async stream(text, prefix = "") { const lines = text.split("\n"); for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) { const line = lines[lineIndex]; if (prefix && lineIndex === 0) { process.stdout.write(prefix); } for (let i2 = 0; i2 < line.length; i2 += this.chunkSize) { const chunk2 = line.slice(i2, i2 + this.chunkSize); process.stdout.write(chunk2); await this.sleep(this.delay); } if (lineIndex < lines.length - 1 || line.length > 0) { process.stdout.write("\n"); } } } sleep(ms) { return new Promise((resolve84) => setTimeout(resolve84, ms)); } }; } }); function isTokenResponse(v) { if (!v || typeof v !== "object") return false; const obj = v; return typeof obj.access_token === "string" && typeof obj.token_type === "string" && typeof obj.expires_in === "number"; } var OAuth2PKCEClient; var init_OAuth2PKCEClient = __esm({ "src/services/cli-auth/OAuth2PKCEClient.ts"() { init_tty(); OAuth2PKCEClient = class { config; codeVerifier = ""; codeChallenge = ""; state = ""; server = null; tokenStoragePath; constructor(config2) { this.config = { ...config2, redirectUri: config2.redirectUri || "http://127.0.0.1:9876/callback", // Auth is hosted on a dedicated subdomain. authServerUrl: config2.authServerUrl || "https://auth.maria-code.ai" }; const configDir = process.env.MARIA_CONFIG_DIR || path258__namespace.join(os29__namespace.homedir(), ".maria"); if (!fs87__namespace.existsSync(configDir)) {