@bonginkan/maria 4.3.36 → 4.3.37

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.
@@ -26066,8 +26066,8 @@ var require_package = __commonJS({
26066
26066
  "package.json"(exports, module) {
26067
26067
  module.exports = {
26068
26068
  name: "@bonginkan/maria",
26069
- version: "4.3.36",
26070
- description: "\u{1F680} MARIA v4.3.36 - 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.",
26069
+ version: "4.3.37",
26070
+ description: "\u{1F680} MARIA v4.3.37 - 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.",
26071
26071
  keywords: [
26072
26072
  "ai",
26073
26073
  "cli",
@@ -28104,7 +28104,7 @@ var init_AuthenticationManager = __esm({
28104
28104
  const response = await fetch(`${this.apiBase}/api/user/profile`, {
28105
28105
  headers: {
28106
28106
  "Authorization": `Bearer ${tokens2.accessToken}`,
28107
- "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.36"}`
28107
+ "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.37"}`
28108
28108
  }
28109
28109
  });
28110
28110
  if (response.status === 401) {
@@ -28758,7 +28758,7 @@ async function callApi(path64, init3 = {}) {
28758
28758
  "Authorization": `Bearer ${token}`,
28759
28759
  "X-Device-Id": getDeviceId(),
28760
28760
  "X-Session-Id": getSessionId() || "",
28761
- "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.36"}`,
28761
+ "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.37"}`,
28762
28762
  "Content-Type": init3.headers?.["Content-Type"] || "application/json"
28763
28763
  });
28764
28764
  const doFetch = async (token) => {
@@ -29023,109 +29023,199 @@ var init_choice_memory = __esm({
29023
29023
  }
29024
29024
  });
29025
29025
 
29026
- // src/services/interactive/triage-orchestrator.ts
29027
- function getConfidenceBand(score) {
29028
- if (score >= TRIAGE_THRESHOLDS.high) {
29029
- return "high";
29026
+ // src/services/cli-auth/api-caller.ts
29027
+ var api_caller_exports = {};
29028
+ __export(api_caller_exports, {
29029
+ RateLimitError: () => RateLimitError,
29030
+ callAPI: () => callAPI,
29031
+ executeAIProxy: () => executeAIProxy,
29032
+ executeChat: () => executeChat,
29033
+ executeCode: () => executeCode
29034
+ });
29035
+ async function callAPI(endpoint, options = {}) {
29036
+ const tokens2 = await authManager2.getValidTokens();
29037
+ if (!tokens2) {
29038
+ throw new Error("Authentication required. Please run /login first.");
29030
29039
  }
29031
- if (score >= TRIAGE_THRESHOLDS.mid) {
29032
- return "mid";
29040
+ const apiBase = process.env.MARIA_API_BASE || "https://api.maria-code.ai";
29041
+ const url2 = `${apiBase}${endpoint}`;
29042
+ const controller = new AbortController();
29043
+ const defaultMs = 6e5;
29044
+ const envMs = Number(process.env.MARIA_API_TIMEOUT_MS || process.env.MARIA_CODE_TIMEOUT_MS || defaultMs);
29045
+ const timeoutMs = Number.isFinite(envMs) && envMs > 0 ? envMs : defaultMs;
29046
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
29047
+ try {
29048
+ const response = await fetch(url2, {
29049
+ method: options.method || "GET",
29050
+ headers: {
29051
+ "Authorization": `Bearer ${tokens2.accessToken}`,
29052
+ "Content-Type": "application/json",
29053
+ ...options.headers
29054
+ },
29055
+ body: options.body ? JSON.stringify(options.body) : void 0,
29056
+ // Note: fetch in Node doesn't accept 'agent' in our typing here; relying on global agent not necessary
29057
+ signal: controller.signal
29058
+ });
29059
+ clearTimeout(timeoutId);
29060
+ if (!response) {
29061
+ throw new Error("\u{1F310} Network error, check connection");
29062
+ }
29063
+ if (response.status === 401) {
29064
+ throw new Error("Session expired. Please run /login again.");
29065
+ }
29066
+ if (response.status === 402) {
29067
+ const data2 = await response.json().catch(() => ({}));
29068
+ throw new Error(`Quota exceeded: ${typeof data2?.message === "string" ? data2.message : "Please wait or /upgrade"}`);
29069
+ }
29070
+ if (response.status === 403) {
29071
+ const data2 = await response.json().catch(() => ({}));
29072
+ throw new Error(`Not available on Free plan: ${typeof data2?.message === "string" ? data2.message : "Run /upgrade"}`);
29073
+ }
29074
+ if (response.status === 429) {
29075
+ const h2 = response.headers;
29076
+ const ra = h2.get("Retry-After");
29077
+ const reset = h2.get("RateLimit-Reset") || h2.get("X-RateLimit-Reset");
29078
+ let waitSec = 3;
29079
+ if (ra && /^\d+$/.test(ra)) {
29080
+ waitSec = +ra;
29081
+ } else if (ra) {
29082
+ const t2 = Date.parse(ra);
29083
+ if (!isNaN(t2)) waitSec = Math.max(1, Math.ceil((t2 - Date.now()) / 1e3));
29084
+ } else if (reset) {
29085
+ waitSec = Math.max(1, Math.ceil((+reset - Date.now()) / 1e3));
29086
+ }
29087
+ throw new RateLimitError(`\u23F1 Wait ${waitSec}s`, waitSec);
29088
+ }
29089
+ if (!response.ok) {
29090
+ const data2 = await response.json().catch(() => ({}));
29091
+ const msg = typeof data2?.error === "string" ? data2.error : `Request failed: ${response.statusText}`;
29092
+ throw new Error(msg);
29093
+ }
29094
+ const data = await response.json();
29095
+ return data;
29096
+ } catch (error2) {
29097
+ clearTimeout(timeoutId);
29098
+ const err = error2;
29099
+ if (err && err.name === "AbortError") {
29100
+ throw new Error("\u{1F310} Network error, check connection");
29101
+ }
29102
+ throw err;
29033
29103
  }
29034
- return "low";
29035
29104
  }
29036
- async function triage(input3, ctx2 = {}) {
29037
- const question = (input3 || "").trim();
29038
- if (!question) {
29039
- return {
29040
- type: "simple",
29041
- confidence: 0.3,
29042
- rationale: ["empty"],
29043
- band: "low"
29044
- };
29105
+ async function executeChat(messages) {
29106
+ const response = await callAPI("/v1/chat", {
29107
+ method: "POST",
29108
+ body: { messages }
29109
+ });
29110
+ return response;
29111
+ }
29112
+ async function executeCode(input3) {
29113
+ const isOptions = typeof input3 === "object";
29114
+ const prompt = isOptions ? input3.prompt : input3;
29115
+ const provider = isOptions ? input3.provider : void 0;
29116
+ const model = isOptions ? input3.model : void 0;
29117
+ const attachments = isOptions ? input3.attachments : void 0;
29118
+ const body = { prompt, taskType: "code" };
29119
+ if (provider) body.provider = provider;
29120
+ if (model) body.model = model;
29121
+ if (attachments && attachments.length > 0) {
29122
+ body.metadata = { attachments };
29045
29123
  }
29046
- const lower2 = question.toLowerCase();
29047
- const rationale = [];
29048
- if (ctx2.recentCommands?.length) {
29049
- const last = ctx2.recentCommands[ctx2.recentCommands.length - 1];
29050
- if (typeof last === "string" && last.startsWith("/code")) {
29051
- rationale.push("recent:/code");
29052
- }
29124
+ const response = await callAPI("/v1/ai-proxy", {
29125
+ method: "POST",
29126
+ body
29127
+ });
29128
+ if (response.data?.routedModel) {
29129
+ response.routedModel = response.data.routedModel;
29053
29130
  }
29054
- if (IMAGE_REGEX.test(lower2)) {
29055
- rationale.push("match:image");
29056
- return {
29057
- type: "route-image",
29058
- confidence: 0.82,
29059
- rationale,
29060
- band: "high",
29061
- next: { route: "/image", args: [question] }
29062
- };
29131
+ if (response.data?.content) {
29132
+ response.output = response.data.content;
29063
29133
  }
29064
- if (VIDEO_REGEX.test(lower2)) {
29065
- rationale.push("match:video");
29066
- return {
29067
- type: "route-video",
29068
- confidence: 0.82,
29069
- rationale,
29070
- band: "high",
29071
- next: { route: "/video", args: [question] }
29134
+ return response;
29135
+ }
29136
+ async function executeAIProxy(provider, model, messages, options) {
29137
+ return callAPI("/v1/ai-proxy", {
29138
+ method: "POST",
29139
+ body: { provider, model, messages, options }
29140
+ });
29141
+ }
29142
+ var authManager2, RateLimitError;
29143
+ var init_api_caller = __esm({
29144
+ "src/services/cli-auth/api-caller.ts"() {
29145
+ init_AuthenticationManager();
29146
+ new https__default.default.Agent({ keepAlive: true });
29147
+ authManager2 = new AuthenticationManager();
29148
+ RateLimitError = class extends Error {
29149
+ constructor(message, retryAfter) {
29150
+ super(message);
29151
+ this.retryAfter = retryAfter;
29152
+ this.name = "RateLimitError";
29153
+ }
29072
29154
  };
29073
29155
  }
29074
- if (CODE_REGEX.test(lower2)) {
29075
- rationale.push("match:code");
29076
- const args2 = normalizeRouteArgs(["--plan-only", question]);
29077
- return {
29078
- type: "route-code",
29079
- confidence: 0.78,
29080
- rationale,
29081
- band: "high",
29082
- next: { route: "/code", args: args2 }
29083
- };
29156
+ });
29157
+
29158
+ // src/services/intelligent-router/LlmTopLevelRouter.ts
29159
+ function extractFirstJson(text) {
29160
+ const fence = /```json\r?\n([\s\S]*?)```/i.exec(text);
29161
+ if (fence) return fence[1];
29162
+ const start = text.indexOf("{");
29163
+ const end = text.lastIndexOf("}");
29164
+ if (start >= 0 && end > start) {
29165
+ const cand = text.slice(start, end + 1);
29166
+ try {
29167
+ JSON.parse(cand);
29168
+ return cand;
29169
+ } catch {
29170
+ }
29084
29171
  }
29085
- if (question.length > 220 || MULTI_SCOPE_REGEX.test(lower2) || /\b(ui|api|backend|database|テスト|設計|要件)\b/.test(lower2)) {
29086
- rationale.push("scope:multi");
29087
- const confidence = question.length > 220 ? 0.72 : 0.6;
29088
- return {
29089
- type: "complex",
29090
- confidence,
29091
- rationale,
29092
- band: getConfidenceBand(confidence)
29093
- };
29172
+ return null;
29173
+ }
29174
+ async function mapInputToTopLevelCommand(input3) {
29175
+ const system = [
29176
+ "You are a router for the MARIA CLI.",
29177
+ "Decide the best command for a single user input.",
29178
+ "Allowed commands: /help, /image, /code, /video, /whoami, /login, /logout, /evaluate, chat.",
29179
+ "Note that /image and /video are for generating them. If a path of a file is provided, you should double think why it's referenced (it may be for coding or chatting or other commands, regarding on the context).",
29180
+ 'Return JSON only with keys: { "command": string, "args"?: string[], "confidence": number }.',
29181
+ "Select chat when the input is a general question or conversation rather than a specific slash command.",
29182
+ "Make sure you set the confidence between 0 and 1.",
29183
+ "Only include args if necessary to pass user content to the command. Do not explain."
29184
+ ].join("\n");
29185
+ const resp = await callAPI("/v1/ai-proxy", {
29186
+ method: "POST",
29187
+ body: {
29188
+ prompt: `${system}
29189
+
29190
+ ---
29191
+
29192
+ ${input3}`,
29193
+ taskType: "routing"
29194
+ }
29195
+ });
29196
+ const raw = (resp?.data?.content || resp?.output || "").trim();
29197
+ const jsonText = extractFirstJson(raw) || raw;
29198
+ let parsed = {};
29199
+ try {
29200
+ parsed = JSON.parse(jsonText);
29201
+ } catch {
29202
+ return null;
29094
29203
  }
29095
- if (question.length <= 140 && QUESTION_REGEX.test(lower2)) {
29096
- rationale.push("short+qa");
29097
- const confidence = question.length < 80 ? 0.72 : 0.62;
29098
- return {
29099
- type: "simple",
29100
- confidence,
29101
- rationale,
29102
- band: getConfidenceBand(confidence)
29103
- };
29204
+ if (!parsed || typeof parsed.command !== "string") return null;
29205
+ const cmd = parsed.command;
29206
+ if (!["/help", "/image", "/code", "/video", "/whoami", "/login", "/logout", "/evaluate", "chat"].includes(cmd)) return null;
29207
+ const out = { command: cmd };
29208
+ if (Array.isArray(parsed.args)) {
29209
+ out.args = parsed.args.filter((a) => typeof a === "string" && a.trim()).map((s2) => s2.trim());
29104
29210
  }
29105
- rationale.push("default:complex");
29106
- const fallbackConfidence = question.length > 80 ? 0.5 : 0.4;
29107
- return {
29108
- type: "complex",
29109
- confidence: fallbackConfidence,
29110
- rationale,
29111
- band: getConfidenceBand(fallbackConfidence)
29112
- };
29113
- }
29114
- function normalizeRouteArgs(args2 = []) {
29115
- return args2.map((arg) => arg.trim()).filter((arg) => arg.length > 0);
29211
+ if (typeof parsed.confidence === "number") {
29212
+ out.confidence = Math.max(0, Math.min(1, parsed.confidence));
29213
+ }
29214
+ return out;
29116
29215
  }
29117
- var TRIAGE_THRESHOLDS, QUESTION_REGEX, CODE_REGEX, IMAGE_REGEX, VIDEO_REGEX, MULTI_SCOPE_REGEX;
29118
- var init_triage_orchestrator = __esm({
29119
- "src/services/interactive/triage-orchestrator.ts"() {
29120
- TRIAGE_THRESHOLDS = Object.freeze({
29121
- high: 0.7,
29122
- mid: 0.35
29123
- });
29124
- QUESTION_REGEX = /(how|what|why|when|どの|どう|なぜ|いつ|とは)\b/i;
29125
- CODE_REGEX = /(create|generate|add|refactor|fix|test|route|build|component|migration|implement|実装|生成|追加|修正)/i;
29126
- IMAGE_REGEX = /(image|画像|svg|png|webp|thumbnail|illustration|アート|描いて)/i;
29127
- VIDEO_REGEX = /(video|動画|mp4|webm|frames|storyboard|アニメーション)/i;
29128
- MULTI_SCOPE_REGEX = /(\band\b|\balso\b|\s+,+\s+)/i;
29216
+ var init_LlmTopLevelRouter = __esm({
29217
+ "src/services/intelligent-router/LlmTopLevelRouter.ts"() {
29218
+ init_api_caller();
29129
29219
  }
29130
29220
  });
29131
29221
 
@@ -29347,7 +29437,7 @@ var init_unknown_command = __esm({
29347
29437
  });
29348
29438
 
29349
29439
  // src/slash-commands/types.ts
29350
- var CommandError, ValidationError, PermissionError, RateLimitError;
29440
+ var CommandError, ValidationError, PermissionError, RateLimitError2;
29351
29441
  var init_types2 = __esm({
29352
29442
  "src/slash-commands/types.ts"() {
29353
29443
  CommandError = class extends Error {
@@ -29373,7 +29463,7 @@ var init_types2 = __esm({
29373
29463
  this.name = "PermissionError";
29374
29464
  }
29375
29465
  };
29376
- RateLimitError = class extends CommandError {
29466
+ RateLimitError2 = class extends CommandError {
29377
29467
  constructor(message, retryAfter) {
29378
29468
  super(message, "RATE_LIMIT_ERROR", 429);
29379
29469
  this.retryAfter = retryAfter;
@@ -36670,8 +36760,7 @@ var init_registry = __esm({
36670
36760
  const { ChatContextService: ChatContextService3 } = await Promise.resolve().then(() => (init_chat_context_service(), chat_context_service_exports));
36671
36761
  const ctxSvc = ChatContextService3.getInstance();
36672
36762
  const usageLine = ctxSvc.getSessionUsageLine();
36673
- const suffix = `
36674
- ${usageLine}`;
36763
+ const suffix = ``;
36675
36764
  result.message = (result.message || "").concat(suffix);
36676
36765
  } catch {
36677
36766
  }
@@ -36735,7 +36824,7 @@ ${usageLine}`;
36735
36824
  }
36736
36825
  }
36737
36826
  } catch (innerError) {
36738
- logger.error(`Failed to load command from ${file}:`, error);
36827
+ logger.error(`Failed to load command from ${file}:`, innerError);
36739
36828
  }
36740
36829
  }
36741
36830
  this.initialized = true;
@@ -36772,8 +36861,8 @@ ${usageLine}`;
36772
36861
  try {
36773
36862
  return await next();
36774
36863
  } catch (innerError) {
36775
- logger.error(`Command ${command.name} failed:`, error);
36776
- throw error;
36864
+ logger.error(`Command ${command.name} failed:`, innerError);
36865
+ throw innerError;
36777
36866
  }
36778
36867
  }
36779
36868
  });
@@ -37816,7 +37905,7 @@ var init_clear_auto_command = __esm({
37816
37905
  const args2 = mode === "display" ? ["--mode", "display"] : [];
37817
37906
  const res = await commandRegistry2.execute("/clear", args2, context2);
37818
37907
  const line = ctx2.getSessionUsageLine();
37819
- const banner = `Auto clear mode: ${mode} \xB7 ${line}`;
37908
+ const banner = `Auto clear mode: ${mode}`;
37820
37909
  if (res?.success) {
37821
37910
  return this.success(`${banner}
37822
37911
  ${res.message || ""}`.trim());
@@ -38482,6 +38571,69 @@ var init_ReadyCommandsService = __esm({
38482
38571
  }
38483
38572
  });
38484
38573
 
38574
+ // src/services/help/HelpArgumentInference.ts
38575
+ function extractFirstJson2(text) {
38576
+ const fence = /```json\r?\n([\s\S]*?)```/i.exec(text);
38577
+ if (fence) return fence[1];
38578
+ const start = text.indexOf("{");
38579
+ const end = text.lastIndexOf("}");
38580
+ if (start >= 0 && end > start) {
38581
+ const cand = text.slice(start, end + 1);
38582
+ try {
38583
+ JSON.parse(cand);
38584
+ return cand;
38585
+ } catch {
38586
+ }
38587
+ }
38588
+ return null;
38589
+ }
38590
+ async function inferHelpTarget(rawText, allowedCommands) {
38591
+ const allowList = allowedCommands.filter((n) => typeof n === "string" && n.trim()).map((n) => n.trim()).slice(0, 200);
38592
+ const system = [
38593
+ "You decide which help to show for the MARIA CLI.",
38594
+ 'Allowed results: { target: "general" } or { target: "command", commandName: <one of allowed> }.',
38595
+ 'Return JSON only with keys: { "target": "general"|"command", "commandName"?: string, "confidence": number }.',
38596
+ "If the user asks about a specific command (by name or description), select that command. Otherwise choose general.",
38597
+ "Use confidence between 0 and 1. Do not explain."
38598
+ ].join("\n");
38599
+ const user = [
38600
+ "User input:",
38601
+ rawText || "(empty)",
38602
+ "",
38603
+ "Allowed command names:",
38604
+ allowList.join(", ")
38605
+ ].join("\n");
38606
+ const resp = await callAPI("/v1/ai-proxy", {
38607
+ method: "POST",
38608
+ body: {
38609
+ prompt: `${system}
38610
+
38611
+ ---
38612
+
38613
+ ${user}`,
38614
+ taskType: "help"
38615
+ }
38616
+ });
38617
+ const raw = (resp?.data?.content || resp?.output || "").trim();
38618
+ const jsonText = extractFirstJson2(raw) || raw;
38619
+ let parsed = {};
38620
+ try {
38621
+ parsed = JSON.parse(jsonText);
38622
+ } catch {
38623
+ return {};
38624
+ }
38625
+ const out = {};
38626
+ if (parsed.target === "general" || parsed.target === "command") out.target = parsed.target;
38627
+ if (typeof parsed.commandName === "string" && parsed.commandName.trim()) out.commandName = parsed.commandName.trim();
38628
+ if (typeof parsed.confidence === "number") out.confidence = Math.max(0, Math.min(1, parsed.confidence));
38629
+ return out;
38630
+ }
38631
+ var init_HelpArgumentInference = __esm({
38632
+ "src/services/help/HelpArgumentInference.ts"() {
38633
+ init_api_caller();
38634
+ }
38635
+ });
38636
+
38485
38637
  // src/slash-commands/categories/core/handlers/HelpCommand.ts
38486
38638
  var HelpCommand_exports = {};
38487
38639
  __export(HelpCommand_exports, {
@@ -38495,6 +38647,8 @@ var init_HelpCommand = __esm({
38495
38647
  init_ReadyCommandsService();
38496
38648
  init_telemetry_helper();
38497
38649
  init_subscription_manager();
38650
+ init_HelpArgumentInference();
38651
+ init_animations();
38498
38652
  HelpCommand = class extends BaseCommand {
38499
38653
  name = "help";
38500
38654
  category = "core";
@@ -38543,6 +38697,26 @@ var init_HelpCommand = __esm({
38543
38697
  await this.trackSuccess(startTime, context2);
38544
38698
  return result2;
38545
38699
  }
38700
+ const text = (args2.raw || []).join(" ").trim();
38701
+ if (text) {
38702
+ const commandsList = (await this.readyService.getAllReadyCommands()).map((c) => c.name);
38703
+ const spin = new ProcessAnimation();
38704
+ spin.start();
38705
+ try {
38706
+ const inferred = await inferHelpTarget(text, commandsList);
38707
+ const threshold = Number(process.env.MARIA_HELP_CONFIDENCE || "0.7");
38708
+ if (inferred && inferred.target === "command" && inferred.commandName && (inferred.confidence ?? 1) >= threshold) {
38709
+ const result2 = await this.showCommandHelp(inferred.commandName);
38710
+ await this.trackSuccess(startTime, context2);
38711
+ return result2;
38712
+ }
38713
+ } finally {
38714
+ try {
38715
+ spin.stop();
38716
+ } catch {
38717
+ }
38718
+ }
38719
+ }
38546
38720
  if (_positional.length > 0) {
38547
38721
  const commandName = _positional[0];
38548
38722
  if (commandName) {
@@ -47560,140 +47734,8 @@ var init_NLInference = __esm({
47560
47734
  }
47561
47735
  });
47562
47736
 
47563
- // src/services/cli-auth/api-caller.ts
47564
- var api_caller_exports = {};
47565
- __export(api_caller_exports, {
47566
- RateLimitError: () => RateLimitError2,
47567
- callAPI: () => callAPI,
47568
- executeAIProxy: () => executeAIProxy,
47569
- executeChat: () => executeChat,
47570
- executeCode: () => executeCode
47571
- });
47572
- async function callAPI(endpoint, options = {}) {
47573
- const tokens2 = await authManager2.getValidTokens();
47574
- if (!tokens2) {
47575
- throw new Error("Authentication required. Please run /login first.");
47576
- }
47577
- const apiBase = process.env.MARIA_API_BASE || "https://api.maria-code.ai";
47578
- const url2 = `${apiBase}${endpoint}`;
47579
- const controller = new AbortController();
47580
- const defaultMs = 6e5;
47581
- const envMs = Number(process.env.MARIA_API_TIMEOUT_MS || process.env.MARIA_CODE_TIMEOUT_MS || defaultMs);
47582
- const timeoutMs = Number.isFinite(envMs) && envMs > 0 ? envMs : defaultMs;
47583
- const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
47584
- try {
47585
- const response = await fetch(url2, {
47586
- method: options.method || "GET",
47587
- headers: {
47588
- "Authorization": `Bearer ${tokens2.accessToken}`,
47589
- "Content-Type": "application/json",
47590
- ...options.headers
47591
- },
47592
- body: options.body ? JSON.stringify(options.body) : void 0,
47593
- // Note: fetch in Node doesn't accept 'agent' in our typing here; relying on global agent not necessary
47594
- signal: controller.signal
47595
- });
47596
- clearTimeout(timeoutId);
47597
- if (!response) {
47598
- throw new Error("\u{1F310} Network error, check connection");
47599
- }
47600
- if (response.status === 401) {
47601
- throw new Error("Session expired. Please run /login again.");
47602
- }
47603
- if (response.status === 402) {
47604
- const data2 = await response.json().catch(() => ({}));
47605
- throw new Error(`Quota exceeded: ${typeof data2?.message === "string" ? data2.message : "Please wait or /upgrade"}`);
47606
- }
47607
- if (response.status === 403) {
47608
- const data2 = await response.json().catch(() => ({}));
47609
- throw new Error(`Not available on Free plan: ${typeof data2?.message === "string" ? data2.message : "Run /upgrade"}`);
47610
- }
47611
- if (response.status === 429) {
47612
- const h2 = response.headers;
47613
- const ra = h2.get("Retry-After");
47614
- const reset = h2.get("RateLimit-Reset") || h2.get("X-RateLimit-Reset");
47615
- let waitSec = 3;
47616
- if (ra && /^\d+$/.test(ra)) {
47617
- waitSec = +ra;
47618
- } else if (ra) {
47619
- const t2 = Date.parse(ra);
47620
- if (!isNaN(t2)) waitSec = Math.max(1, Math.ceil((t2 - Date.now()) / 1e3));
47621
- } else if (reset) {
47622
- waitSec = Math.max(1, Math.ceil((+reset - Date.now()) / 1e3));
47623
- }
47624
- throw new RateLimitError2(`\u23F1 Wait ${waitSec}s`, waitSec);
47625
- }
47626
- if (!response.ok) {
47627
- const data2 = await response.json().catch(() => ({}));
47628
- const msg = typeof data2?.error === "string" ? data2.error : `Request failed: ${response.statusText}`;
47629
- throw new Error(msg);
47630
- }
47631
- const data = await response.json();
47632
- return data;
47633
- } catch (error2) {
47634
- clearTimeout(timeoutId);
47635
- const err = error2;
47636
- if (err && err.name === "AbortError") {
47637
- throw new Error("\u{1F310} Network error, check connection");
47638
- }
47639
- throw err;
47640
- }
47641
- }
47642
- async function executeChat(messages) {
47643
- const response = await callAPI("/v1/chat", {
47644
- method: "POST",
47645
- body: { messages }
47646
- });
47647
- return response;
47648
- }
47649
- async function executeCode(input3) {
47650
- const isOptions = typeof input3 === "object";
47651
- const prompt = isOptions ? input3.prompt : input3;
47652
- const provider = isOptions ? input3.provider : void 0;
47653
- const model = isOptions ? input3.model : void 0;
47654
- const attachments = isOptions ? input3.attachments : void 0;
47655
- const body = { prompt, taskType: "code" };
47656
- if (provider) body.provider = provider;
47657
- if (model) body.model = model;
47658
- if (attachments && attachments.length > 0) {
47659
- body.metadata = { attachments };
47660
- }
47661
- const response = await callAPI("/v1/ai-proxy", {
47662
- method: "POST",
47663
- body
47664
- });
47665
- if (response.data?.routedModel) {
47666
- response.routedModel = response.data.routedModel;
47667
- }
47668
- if (response.data?.content) {
47669
- response.output = response.data.content;
47670
- }
47671
- return response;
47672
- }
47673
- async function executeAIProxy(provider, model, messages, options) {
47674
- return callAPI("/v1/ai-proxy", {
47675
- method: "POST",
47676
- body: { provider, model, messages, options }
47677
- });
47678
- }
47679
- var authManager2, RateLimitError2;
47680
- var init_api_caller = __esm({
47681
- "src/services/cli-auth/api-caller.ts"() {
47682
- init_AuthenticationManager();
47683
- new https__default.default.Agent({ keepAlive: true });
47684
- authManager2 = new AuthenticationManager();
47685
- RateLimitError2 = class extends Error {
47686
- constructor(message, retryAfter) {
47687
- super(message);
47688
- this.retryAfter = retryAfter;
47689
- this.name = "RateLimitError";
47690
- }
47691
- };
47692
- }
47693
- });
47694
-
47695
47737
  // src/services/media-orchestrator/ImageArgumentInference.ts
47696
- function extractFirstJson(text) {
47738
+ function extractFirstJson3(text) {
47697
47739
  const fence = /```json\r?\n([\s\S]*?)```/i.exec(text);
47698
47740
  if (fence) return fence[1];
47699
47741
  const fencePlain = /```\s*\r?\n([\s\S]*?)```/i.exec(text);
@@ -47763,7 +47805,7 @@ ${user}`,
47763
47805
  }
47764
47806
  });
47765
47807
  const raw = (response?.data?.content || response?.output || "").trim();
47766
- const jsonText = extractFirstJson(raw) || raw;
47808
+ const jsonText = extractFirstJson3(raw) || raw;
47767
47809
  let parsed;
47768
47810
  try {
47769
47811
  parsed = JSON.parse(jsonText);
@@ -51219,7 +51261,7 @@ var init_about_command = __esm({
51219
51261
  async execute(args2, context2) {
51220
51262
  const output3 = [];
51221
51263
  output3.push("");
51222
- output3.push(chalk14__default.default.cyan.bold("\u{1F916} About MARIA v4.3.36"));
51264
+ output3.push(chalk14__default.default.cyan.bold("\u{1F916} About MARIA v4.3.37"));
51223
51265
  output3.push(chalk14__default.default.gray("\u2550".repeat(40)));
51224
51266
  output3.push("");
51225
51267
  output3.push(chalk14__default.default.white.bold("MARIA - Minimal API, Maximum Power"));
@@ -54608,6 +54650,62 @@ var init_code_utils = __esm({
54608
54650
  ]);
54609
54651
  }
54610
54652
  });
54653
+
54654
+ // src/services/code-orchestrator/ArgumentInference.ts
54655
+ function extractFirstJson4(text) {
54656
+ const fence = /```json\r?\n([\s\S]*?)```/i.exec(text);
54657
+ if (fence) return fence[1];
54658
+ const start = text.indexOf("{");
54659
+ const end = text.lastIndexOf("}");
54660
+ if (start >= 0 && end > start) {
54661
+ const cand = text.slice(start, end + 1);
54662
+ try {
54663
+ JSON.parse(cand);
54664
+ return cand;
54665
+ } catch {
54666
+ }
54667
+ }
54668
+ return null;
54669
+ }
54670
+ async function inferCodeArgs(rawText) {
54671
+ const system = [
54672
+ "You extract structured options for a code command.",
54673
+ 'Return JSON only with keys: { "planOnly"?: boolean, "dryRun"?: boolean, "output"?: "names"|"summary"|"detail", "previewLines"?: number }.',
54674
+ "Decide from the user text whether planOnly or dryRun should be true. Do not explain.",
54675
+ "Only include output if the user requests preview detail or summary mode. Only include previewLines if a specific number of lines is requested."
54676
+ ].join("\n");
54677
+ const resp = await callAPI("/v1/ai-proxy", {
54678
+ method: "POST",
54679
+ body: {
54680
+ prompt: `${system}
54681
+
54682
+ ---
54683
+
54684
+ ${rawText}`,
54685
+ taskType: "code"
54686
+ }
54687
+ });
54688
+ const raw = (resp?.data?.content || resp?.output || "").trim();
54689
+ const jsonText = extractFirstJson4(raw) || raw;
54690
+ let parsed = {};
54691
+ try {
54692
+ parsed = JSON.parse(jsonText);
54693
+ } catch {
54694
+ return {};
54695
+ }
54696
+ const out = {};
54697
+ if (typeof parsed.planOnly === "boolean") out.planOnly = parsed.planOnly;
54698
+ if (typeof parsed.dryRun === "boolean") out.dryRun = parsed.dryRun;
54699
+ if (typeof parsed.output === "string" && (parsed.output === "names" || parsed.output === "summary" || parsed.output === "detail")) out.output = parsed.output;
54700
+ if (typeof parsed.previewLines === "number" && Number.isFinite(parsed.previewLines) && parsed.previewLines > 0) out.previewLines = Math.min(2e3, Math.floor(parsed.previewLines));
54701
+ if (out.planOnly) out.dryRun = false;
54702
+ return out;
54703
+ }
54704
+ var init_ArgumentInference = __esm({
54705
+ "src/services/code-orchestrator/ArgumentInference.ts"() {
54706
+ init_api_caller();
54707
+ }
54708
+ });
54611
54709
  async function scanRepo(cwd2) {
54612
54710
  if (_cache && _cache.root === cwd2) return _cache;
54613
54711
  const root = cwd2;
@@ -55997,7 +56095,7 @@ function mapCodeErrorToReason(err) {
55997
56095
  const error2 = err;
55998
56096
  const message = typeof error2?.message === "string" ? error2.message.toLowerCase() : "";
55999
56097
  const code = typeof error2?.code === "string" ? error2.code.toLowerCase() : "";
56000
- if (error2 instanceof RateLimitError2 || message.includes("rate") && message.includes("limit")) {
56098
+ if (error2 instanceof RateLimitError || message.includes("rate") && message.includes("limit")) {
56001
56099
  return "rate-limit";
56002
56100
  }
56003
56101
  if (message.includes("timeout") || code === "etimedout") {
@@ -56474,6 +56572,7 @@ var init_code_command = __esm({
56474
56572
  init_rate_limit_handler();
56475
56573
  init_animations();
56476
56574
  init_code_utils();
56575
+ init_ArgumentInference();
56477
56576
  LANGUAGE_EXTENSIONS = {
56478
56577
  javascript: ".js",
56479
56578
  typescript: ".ts",
@@ -56513,6 +56612,35 @@ var init_code_command = __esm({
56513
56612
  }
56514
56613
  try {
56515
56614
  const opts = this.parseV2Options(commandArgs.raw);
56615
+ try {
56616
+ const rawText = commandArgs.raw.join(" ");
56617
+ const explicitPlan = commandArgs.raw.includes("--plan-only") || commandArgs.raw.includes("--sow");
56618
+ const explicitDry = commandArgs.raw.includes("--dry-run");
56619
+ const explicitOutput = commandArgs.raw.some((x2) => x2.startsWith("--output") || x2 === "--verbose" || x2 === "-v");
56620
+ const explicitPreview = commandArgs.raw.some((x2) => x2.startsWith("--preview-lines"));
56621
+ const preSpin = new ProcessAnimation();
56622
+ preSpin.start();
56623
+ let inferred = {};
56624
+ try {
56625
+ inferred = await inferCodeArgs(rawText);
56626
+ } finally {
56627
+ try {
56628
+ preSpin.stop();
56629
+ } catch {
56630
+ }
56631
+ }
56632
+ if (!explicitPlan && !explicitDry) {
56633
+ if (typeof inferred.planOnly === "boolean") opts.planOnly = inferred.planOnly;
56634
+ if (typeof inferred.dryRun === "boolean") opts.dryRun = inferred.dryRun;
56635
+ }
56636
+ if (!explicitOutput && inferred.output) {
56637
+ opts.output = inferred.output;
56638
+ }
56639
+ if (!explicitPreview && typeof inferred.previewLines === "number") {
56640
+ opts.previewLines = inferred.previewLines;
56641
+ }
56642
+ } catch {
56643
+ }
56516
56644
  if (opts.planOnly) {
56517
56645
  opts.apply = false;
56518
56646
  opts.dryRun = false;
@@ -56653,7 +56781,7 @@ ${user}`
56653
56781
  }
56654
56782
  });
56655
56783
  const content = (resp?.data?.content || resp?.content || "").trim();
56656
- const extractFirstJson3 = (text) => {
56784
+ const extractFirstJson6 = (text) => {
56657
56785
  const fence = /```\s*json\s*\r?\n([\s\S]*?)```/i.exec(text);
56658
56786
  if (fence) return fence[1];
56659
56787
  const generic = /```\s*\r?\n([\s\S]*?)```/i.exec(text);
@@ -56676,7 +56804,7 @@ ${user}`
56676
56804
  }
56677
56805
  return null;
56678
56806
  };
56679
- const jsonText = extractFirstJson3(content) || content;
56807
+ const jsonText = extractFirstJson6(content) || content;
56680
56808
  let parsed = {};
56681
56809
  try {
56682
56810
  parsed = JSON.parse(jsonText);
@@ -71656,7 +71784,7 @@ ${user}`,
71656
71784
  };
71657
71785
  }
71658
71786
  });
71659
- function extractFirstJson2(text) {
71787
+ function extractFirstJson5(text) {
71660
71788
  const fence = /```json\r?\n([\s\S]*?)```/i.exec(text);
71661
71789
  if (fence) return fence[1];
71662
71790
  const start = text.indexOf("{");
@@ -71703,7 +71831,7 @@ ${user}`,
71703
71831
  }
71704
71832
  });
71705
71833
  const raw = (response?.data?.content || response?.output || "").trim();
71706
- const jsonText = extractFirstJson2(raw) || raw;
71834
+ const jsonText = extractFirstJson5(raw) || raw;
71707
71835
  let parsed = {};
71708
71836
  try {
71709
71837
  parsed = JSON.parse(jsonText);
@@ -71724,7 +71852,7 @@ ${user}`,
71724
71852
  }
71725
71853
  return out;
71726
71854
  }
71727
- var init_ArgumentInference = __esm({
71855
+ var init_ArgumentInference2 = __esm({
71728
71856
  "src/services/evaluation/ArgumentInference.ts"() {
71729
71857
  init_api_caller();
71730
71858
  }
@@ -71745,7 +71873,7 @@ var init_evaluate_command = __esm({
71745
71873
  init_EvaluationOrchestrator();
71746
71874
  init_api_caller();
71747
71875
  init_animations();
71748
- init_ArgumentInference();
71876
+ init_ArgumentInference2();
71749
71877
  EvaluateCommand = class extends BaseCommand {
71750
71878
  name = "evaluate";
71751
71879
  category = "evaluation";
@@ -72428,7 +72556,7 @@ __export(slash_commands_exports, {
72428
72556
  MemoryStatusCommand: () => MemoryStatusCommand,
72429
72557
  PermissionError: () => PermissionError,
72430
72558
  PlanCommand: () => PlanCommand,
72431
- RateLimitError: () => RateLimitError,
72559
+ RateLimitError: () => RateLimitError2,
72432
72560
  RateLimitMiddleware: () => RateLimitMiddleware,
72433
72561
  RecallCommand: () => RecallCommand,
72434
72562
  RememberCommand: () => RememberCommand,
@@ -76582,47 +76710,23 @@ async function handleLine(line, options = {}) {
76582
76710
  }
76583
76711
  const consumed = await handleSlash(input3);
76584
76712
  if (consumed) return;
76585
- let triageResult = options.triageResult ?? null;
76586
- if (!options.skipTriage) {
76587
- triageResult = await triage(input3, {
76588
- locale: process.env.LANG,
76589
- recentCommands: []
76590
- });
76591
- if (
76592
- /*false && for debugging*/
76593
- triageResult.next?.route
76594
- ) {
76595
- const commandParts = [
76596
- triageResult.next.route,
76597
- ...triageResult.next.args ?? []
76598
- ];
76599
- const routedLine = commandParts.join(" ").trim();
76600
- console.log(chalk14__default.default.white("Routed:"));
76601
- console.log(chalk14__default.default.white(routedLine));
76602
- await handleLine(routedLine, {
76603
- skipChoiceResolution: true,
76604
- skipTriage: true
76605
- });
76606
- console.log(chalk14__default.default.white(""));
76607
- console.log(chalk14__default.default.white("Summary:"));
76608
- if (triageResult.type === "route-code") {
76609
- console.log(chalk14__default.default.white("OK: routed to /code plan-only"));
76610
- console.log(chalk14__default.default.white("Next steps:"));
76611
- console.log(chalk14__default.default.white("- Run /code --apply --yes after reviewing the plan"));
76612
- } else if (triageResult.type === "route-image") {
76613
- console.log(chalk14__default.default.white("OK: routed to /image"));
76614
- console.log(chalk14__default.default.white("Next steps:"));
76615
- console.log(chalk14__default.default.white("- Review generated images and iterate if needed"));
76616
- } else if (triageResult.type === "route-video") {
76617
- console.log(chalk14__default.default.white("OK: routed to /video"));
76618
- console.log(chalk14__default.default.white("Next steps:"));
76619
- console.log(chalk14__default.default.white("- Inspect the storyboard or render output"));
76620
- } else {
76621
- console.log(chalk14__default.default.white("OK: routed"));
76622
- console.log(chalk14__default.default.white("Next steps:"));
76623
- console.log(chalk14__default.default.white("- Follow the routed workflow"));
76713
+ if (!input3.startsWith("/")) {
76714
+ const mapped = await mapInputToTopLevelCommand(input3);
76715
+ if (process.env.MARIA_DEBUG === "1") {
76716
+ console.log(chalk14__default.default.white(`Command: {command: '${mapped.command}', args: '${mapped.args}', confidence: '${mapped.confidence}'}`));
76717
+ }
76718
+ try {
76719
+ const threshold = Number(process.env.MARIA_ROUTE_CONFIDENCE || "0.7");
76720
+ if (mapped && mapped.command) {
76721
+ const conf = typeof mapped.confidence === "number" ? mapped.confidence : 1;
76722
+ if (mapped.command === "chat") {
76723
+ } else if (conf >= threshold) {
76724
+ const routed = [mapped.command, ...mapped.args || [input3]].join(" ").trim();
76725
+ await handleLine(routed, { skipChoiceResolution: true, skipTriage: true });
76726
+ return;
76727
+ }
76624
76728
  }
76625
- return;
76729
+ } finally {
76626
76730
  }
76627
76731
  }
76628
76732
  const isAuthenticated = await authManager.isAuthenticated();
@@ -76635,73 +76739,7 @@ async function handleLine(line, options = {}) {
76635
76739
  const user = { role: "user", content: input3, timestamp: /* @__PURE__ */ new Date() };
76636
76740
  session.push(user);
76637
76741
  if (store?.addMessage) await store.addMessage(user);
76638
- if (triageResult?.type === "complex") {
76639
- await handleComplexChat(input3, triageResult);
76640
- return;
76641
- }
76642
- await streamAnswer(input3, { triage: triageResult });
76643
- }
76644
- async function handleComplexChat(request, triageResult) {
76645
- const animation = new ProcessAnimation();
76646
- animation.start();
76647
- try {
76648
- const authed = await authManager.isAuthenticated();
76649
- let content = "";
76650
- if (authed) {
76651
- try {
76652
- const resp = await callApiJson("/api/ai", {
76653
- method: "POST",
76654
- body: JSON.stringify({ prompt: request, taskType: "planning" }),
76655
- headers: { "Content-Type": "application/json" }
76656
- });
76657
- content = resp?.data?.response || resp?.data?.content || "";
76658
- } catch {
76659
- }
76660
- }
76661
- if (!content) {
76662
- animation.stop();
76663
- await streamAnswer(request, { triage: triageResult });
76664
- return;
76665
- }
76666
- animation.stop();
76667
- const cleaned = content && typeof content === "string" ? content : buildComplexPlanSteps(request).join("\n");
76668
- console.log(chalk14__default.default.white(cleaned));
76669
- const planMessage = {
76670
- role: "assistant",
76671
- content: cleaned,
76672
- timestamp: /* @__PURE__ */ new Date(),
76673
- metadata: { tag: "complex-chat", triage: triageResult }
76674
- };
76675
- session.push(planMessage);
76676
- if (store?.addMessage) await store.addMessage(planMessage);
76677
- console.log(chalk14__default.default.white(""));
76678
- console.log(chalk14__default.default.white("Summary:"));
76679
- console.log(chalk14__default.default.white("OK: plan prepared"));
76680
- console.log(chalk14__default.default.white("Next steps:"));
76681
- console.log(chalk14__default.default.white("- Ask to apply or adjust the plan"));
76682
- } finally {
76683
- try {
76684
- animation.stop();
76685
- } catch {
76686
- }
76687
- }
76688
- }
76689
- function buildComplexPlanSteps(request) {
76690
- const scoped = request.trim();
76691
- const steps = [
76692
- `Clarify scope, constraints, and success criteria for "${scoped}"`,
76693
- `Review existing modules in src/ and docs/ for related work`,
76694
- `Design the solution with safe defaults and feature flags if needed`,
76695
- `Implement changes and document decisions`,
76696
- `Validate with pnpm test and peer review artifacts`
76697
- ];
76698
- if (/(test|spec|verify|検証)/i.test(scoped)) {
76699
- steps.push("Extend or add Vitest coverage for new behaviour");
76700
- }
76701
- if (/(ui|frontend|component|画面)/i.test(scoped)) {
76702
- steps.push("Capture CLI or UI snapshots to confirm UX changes");
76703
- }
76704
- return steps;
76742
+ await streamAnswer(input3, {});
76705
76743
  }
76706
76744
  async function tryResolveChoice(rawLine) {
76707
76745
  const resolution = choiceMemory.resolve(rawLine);
@@ -76800,9 +76838,8 @@ var init_cli = __esm({
76800
76838
  init_version();
76801
76839
  init_animations();
76802
76840
  init_cli_auth();
76803
- init_api_client();
76804
76841
  init_choice_memory();
76805
- init_triage_orchestrator();
76842
+ init_LlmTopLevelRouter();
76806
76843
  init_handle_slash();
76807
76844
  init_session_state();
76808
76845
  init_process_handlers();