@bonginkan/maria 4.3.31 → 4.3.32

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.cjs CHANGED
@@ -1704,7 +1704,7 @@ var init_AuthenticationManager = __esm({
1704
1704
  const response = await fetch(`${this.apiBase}/api/user/profile`, {
1705
1705
  headers: {
1706
1706
  "Authorization": `Bearer ${tokens2.accessToken}`,
1707
- "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.31"}`
1707
+ "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.32"}`
1708
1708
  }
1709
1709
  });
1710
1710
  if (response.status === 401) {
@@ -2407,7 +2407,7 @@ async function callApi(path64, init3 = {}) {
2407
2407
  "Authorization": `Bearer ${token}`,
2408
2408
  "X-Device-Id": getDeviceId(),
2409
2409
  "X-Session-Id": getSessionId() || "",
2410
- "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.31"}`,
2410
+ "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.32"}`,
2411
2411
  "Content-Type": init3.headers?.["Content-Type"] || "application/json"
2412
2412
  });
2413
2413
  const doFetch = async (token) => {
@@ -16121,8 +16121,8 @@ var require_package = __commonJS({
16121
16121
  "package.json"(exports, module) {
16122
16122
  module.exports = {
16123
16123
  name: "@bonginkan/maria",
16124
- version: "4.3.31",
16125
- description: "\u{1F680} MARIA v4.3.31 - 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.",
16124
+ version: "4.3.32",
16125
+ description: "\u{1F680} MARIA v4.3.32 - 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.",
16126
16126
  keywords: [
16127
16127
  "ai",
16128
16128
  "cli",
@@ -25817,7 +25817,7 @@ var init_about_command = __esm({
25817
25817
  async execute(args2, context2) {
25818
25818
  const output3 = [];
25819
25819
  output3.push("");
25820
- output3.push(chalk40__default.default.cyan.bold("\u{1F916} About MARIA v4.3.31"));
25820
+ output3.push(chalk40__default.default.cyan.bold("\u{1F916} About MARIA v4.3.32"));
25821
25821
  output3.push(chalk40__default.default.gray("\u2550".repeat(40)));
25822
25822
  output3.push("");
25823
25823
  output3.push(chalk40__default.default.white.bold("MARIA - Minimal API, Maximum Power"));
@@ -57562,16 +57562,7 @@ var init_EvaluationOrchestrator = __esm({
57562
57562
  code: options.code,
57563
57563
  files
57564
57564
  };
57565
- let result;
57566
- if (options.llmScoring !== false) {
57567
- try {
57568
- result = await this.scoreWithLLM(input3, criteria);
57569
- } catch {
57570
- result = await this.engine.evaluate(input3, criteria);
57571
- }
57572
- } else {
57573
- result = await this.engine.evaluate(input3, criteria);
57574
- }
57565
+ const result = await this.scoreWithLLM(input3, criteria);
57575
57566
  result.files = input3.files || [];
57576
57567
  return { criteriaPath, result };
57577
57568
  }
@@ -57590,7 +57581,7 @@ var init_EvaluationOrchestrator = __esm({
57590
57581
  await fs19.promises.mkdir(dir, { recursive: true });
57591
57582
  const system = [
57592
57583
  "You are an expert evaluation designer.",
57593
- "Create a JSON criteria file for evaluating the given idea/code/files.",
57584
+ "Create a JSON criteria file for evaluating the given idea/code/files. If a local file path is provided, make sure you read the uploaded file before taking any actions.",
57594
57585
  "Respond ONLY with a single multi-file section in this exact format:",
57595
57586
  `[BEGIN file: ${targetPath}]`,
57596
57587
  "{JSON}",
@@ -57648,12 +57639,22 @@ ${user}`,
57648
57639
  return map;
57649
57640
  }
57650
57641
  extractFirstJsonObject(text) {
57651
- const fence = /```json\r?\n([\s\S]*?)```/i.exec(text);
57652
- if (fence) return fence[1];
57653
- const start = text.indexOf("{");
57654
- const end = text.lastIndexOf("}");
57642
+ const fenceJson = /```\s*json\s*\r?\n([\s\S]*?)```/i.exec(text);
57643
+ if (fenceJson) return fenceJson[1];
57644
+ const fencePlain = /```\s*\r?\n([\s\S]*?)```/i.exec(text);
57645
+ if (fencePlain) {
57646
+ const body = fencePlain[1];
57647
+ try {
57648
+ JSON.parse(body);
57649
+ return body;
57650
+ } catch {
57651
+ }
57652
+ }
57653
+ const defenced = text.replace(/```[a-zA-Z]*\s*\r?\n([\s\S]*?)```/g, "$1");
57654
+ const start = defenced.indexOf("{");
57655
+ const end = defenced.lastIndexOf("}");
57655
57656
  if (start >= 0 && end > start) {
57656
- const cand = text.slice(start, end + 1);
57657
+ const cand = defenced.slice(start, end + 1);
57657
57658
  try {
57658
57659
  JSON.parse(cand);
57659
57660
  return cand;
@@ -57664,18 +57665,20 @@ ${user}`,
57664
57665
  }
57665
57666
  async scoreWithLLM(input3, criteria) {
57666
57667
  const criteriaPreview = criteria.items.map((it) => ({ id: it.id, name: it.name, weight: it.weight, rubric: it.rubric })).slice(0, 20);
57667
- const bundleParts = [];
57668
- if (input3.idea) bundleParts.push(`Idea:
57668
+ const parts = [];
57669
+ if (input3.idea) parts.push(`Idea:
57669
57670
  ${input3.idea}`);
57670
- if (input3.code) bundleParts.push(`Code:
57671
+ if (input3.code) parts.push(`Code:
57671
57672
  ${input3.code}`);
57672
- if (input3.files && input3.files.length) {
57673
- bundleParts.push(`Files:
57674
- ${input3.files.slice(0, 5).map((f3) => `- ${f3.path}`).join("\n")}`);
57673
+ const files = input3.files || [];
57674
+ if (files.length) {
57675
+ parts.push(`Files attached:
57676
+ ${files.slice(0, 20).map((f3) => `- ${f3.path}`).join("\n")}`);
57675
57677
  }
57676
- const bundle = bundleParts.join("\n\n");
57678
+ const bundle = parts.join("\n\n");
57677
57679
  const system = [
57678
57680
  "You are an impartial evaluator. Score each criterion between 0 and 1.",
57681
+ "If a local file path is provided, make sure you read the uploaded file before taking any actions.",
57679
57682
  "Return JSON only in the following schema:",
57680
57683
  '{ "totalScore": number (0..1), "details": [{ "id": string, "score": number (0..1), "reason": string }] }',
57681
57684
  "Keep reasons short (<= 120 chars)."
@@ -57685,15 +57688,23 @@ ${input3.files.slice(0, 5).map((f3) => `- ${f3.path}`).join("\n")}`);
57685
57688
  "Input to evaluate:",
57686
57689
  bundle
57687
57690
  ].join("\n\n");
57691
+ (input3.files || []).some((f3) => f3.mime && f3.mime !== "text/plain");
57692
+ const provider = "google";
57693
+ const model = "gemini-2.5-flash";
57688
57694
  const response = await callAPI("/v1/ai-proxy", {
57689
57695
  method: "POST",
57690
57696
  body: {
57697
+ provider,
57698
+ model,
57691
57699
  prompt: `${system}
57692
57700
 
57693
57701
  ---
57694
57702
 
57695
57703
  ${user}`,
57696
- taskType: "evaluation"
57704
+ taskType: "evaluation",
57705
+ metadata: {
57706
+ attachments: (input3.files || []).map((f3) => this.toAttachmentPayload(f3))
57707
+ }
57697
57708
  }
57698
57709
  });
57699
57710
  const raw = (response?.data?.content || response?.output || "").trim();
@@ -57703,7 +57714,12 @@ ${user}`,
57703
57714
  if (sections.size > 0) {
57704
57715
  jsonText = Array.from(sections.values())[0];
57705
57716
  }
57706
- const parsed = JSON.parse(jsonText);
57717
+ let parsed;
57718
+ try {
57719
+ parsed = JSON.parse(jsonText);
57720
+ } catch {
57721
+ return { totalScore: 0, details: criteria.items.map((it) => ({ id: it.id, name: it.name, weight: it.weight, score: 0, reason: "" })), passThroughText: raw };
57722
+ }
57707
57723
  const details = criteria.items.map((it) => {
57708
57724
  const found = parsed.details.find((d) => d.id === it.id);
57709
57725
  const score = Math.max(0, Math.min(1, found?.score ?? 0));
@@ -57714,22 +57730,61 @@ ${user}`,
57714
57730
  const totalScore = Number.isFinite(parsed.totalScore) ? Math.max(0, Math.min(1, parsed.totalScore)) : weighted;
57715
57731
  return { totalScore, details };
57716
57732
  }
57733
+ toAttachmentPayload(file) {
57734
+ const ext2 = path10__namespace.default.extname(file.path).toLowerCase();
57735
+ const mime = file.mime || (ext2 === ".pdf" ? "application/pdf" : "text/plain");
57736
+ const b64 = file.binaryBase64 || Buffer.from(file.content || "", "utf8").toString("base64");
57737
+ return { name: path10__namespace.default.basename(file.path), path: file.path, mime, data_base64: b64 };
57738
+ }
57717
57739
  async readFiles(pathsInput) {
57718
57740
  const out = [];
57719
57741
  for (const p of pathsInput) {
57720
- const abs = path10__namespace.default.isAbsolute(p) ? p : path10__namespace.default.join(this.projectRoot, p);
57742
+ const normalized = p.replace(/^"|"$/g, "").replace(/^'|'$/g, "");
57743
+ const abs = path10__namespace.default.isAbsolute(normalized) ? normalized : path10__namespace.default.join(this.projectRoot, normalized);
57721
57744
  try {
57722
57745
  const stat13 = await fs19.promises.stat(abs);
57723
57746
  if (stat13.isDirectory()) {
57724
57747
  continue;
57725
57748
  }
57726
- const content = await fs19.promises.readFile(abs, "utf8");
57727
- out.push({ path: abs, content });
57749
+ const ext2 = path10__namespace.default.extname(abs).toLowerCase();
57750
+ const raw = await fs19.promises.readFile(abs);
57751
+ let content = "";
57752
+ if (/\.pdf$/i.test(abs)) {
57753
+ content = await this.tryExtractPdfText(abs);
57754
+ } else {
57755
+ try {
57756
+ content = raw.toString("utf8");
57757
+ } catch {
57758
+ content = "";
57759
+ }
57760
+ }
57761
+ const mime = ext2 === ".pdf" ? "application/pdf" : "text/plain";
57762
+ const binaryBase64 = raw.toString("base64");
57763
+ out.push({ path: abs, content, binaryBase64, mime });
57728
57764
  } catch {
57729
57765
  }
57730
57766
  }
57731
57767
  return out;
57732
57768
  }
57769
+ async tryExtractPdfText(absPath) {
57770
+ try {
57771
+ const buf = await fs19.promises.readFile(absPath);
57772
+ try {
57773
+ const mod = await import('pdf-parse');
57774
+ const pdfParse = mod?.default || mod;
57775
+ if (typeof pdfParse === "function") {
57776
+ const res = await pdfParse(buf);
57777
+ const text = (res?.text || "").trim();
57778
+ if (text) return text;
57779
+ }
57780
+ } catch {
57781
+ }
57782
+ const kb = Math.round(buf.byteLength / 1024);
57783
+ return `[[PDF ${absPath} (${kb} KB) \u2014 text extraction unavailable in this environment]]`;
57784
+ } catch {
57785
+ return "[[PDF read error]]";
57786
+ }
57787
+ }
57733
57788
  };
57734
57789
  }
57735
57790
  });
@@ -57761,6 +57816,7 @@ async function inferAssessParams(rawText, cwd2) {
57761
57816
  "You extract structured options for an evaluation command.",
57762
57817
  'Return JSON only with keys: { "criteriaPath"?: string, "regenerate"?: boolean, "criteriaOnly"?: boolean, "files"?: string[], "idea"?: string, "code"?: string }.',
57763
57818
  'Prefer concise relative paths for criteria (e.g., "AGI-hackathon-ideathon/evaluation.criteria.json").',
57819
+ 'If the text says "do not regenerate" or "DO NOT regenerate", set regenerate=false (override any other hint).',
57764
57820
  "If the text asks to create/save criteria/rubric (without asking for evaluation), set criteriaOnly=true.",
57765
57821
  "If the text mentions saving criteria to a folder, set criteriaPath accordingly and regenerate=true.",
57766
57822
  "If it references files or folders, include them in files[] (relative to cwd).",
@@ -57922,7 +57978,9 @@ var init_evaluate_command = __esm({
57922
57978
  }
57923
57979
  const filesOption = options["file"];
57924
57980
  const filesFromFlags = Array.isArray(filesOption) ? filesOption : filesOption ? [filesOption] : [];
57925
- const files = Array.from(/* @__PURE__ */ new Set([...inferred.files || [], ...filesFromFlags]));
57981
+ const detectedFromText = Array.from(rawText.match(/[A-Za-z]:\\[^\r\n]+/g) || []).map((s2) => s2.trim().replace(/[\s\.,;\)]*$/, ""));
57982
+ const noRegen = /\bdo\s*not\s*regenerate\b|\bdo\s*not\s*re\s*gen\b|\bdo\s*not\s*re\s*create\b|\bno\s*regen\b|\bDO\s*NOT\s*REGENERATE\b/i.test(rawText);
57983
+ const files = Array.from(/* @__PURE__ */ new Set([...inferred.files || [], ...filesFromFlags, ...detectedFromText]));
57926
57984
  const orchestrator = new EvaluationOrchestrator(root);
57927
57985
  const spinner = new ProcessAnimation();
57928
57986
  spinner.start();
@@ -57935,7 +57993,7 @@ var init_evaluate_command = __esm({
57935
57993
  files,
57936
57994
  idea: options["idea"] || inferred.idea || void 0,
57937
57995
  code: options["code"] || inferred.code || void 0,
57938
- regenerateCriteria: !!options["regenerate"] || !!options["regen"] || !options["criteria"] || !!inferred.regenerate,
57996
+ regenerateCriteria: noRegen ? false : !!options["regenerate"] || !!options["regen"] || !options["criteria"] || !!inferred.regenerate,
57939
57997
  llmScoring: options["no-llm-scoring"] ? false : true,
57940
57998
  criteriaOnly: !!options["criteria-only"] || !!inferred.criteriaOnly
57941
57999
  });
@@ -57953,29 +58011,34 @@ var init_evaluate_command = __esm({
57953
58011
  "- A one-line overall verdict",
57954
58012
  "- A weighted score (0-100)",
57955
58013
  "- A short bullet breakdown per criterion (name: score/100 - brief reason)",
57956
- "Be direct and professional."
58014
+ "Be direct and professional.",
58015
+ // Strong guard: attachments are uploaded; do not ask for local file content
58016
+ "The input files are already uploaded and referenced via file URIs.",
58017
+ "Use the provided attachments; do not ask the user to paste file contents.",
58018
+ "Do not claim you cannot access local file paths."
57957
58019
  ].join("\n");
57958
58020
  if (result === null) {
57959
58021
  const rel = path10__namespace.default.relative(root, criteriaPath);
57960
58022
  return this.success(`Criteria file created: ${rel}`);
57961
58023
  }
58024
+ if (result?.passThroughText) {
58025
+ return this.success(result.passThroughText, {
58026
+ type: "evaluation-assess-passthrough",
58027
+ total: 0
58028
+ });
58029
+ }
57962
58030
  const breakdown = result.details.map((d) => `- ${d.name} (${Math.round(d.weight * 100)}%): ${Math.round(d.score * 100)}/100 - ${d.reason}`).join("\n");
57963
58031
  const user = [
57964
58032
  `Project root: ${path10__namespace.default.basename(root)}`,
57965
58033
  `Criteria file: ${path10__namespace.default.relative(root, criteriaPath)}`,
57966
- `Heuristic total: ${Math.round(result.totalScore * 100)}/100`,
58034
+ `Weighted total: ${Math.round(result.totalScore * 100)}/100`,
57967
58035
  `Breakdown:
57968
58036
  ${breakdown}`,
57969
58037
  options["idea"] || inferred.idea ? `Idea:
57970
58038
  ${options["idea"] || inferred.idea}` : void 0,
57971
58039
  options["code"] || inferred.code ? `Code snippet:
57972
- ${options["code"] || inferred.code}` : void 0,
57973
- files.length ? `File contents:
57974
- ${files.map((f3) => {
57975
- const fObj = result?.files?.find?.((x2) => x2.path === f3);
57976
- return fObj ? `### ${fObj.path}
57977
- ${fObj.content}` : `### ${f3}`;
57978
- }).join("\n\n")}` : void 0
58040
+ ${options["code"] || inferred.code}` : void 0
58041
+ // No inline file contents; rely on attachments only
57979
58042
  ].filter(Boolean).join("\n\n");
57980
58043
  const llmSpinner = new ProcessAnimation();
57981
58044
  llmSpinner.start();
@@ -57985,42 +58048,53 @@ ${fObj.content}` : `### ${f3}`;
57985
58048
  "\n---\n",
57986
58049
  user
57987
58050
  ].join("\n");
58051
+ const attachments = Array.isArray(result?.files) ? result.files.map((f3) => ({
58052
+ name: path10__namespace.default.basename(String(f3.path || "attachment.txt")),
58053
+ path: String(f3.path || ""),
58054
+ mime: String(f3.mime || "text/plain"),
58055
+ data_base64: f3.binaryBase64 ? String(f3.binaryBase64) : f3.content ? Buffer.from(f3.content, "utf8").toString("base64") : void 0
58056
+ })).filter((a) => !!a.data_base64) : [];
57988
58057
  const response = await callAPI("/v1/ai-proxy", {
57989
58058
  method: "POST",
57990
58059
  body: {
58060
+ // Force Google route and always use the attachments-capable model
58061
+ provider: "google",
58062
+ model: "gemini-2.5-flash",
57991
58063
  prompt: enriched,
57992
- taskType: "evaluation"
58064
+ taskType: "evaluation",
58065
+ metadata: attachments.length ? { attachments } : void 0
57993
58066
  }
57994
58067
  });
57995
58068
  const routedModel = response?.data?.routedModel;
57996
58069
  const content = (response?.data?.content || response?.output || "").trim();
58070
+ const uploads = response?.data?.uploads || [];
57997
58071
  if (content) {
57998
- return this.success(content, {
58072
+ const uploadNote = uploads.length ? `Attached ${uploads.length} file(s) uploaded and referenced.` : attachments.length ? `Attached ${attachments.length} local file(s).` : void 0;
58073
+ const finalText = uploadNote ? `${uploadNote}
58074
+
58075
+ ${content}` : content;
58076
+ return this.success(finalText, {
57999
58077
  type: "evaluation-assess",
58000
58078
  total: result.totalScore,
58001
58079
  details: result.details,
58002
- routedModel
58080
+ routedModel,
58081
+ uploads
58003
58082
  });
58004
58083
  }
58005
58084
  } catch (e2) {
58085
+ try {
58086
+ llmSpinner.stop();
58087
+ } catch {
58088
+ }
58089
+ const msg = e2?.message || "LLM scoring failed";
58090
+ return this.error(`Evaluation failed: ${msg}`, "EVALUATION_ERROR", "LLM scoring is required and fallback is disabled");
58006
58091
  } finally {
58007
58092
  try {
58008
58093
  llmSpinner.stop();
58009
58094
  } catch {
58010
58095
  }
58011
58096
  }
58012
- const lines = [];
58013
- lines.push("Evaluation Summary (local fallback)");
58014
- lines.push(`Weighted Score: ${Math.round(result.totalScore * 100)}/100`);
58015
- lines.push("\nBreakdown:");
58016
- for (const d of result.details) {
58017
- lines.push(`- ${d.name} (${Math.round(d.weight * 100)}%): ${Math.round(d.score * 100)}/100 - ${d.reason}`);
58018
- }
58019
- return this.success(lines.join("\n"), {
58020
- type: "evaluation-assess",
58021
- total: result.totalScore,
58022
- details: result.details
58023
- });
58097
+ return this.error("Evaluation failed: unknown state", "EVALUATION_ERROR");
58024
58098
  }
58025
58099
  /**
58026
58100
  * Run A/B evaluation test