@bonginkan/maria 4.3.17 → 4.3.18

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.
@@ -26038,8 +26038,8 @@ var require_package = __commonJS({
26038
26038
  "package.json"(exports, module) {
26039
26039
  module.exports = {
26040
26040
  name: "@bonginkan/maria",
26041
- version: "4.3.17",
26042
- description: "\u{1F680} MARIA v4.3.17 - Enterprise AI Development Platform with identity system and character voice implementation. Features 74 production-ready commands with comprehensive fallback implementation, local LLM support, and zero external dependencies. Includes natural language coding, AI safety evaluation, intelligent evolution system, episodic memory with PII masking, and real-time monitoring dashboard. Built with TypeScript AST-powered code generation, OAuth2.0 + PKCE authentication, quantum-resistant cryptography, and enterprise-grade performance.",
26041
+ version: "4.3.18",
26042
+ description: "\u{1F680} MARIA v4.3.18 - Enterprise AI Development Platform with identity system and character voice implementation. Features 74 production-ready commands with comprehensive fallback implementation, local LLM support, and zero external dependencies. Includes natural language coding, AI safety evaluation, intelligent evolution system, episodic memory with PII masking, and real-time monitoring dashboard. Built with TypeScript AST-powered code generation, OAuth2.0 + PKCE authentication, quantum-resistant cryptography, and enterprise-grade performance.",
26043
26043
  keywords: [
26044
26044
  "ai",
26045
26045
  "cli",
@@ -28071,7 +28071,7 @@ var init_AuthenticationManager = __esm({
28071
28071
  const response = await fetch(`${this.apiBase}/api/user/profile`, {
28072
28072
  headers: {
28073
28073
  "Authorization": `Bearer ${tokens2.accessToken}`,
28074
- "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.17"}`
28074
+ "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.18"}`
28075
28075
  }
28076
28076
  });
28077
28077
  if (response.status === 401) {
@@ -28703,7 +28703,7 @@ async function callApi(path60, init3 = {}) {
28703
28703
  "Authorization": `Bearer ${token}`,
28704
28704
  "X-Device-Id": getDeviceId(),
28705
28705
  "X-Session-Id": getSessionId() || "",
28706
- "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.17"}`,
28706
+ "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.18"}`,
28707
28707
  "Content-Type": init3.headers?.["Content-Type"] || "application/json"
28708
28708
  });
28709
28709
  const doFetch = async (token) => {
@@ -50559,7 +50559,7 @@ var init_about_command = __esm({
50559
50559
  async execute(args2, context2) {
50560
50560
  const output3 = [];
50561
50561
  output3.push("");
50562
- output3.push(chalk14__default.default.cyan.bold("\u{1F916} About MARIA v4.3.17"));
50562
+ output3.push(chalk14__default.default.cyan.bold("\u{1F916} About MARIA v4.3.18"));
50563
50563
  output3.push(chalk14__default.default.gray("\u2550".repeat(40)));
50564
50564
  output3.push("");
50565
50565
  output3.push(chalk14__default.default.white.bold("MARIA - Minimal API, Maximum Power"));
@@ -53705,6 +53705,249 @@ var init_rate_limit_handler = __esm({
53705
53705
  "src/services/api-client/rate-limit-handler.ts"() {
53706
53706
  }
53707
53707
  });
53708
+ function extractCodeInfo(codeBlock) {
53709
+ const match2 = codeBlock.match(/```([^\n]*)\n?([\s\S]*?)```/);
53710
+ if (!match2) {
53711
+ return { language: "text", code: codeBlock, extension: "txt" };
53712
+ }
53713
+ const fenceHeader = match2[1] || "";
53714
+ const language = fenceHeader.split(/\s+/)[0] || "text";
53715
+ const code = match2[2] || "";
53716
+ let filename;
53717
+ const fnameHeader = fenceHeader.match(/filename\s*=\s*([^\s]+)/i);
53718
+ if (fnameHeader) filename = sanitizeFilename(fnameHeader[1]);
53719
+ if (!filename) {
53720
+ const firstLine = (code.split(/\r?\n/, 1)[0] || "").trim();
53721
+ const commentName = firstLine.match(/^\/\/\s*filename:\s*(.+)$/i) || firstLine.match(/^#\s*filename:\s*(.+)$/i) || firstLine.match(/^<!--\s*filename:\s*(.+?)\s*-->$/i) || firstLine.match(/^\/\*\s*filename:\s*(.+?)\s*\*\/$/i);
53722
+ if (commentName && commentName[1]) filename = sanitizeFilename(commentName[1]);
53723
+ }
53724
+ const extension = inferExtensionFromContent(language, code) || "txt";
53725
+ return { language, code, extension, filename };
53726
+ }
53727
+ function extractAllCodeInfos(markdown) {
53728
+ const out = [];
53729
+ const proto = /\[BEGIN\s+file:\s*([^\]\n]+)\]\s*\n([\s\S]*?)\[END\]/g;
53730
+ const protoMatches = markdown.matchAll(proto);
53731
+ let anyProto = false;
53732
+ for (const m2 of protoMatches) {
53733
+ anyProto = true;
53734
+ const fname = (m2[1] || "").trim();
53735
+ const body = m2[2] || "";
53736
+ const ext2 = (fname.split(".").pop() || "txt").toLowerCase();
53737
+ out.push({ language: ext2, code: body, extension: ext2, filename: sanitizeFilenameStrict(fname) });
53738
+ }
53739
+ if (anyProto) return out;
53740
+ const blocks = [];
53741
+ const re = /```[^`]*\n[\s\S]*?```/g;
53742
+ const matches = markdown.match(re);
53743
+ if (matches && matches.length > 0) {
53744
+ for (const m2 of matches) {
53745
+ try {
53746
+ blocks.push(extractCodeInfo(m2));
53747
+ } catch {
53748
+ }
53749
+ }
53750
+ } else {
53751
+ blocks.push(extractCodeInfo(`\`\`\`text
53752
+ ${markdown}
53753
+ \`\`\``));
53754
+ }
53755
+ return blocks;
53756
+ }
53757
+ function sanitizeFilename(name2) {
53758
+ const base = name2.replace(/^[\\/]+/, "").replace(/[\0<>:"|?*]/g, "").trim();
53759
+ return base || "file";
53760
+ }
53761
+ function inferExtensionFromContent(language, code) {
53762
+ const lowerLang = (language || "").toLowerCase();
53763
+ code.toLowerCase();
53764
+ if (/<!doctype\s+html>/i.test(code) || /<html[\s>]/i.test(code)) return "html";
53765
+ if (/^\s*\{[\s\S]*\}\s*$/.test(code.trim())) return "json";
53766
+ if (/^\s*#include\s+</m.test(code)) return "c";
53767
+ const hasReact = /(^|\s)from\s+['"]react['"]|^\s*import\s+React/m.test(code);
53768
+ const hasJSX = /<([A-Za-z][\w:-]*)(\s|>|\/)>?/m.test(code);
53769
+ const hasTypeScriptHints = /(\binterface\s+\w+\b|\btype\s+\w+\s*=|:\s*[A-Za-z_][\w<>\[\]| &?:]*)/m.test(code) || /React\.FC\s*</m.test(code) || /<\w+\s*<\w+>/.test(code);
53770
+ if (hasReact || /jsx|tsx/.test(lowerLang) || hasJSX) {
53771
+ if (lowerLang.includes("tsx") || hasTypeScriptHints) return "tsx";
53772
+ return "jsx";
53773
+ }
53774
+ if (/^\s*<\?xml/m.test(code)) return "xml";
53775
+ if (/^#!/.test(code)) return "sh";
53776
+ if (/^\s*package\s+[a-zA-Z0-9_.]+;/.test(code)) return "java";
53777
+ const map = {
53778
+ javascript: "js",
53779
+ typescript: "ts",
53780
+ jsx: "jsx",
53781
+ tsx: "tsx",
53782
+ python: "py",
53783
+ java: "java",
53784
+ cpp: "cpp",
53785
+ c: "c",
53786
+ csharp: "cs",
53787
+ php: "php",
53788
+ ruby: "rb",
53789
+ go: "go",
53790
+ rust: "rs",
53791
+ swift: "swift",
53792
+ kotlin: "kt",
53793
+ html: "html",
53794
+ css: "css",
53795
+ scss: "scss",
53796
+ json: "json",
53797
+ yaml: "yaml",
53798
+ yml: "yml",
53799
+ xml: "xml",
53800
+ sql: "sql",
53801
+ bash: "sh",
53802
+ shell: "sh",
53803
+ sh: "sh",
53804
+ dockerfile: "dockerfile",
53805
+ makefile: "makefile",
53806
+ markdown: "md",
53807
+ md: "md",
53808
+ text: "txt"
53809
+ };
53810
+ return map[lowerLang];
53811
+ }
53812
+ function sanitizeFilenameStrict(name2) {
53813
+ const RESERVED = /* @__PURE__ */ new Set([
53814
+ "con",
53815
+ "prn",
53816
+ "aux",
53817
+ "nul",
53818
+ "com1",
53819
+ "com2",
53820
+ "com3",
53821
+ "com4",
53822
+ "com5",
53823
+ "com6",
53824
+ "com7",
53825
+ "com8",
53826
+ "com9",
53827
+ "lpt1",
53828
+ "lpt2",
53829
+ "lpt3",
53830
+ "lpt4",
53831
+ "lpt5",
53832
+ "lpt6",
53833
+ "lpt7",
53834
+ "lpt8",
53835
+ "lpt9"
53836
+ ]);
53837
+ const cleaned = name2.replace(/[\u0000-\u001F\x7F<>:"/\\|?*]/g, "-").replace(/\s+/g, " ").trim();
53838
+ const leaf = cleaned.split(/[\\/]/).pop() || "file";
53839
+ const stem = leaf.replace(/\.[^.]+$/, "");
53840
+ if (leaf.includes("..") || RESERVED.has(stem.toLowerCase())) return "file";
53841
+ return leaf.length > 128 ? leaf.slice(0, 120) : leaf;
53842
+ }
53843
+ function coerceExtension(ext2, fallback2) {
53844
+ const e2 = (ext2 || "").toLowerCase().replace(/^\./, "");
53845
+ if (ALLOWED_EXTS.has(e2)) return e2;
53846
+ return fallback2;
53847
+ }
53848
+ function safeResolve(root, fname) {
53849
+ const abs = path11__namespace.resolve(root, fname);
53850
+ const base = path11__namespace.resolve(root);
53851
+ if (!(abs + path11__namespace.sep).startsWith(base + path11__namespace.sep) && abs !== base) {
53852
+ throw new Error("Path traversal detected");
53853
+ }
53854
+ return abs;
53855
+ }
53856
+ async function ensureUniquePath(absPath) {
53857
+ const dir = path11__namespace.dirname(absPath);
53858
+ const ext2 = path11__namespace.extname(absPath);
53859
+ const base = path11__namespace.basename(absPath, ext2);
53860
+ let candidate = absPath;
53861
+ let i2 = 1;
53862
+ while (true) {
53863
+ try {
53864
+ await fsp__namespace.access(candidate);
53865
+ candidate = path11__namespace.join(dir, `${base}(${i2})${ext2}`);
53866
+ i2++;
53867
+ } catch {
53868
+ return candidate;
53869
+ }
53870
+ }
53871
+ }
53872
+ function isLikelyBinary(text) {
53873
+ if (text.includes("\0")) return true;
53874
+ const len = Math.min(text.length, 8192);
53875
+ let nonText = 0;
53876
+ for (let i2 = 0; i2 < len; i2++) {
53877
+ const code = text.charCodeAt(i2);
53878
+ const isPrintable = code >= 9 && code <= 13 || code >= 32 && code <= 126 || code >= 160;
53879
+ if (!isPrintable) nonText++;
53880
+ }
53881
+ return nonText / Math.max(1, len) > 0.15;
53882
+ }
53883
+ function generateCodeFilename(prompt, language, extension, code, suggested) {
53884
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
53885
+ if (suggested) return sanitizeFilename(suggested);
53886
+ if (code) {
53887
+ if (/<!doctype\s+html>/i.test(code) || /<html[\s>]/i.test(code)) return "index.html";
53888
+ if (/^\s*import\s+react/m.test(code)) return "App." + (extension || "tsx");
53889
+ if (/express\(\)/.test(code) || /from\s+express/.test(code)) return `server.${extension || "js"}`;
53890
+ if (/^#!\//.test(code)) return `script.${extension || "sh"}`;
53891
+ }
53892
+ const promptLower = (prompt || "").toLowerCase();
53893
+ let baseName = "code";
53894
+ if (promptLower.includes("api")) baseName = "api";
53895
+ else if (promptLower.includes("server")) baseName = "server";
53896
+ else if (promptLower.includes("client")) baseName = "client";
53897
+ else if (promptLower.includes("component")) baseName = "component";
53898
+ else if (promptLower.includes("function")) baseName = "function";
53899
+ else if (promptLower.includes("class")) baseName = "class";
53900
+ else if (promptLower.includes("test")) baseName = "test";
53901
+ else if (promptLower.includes("script")) baseName = "script";
53902
+ else if (promptLower.includes("app")) baseName = "app";
53903
+ else if (promptLower.includes("main")) baseName = "main";
53904
+ else if (promptLower.includes("index")) baseName = "index";
53905
+ else if (promptLower.includes("util")) baseName = "utils";
53906
+ else if (promptLower.includes("helper")) baseName = "helper";
53907
+ else if (promptLower.includes("service")) baseName = "service";
53908
+ else if (promptLower.includes("model")) baseName = "model";
53909
+ else if (promptLower.includes("controller")) baseName = "controller";
53910
+ else if (promptLower.includes("route")) baseName = "routes";
53911
+ else if (promptLower.includes("config")) baseName = "config";
53912
+ if (baseName === "index" && extension) return `index.${extension}`;
53913
+ return `${baseName}_${timestamp}.${extension}`;
53914
+ }
53915
+ var ALLOWED_EXTS;
53916
+ var init_code_utils = __esm({
53917
+ "src/cli/code-utils.ts"() {
53918
+ ALLOWED_EXTS = /* @__PURE__ */ new Set([
53919
+ "ts",
53920
+ "tsx",
53921
+ "js",
53922
+ "jsx",
53923
+ "mjs",
53924
+ "cjs",
53925
+ "json",
53926
+ "yml",
53927
+ "yaml",
53928
+ "md",
53929
+ "html",
53930
+ "css",
53931
+ "scss",
53932
+ "py",
53933
+ "java",
53934
+ "kt",
53935
+ "rb",
53936
+ "go",
53937
+ "rs",
53938
+ "swift",
53939
+ "c",
53940
+ "cpp",
53941
+ "cs",
53942
+ "sh",
53943
+ "xml",
53944
+ "sql",
53945
+ "dockerfile",
53946
+ "makefile",
53947
+ "txt"
53948
+ ]);
53949
+ }
53950
+ });
53708
53951
  async function scanRepo(cwd2) {
53709
53952
  if (_cache && _cache.root === cwd2) return _cache;
53710
53953
  const root = cwd2;
@@ -54796,7 +55039,18 @@ async function orchestrate(request, opts) {
54796
55039
  async () => {
54797
55040
  const started = Date.now();
54798
55041
  try {
54799
- const response = await executeCode(request);
55042
+ const FILE_FORMAT_INSTRUCTIONS = [
55043
+ "You are a senior software engineer. Respond with CODE ONLY.",
55044
+ "At the very start of each file, include a filename hint as a comment on the first line:",
55045
+ "// filename: <name.ext> (or # filename: <name.ext> for Python, <!-- filename: name.ext --> for HTML/CSS)",
55046
+ "If multiple files are required, use the strict multi-file protocol with one or more file sections:",
55047
+ "[BEGIN file: path]\n<content>\n[END]",
55048
+ "Do not include any prose before/after; no menus/questions/suggestions; start immediately with ``` or [BEGIN file: ...]."
55049
+ ].join("\n");
55050
+ const enriched = `${FILE_FORMAT_INSTRUCTIONS}
55051
+
55052
+ ${request}`;
55053
+ const response = await executeCode(enriched);
54800
55054
  const raw = (response.output || response?.data?.content || "").trim();
54801
55055
  if (!raw) {
54802
55056
  return {
@@ -54862,8 +55116,10 @@ async function orchestrate(request, opts) {
54862
55116
  } else {
54863
55117
  for (let i2 = 0; i2 < blocks.length; i2++) {
54864
55118
  const b = blocks[i2];
55119
+ const desired = typeof b.filename === "string" && b.filename.trim() ? b.filename.trim() : null;
55120
+ const path60 = desired || suggestName2(request, b.language, i2);
54865
55121
  initial.push({
54866
- path: suggestName2(request, b.language, i2),
55122
+ path: path60,
54867
55123
  kind: "source",
54868
55124
  action: "create",
54869
55125
  description: describe2(b.language, ""),
@@ -54879,6 +55135,21 @@ async function orchestrate(request, opts) {
54879
55135
  }
54880
55136
  }
54881
55137
  const normalized = await normalizePlans(initial, { root: opts.root });
55138
+ try {
55139
+ const [{ access: access18 }, path60] = await Promise.all([
55140
+ import('fs/promises'),
55141
+ import('path')
55142
+ ]);
55143
+ for (const p of normalized) {
55144
+ try {
55145
+ await access18(path60.join(opts.root, p.path));
55146
+ p.action = "modify";
55147
+ } catch {
55148
+ p.action = "create";
55149
+ }
55150
+ }
55151
+ } catch {
55152
+ }
54882
55153
  const validated = await validatePlan(normalized, { root: opts.root, profile, flags: { maxFiles: opts.flags.maxFiles, yes: opts.flags.yes, interactive: !!opts.flags.interactive, ...opts.flags } });
54883
55154
  const outputMode = resolveOutputMode(opts.flags.output, validated.files.length, !!opts.flags.hideCode);
54884
55155
  const displayFiles = validated.files.concat(
@@ -55012,6 +55283,15 @@ function mapCodeErrorToReason(err) {
55012
55283
  }
55013
55284
  function extractBlocks(content) {
55014
55285
  const blocks = [];
55286
+ const proto = /\[BEGIN\s+file:\s*([^\]\n]+)\]\s*\n([\s\S]*?)\[END\]/g;
55287
+ let pm;
55288
+ while ((pm = proto.exec(content)) !== null) {
55289
+ const fname = (pm[1] || "").trim();
55290
+ const body = (pm[2] || "").trim();
55291
+ const ext2 = (fname.split(".").pop() || "txt").toLowerCase();
55292
+ blocks.push({ language: ext2 || "text", code: body, filename: fname });
55293
+ }
55294
+ if (blocks.length > 0) return blocks;
55015
55295
  const re = /```(\w*)\n([\s\S]*?)```/g;
55016
55296
  let m2;
55017
55297
  while ((m2 = re.exec(content)) !== null) blocks.push({ language: m2[1] || "javascript", code: m2[2].trim() });
@@ -55250,6 +55530,7 @@ var init_code_command = __esm({
55250
55530
  init_base_command();
55251
55531
  init_rate_limit_handler();
55252
55532
  init_animations();
55533
+ init_code_utils();
55253
55534
  LANGUAGE_EXTENSIONS = {
55254
55535
  javascript: ".js",
55255
55536
  typescript: ".ts",
@@ -55482,10 +55763,19 @@ ${pretty}`);
55482
55763
  const count = Math.min(blocks.length, limit);
55483
55764
  for (let i2 = 0; i2 < count; i2++) {
55484
55765
  const block = blocks[i2];
55485
- const filename = this.generateFilename(request, block.language);
55486
- const ext2 = LANGUAGE_EXTENSIONS[block.language] || ".txt";
55487
- const naive = i2 === 0 ? `${filename}${ext2}` : `${filename}_${i2 + 1}${ext2}`;
55488
- plans.push({ path: naive, kind: "source", action: "create", description: this.describeBrief(block.language, naive), language: block.language, preview: block.code });
55766
+ const suggested = this.extractSuggestedFilename(block.code);
55767
+ const inferredExt = inferExtensionFromContent(block.language, block.code) || "txt";
55768
+ let finalName;
55769
+ if (suggested) {
55770
+ const clean = sanitizeFilenameStrict(suggested);
55771
+ const hasExt = /\.[A-Za-z0-9._-]+$/.test(clean);
55772
+ finalName = hasExt ? clean : `${clean}.${inferredExt}`;
55773
+ } else {
55774
+ const base = this.generateFilename(request, block.language);
55775
+ const ext2 = LANGUAGE_EXTENSIONS[block.language] || `.${inferredExt}`;
55776
+ finalName = i2 === 0 ? `${base}${ext2}` : `${base}_${i2 + 1}${ext2}`;
55777
+ }
55778
+ plans.push({ path: finalName, kind: "source", action: "create", description: this.describeBrief(block.language, finalName), language: block.language, preview: block.code });
55489
55779
  }
55490
55780
  const { normalizePlans: normalizePlans2 } = await Promise.resolve().then(() => (init_FilePlanBuilder(), FilePlanBuilder_exports));
55491
55781
  const normalized = await normalizePlans2(plans, { root });
@@ -55495,6 +55785,18 @@ ${pretty}`);
55495
55785
  }
55496
55786
  return normalized;
55497
55787
  }
55788
+ extractSuggestedFilename(code) {
55789
+ const firstLine = (code.split(/\r?\n/, 1)[0] || "").trim();
55790
+ const m1 = firstLine.match(/^\/\/\s*filename:\s*(.+)$/i);
55791
+ if (m1?.[1]) return m1[1].trim();
55792
+ const m2 = firstLine.match(/^#\s*filename:\s*(.+)$/i);
55793
+ if (m2?.[1]) return m2[1].trim();
55794
+ const m3 = firstLine.match(/^<!--\s*filename:\s*(.+?)\s*-->$/i);
55795
+ if (m3?.[1]) return m3[1].trim();
55796
+ const m4 = firstLine.match(/^\/\*\s*filename:\s*(.+?)\s*\*\/$/i);
55797
+ if (m4?.[1]) return m4[1].trim();
55798
+ return void 0;
55799
+ }
55498
55800
  describeBrief(language, final) {
55499
55801
  const l = language.toLowerCase();
55500
55802
  if (/tsx|jsx/.test(l) || /\.tsx$|\.jsx$/.test(final)) return "UI component";
@@ -55609,7 +55911,10 @@ ${pretty}`);
55609
55911
  * Detect programming language from content
55610
55912
  */
55611
55913
  detectLanguage(code) {
55612
- if (code.includes("import React") || code.includes("<")) return "jsx";
55914
+ const hasReact = /(^|\s)from\s+['"]react['"]|^\s*import\s+React/m.test(code);
55915
+ const hasJSX = /<([A-Za-z][\w:-]*)(\s|>|\/)>?/m.test(code);
55916
+ const hasTS = /(\binterface\s+\w+\b|\btype\s+\w+\s*=|:\s*[A-Za-z_][\w<>\[\]| &?:]*)/m.test(code) || /React\.FC\s*</m.test(code);
55917
+ if (hasReact || hasJSX) return hasTS ? "tsx" : "jsx";
55613
55918
  if (code.includes("interface ") || code.includes(": string")) return "typescript";
55614
55919
  if (code.includes("def ") || code.includes("print(")) return "python";
55615
55920
  if (code.includes("func ") || code.includes("package main")) return "go";
@@ -72501,7 +72806,7 @@ var init_ai_response_service = __esm({
72501
72806
  */
72502
72807
  async callLLM(prompt, opts = {}) {
72503
72808
  const {
72504
- system = PLAIN_OUTPUT ? "Return ONLY the answer (or ONLY code). No menus, no lists, no guided flows. Always respond in English." : "You are a helpful senior engineer. Always respond in English. Provide direct, production-quality answers.",
72809
+ system = PLAIN_OUTPUT ? "Return ONLY the answer (or ONLY code). No menus, no lists, no guided flows. Always respond in English." : "You are a helpful senior engineer. Always respond in English. Provide direct, production-quality answers. Make sure you answer in plain text, as a natural chat.",
72505
72810
  model = void 0,
72506
72811
  provider = DEFAULT_PROVIDER2,
72507
72812
  temperature = 0.2,
@@ -73740,243 +74045,6 @@ var init_server = __esm({
73740
74045
  init_text_logger();
73741
74046
  }
73742
74047
  });
73743
- function extractCodeInfo(codeBlock) {
73744
- const match2 = codeBlock.match(/```([^\n]*)\n?([\s\S]*?)```/);
73745
- if (!match2) {
73746
- return { language: "text", code: codeBlock, extension: "txt" };
73747
- }
73748
- const fenceHeader = match2[1] || "";
73749
- const language = fenceHeader.split(/\s+/)[0] || "text";
73750
- const code = match2[2] || "";
73751
- let filename;
73752
- const fnameHeader = fenceHeader.match(/filename\s*=\s*([^\s]+)/i);
73753
- if (fnameHeader) filename = sanitizeFilename(fnameHeader[1]);
73754
- if (!filename) {
73755
- const firstLine = (code.split(/\r?\n/, 1)[0] || "").trim();
73756
- const commentName = firstLine.match(/^\/\/\s*filename:\s*(.+)$/i) || firstLine.match(/^#\s*filename:\s*(.+)$/i) || firstLine.match(/^<!--\s*filename:\s*(.+?)\s*-->$/i) || firstLine.match(/^\/\*\s*filename:\s*(.+?)\s*\*\/$/i);
73757
- if (commentName && commentName[1]) filename = sanitizeFilename(commentName[1]);
73758
- }
73759
- const extension = inferExtensionFromContent(language, code) || "txt";
73760
- return { language, code, extension, filename };
73761
- }
73762
- function extractAllCodeInfos(markdown) {
73763
- const out = [];
73764
- const proto = /\[BEGIN\s+file:\s*([^\]\n]+)\]\s*\n([\s\S]*?)\[END\]/g;
73765
- const protoMatches = markdown.matchAll(proto);
73766
- let anyProto = false;
73767
- for (const m2 of protoMatches) {
73768
- anyProto = true;
73769
- const fname = (m2[1] || "").trim();
73770
- const body = m2[2] || "";
73771
- const ext2 = (fname.split(".").pop() || "txt").toLowerCase();
73772
- out.push({ language: ext2, code: body, extension: ext2, filename: sanitizeFilenameStrict(fname) });
73773
- }
73774
- if (anyProto) return out;
73775
- const blocks = [];
73776
- const re = /```[^`]*\n[\s\S]*?```/g;
73777
- const matches = markdown.match(re);
73778
- if (matches && matches.length > 0) {
73779
- for (const m2 of matches) {
73780
- try {
73781
- blocks.push(extractCodeInfo(m2));
73782
- } catch {
73783
- }
73784
- }
73785
- } else {
73786
- blocks.push(extractCodeInfo(`\`\`\`text
73787
- ${markdown}
73788
- \`\`\``));
73789
- }
73790
- return blocks;
73791
- }
73792
- function sanitizeFilename(name2) {
73793
- const base = name2.replace(/^[\\/]+/, "").replace(/[\0<>:"|?*]/g, "").trim();
73794
- return base || "file";
73795
- }
73796
- function inferExtensionFromContent(language, code) {
73797
- const lowerLang = (language || "").toLowerCase();
73798
- code.toLowerCase();
73799
- if (/<!doctype\s+html>/i.test(code) || /<html[\s>]/i.test(code)) return "html";
73800
- if (/^\s*\{[\s\S]*\}\s*$/.test(code.trim())) return "json";
73801
- if (/^\s*#include\s+</m.test(code)) return "c";
73802
- if (/^\s*import\s+react/m.test(code) || /jsx/m.test(lowerLang)) return "jsx";
73803
- if (/^\s*<\?xml/m.test(code)) return "xml";
73804
- if (/^#!/.test(code)) return "sh";
73805
- if (/^\s*package\s+[a-zA-Z0-9_.]+;/.test(code)) return "java";
73806
- const map = {
73807
- javascript: "js",
73808
- typescript: "ts",
73809
- jsx: "jsx",
73810
- tsx: "tsx",
73811
- python: "py",
73812
- java: "java",
73813
- cpp: "cpp",
73814
- c: "c",
73815
- csharp: "cs",
73816
- php: "php",
73817
- ruby: "rb",
73818
- go: "go",
73819
- rust: "rs",
73820
- swift: "swift",
73821
- kotlin: "kt",
73822
- html: "html",
73823
- css: "css",
73824
- scss: "scss",
73825
- json: "json",
73826
- yaml: "yaml",
73827
- yml: "yml",
73828
- xml: "xml",
73829
- sql: "sql",
73830
- bash: "sh",
73831
- shell: "sh",
73832
- sh: "sh",
73833
- dockerfile: "dockerfile",
73834
- makefile: "makefile",
73835
- markdown: "md",
73836
- md: "md",
73837
- text: "txt"
73838
- };
73839
- return map[lowerLang];
73840
- }
73841
- function sanitizeFilenameStrict(name2) {
73842
- const RESERVED = /* @__PURE__ */ new Set([
73843
- "con",
73844
- "prn",
73845
- "aux",
73846
- "nul",
73847
- "com1",
73848
- "com2",
73849
- "com3",
73850
- "com4",
73851
- "com5",
73852
- "com6",
73853
- "com7",
73854
- "com8",
73855
- "com9",
73856
- "lpt1",
73857
- "lpt2",
73858
- "lpt3",
73859
- "lpt4",
73860
- "lpt5",
73861
- "lpt6",
73862
- "lpt7",
73863
- "lpt8",
73864
- "lpt9"
73865
- ]);
73866
- const cleaned = name2.replace(/[\u0000-\u001F\x7F<>:"/\\|?*]/g, "-").replace(/\s+/g, " ").trim();
73867
- const leaf = cleaned.split(/[\\/]/).pop() || "file";
73868
- const stem = leaf.replace(/\.[^.]+$/, "");
73869
- if (leaf.includes("..") || RESERVED.has(stem.toLowerCase())) return "file";
73870
- return leaf.length > 128 ? leaf.slice(0, 120) : leaf;
73871
- }
73872
- function coerceExtension(ext2, fallback2) {
73873
- const e2 = (ext2 || "").toLowerCase().replace(/^\./, "");
73874
- if (ALLOWED_EXTS.has(e2)) return e2;
73875
- return fallback2;
73876
- }
73877
- function safeResolve(root, fname) {
73878
- const abs = path11__namespace.resolve(root, fname);
73879
- const base = path11__namespace.resolve(root);
73880
- if (!(abs + path11__namespace.sep).startsWith(base + path11__namespace.sep) && abs !== base) {
73881
- throw new Error("Path traversal detected");
73882
- }
73883
- return abs;
73884
- }
73885
- async function ensureUniquePath(absPath) {
73886
- const dir = path11__namespace.dirname(absPath);
73887
- const ext2 = path11__namespace.extname(absPath);
73888
- const base = path11__namespace.basename(absPath, ext2);
73889
- let candidate = absPath;
73890
- let i2 = 1;
73891
- while (true) {
73892
- try {
73893
- await fsp__namespace.access(candidate);
73894
- candidate = path11__namespace.join(dir, `${base}(${i2})${ext2}`);
73895
- i2++;
73896
- } catch {
73897
- return candidate;
73898
- }
73899
- }
73900
- }
73901
- function isLikelyBinary(text) {
73902
- if (text.includes("\0")) return true;
73903
- const len = Math.min(text.length, 8192);
73904
- let nonText = 0;
73905
- for (let i2 = 0; i2 < len; i2++) {
73906
- const code = text.charCodeAt(i2);
73907
- const isPrintable = code >= 9 && code <= 13 || code >= 32 && code <= 126 || code >= 160;
73908
- if (!isPrintable) nonText++;
73909
- }
73910
- return nonText / Math.max(1, len) > 0.15;
73911
- }
73912
- function generateCodeFilename(prompt, language, extension, code, suggested) {
73913
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
73914
- if (suggested) return sanitizeFilename(suggested);
73915
- if (code) {
73916
- if (/<!doctype\s+html>/i.test(code) || /<html[\s>]/i.test(code)) return "index.html";
73917
- if (/^\s*import\s+react/m.test(code)) return "App." + (extension || "tsx");
73918
- if (/express\(\)/.test(code) || /from\s+express/.test(code)) return `server.${extension || "js"}`;
73919
- if (/^#!\//.test(code)) return `script.${extension || "sh"}`;
73920
- }
73921
- const promptLower = (prompt || "").toLowerCase();
73922
- let baseName = "code";
73923
- if (promptLower.includes("api")) baseName = "api";
73924
- else if (promptLower.includes("server")) baseName = "server";
73925
- else if (promptLower.includes("client")) baseName = "client";
73926
- else if (promptLower.includes("component")) baseName = "component";
73927
- else if (promptLower.includes("function")) baseName = "function";
73928
- else if (promptLower.includes("class")) baseName = "class";
73929
- else if (promptLower.includes("test")) baseName = "test";
73930
- else if (promptLower.includes("script")) baseName = "script";
73931
- else if (promptLower.includes("app")) baseName = "app";
73932
- else if (promptLower.includes("main")) baseName = "main";
73933
- else if (promptLower.includes("index")) baseName = "index";
73934
- else if (promptLower.includes("util")) baseName = "utils";
73935
- else if (promptLower.includes("helper")) baseName = "helper";
73936
- else if (promptLower.includes("service")) baseName = "service";
73937
- else if (promptLower.includes("model")) baseName = "model";
73938
- else if (promptLower.includes("controller")) baseName = "controller";
73939
- else if (promptLower.includes("route")) baseName = "routes";
73940
- else if (promptLower.includes("config")) baseName = "config";
73941
- if (baseName === "index" && extension) return `index.${extension}`;
73942
- return `${baseName}_${timestamp}.${extension}`;
73943
- }
73944
- var ALLOWED_EXTS;
73945
- var init_code_utils = __esm({
73946
- "src/cli/code-utils.ts"() {
73947
- ALLOWED_EXTS = /* @__PURE__ */ new Set([
73948
- "ts",
73949
- "tsx",
73950
- "js",
73951
- "jsx",
73952
- "mjs",
73953
- "cjs",
73954
- "json",
73955
- "yml",
73956
- "yaml",
73957
- "md",
73958
- "html",
73959
- "css",
73960
- "scss",
73961
- "py",
73962
- "java",
73963
- "kt",
73964
- "rb",
73965
- "go",
73966
- "rs",
73967
- "swift",
73968
- "c",
73969
- "cpp",
73970
- "cs",
73971
- "sh",
73972
- "xml",
73973
- "sql",
73974
- "dockerfile",
73975
- "makefile",
73976
- "txt"
73977
- ]);
73978
- }
73979
- });
73980
74048
 
73981
74049
  // src/cli.ts
73982
74050
  var cli_exports = {};
@@ -74218,13 +74286,10 @@ async function handleComplexChat(request, triageResult) {
74218
74286
  } catch {
74219
74287
  }
74220
74288
  }
74221
- if (!content && ai?.generateResponse) {
74222
- content = await ai.generateResponse({
74223
- userInput: `Create a concise plan and next steps for: ${request}`,
74224
- sessionMemory: [],
74225
- provider: process.env.MARIA_PROVIDER || "google",
74226
- model: process.env.MARIA_MODEL || "gemini-2.5-flash"
74227
- });
74289
+ if (!content) {
74290
+ animation.stop();
74291
+ await streamAnswer(request, { triage: triageResult });
74292
+ return;
74228
74293
  }
74229
74294
  animation.stop();
74230
74295
  const cleaned = content && typeof content === "string" ? content : buildComplexPlanSteps(request).join("\n");