@bonginkan/maria 4.3.35 → 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.
- package/README.md +4 -4
- package/dist/READY.manifest.json +26 -18
- package/dist/bin/maria.cjs +1154 -441
- package/dist/bin/maria.cjs.map +1 -1
- package/dist/cli.cjs +1156 -443
- package/dist/cli.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/server/express-server.cjs +52 -12
- package/dist/server/express-server.js +52 -12
- package/dist/server-express.cjs +52 -12
- package/dist/server-express.cjs.map +1 -1
- package/package.json +2 -2
- package/src/slash-commands/READY.manifest.json +26 -18
package/dist/bin/maria.cjs
CHANGED
|
@@ -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.
|
|
26070
|
-
description: "\u{1F680} MARIA v4.3.
|
|
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.
|
|
28107
|
+
"User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.37"}`
|
|
28108
28108
|
}
|
|
28109
28109
|
});
|
|
28110
28110
|
if (response.status === 401) {
|
|
@@ -28714,6 +28714,17 @@ var init_withAuth = __esm({
|
|
|
28714
28714
|
];
|
|
28715
28715
|
}
|
|
28716
28716
|
});
|
|
28717
|
+
|
|
28718
|
+
// src/services/cli-auth/api-client.ts
|
|
28719
|
+
var api_client_exports = {};
|
|
28720
|
+
__export(api_client_exports, {
|
|
28721
|
+
ERR: () => ERR,
|
|
28722
|
+
callApi: () => callApi,
|
|
28723
|
+
callApiJson: () => callApiJson,
|
|
28724
|
+
clientThrottle: () => clientThrottle,
|
|
28725
|
+
streamApi: () => streamApi,
|
|
28726
|
+
uploadFile: () => uploadFile
|
|
28727
|
+
});
|
|
28717
28728
|
function getDeviceId() {
|
|
28718
28729
|
if (!global.MARIA_DEVICE_ID) {
|
|
28719
28730
|
global.MARIA_DEVICE_ID = v4_default();
|
|
@@ -28723,6 +28734,17 @@ function getDeviceId() {
|
|
|
28723
28734
|
function getSessionId() {
|
|
28724
28735
|
return global.MARIA_SESSION_ID;
|
|
28725
28736
|
}
|
|
28737
|
+
function clientThrottle(endpoint) {
|
|
28738
|
+
const now2 = Date.now();
|
|
28739
|
+
const lastCall = rateLimitMap.get(endpoint) || 0;
|
|
28740
|
+
const wait = MIN_GAP_MS - (now2 - lastCall);
|
|
28741
|
+
if (wait > 0) {
|
|
28742
|
+
const waitSeconds = Math.ceil(wait / 1e3);
|
|
28743
|
+
console.log(chalk14__default.default.yellow(`\u23F1\uFE0F Rate limit: wait ${waitSeconds}s`));
|
|
28744
|
+
throw { ...ERR.RATE, waitTime: waitSeconds };
|
|
28745
|
+
}
|
|
28746
|
+
rateLimitMap.set(endpoint, now2);
|
|
28747
|
+
}
|
|
28726
28748
|
async function callApi(path64, init3 = {}) {
|
|
28727
28749
|
const apiBase = process.env.MARIA_API_BASE || "https://api.maria-code.ai";
|
|
28728
28750
|
const fullUrl = `${apiBase}${path64}`;
|
|
@@ -28736,7 +28758,7 @@ async function callApi(path64, init3 = {}) {
|
|
|
28736
28758
|
"Authorization": `Bearer ${token}`,
|
|
28737
28759
|
"X-Device-Id": getDeviceId(),
|
|
28738
28760
|
"X-Session-Id": getSessionId() || "",
|
|
28739
|
-
"User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.
|
|
28761
|
+
"User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.37"}`,
|
|
28740
28762
|
"Content-Type": init3.headers?.["Content-Type"] || "application/json"
|
|
28741
28763
|
});
|
|
28742
28764
|
const doFetch = async (token) => {
|
|
@@ -28804,7 +28826,48 @@ async function callApiJson(path64, init3 = {}) {
|
|
|
28804
28826
|
}
|
|
28805
28827
|
return response.json();
|
|
28806
28828
|
}
|
|
28807
|
-
|
|
28829
|
+
async function* streamApi(path64, init3 = {}) {
|
|
28830
|
+
const response = await callApi(path64, {
|
|
28831
|
+
...init3,
|
|
28832
|
+
headers: {
|
|
28833
|
+
...init3.headers,
|
|
28834
|
+
"Accept": "text/event-stream"
|
|
28835
|
+
}
|
|
28836
|
+
});
|
|
28837
|
+
if (!response.ok) {
|
|
28838
|
+
throw new Error(`Stream error: ${response.status}`);
|
|
28839
|
+
}
|
|
28840
|
+
const reader = response.body?.getReader();
|
|
28841
|
+
if (!reader) {
|
|
28842
|
+
throw new Error("No response body");
|
|
28843
|
+
}
|
|
28844
|
+
const decoder = new TextDecoder();
|
|
28845
|
+
try {
|
|
28846
|
+
while (true) {
|
|
28847
|
+
const { done, value } = await reader.read();
|
|
28848
|
+
if (done) break;
|
|
28849
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
28850
|
+
yield chunk;
|
|
28851
|
+
}
|
|
28852
|
+
} finally {
|
|
28853
|
+
reader.releaseLock();
|
|
28854
|
+
}
|
|
28855
|
+
}
|
|
28856
|
+
async function uploadFile(path64, file, metadata5 = {}) {
|
|
28857
|
+
const formData = new FormData();
|
|
28858
|
+
formData.append("file", new Blob([file]));
|
|
28859
|
+
Object.entries(metadata5).forEach(([key, value]) => {
|
|
28860
|
+
formData.append(key, String(value));
|
|
28861
|
+
});
|
|
28862
|
+
return callApiJson(path64, {
|
|
28863
|
+
method: "POST",
|
|
28864
|
+
body: formData,
|
|
28865
|
+
headers: {
|
|
28866
|
+
// Don't set Content-Type, let browser set it with boundary
|
|
28867
|
+
}
|
|
28868
|
+
});
|
|
28869
|
+
}
|
|
28870
|
+
var ERR, rateLimitMap, MIN_GAP_MS;
|
|
28808
28871
|
var init_api_client = __esm({
|
|
28809
28872
|
"src/services/cli-auth/api-client.ts"() {
|
|
28810
28873
|
init_AuthenticationManager();
|
|
@@ -28817,6 +28880,8 @@ var init_api_client = __esm({
|
|
|
28817
28880
|
NETWORK: { msg: "\u{1F310} Network error, check connection", code: 1 },
|
|
28818
28881
|
RATE: { msg: "\u23F3 Rate limited, retrying...", code: 1 }
|
|
28819
28882
|
};
|
|
28883
|
+
rateLimitMap = /* @__PURE__ */ new Map();
|
|
28884
|
+
MIN_GAP_MS = 3e3;
|
|
28820
28885
|
}
|
|
28821
28886
|
});
|
|
28822
28887
|
|
|
@@ -28958,109 +29023,199 @@ var init_choice_memory = __esm({
|
|
|
28958
29023
|
}
|
|
28959
29024
|
});
|
|
28960
29025
|
|
|
28961
|
-
// src/services/
|
|
28962
|
-
|
|
28963
|
-
|
|
28964
|
-
|
|
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.");
|
|
28965
29039
|
}
|
|
28966
|
-
|
|
28967
|
-
|
|
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;
|
|
28968
29103
|
}
|
|
28969
|
-
return "low";
|
|
28970
29104
|
}
|
|
28971
|
-
async function
|
|
28972
|
-
const
|
|
28973
|
-
|
|
28974
|
-
|
|
28975
|
-
|
|
28976
|
-
|
|
28977
|
-
|
|
28978
|
-
|
|
28979
|
-
|
|
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 };
|
|
28980
29123
|
}
|
|
28981
|
-
const
|
|
28982
|
-
|
|
28983
|
-
|
|
28984
|
-
|
|
28985
|
-
|
|
28986
|
-
|
|
28987
|
-
}
|
|
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;
|
|
28988
29130
|
}
|
|
28989
|
-
if (
|
|
28990
|
-
|
|
28991
|
-
return {
|
|
28992
|
-
type: "route-image",
|
|
28993
|
-
confidence: 0.82,
|
|
28994
|
-
rationale,
|
|
28995
|
-
band: "high",
|
|
28996
|
-
next: { route: "/image", args: [question] }
|
|
28997
|
-
};
|
|
29131
|
+
if (response.data?.content) {
|
|
29132
|
+
response.output = response.data.content;
|
|
28998
29133
|
}
|
|
28999
|
-
|
|
29000
|
-
|
|
29001
|
-
|
|
29002
|
-
|
|
29003
|
-
|
|
29004
|
-
|
|
29005
|
-
|
|
29006
|
-
|
|
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
|
+
}
|
|
29007
29154
|
};
|
|
29008
29155
|
}
|
|
29009
|
-
|
|
29010
|
-
|
|
29011
|
-
|
|
29012
|
-
|
|
29013
|
-
|
|
29014
|
-
|
|
29015
|
-
|
|
29016
|
-
|
|
29017
|
-
|
|
29018
|
-
|
|
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
|
+
}
|
|
29019
29171
|
}
|
|
29020
|
-
|
|
29021
|
-
|
|
29022
|
-
|
|
29023
|
-
|
|
29024
|
-
|
|
29025
|
-
|
|
29026
|
-
|
|
29027
|
-
|
|
29028
|
-
}
|
|
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;
|
|
29029
29203
|
}
|
|
29030
|
-
if (
|
|
29031
|
-
|
|
29032
|
-
|
|
29033
|
-
|
|
29034
|
-
|
|
29035
|
-
|
|
29036
|
-
rationale,
|
|
29037
|
-
band: getConfidenceBand(confidence)
|
|
29038
|
-
};
|
|
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());
|
|
29039
29210
|
}
|
|
29040
|
-
|
|
29041
|
-
|
|
29042
|
-
|
|
29043
|
-
|
|
29044
|
-
confidence: fallbackConfidence,
|
|
29045
|
-
rationale,
|
|
29046
|
-
band: getConfidenceBand(fallbackConfidence)
|
|
29047
|
-
};
|
|
29048
|
-
}
|
|
29049
|
-
function normalizeRouteArgs(args2 = []) {
|
|
29050
|
-
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;
|
|
29051
29215
|
}
|
|
29052
|
-
var
|
|
29053
|
-
|
|
29054
|
-
|
|
29055
|
-
TRIAGE_THRESHOLDS = Object.freeze({
|
|
29056
|
-
high: 0.7,
|
|
29057
|
-
mid: 0.35
|
|
29058
|
-
});
|
|
29059
|
-
QUESTION_REGEX = /(how|what|why|when|どの|どう|なぜ|いつ|とは)\b/i;
|
|
29060
|
-
CODE_REGEX = /(create|generate|add|refactor|fix|test|route|build|component|migration|implement|実装|生成|追加|修正)/i;
|
|
29061
|
-
IMAGE_REGEX = /(image|画像|svg|png|webp|thumbnail|illustration|アート|描いて)/i;
|
|
29062
|
-
VIDEO_REGEX = /(video|動画|mp4|webm|frames|storyboard|アニメーション)/i;
|
|
29063
|
-
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();
|
|
29064
29219
|
}
|
|
29065
29220
|
});
|
|
29066
29221
|
|
|
@@ -29282,7 +29437,7 @@ var init_unknown_command = __esm({
|
|
|
29282
29437
|
});
|
|
29283
29438
|
|
|
29284
29439
|
// src/slash-commands/types.ts
|
|
29285
|
-
var CommandError, ValidationError, PermissionError,
|
|
29440
|
+
var CommandError, ValidationError, PermissionError, RateLimitError2;
|
|
29286
29441
|
var init_types2 = __esm({
|
|
29287
29442
|
"src/slash-commands/types.ts"() {
|
|
29288
29443
|
CommandError = class extends Error {
|
|
@@ -29308,7 +29463,7 @@ var init_types2 = __esm({
|
|
|
29308
29463
|
this.name = "PermissionError";
|
|
29309
29464
|
}
|
|
29310
29465
|
};
|
|
29311
|
-
|
|
29466
|
+
RateLimitError2 = class extends CommandError {
|
|
29312
29467
|
constructor(message, retryAfter) {
|
|
29313
29468
|
super(message, "RATE_LIMIT_ERROR", 429);
|
|
29314
29469
|
this.retryAfter = retryAfter;
|
|
@@ -36605,8 +36760,7 @@ var init_registry = __esm({
|
|
|
36605
36760
|
const { ChatContextService: ChatContextService3 } = await Promise.resolve().then(() => (init_chat_context_service(), chat_context_service_exports));
|
|
36606
36761
|
const ctxSvc = ChatContextService3.getInstance();
|
|
36607
36762
|
const usageLine = ctxSvc.getSessionUsageLine();
|
|
36608
|
-
const suffix =
|
|
36609
|
-
${usageLine}`;
|
|
36763
|
+
const suffix = ``;
|
|
36610
36764
|
result.message = (result.message || "").concat(suffix);
|
|
36611
36765
|
} catch {
|
|
36612
36766
|
}
|
|
@@ -36670,7 +36824,7 @@ ${usageLine}`;
|
|
|
36670
36824
|
}
|
|
36671
36825
|
}
|
|
36672
36826
|
} catch (innerError) {
|
|
36673
|
-
logger.error(`Failed to load command from ${file}:`,
|
|
36827
|
+
logger.error(`Failed to load command from ${file}:`, innerError);
|
|
36674
36828
|
}
|
|
36675
36829
|
}
|
|
36676
36830
|
this.initialized = true;
|
|
@@ -36707,8 +36861,8 @@ ${usageLine}`;
|
|
|
36707
36861
|
try {
|
|
36708
36862
|
return await next();
|
|
36709
36863
|
} catch (innerError) {
|
|
36710
|
-
logger.error(`Command ${command.name} failed:`,
|
|
36711
|
-
throw
|
|
36864
|
+
logger.error(`Command ${command.name} failed:`, innerError);
|
|
36865
|
+
throw innerError;
|
|
36712
36866
|
}
|
|
36713
36867
|
}
|
|
36714
36868
|
});
|
|
@@ -37645,6 +37799,7 @@ var init_clear_command = __esm({
|
|
|
37645
37799
|
init_telemetry_helper();
|
|
37646
37800
|
init_subscription_manager();
|
|
37647
37801
|
init_terminal();
|
|
37802
|
+
init_chat_context_service();
|
|
37648
37803
|
ClearCommand = class extends BaseCommand {
|
|
37649
37804
|
name = "clear";
|
|
37650
37805
|
category = "conversation";
|
|
@@ -37661,34 +37816,46 @@ var init_clear_command = __esm({
|
|
|
37661
37816
|
async execute(args2, context2) {
|
|
37662
37817
|
const startTime = Date.now();
|
|
37663
37818
|
try {
|
|
37819
|
+
let mode = "session";
|
|
37820
|
+
const idx = Array.isArray(args2.raw) ? args2.raw.indexOf("--mode") : -1;
|
|
37821
|
+
if (idx >= 0) {
|
|
37822
|
+
const val = String(args2.raw[idx + 1] || "").toLowerCase();
|
|
37823
|
+
if (val === "display" || val === "session" || val === "all") mode = val;
|
|
37824
|
+
}
|
|
37664
37825
|
clearTerminal();
|
|
37665
|
-
|
|
37666
|
-
|
|
37667
|
-
|
|
37668
|
-
|
|
37669
|
-
|
|
37670
|
-
context2.session.context = {};
|
|
37671
|
-
}
|
|
37672
|
-
if (context2.session.messages) {
|
|
37673
|
-
context2.session.messages = [];
|
|
37674
|
-
}
|
|
37826
|
+
const chat = ChatContextService.getInstance();
|
|
37827
|
+
if (mode === "display") {
|
|
37828
|
+
chat.clearContext({ soft: true });
|
|
37829
|
+
} else {
|
|
37830
|
+
chat.clearContext();
|
|
37675
37831
|
}
|
|
37832
|
+
const quotaLeft = (() => {
|
|
37833
|
+
const rec = context2;
|
|
37834
|
+
const v = rec && typeof rec["quotaLeft"] === "number" ? rec["quotaLeft"] : 999;
|
|
37835
|
+
return v;
|
|
37836
|
+
})();
|
|
37676
37837
|
await trackCommand({
|
|
37677
37838
|
cmd: "clear",
|
|
37678
37839
|
status: "success",
|
|
37679
37840
|
latencyMs: Date.now() - startTime,
|
|
37680
|
-
plan: getUserPlan(),
|
|
37681
|
-
quotaLeft
|
|
37841
|
+
plan: await getUserPlan(),
|
|
37842
|
+
quotaLeft
|
|
37682
37843
|
});
|
|
37683
|
-
const
|
|
37684
|
-
|
|
37844
|
+
const suffix = mode === "display" ? "display only" : "context reset";
|
|
37845
|
+
const message = chalk14__default.default.green("\u2705 Cleared") + chalk14__default.default.gray(` \xB7 ${suffix}`);
|
|
37846
|
+
return this.success(withQuotaFooter(message, quotaLeft));
|
|
37685
37847
|
} catch (error2) {
|
|
37848
|
+
const quotaLeft = (() => {
|
|
37849
|
+
const rec = context2;
|
|
37850
|
+
const v = rec && typeof rec["quotaLeft"] === "number" ? rec["quotaLeft"] : 999;
|
|
37851
|
+
return v;
|
|
37852
|
+
})();
|
|
37686
37853
|
await trackCommand({
|
|
37687
37854
|
cmd: "clear",
|
|
37688
37855
|
status: "error",
|
|
37689
37856
|
latencyMs: Date.now() - startTime,
|
|
37690
|
-
plan: getUserPlan(),
|
|
37691
|
-
quotaLeft
|
|
37857
|
+
plan: await getUserPlan(),
|
|
37858
|
+
quotaLeft
|
|
37692
37859
|
});
|
|
37693
37860
|
clearTerminal();
|
|
37694
37861
|
return this.success(chalk14__default.default.green("\u2705 Cleared"));
|
|
@@ -37738,7 +37905,7 @@ var init_clear_auto_command = __esm({
|
|
|
37738
37905
|
const args2 = mode === "display" ? ["--mode", "display"] : [];
|
|
37739
37906
|
const res = await commandRegistry2.execute("/clear", args2, context2);
|
|
37740
37907
|
const line = ctx2.getSessionUsageLine();
|
|
37741
|
-
const banner = `Auto clear mode: ${mode}
|
|
37908
|
+
const banner = `Auto clear mode: ${mode}`;
|
|
37742
37909
|
if (res?.success) {
|
|
37743
37910
|
return this.success(`${banner}
|
|
37744
37911
|
${res.message || ""}`.trim());
|
|
@@ -38404,6 +38571,69 @@ var init_ReadyCommandsService = __esm({
|
|
|
38404
38571
|
}
|
|
38405
38572
|
});
|
|
38406
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
|
+
|
|
38407
38637
|
// src/slash-commands/categories/core/handlers/HelpCommand.ts
|
|
38408
38638
|
var HelpCommand_exports = {};
|
|
38409
38639
|
__export(HelpCommand_exports, {
|
|
@@ -38417,6 +38647,8 @@ var init_HelpCommand = __esm({
|
|
|
38417
38647
|
init_ReadyCommandsService();
|
|
38418
38648
|
init_telemetry_helper();
|
|
38419
38649
|
init_subscription_manager();
|
|
38650
|
+
init_HelpArgumentInference();
|
|
38651
|
+
init_animations();
|
|
38420
38652
|
HelpCommand = class extends BaseCommand {
|
|
38421
38653
|
name = "help";
|
|
38422
38654
|
category = "core";
|
|
@@ -38465,6 +38697,26 @@ var init_HelpCommand = __esm({
|
|
|
38465
38697
|
await this.trackSuccess(startTime, context2);
|
|
38466
38698
|
return result2;
|
|
38467
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
|
+
}
|
|
38468
38720
|
if (_positional.length > 0) {
|
|
38469
38721
|
const commandName = _positional[0];
|
|
38470
38722
|
if (commandName) {
|
|
@@ -38611,44 +38863,6 @@ var init_HelpCommand = __esm({
|
|
|
38611
38863
|
* Show help for specific command
|
|
38612
38864
|
*/
|
|
38613
38865
|
async showCommandHelp(commandName) {
|
|
38614
|
-
if (commandName.replace(/^\//, "") === "code") {
|
|
38615
|
-
const lines2 = [];
|
|
38616
|
-
lines2.push("Usage: /code <request> [flags]");
|
|
38617
|
-
lines2.push("");
|
|
38618
|
-
lines2.push("Flags:");
|
|
38619
|
-
lines2.push(" --plan-only|--sow Show plan only (no writes)");
|
|
38620
|
-
lines2.push(" --apply Apply plan (use with --yes for non-interactive)");
|
|
38621
|
-
lines2.push(" --dry-run No writes; render output and hints");
|
|
38622
|
-
lines2.push(" --interactive Approve interactively (a=all s=skip v=view d=diff q=cancel)");
|
|
38623
|
-
lines2.push(" --yes Approve all (including overwrites)");
|
|
38624
|
-
lines2.push(" --max-files N Clamp number of files");
|
|
38625
|
-
lines2.push(" --root DIR Output root directory");
|
|
38626
|
-
lines2.push(" --rollback on|off Rollback on failure (default on)");
|
|
38627
|
-
lines2.push(" --output names|summary|detail");
|
|
38628
|
-
lines2.push(" --no-code Hide code blocks entirely");
|
|
38629
|
-
lines2.push(" --preview-lines N Show head of code in detail mode");
|
|
38630
|
-
lines2.push(" --git-guard on|off Check clean git tree before apply (CI default on)");
|
|
38631
|
-
lines2.push(" --git-commit on|off Create a single git commit after apply");
|
|
38632
|
-
lines2.push(" --git-branch <name> Create/switch branch before committing");
|
|
38633
|
-
lines2.push(" --git-tag <name> Create an annotated tag after committing");
|
|
38634
|
-
lines2.push(" --git-tag-prefix <pfx> Use standardized tag when --git-tag auto: <pfx><YYYYMMDD>-<shortsha>");
|
|
38635
|
-
lines2.push(" --git-push on|off Push commit and tag to remote");
|
|
38636
|
-
lines2.push(" --git-push-remote <name> Remote name for push (default origin)");
|
|
38637
|
-
lines2.push(" --allow-dotfiles Allow writing dotfiles (default deny)");
|
|
38638
|
-
lines2.push(" --confirm-overwrites <globs>");
|
|
38639
|
-
lines2.push("");
|
|
38640
|
-
lines2.push("Tips:");
|
|
38641
|
-
lines2.push(' HINT: Try /code --plan-only "your request" before applying changes');
|
|
38642
|
-
lines2.push(" Recipes:");
|
|
38643
|
-
lines2.push(' \u2022 Plan only: /code --plan-only "create auth form + API"');
|
|
38644
|
-
lines2.push(' \u2022 Apply with limit: /code --apply --yes --max-files 5 "react + test"');
|
|
38645
|
-
lines2.push(' \u2022 Interactive: /code --interactive --output detail --preview-lines 20 "routes + guards"');
|
|
38646
|
-
lines2.push(" \u2022 Apply + branch + auto tag + push:");
|
|
38647
|
-
lines2.push(" /code --apply --yes --git-guard on --git-commit on \\");
|
|
38648
|
-
lines2.push(" --git-branch feature/code-plan --git-tag auto --git-tag-prefix code-plan- \\");
|
|
38649
|
-
lines2.push(' --git-push on --git-push-remote origin "implement auth + tests"');
|
|
38650
|
-
return this.success(lines2.join("\n"));
|
|
38651
|
-
}
|
|
38652
38866
|
const command = await this.readyService.getCommand(commandName);
|
|
38653
38867
|
if (!command) {
|
|
38654
38868
|
const searchResults = await this.readyService.searchCommands(commandName, 3);
|
|
@@ -47421,6 +47635,201 @@ var init_types4 = __esm({
|
|
|
47421
47635
|
];
|
|
47422
47636
|
}
|
|
47423
47637
|
});
|
|
47638
|
+
|
|
47639
|
+
// src/services/media-orchestrator/NLInference.ts
|
|
47640
|
+
function clampSize(size) {
|
|
47641
|
+
const clamp = (n) => Math.min(2048, Math.max(256, Math.floor(n)));
|
|
47642
|
+
return [clamp(size[0]), clamp(size[1])];
|
|
47643
|
+
}
|
|
47644
|
+
function parseExplicitSize(text) {
|
|
47645
|
+
const m2 = /(\d{2,4})\s*[x×]\s*(\d{2,4})/i.exec(text);
|
|
47646
|
+
if (m2) {
|
|
47647
|
+
const w = Number(m2[1]);
|
|
47648
|
+
const h2 = Number(m2[2]);
|
|
47649
|
+
if (Number.isFinite(w) && Number.isFinite(h2)) return clampSize([w, h2]);
|
|
47650
|
+
}
|
|
47651
|
+
const p = /(2160|1440|1080|720)\s*p\b/i.exec(text);
|
|
47652
|
+
if (p) {
|
|
47653
|
+
const h2 = Number(p[1]);
|
|
47654
|
+
const map = {
|
|
47655
|
+
2160: [3840, 2160],
|
|
47656
|
+
1440: [2560, 1440],
|
|
47657
|
+
1080: [1920, 1080],
|
|
47658
|
+
720: [1280, 720]
|
|
47659
|
+
};
|
|
47660
|
+
return clampSize(map[h2]);
|
|
47661
|
+
}
|
|
47662
|
+
return void 0;
|
|
47663
|
+
}
|
|
47664
|
+
function parseAspect(text) {
|
|
47665
|
+
if (/16\s*:\s*9/.test(text)) return "16:9";
|
|
47666
|
+
if (/9\s*:\s*16/.test(text)) return "9:16";
|
|
47667
|
+
if (/1\s*:\s*1/.test(text)) return "1:1";
|
|
47668
|
+
if (/(wide|landscape)/i.test(text)) return "16:9";
|
|
47669
|
+
if (/(tall|portrait)/i.test(text)) return "9:16";
|
|
47670
|
+
if (/(landscape|横長|横向き)/i.test(text)) return "16:9";
|
|
47671
|
+
if (/(portrait|縦長|縦向き)/i.test(text)) return "9:16";
|
|
47672
|
+
if (/(square|正方形|スクエア)/i.test(text)) return "1:1";
|
|
47673
|
+
return void 0;
|
|
47674
|
+
}
|
|
47675
|
+
function deriveSizeFromAspect(aspect, base) {
|
|
47676
|
+
const side = 1024;
|
|
47677
|
+
if (aspect === "1:1") return clampSize([side, side]);
|
|
47678
|
+
if (aspect === "16:9") {
|
|
47679
|
+
const w2 = Math.max(side, 1280);
|
|
47680
|
+
const h3 = Math.round(w2 / 16 * 9);
|
|
47681
|
+
return clampSize([w2, h3]);
|
|
47682
|
+
}
|
|
47683
|
+
const h2 = Math.max(side, 1920);
|
|
47684
|
+
const w = Math.round(h2 / 16 * 9);
|
|
47685
|
+
return clampSize([w, h2]);
|
|
47686
|
+
}
|
|
47687
|
+
function parse4KHints(text, aspect) {
|
|
47688
|
+
if (/(\b4k\b|uhd|超高精細|超高解像度)/i.test(text)) {
|
|
47689
|
+
if (aspect === "1:1" || /square|正方形|スクエア/i.test(text)) return clampSize([2048, 2048]);
|
|
47690
|
+
if (aspect === "9:16" || /(portrait|縦長|縦向き)/i.test(text)) return clampSize([1152, 2048]);
|
|
47691
|
+
return clampSize([2048, 1152]);
|
|
47692
|
+
}
|
|
47693
|
+
if (/(2k|1440p)/i.test(text)) {
|
|
47694
|
+
if (aspect === "1:1") return clampSize([1440, 1440]);
|
|
47695
|
+
if (aspect === "9:16") return clampSize([810, 1440]);
|
|
47696
|
+
return clampSize([1440, 810]);
|
|
47697
|
+
}
|
|
47698
|
+
return void 0;
|
|
47699
|
+
}
|
|
47700
|
+
function parseUseCaseSize(text, aspectHint) {
|
|
47701
|
+
if (/(icon|アイコン)/i.test(text)) return [512, 512];
|
|
47702
|
+
if (/(thumbnail|サムネ)/i.test(text)) return [1280, 720];
|
|
47703
|
+
if (/(instagram\s*story|インスタ\s*ストーリー)/i.test(text)) return [1080, 1920];
|
|
47704
|
+
if (/(instagram\s*post|インスタ\s*投稿)/i.test(text)) return [1080, 1080];
|
|
47705
|
+
if (/(twitter\s*header|x\s*header)/i.test(text)) return [1500, 500];
|
|
47706
|
+
if (/(hd|フルhd)/i.test(text)) return [1920, 1080];
|
|
47707
|
+
if (aspectHint) return deriveSizeFromAspect(aspectHint);
|
|
47708
|
+
if (/(portrait|縦長|縦向き)/i.test(text)) return deriveSizeFromAspect("9:16");
|
|
47709
|
+
if (/(landscape|横長|横向き)/i.test(text)) return deriveSizeFromAspect("16:9");
|
|
47710
|
+
if (/(square|正方形|スクエア)/i.test(text)) return [1024, 1024];
|
|
47711
|
+
return void 0;
|
|
47712
|
+
}
|
|
47713
|
+
function inferFormat(text) {
|
|
47714
|
+
if (/(png|透過|alpha)/i.test(text)) return "png";
|
|
47715
|
+
if (/(webp|ウェブピー)/i.test(text)) return "webp";
|
|
47716
|
+
if (/(jpg|jpeg|写真|photo)/i.test(text)) return "jpg";
|
|
47717
|
+
return void 0;
|
|
47718
|
+
}
|
|
47719
|
+
function inferImageOptionsFromText(text) {
|
|
47720
|
+
const lower2 = text.toLowerCase();
|
|
47721
|
+
const aspect = parseAspect(lower2);
|
|
47722
|
+
const exp = parseExplicitSize(lower2);
|
|
47723
|
+
const k4 = parse4KHints(lower2, aspect);
|
|
47724
|
+
const use = parseUseCaseSize(lower2, aspect);
|
|
47725
|
+
const size = exp || k4 || use;
|
|
47726
|
+
const format = inferFormat(lower2);
|
|
47727
|
+
const out = {};
|
|
47728
|
+
if (size) out.size = size;
|
|
47729
|
+
if (format) out.format = format;
|
|
47730
|
+
return out;
|
|
47731
|
+
}
|
|
47732
|
+
var init_NLInference = __esm({
|
|
47733
|
+
"src/services/media-orchestrator/NLInference.ts"() {
|
|
47734
|
+
}
|
|
47735
|
+
});
|
|
47736
|
+
|
|
47737
|
+
// src/services/media-orchestrator/ImageArgumentInference.ts
|
|
47738
|
+
function extractFirstJson3(text) {
|
|
47739
|
+
const fence = /```json\r?\n([\s\S]*?)```/i.exec(text);
|
|
47740
|
+
if (fence) return fence[1];
|
|
47741
|
+
const fencePlain = /```\s*\r?\n([\s\S]*?)```/i.exec(text);
|
|
47742
|
+
if (fencePlain) {
|
|
47743
|
+
try {
|
|
47744
|
+
JSON.parse(fencePlain[1]);
|
|
47745
|
+
return fencePlain[1];
|
|
47746
|
+
} catch {
|
|
47747
|
+
}
|
|
47748
|
+
}
|
|
47749
|
+
const start = text.indexOf("{");
|
|
47750
|
+
const end = text.lastIndexOf("}");
|
|
47751
|
+
if (start >= 0 && end > start) {
|
|
47752
|
+
const cand = text.slice(start, end + 1);
|
|
47753
|
+
try {
|
|
47754
|
+
JSON.parse(cand);
|
|
47755
|
+
return cand;
|
|
47756
|
+
} catch {
|
|
47757
|
+
}
|
|
47758
|
+
}
|
|
47759
|
+
return null;
|
|
47760
|
+
}
|
|
47761
|
+
function clampSize2(size) {
|
|
47762
|
+
const clamp = (n) => Math.min(4096, Math.max(256, Math.floor(n)));
|
|
47763
|
+
return [clamp(size[0]), clamp(size[1])];
|
|
47764
|
+
}
|
|
47765
|
+
function parseSizeAny(x2) {
|
|
47766
|
+
if (typeof x2 === "string") {
|
|
47767
|
+
const m2 = /^\s*(\d{2,4})x(\d{2,4})\s*$/i.exec(x2);
|
|
47768
|
+
if (m2) return clampSize2([Number(m2[1]), Number(m2[2])]);
|
|
47769
|
+
}
|
|
47770
|
+
if (x2 && typeof x2 === "object") {
|
|
47771
|
+
const any = x2;
|
|
47772
|
+
const w = Number(any.width ?? any.w);
|
|
47773
|
+
const h2 = Number(any.height ?? any.h);
|
|
47774
|
+
if (Number.isFinite(w) && Number.isFinite(h2)) return clampSize2([w, h2]);
|
|
47775
|
+
}
|
|
47776
|
+
return void 0;
|
|
47777
|
+
}
|
|
47778
|
+
function sanitizeFormat(fmt) {
|
|
47779
|
+
if (typeof fmt !== "string") return void 0;
|
|
47780
|
+
const f3 = fmt.toLowerCase();
|
|
47781
|
+
const mapped = f3 === "jpeg" ? "jpg" : f3;
|
|
47782
|
+
return ["png", "webp", "jpg"].includes(mapped) ? mapped : void 0;
|
|
47783
|
+
}
|
|
47784
|
+
async function inferImageArgsLLM(promptText) {
|
|
47785
|
+
const system = [
|
|
47786
|
+
"You extract image generation options from user natural language.",
|
|
47787
|
+
'Return JSON only with keys: { "size"?: "WIDTHxHEIGHT", "format"?: "png|webp|jpg", "count"?: number }.',
|
|
47788
|
+
'Only include "count" if the user explicitly specifies the number of images (e.g., "2 images"). Otherwise omit (default is 1).',
|
|
47789
|
+
'Only include "format" if the user explicitly specifies a format (e.g., "png", "webp", "jpg", transparency). Otherwise omit (default is png).',
|
|
47790
|
+
'Size must be a single string "WIDTHxHEIGHT". If the user implies aspect/resolution (e.g., "wide"/"landscape" => 16:9, "tall"/"portrait" => 9:16, "square" => 1:1, or 4K/UHD/1080p/720p), select a reasonable resolution within 256..4096 per side and return it as "WIDTHxHEIGHT".',
|
|
47791
|
+
"If size is not specified or implied, omit it (default is 1024x1024).",
|
|
47792
|
+
"Do NOT include model or keepExif unless the user explicitly specified them; otherwise omit.",
|
|
47793
|
+
"Do not include any explanation text; JSON only."
|
|
47794
|
+
].join("\n");
|
|
47795
|
+
const user = promptText;
|
|
47796
|
+
const response = await callAPI("/v1/ai-proxy", {
|
|
47797
|
+
method: "POST",
|
|
47798
|
+
body: {
|
|
47799
|
+
prompt: `${system}
|
|
47800
|
+
|
|
47801
|
+
---
|
|
47802
|
+
|
|
47803
|
+
${user}`,
|
|
47804
|
+
taskType: "media"
|
|
47805
|
+
}
|
|
47806
|
+
});
|
|
47807
|
+
const raw = (response?.data?.content || response?.output || "").trim();
|
|
47808
|
+
const jsonText = extractFirstJson3(raw) || raw;
|
|
47809
|
+
let parsed;
|
|
47810
|
+
try {
|
|
47811
|
+
parsed = JSON.parse(jsonText);
|
|
47812
|
+
} catch {
|
|
47813
|
+
return {};
|
|
47814
|
+
}
|
|
47815
|
+
const out = {};
|
|
47816
|
+
const size = parseSizeAny(parsed?.size);
|
|
47817
|
+
if (size) out.size = size;
|
|
47818
|
+
const fmt = sanitizeFormat(parsed?.format);
|
|
47819
|
+
if (fmt) out.format = fmt;
|
|
47820
|
+
if (Number.isFinite(Number(parsed?.count))) {
|
|
47821
|
+
const n = Math.max(1, Math.min(8, Math.floor(Number(parsed.count))));
|
|
47822
|
+
out.count = n;
|
|
47823
|
+
}
|
|
47824
|
+
if (typeof parsed?.model === "string" && parsed.model.trim()) out.model = String(parsed.model).trim();
|
|
47825
|
+
if (typeof parsed?.keepExif === "boolean") out.keepExif = parsed.keepExif;
|
|
47826
|
+
return out;
|
|
47827
|
+
}
|
|
47828
|
+
var init_ImageArgumentInference = __esm({
|
|
47829
|
+
"src/services/media-orchestrator/ImageArgumentInference.ts"() {
|
|
47830
|
+
init_api_caller();
|
|
47831
|
+
}
|
|
47832
|
+
});
|
|
47424
47833
|
function parseSize(value) {
|
|
47425
47834
|
const m2 = /^\s*(\d{2,4})x(\d{2,4})\s*$/i.exec(value || "");
|
|
47426
47835
|
if (!m2) throw new Error(`invalid size: ${value}`);
|
|
@@ -47453,6 +47862,8 @@ function normalizeImageArgs(raw, root) {
|
|
|
47453
47862
|
planOnly: false,
|
|
47454
47863
|
dryRun: false
|
|
47455
47864
|
};
|
|
47865
|
+
let explicitSize = false;
|
|
47866
|
+
let explicitFormat = false;
|
|
47456
47867
|
while (args2.length) {
|
|
47457
47868
|
const x2 = args2.shift();
|
|
47458
47869
|
if (!x2.startsWith("--")) continue;
|
|
@@ -47461,12 +47872,14 @@ function normalizeImageArgs(raw, root) {
|
|
|
47461
47872
|
switch (k) {
|
|
47462
47873
|
case "size":
|
|
47463
47874
|
out.size = parseSize(String(v));
|
|
47875
|
+
explicitSize = true;
|
|
47464
47876
|
break;
|
|
47465
47877
|
case "format": {
|
|
47466
47878
|
const rawFmt = String(v).toLowerCase();
|
|
47467
47879
|
const mapped = rawFmt === "jpeg" ? "jpg" : rawFmt;
|
|
47468
47880
|
if (!["png", "webp", "jpg"].includes(mapped)) throw new Error("invalid format");
|
|
47469
47881
|
out.format = mapped;
|
|
47882
|
+
explicitFormat = true;
|
|
47470
47883
|
break;
|
|
47471
47884
|
}
|
|
47472
47885
|
case "count": {
|
|
@@ -47507,6 +47920,21 @@ function normalizeImageArgs(raw, root) {
|
|
|
47507
47920
|
break;
|
|
47508
47921
|
}
|
|
47509
47922
|
}
|
|
47923
|
+
try {
|
|
47924
|
+
const inferred = inferImageOptionsFromText(prompt);
|
|
47925
|
+
if (!explicitSize && inferred.size) out.size = inferred.size;
|
|
47926
|
+
if (!explicitFormat && inferred.format) out.format = inferred.format;
|
|
47927
|
+
} catch {
|
|
47928
|
+
}
|
|
47929
|
+
try {
|
|
47930
|
+
if (String(process.env.MARIA_USE_LLM_INFER || "1") === "1" && (!explicitSize || !explicitFormat)) {
|
|
47931
|
+
global.__MARIA_IMAGE_LLM_INFER__ = async () => {
|
|
47932
|
+
const llm = await inferImageArgsLLM(prompt);
|
|
47933
|
+
return llm;
|
|
47934
|
+
};
|
|
47935
|
+
}
|
|
47936
|
+
} catch {
|
|
47937
|
+
}
|
|
47510
47938
|
const pixels = out.size[0] * out.size[1] * out.count;
|
|
47511
47939
|
if (pixels > (out.budgetPixels || 0)) throw new Error("budget exceeded");
|
|
47512
47940
|
if (!out.apply && !out.planOnly && !out.dryRun) {
|
|
@@ -47539,7 +47967,8 @@ function normalizeVideoArgs(raw, root) {
|
|
|
47539
47967
|
retry: 2,
|
|
47540
47968
|
apply: false,
|
|
47541
47969
|
planOnly: false,
|
|
47542
|
-
dryRun: false
|
|
47970
|
+
dryRun: false,
|
|
47971
|
+
aspect: "16:9"
|
|
47543
47972
|
};
|
|
47544
47973
|
while (args2.length) {
|
|
47545
47974
|
const x2 = args2.shift();
|
|
@@ -47553,9 +47982,43 @@ function normalizeVideoArgs(raw, root) {
|
|
|
47553
47982
|
case "fps":
|
|
47554
47983
|
out.fps = clampInt(v, 1, 60, "fps");
|
|
47555
47984
|
break;
|
|
47556
|
-
case "
|
|
47557
|
-
|
|
47985
|
+
case "size": {
|
|
47986
|
+
const sz = parseSize(String(v));
|
|
47987
|
+
out.size = sz;
|
|
47988
|
+
out.aspect = sz[0] >= sz[1] ? "16:9" : "9:16";
|
|
47558
47989
|
break;
|
|
47990
|
+
}
|
|
47991
|
+
case "res": {
|
|
47992
|
+
const sv = String(v).toLowerCase().replace(/p$/, "");
|
|
47993
|
+
if (/^\d+x\d+$/i.test(String(v))) {
|
|
47994
|
+
out.size = parseSize(String(v));
|
|
47995
|
+
out.aspect = out.size[0] >= out.size[1] ? "16:9" : "9:16";
|
|
47996
|
+
} else if (sv === "720") {
|
|
47997
|
+
out.size = out.aspect === "9:16" ? [720, 1280] : [1280, 720];
|
|
47998
|
+
} else if (sv === "1080") {
|
|
47999
|
+
out.size = out.aspect === "9:16" ? [1080, 1920] : [1920, 1080];
|
|
48000
|
+
} else {
|
|
48001
|
+
throw new Error("invalid res (use 720|1080 or WIDTHxHEIGHT)");
|
|
48002
|
+
}
|
|
48003
|
+
break;
|
|
48004
|
+
}
|
|
48005
|
+
case "aspect": {
|
|
48006
|
+
const a = String(v);
|
|
48007
|
+
if (a !== "16:9" && a !== "9:16") throw new Error("invalid aspect (use 16:9|9:16)");
|
|
48008
|
+
out.aspect = a;
|
|
48009
|
+
const [w, h2] = out.size;
|
|
48010
|
+
if (w === 1280 && h2 === 720 || w === 720 && h2 === 1280 || w === 1920 && h2 === 1080 || w === 1080 && h2 === 1920) {
|
|
48011
|
+
if (a === "9:16") {
|
|
48012
|
+
if (h2 === 720) out.size = [720, 1280];
|
|
48013
|
+
else if (h2 === 1080) out.size = [1080, 1920];
|
|
48014
|
+
} else {
|
|
48015
|
+
if (w === 720) out.size = [1280, 720];
|
|
48016
|
+
else if (w === 1080) out.size = [1920, 1080];
|
|
48017
|
+
if (w === 1080 && h2 === 1920) out.size = [1920, 1080];
|
|
48018
|
+
}
|
|
48019
|
+
}
|
|
48020
|
+
break;
|
|
48021
|
+
}
|
|
47559
48022
|
case "format":
|
|
47560
48023
|
if (!["mp4", "webm"].includes(String(v))) throw new Error("invalid format");
|
|
47561
48024
|
out.format = v;
|
|
@@ -47591,7 +48054,11 @@ function normalizeVideoArgs(raw, root) {
|
|
|
47591
48054
|
}
|
|
47592
48055
|
const caps = chooseCaps("video", out.model);
|
|
47593
48056
|
if (caps?.maxVideoSize) {
|
|
47594
|
-
|
|
48057
|
+
const reqMax = Math.max(out.size[0], out.size[1]);
|
|
48058
|
+
const reqMin = Math.min(out.size[0], out.size[1]);
|
|
48059
|
+
const capMax = Math.max(caps.maxVideoSize[0], caps.maxVideoSize[1]);
|
|
48060
|
+
const capMin = Math.min(caps.maxVideoSize[0], caps.maxVideoSize[1]);
|
|
48061
|
+
if (reqMax > capMax || reqMin > capMin) throw new Error("resolution exceeds model capability");
|
|
47595
48062
|
}
|
|
47596
48063
|
if (caps?.maxDuration && out.duration > caps.maxDuration) throw new Error("duration exceeds model capability");
|
|
47597
48064
|
if (caps?.maxFps && out.fps > caps.maxFps) throw new Error("fps exceeds model capability");
|
|
@@ -47619,6 +48086,8 @@ function sanitizeOut(outDir, root) {
|
|
|
47619
48086
|
var init_Normalizer = __esm({
|
|
47620
48087
|
"src/services/media-orchestrator/Normalizer.ts"() {
|
|
47621
48088
|
init_types4();
|
|
48089
|
+
init_NLInference();
|
|
48090
|
+
init_ImageArgumentInference();
|
|
47622
48091
|
}
|
|
47623
48092
|
});
|
|
47624
48093
|
function ensureDirSync(p) {
|
|
@@ -48480,6 +48949,19 @@ var init_image_command = __esm({
|
|
|
48480
48949
|
const spinner = new ProcessAnimation();
|
|
48481
48950
|
spinner.start();
|
|
48482
48951
|
try {
|
|
48952
|
+
try {
|
|
48953
|
+
const hook = global.__MARIA_IMAGE_LLM_INFER__;
|
|
48954
|
+
if (hook) {
|
|
48955
|
+
const llm = await hook();
|
|
48956
|
+
if (llm) {
|
|
48957
|
+
if (llm.size && (!Array.isArray(cli.size) || cli.size.length !== 2)) cli.size = llm.size;
|
|
48958
|
+
if (llm.size && Array.isArray(llm.size)) cli.size = llm.size;
|
|
48959
|
+
if (llm.format) cli.format = llm.format;
|
|
48960
|
+
if (Number.isFinite(Number(llm.count))) cli.count = Math.max(1, Math.min(8, Math.floor(Number(llm.count))));
|
|
48961
|
+
}
|
|
48962
|
+
}
|
|
48963
|
+
} catch {
|
|
48964
|
+
}
|
|
48483
48965
|
const useRemote = String(process.env.MARIA_USE_REMOTE_MEDIA || "").toLowerCase() === "1" && await authManager.isAuthenticated();
|
|
48484
48966
|
if (useRemote) {
|
|
48485
48967
|
try {
|
|
@@ -48791,12 +49273,18 @@ async function runVideoPipeline(params2, opts) {
|
|
|
48791
49273
|
const { GoogleGenAI } = __require("@google/genai");
|
|
48792
49274
|
const ai2 = new GoogleGenAI({ apiKey });
|
|
48793
49275
|
const modelName = params2.model || "veo-3.0-generate-001";
|
|
48794
|
-
const aspectRatio =
|
|
49276
|
+
const aspectRatio = "16:9";
|
|
49277
|
+
const resolution = Math.max(params2.size[0], params2.size[1]) >= 1920 ? "1080p" : "720p";
|
|
48795
49278
|
const effectiveDuration = 8;
|
|
48796
49279
|
let operation = await ai2.models.generateVideos({
|
|
48797
49280
|
model: modelName,
|
|
48798
49281
|
prompt: String(params2.prompt),
|
|
48799
|
-
config: {
|
|
49282
|
+
config: {
|
|
49283
|
+
aspectRatio,
|
|
49284
|
+
/* resolution: resolution, */
|
|
49285
|
+
durationSeconds: effectiveDuration,
|
|
49286
|
+
frameRate: params2.fps
|
|
49287
|
+
}
|
|
48800
49288
|
});
|
|
48801
49289
|
const pollStart = Date.now();
|
|
48802
49290
|
const maxWaitMs = 6 * 60 * 1e3;
|
|
@@ -48948,7 +49436,7 @@ var init_video_command = __esm({
|
|
|
48948
49436
|
category = "media";
|
|
48949
49437
|
description = "Generate videos using Gemini (frames fallback when mux unavailable)";
|
|
48950
49438
|
aliases = [];
|
|
48951
|
-
usage = '/video "prompt" [--duration 8] [--fps 24] [--res
|
|
49439
|
+
usage = '/video "prompt" [--duration 8] [--fps 24] [--aspect 16:9|9:16] [--res 720|1080] [--format mp4|webm] [--model gemini-...] [--seed N] [--out dir] [--apply|--plan-only|--dry-run] [--concurrency N] [--retry N]';
|
|
48952
49440
|
examples = [
|
|
48953
49441
|
{ input: '/video "product demo" --duration 8 --fps 24 --res 1280x720 --apply', description: "Generate a short demo video" }
|
|
48954
49442
|
];
|
|
@@ -48969,11 +49457,15 @@ var init_video_command = __esm({
|
|
|
48969
49457
|
const useRemote = String(process.env.MARIA_USE_REMOTE_MEDIA || "").toLowerCase() === "1" && await authManager.isAuthenticated();
|
|
48970
49458
|
if (useRemote) {
|
|
48971
49459
|
try {
|
|
49460
|
+
const isPortrait = cli.size[1] > cli.size[0];
|
|
49461
|
+
const maxEdge = Math.max(cli.size[0], cli.size[1]);
|
|
49462
|
+
const discrete = maxEdge >= 1920 ? "1080" : maxEdge >= 1280 ? "720" : void 0;
|
|
48972
49463
|
const body = {
|
|
48973
49464
|
prompt: cli.prompt,
|
|
48974
49465
|
duration: cli.duration,
|
|
48975
49466
|
fps: cli.fps,
|
|
48976
|
-
res: `${cli.size[0]}x${cli.size[1]}`,
|
|
49467
|
+
res: discrete ? discrete : `${cli.size[0]}x${cli.size[1]}`,
|
|
49468
|
+
aspect: isPortrait ? "9:16" : "16:9",
|
|
48977
49469
|
format: cli.format,
|
|
48978
49470
|
model: cli.model,
|
|
48979
49471
|
seed: cli.seed
|
|
@@ -50769,7 +51261,7 @@ var init_about_command = __esm({
|
|
|
50769
51261
|
async execute(args2, context2) {
|
|
50770
51262
|
const output3 = [];
|
|
50771
51263
|
output3.push("");
|
|
50772
|
-
output3.push(chalk14__default.default.cyan.bold("\u{1F916} About MARIA v4.3.
|
|
51264
|
+
output3.push(chalk14__default.default.cyan.bold("\u{1F916} About MARIA v4.3.37"));
|
|
50773
51265
|
output3.push(chalk14__default.default.gray("\u2550".repeat(40)));
|
|
50774
51266
|
output3.push("");
|
|
50775
51267
|
output3.push(chalk14__default.default.white.bold("MARIA - Minimal API, Maximum Power"));
|
|
@@ -54158,6 +54650,62 @@ var init_code_utils = __esm({
|
|
|
54158
54650
|
]);
|
|
54159
54651
|
}
|
|
54160
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
|
+
});
|
|
54161
54709
|
async function scanRepo(cwd2) {
|
|
54162
54710
|
if (_cache && _cache.root === cwd2) return _cache;
|
|
54163
54711
|
const root = cwd2;
|
|
@@ -54432,7 +54980,8 @@ function formatPlan(summary, opts) {
|
|
|
54432
54980
|
if (opts.requestText && opts.requestText.trim().length > 0) {
|
|
54433
54981
|
lines.push(opts.requestText.trim(), "");
|
|
54434
54982
|
}
|
|
54435
|
-
|
|
54983
|
+
const headerLabel = opts.planView ? "Planned Artifacts" : "Modified Artifacts";
|
|
54984
|
+
lines.push(`${headerLabel} (${summary.planned} files):`);
|
|
54436
54985
|
const warnMap = buildPerFileWarnings(summary.files, opts.validated);
|
|
54437
54986
|
const skippedSet = new Set(opts.validated?.skipped || []);
|
|
54438
54987
|
for (const f3 of summary.files) {
|
|
@@ -54457,18 +55006,20 @@ function formatPlan(summary, opts) {
|
|
|
54457
55006
|
lines.push(diff, "");
|
|
54458
55007
|
}
|
|
54459
55008
|
}
|
|
54460
|
-
|
|
54461
|
-
|
|
54462
|
-
|
|
54463
|
-
|
|
54464
|
-
|
|
54465
|
-
|
|
54466
|
-
|
|
54467
|
-
|
|
54468
|
-
|
|
55009
|
+
if (!opts.planView) {
|
|
55010
|
+
const created = summary.files.filter((f3) => f3.action === "create").length;
|
|
55011
|
+
const modified = summary.files.filter((f3) => f3.action === "modify").length;
|
|
55012
|
+
const skipped = opts.validated?.skipped?.length || 0;
|
|
55013
|
+
const okPhrase = created > 0 ? `${created + modified} files created/modified` : `${modified} files modified`;
|
|
55014
|
+
lines.push(`OK: ${okPhrase}`);
|
|
55015
|
+
if (skipped > 0) lines.push(`WARN: ${skipped} file${skipped > 1 ? "s" : ""} skipped`);
|
|
55016
|
+
lines.push("Next steps:");
|
|
55017
|
+
if (large) {
|
|
55018
|
+
lines.push('- Large output \u2013 previews suppressed. Use --output diff or press "d" in interactive mode');
|
|
55019
|
+
}
|
|
55020
|
+
lines.push("- If this looks correct, commit the changes");
|
|
55021
|
+
lines.push('- For a full diff: rerun with --output diff or press "d" in interactive mode');
|
|
54469
55022
|
}
|
|
54470
|
-
lines.push("- If this looks correct, commit the changes");
|
|
54471
|
-
lines.push('- For a full diff: rerun with --output diff or press "d" in interactive mode');
|
|
54472
55023
|
return lines.join("\n");
|
|
54473
55024
|
}
|
|
54474
55025
|
function okLine(text) {
|
|
@@ -54504,9 +55055,10 @@ function formatPlanAsDiff(files, opts) {
|
|
|
54504
55055
|
bytesUsed += diffBytes;
|
|
54505
55056
|
shownFiles++;
|
|
54506
55057
|
}
|
|
54507
|
-
|
|
55058
|
+
const totalDiffTargets = files.filter((f3) => f3.action === "modify").length;
|
|
55059
|
+
if (totalDiffTargets > shownFiles) {
|
|
54508
55060
|
lines.push(`
|
|
54509
|
-
[${
|
|
55061
|
+
[${totalDiffTargets - shownFiles} more file(s) omitted; re-run with --output diff --diff-lines ${budget.diffLines ?? 200}]`);
|
|
54510
55062
|
}
|
|
54511
55063
|
return lines.join("\n");
|
|
54512
55064
|
}
|
|
@@ -54748,129 +55300,6 @@ var init_InteractiveController = __esm({
|
|
|
54748
55300
|
init_OutputFormatter();
|
|
54749
55301
|
}
|
|
54750
55302
|
});
|
|
54751
|
-
|
|
54752
|
-
// src/services/cli-auth/api-caller.ts
|
|
54753
|
-
var api_caller_exports = {};
|
|
54754
|
-
__export(api_caller_exports, {
|
|
54755
|
-
RateLimitError: () => RateLimitError2,
|
|
54756
|
-
callAPI: () => callAPI,
|
|
54757
|
-
executeAIProxy: () => executeAIProxy,
|
|
54758
|
-
executeChat: () => executeChat,
|
|
54759
|
-
executeCode: () => executeCode
|
|
54760
|
-
});
|
|
54761
|
-
async function callAPI(endpoint, options = {}) {
|
|
54762
|
-
const tokens2 = await authManager2.getValidTokens();
|
|
54763
|
-
if (!tokens2) {
|
|
54764
|
-
throw new Error("Authentication required. Please run /login first.");
|
|
54765
|
-
}
|
|
54766
|
-
const apiBase = process.env.MARIA_API_BASE || "https://api.maria-code.ai";
|
|
54767
|
-
const url2 = `${apiBase}${endpoint}`;
|
|
54768
|
-
const controller = new AbortController();
|
|
54769
|
-
const defaultMs = 6e5;
|
|
54770
|
-
const envMs = Number(process.env.MARIA_API_TIMEOUT_MS || process.env.MARIA_CODE_TIMEOUT_MS || defaultMs);
|
|
54771
|
-
const timeoutMs = Number.isFinite(envMs) && envMs > 0 ? envMs : defaultMs;
|
|
54772
|
-
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
54773
|
-
try {
|
|
54774
|
-
const response = await fetch(url2, {
|
|
54775
|
-
method: options.method || "GET",
|
|
54776
|
-
headers: {
|
|
54777
|
-
"Authorization": `Bearer ${tokens2.accessToken}`,
|
|
54778
|
-
"Content-Type": "application/json",
|
|
54779
|
-
...options.headers
|
|
54780
|
-
},
|
|
54781
|
-
body: options.body ? JSON.stringify(options.body) : void 0,
|
|
54782
|
-
agent,
|
|
54783
|
-
// Use keep-alive agent
|
|
54784
|
-
signal: controller.signal
|
|
54785
|
-
});
|
|
54786
|
-
clearTimeout(timeoutId);
|
|
54787
|
-
if (!response) {
|
|
54788
|
-
throw new Error("\u{1F310} Network error, check connection");
|
|
54789
|
-
}
|
|
54790
|
-
if (response.status === 401) {
|
|
54791
|
-
throw new Error("Session expired. Please run /login again.");
|
|
54792
|
-
}
|
|
54793
|
-
if (response.status === 402) {
|
|
54794
|
-
const data2 = await response.json().catch(() => ({}));
|
|
54795
|
-
throw new Error(`Quota exceeded: ${data2.message || "Please wait or /upgrade"}`);
|
|
54796
|
-
}
|
|
54797
|
-
if (response.status === 403) {
|
|
54798
|
-
const data2 = await response.json().catch(() => ({}));
|
|
54799
|
-
throw new Error(`Not available on Free plan: ${data2.message || "Run /upgrade"}`);
|
|
54800
|
-
}
|
|
54801
|
-
if (response.status === 429) {
|
|
54802
|
-
const h2 = response.headers;
|
|
54803
|
-
const ra = h2.get("Retry-After");
|
|
54804
|
-
const reset = h2.get("RateLimit-Reset") || h2.get("X-RateLimit-Reset");
|
|
54805
|
-
let waitSec = 3;
|
|
54806
|
-
if (ra && /^\d+$/.test(ra)) {
|
|
54807
|
-
waitSec = +ra;
|
|
54808
|
-
} else if (ra) {
|
|
54809
|
-
const t2 = Date.parse(ra);
|
|
54810
|
-
if (!isNaN(t2)) waitSec = Math.max(1, Math.ceil((t2 - Date.now()) / 1e3));
|
|
54811
|
-
} else if (reset) {
|
|
54812
|
-
waitSec = Math.max(1, Math.ceil((+reset - Date.now()) / 1e3));
|
|
54813
|
-
}
|
|
54814
|
-
throw new RateLimitError2(`\u23F1 Wait ${waitSec}s`, waitSec);
|
|
54815
|
-
}
|
|
54816
|
-
if (!response.ok) {
|
|
54817
|
-
const data2 = await response.json().catch(() => ({}));
|
|
54818
|
-
throw new Error(data2.error || `Request failed: ${response.statusText}`);
|
|
54819
|
-
}
|
|
54820
|
-
const data = await response.json();
|
|
54821
|
-
return data;
|
|
54822
|
-
} catch (error2) {
|
|
54823
|
-
clearTimeout(timeoutId);
|
|
54824
|
-
if (error2.name === "AbortError") {
|
|
54825
|
-
throw new Error("\u{1F310} Network error, check connection");
|
|
54826
|
-
}
|
|
54827
|
-
throw error2;
|
|
54828
|
-
}
|
|
54829
|
-
}
|
|
54830
|
-
async function executeChat(messages) {
|
|
54831
|
-
const response = await callAPI("/v1/chat", {
|
|
54832
|
-
method: "POST",
|
|
54833
|
-
body: { messages }
|
|
54834
|
-
});
|
|
54835
|
-
return response;
|
|
54836
|
-
}
|
|
54837
|
-
async function executeCode(prompt) {
|
|
54838
|
-
const response = await callAPI("/v1/ai-proxy", {
|
|
54839
|
-
method: "POST",
|
|
54840
|
-
body: {
|
|
54841
|
-
prompt,
|
|
54842
|
-
taskType: "code"
|
|
54843
|
-
}
|
|
54844
|
-
});
|
|
54845
|
-
if (response.data?.routedModel) {
|
|
54846
|
-
response.routedModel = response.data.routedModel;
|
|
54847
|
-
}
|
|
54848
|
-
if (response.data?.content) {
|
|
54849
|
-
response.output = response.data.content;
|
|
54850
|
-
}
|
|
54851
|
-
return response;
|
|
54852
|
-
}
|
|
54853
|
-
async function executeAIProxy(provider, model, messages, options) {
|
|
54854
|
-
return callAPI("/v1/ai-proxy", {
|
|
54855
|
-
method: "POST",
|
|
54856
|
-
body: { provider, model, messages, options }
|
|
54857
|
-
});
|
|
54858
|
-
}
|
|
54859
|
-
var agent, authManager2, RateLimitError2;
|
|
54860
|
-
var init_api_caller = __esm({
|
|
54861
|
-
"src/services/cli-auth/api-caller.ts"() {
|
|
54862
|
-
init_AuthenticationManager();
|
|
54863
|
-
agent = new https__default.default.Agent({ keepAlive: true });
|
|
54864
|
-
authManager2 = new AuthenticationManager();
|
|
54865
|
-
RateLimitError2 = class extends Error {
|
|
54866
|
-
constructor(message, retryAfter) {
|
|
54867
|
-
super(message);
|
|
54868
|
-
this.retryAfter = retryAfter;
|
|
54869
|
-
this.name = "RateLimitError";
|
|
54870
|
-
}
|
|
54871
|
-
};
|
|
54872
|
-
}
|
|
54873
|
-
});
|
|
54874
55303
|
async function mapAttachmentsToTargets(attached, opts) {
|
|
54875
55304
|
const warnings = [];
|
|
54876
55305
|
const mapped = [];
|
|
@@ -55318,7 +55747,68 @@ ${requestPreamble}
|
|
|
55318
55747
|
${request}
|
|
55319
55748
|
|
|
55320
55749
|
${editContext}`;
|
|
55321
|
-
const
|
|
55750
|
+
const ctxAttachments = Array.isArray(opts.attachedFiles) && opts.attachedFiles.length > 0 ? opts.attachedFiles.map((f3) => ({
|
|
55751
|
+
name: f3.originalName,
|
|
55752
|
+
path: f3.pathHint,
|
|
55753
|
+
mime: f3.mime || "text/plain",
|
|
55754
|
+
data_base64: f3.content ? Buffer.from(f3.content, "utf8").toString("base64") : void 0
|
|
55755
|
+
})).map((a) => a.data_base64 ? a : { ...a, data_base64: void 0 }) : [];
|
|
55756
|
+
const pathAttachments = [];
|
|
55757
|
+
if (explicitFiles.length > 0) {
|
|
55758
|
+
try {
|
|
55759
|
+
const fs51 = await import('fs/promises');
|
|
55760
|
+
const pathMod = await import('path');
|
|
55761
|
+
for (const rel of explicitFiles) {
|
|
55762
|
+
try {
|
|
55763
|
+
const full = explicitAbsMap[rel] || pathMod.join(opts.root, rel);
|
|
55764
|
+
const stat13 = await fs51.stat(full).catch(() => null);
|
|
55765
|
+
if (!stat13 || !stat13.isFile()) continue;
|
|
55766
|
+
const buf = await fs51.readFile(full);
|
|
55767
|
+
const ext2 = (pathMod.extname(full) || "").toLowerCase();
|
|
55768
|
+
const mime = ext2 === ".pdf" ? "application/pdf" : ext2 === ".png" ? "image/png" : ext2 === ".jpg" || ext2 === ".jpeg" ? "image/jpeg" : ext2 === ".webp" ? "image/webp" : ext2 === ".gif" ? "image/gif" : ext2 === ".bmp" ? "image/bmp" : ext2 === ".svg" ? "image/svg+xml" : ext2 === ".tif" || ext2 === ".tiff" ? "image/tiff" : ext2 === ".heic" ? "image/heic" : ext2 === ".heif" ? "image/heif" : "text/plain";
|
|
55769
|
+
pathAttachments.push({
|
|
55770
|
+
name: pathMod.basename(full),
|
|
55771
|
+
path: full,
|
|
55772
|
+
mime,
|
|
55773
|
+
data_base64: buf.toString("base64")
|
|
55774
|
+
});
|
|
55775
|
+
} catch {
|
|
55776
|
+
}
|
|
55777
|
+
}
|
|
55778
|
+
} catch {
|
|
55779
|
+
}
|
|
55780
|
+
}
|
|
55781
|
+
const hydratedCtx = [];
|
|
55782
|
+
if (ctxAttachments.length > 0) {
|
|
55783
|
+
try {
|
|
55784
|
+
const fs51 = await import('fs/promises');
|
|
55785
|
+
for (const a of ctxAttachments) {
|
|
55786
|
+
if (a.data_base64) {
|
|
55787
|
+
hydratedCtx.push(a);
|
|
55788
|
+
continue;
|
|
55789
|
+
}
|
|
55790
|
+
const p = a.path || "";
|
|
55791
|
+
if (!p) {
|
|
55792
|
+
continue;
|
|
55793
|
+
}
|
|
55794
|
+
try {
|
|
55795
|
+
const stat13 = await fs51.stat(p).catch(() => null);
|
|
55796
|
+
if (!stat13 || !stat13.isFile()) {
|
|
55797
|
+
hydratedCtx.push(a);
|
|
55798
|
+
continue;
|
|
55799
|
+
}
|
|
55800
|
+
const buf = await fs51.readFile(p);
|
|
55801
|
+
hydratedCtx.push({ ...a, data_base64: buf.toString("base64") });
|
|
55802
|
+
} catch {
|
|
55803
|
+
hydratedCtx.push(a);
|
|
55804
|
+
}
|
|
55805
|
+
}
|
|
55806
|
+
} catch {
|
|
55807
|
+
hydratedCtx.push(...ctxAttachments);
|
|
55808
|
+
}
|
|
55809
|
+
}
|
|
55810
|
+
const allAttachments = (hydratedCtx.length ? hydratedCtx : ctxAttachments).concat(pathAttachments);
|
|
55811
|
+
const response = await executeCode(allAttachments.length > 0 ? { prompt: enriched, provider: "google", model: "gemini-2.5-flash", attachments: allAttachments } : enriched);
|
|
55322
55812
|
const raw = (response.output || response?.data?.content || "").trim();
|
|
55323
55813
|
if (!raw) {
|
|
55324
55814
|
return {
|
|
@@ -55447,6 +55937,7 @@ ${editContext}`;
|
|
|
55447
55937
|
const remainingSkipped = (validated.skipped || []).filter((p) => !skippedPlans.some((sp) => sp.path === p)).map((p) => ({ path: p, kind: "source", action: "skip", description: "" }));
|
|
55448
55938
|
const displayFiles = validated.files.concat(skippedPlans).concat(remainingSkipped);
|
|
55449
55939
|
const summary = summarizePlan(displayFiles);
|
|
55940
|
+
const planView = opts.flags.planOnly || opts.flags.dryRun || !opts.flags.apply;
|
|
55450
55941
|
const lines = [
|
|
55451
55942
|
formatPlan(summary, {
|
|
55452
55943
|
mode: outputMode,
|
|
@@ -55454,11 +55945,26 @@ ${editContext}`;
|
|
|
55454
55945
|
diffBudget: collectDiffBudget(opts.flags),
|
|
55455
55946
|
root: opts.root,
|
|
55456
55947
|
requestText: request,
|
|
55457
|
-
validated: { warnings: validated.warnings.slice(), skipped: validated.skipped.slice() }
|
|
55948
|
+
validated: { warnings: validated.warnings.slice(), skipped: validated.skipped.slice() },
|
|
55949
|
+
planView
|
|
55458
55950
|
})
|
|
55459
55951
|
];
|
|
55460
55952
|
if (opts.flags.planOnly || opts.flags.dryRun || !opts.flags.apply) {
|
|
55461
|
-
|
|
55953
|
+
let specMarkdown;
|
|
55954
|
+
try {
|
|
55955
|
+
const prompt = buildSpecPrompt(request, normalized);
|
|
55956
|
+
const { callApiJson: callApiJson4 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
55957
|
+
try {
|
|
55958
|
+
const resp = await callApiJson4("/v1/ai-proxy", { method: "POST", body: JSON.stringify({ prompt, taskType: "chat" }), headers: { "Content-Type": "application/json" } });
|
|
55959
|
+
const content = resp?.data?.content || resp?.content;
|
|
55960
|
+
if (content && typeof content === "string") specMarkdown = content;
|
|
55961
|
+
} catch {
|
|
55962
|
+
}
|
|
55963
|
+
} catch {
|
|
55964
|
+
}
|
|
55965
|
+
const res = { plan: normalized, validated, summaryLines: withNotices(lines) };
|
|
55966
|
+
if (specMarkdown && typeof specMarkdown === "string" && specMarkdown.trim()) res.specMarkdown = specMarkdown;
|
|
55967
|
+
return res;
|
|
55462
55968
|
}
|
|
55463
55969
|
if (opts.flags.interactive && !opts.flags.yes && !process.stdin.isTTY) {
|
|
55464
55970
|
lines.push("", "WARN: Non-TTY interactive request downgraded to plan-only. Re-run with --yes to apply non-interactively.");
|
|
@@ -55538,6 +56044,36 @@ ${editContext}`;
|
|
|
55538
56044
|
return { plan: normalized, validated, summaryLines: withNotices([errorLine(err)]) };
|
|
55539
56045
|
}
|
|
55540
56046
|
}
|
|
56047
|
+
function buildSpecPrompt(request, plan) {
|
|
56048
|
+
const tree = {};
|
|
56049
|
+
for (const f3 of plan) {
|
|
56050
|
+
const dir = f3.path.split("/").slice(0, -1).join("/") || ".";
|
|
56051
|
+
if (!tree[dir]) tree[dir] = [];
|
|
56052
|
+
tree[dir].push(`${f3.action} ${f3.path} ${f3.language ? "(" + f3.language + ")" : ""}`.trim());
|
|
56053
|
+
}
|
|
56054
|
+
const treeLines = [];
|
|
56055
|
+
for (const [dir, items] of Object.entries(tree)) {
|
|
56056
|
+
treeLines.push(`- ${dir}`);
|
|
56057
|
+
for (const it of items) treeLines.push(` - ${it}`);
|
|
56058
|
+
}
|
|
56059
|
+
return [
|
|
56060
|
+
"You are a senior staff engineer. Produce a concise, high-quality Markdown spec for the following code change plan.",
|
|
56061
|
+
"",
|
|
56062
|
+
"Sections:",
|
|
56063
|
+
"- Overview",
|
|
56064
|
+
"- File Tree",
|
|
56065
|
+
"- Per-file Rationale (what/why)",
|
|
56066
|
+
"- Next Steps",
|
|
56067
|
+
"",
|
|
56068
|
+
"Request:",
|
|
56069
|
+
"```",
|
|
56070
|
+
request,
|
|
56071
|
+
"```",
|
|
56072
|
+
"",
|
|
56073
|
+
"Planned files:",
|
|
56074
|
+
treeLines.join("\n")
|
|
56075
|
+
].join("\n");
|
|
56076
|
+
}
|
|
55541
56077
|
function normalizePreviewLines(n) {
|
|
55542
56078
|
return typeof n === "number" && n > 0 ? n : void 0;
|
|
55543
56079
|
}
|
|
@@ -55559,7 +56095,7 @@ function mapCodeErrorToReason(err) {
|
|
|
55559
56095
|
const error2 = err;
|
|
55560
56096
|
const message = typeof error2?.message === "string" ? error2.message.toLowerCase() : "";
|
|
55561
56097
|
const code = typeof error2?.code === "string" ? error2.code.toLowerCase() : "";
|
|
55562
|
-
if (error2 instanceof
|
|
56098
|
+
if (error2 instanceof RateLimitError || message.includes("rate") && message.includes("limit")) {
|
|
55563
56099
|
return "rate-limit";
|
|
55564
56100
|
}
|
|
55565
56101
|
if (message.includes("timeout") || code === "etimedout") {
|
|
@@ -55732,7 +56268,7 @@ function scanSoftIssues(files) {
|
|
|
55732
56268
|
return { hasTrailingWhitespace: tw, hasConflictMarkers: cm };
|
|
55733
56269
|
}
|
|
55734
56270
|
function parseExplicitFilenames(request) {
|
|
55735
|
-
const matches = request.match(/([\w
|
|
56271
|
+
const matches = request.match(/([\w\-./\\:]+\.[A-Za-z0-9]{1,10})/gi);
|
|
55736
56272
|
if (!matches) return [];
|
|
55737
56273
|
const seen = /* @__PURE__ */ new Set();
|
|
55738
56274
|
const out = [];
|
|
@@ -56032,9 +56568,11 @@ var LANGUAGE_EXTENSIONS, CodeCommand, codeCommand, metadata3;
|
|
|
56032
56568
|
var init_code_command = __esm({
|
|
56033
56569
|
"src/slash-commands/categories/code/code.command.ts"() {
|
|
56034
56570
|
init_base_command();
|
|
56571
|
+
init_api_caller();
|
|
56035
56572
|
init_rate_limit_handler();
|
|
56036
56573
|
init_animations();
|
|
56037
56574
|
init_code_utils();
|
|
56575
|
+
init_ArgumentInference();
|
|
56038
56576
|
LANGUAGE_EXTENSIONS = {
|
|
56039
56577
|
javascript: ".js",
|
|
56040
56578
|
typescript: ".ts",
|
|
@@ -56053,7 +56591,7 @@ var init_code_command = __esm({
|
|
|
56053
56591
|
name = "code";
|
|
56054
56592
|
category = "implementation";
|
|
56055
56593
|
description = "Generate code with AI";
|
|
56056
|
-
usage = "<request> [--plan-only|--sow] [--apply] [--dry-run] [--interactive] [--yes] [--max-files N] [--root DIR] [--rollback on|off] [--output names|summary|detail|diff] [--no-code] [--preview-lines N] [--only-attached] [--attach-mode strict|assist] [--max-attachments N] [--diff-lines N] [--diff-bytes N] [--diff-hunks N]";
|
|
56594
|
+
usage = "<request> [--plan-only|--sow] [--apply] [--dry-run] [--interactive] [--yes] [--max-files N] [--root DIR] [--rollback on|off] [--output names|summary|detail|diff] [--no-code] [--preview-lines N] [--only-attached] [--attach-mode strict|assist] [--max-attachments N] [--diff-lines N] [--diff-bytes N] [--diff-hunks N] [--diff-global-max-files N] [--diff-global-max-bytes N]";
|
|
56057
56595
|
aliases = ["c"];
|
|
56058
56596
|
examples = [
|
|
56059
56597
|
{
|
|
@@ -56068,12 +56606,50 @@ var init_code_command = __esm({
|
|
|
56068
56606
|
}
|
|
56069
56607
|
];
|
|
56070
56608
|
async execute(commandArgs, context2) {
|
|
56071
|
-
const request = commandArgs.raw.join(" ").trim();
|
|
56609
|
+
const request = await this.ensureLanguageDefaults(commandArgs.raw.join(" ").trim());
|
|
56072
56610
|
if (!request) {
|
|
56073
56611
|
return this.error("Please provide a code request \xB7 Example: /code create button component\nTip: Use --plan-only to safely review the plan, or --output detail to preview snippet heads.");
|
|
56074
56612
|
}
|
|
56075
56613
|
try {
|
|
56076
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
|
+
}
|
|
56644
|
+
if (opts.planOnly) {
|
|
56645
|
+
opts.apply = false;
|
|
56646
|
+
opts.dryRun = false;
|
|
56647
|
+
}
|
|
56648
|
+
if (opts.dryRun) {
|
|
56649
|
+
opts.apply = false;
|
|
56650
|
+
}
|
|
56651
|
+
if (opts.dryRun && !opts.output) opts.output = "detail";
|
|
56652
|
+
if (opts.dryRun && !opts.previewLines) opts.previewLines = 50;
|
|
56077
56653
|
const root = opts.root || process.cwd();
|
|
56078
56654
|
const { orchestrate: orchestrate2 } = await Promise.resolve().then(() => (init_Orchestrator(), Orchestrator_exports));
|
|
56079
56655
|
const attachments = await this.collectAttachedFiles(context2).catch(() => []);
|
|
@@ -56083,8 +56659,57 @@ var init_code_command = __esm({
|
|
|
56083
56659
|
const spinner = new ProcessAnimation();
|
|
56084
56660
|
spinner.start();
|
|
56085
56661
|
try {
|
|
56086
|
-
const res = await orchestrate2(request, { root, flags: { planOnly: opts.planOnly, apply: opts.apply, dryRun: opts.dryRun, interactive: opts.interactive, yes: opts.yes, maxFiles: opts.maxFiles, output: opts.output, hideCode: opts.noCode, previewLines: this.normalizePreviewLines(opts.previewLines), verbose: opts.verbose, onlyAttached: opts.onlyAttached, attachMode: opts.attachMode, maxAttachments: opts.maxAttachments, diffLines: opts.diffLines, diffBytes: opts.diffBytes, diffHunks: opts.diffHunks, allowDotfiles: opts.allowDotfiles }, abortSignal: abort.signal, attachedFiles: attachments });
|
|
56087
|
-
|
|
56662
|
+
const res = await orchestrate2(request, { root, flags: { planOnly: opts.planOnly, apply: opts.apply, dryRun: opts.dryRun, interactive: opts.interactive, yes: opts.yes, maxFiles: opts.maxFiles, output: opts.output, hideCode: opts.noCode, previewLines: this.normalizePreviewLines(opts.previewLines), verbose: opts.verbose, onlyAttached: opts.onlyAttached, attachMode: opts.attachMode, maxAttachments: opts.maxAttachments, diffLines: opts.diffLines, diffBytes: opts.diffBytes, diffHunks: opts.diffHunks, diffGlobalMaxFiles: opts.diffGlobalMaxFiles, diffGlobalMaxBytes: opts.diffGlobalMaxBytes, allowDotfiles: opts.allowDotfiles }, abortSignal: abort.signal, attachedFiles: attachments });
|
|
56663
|
+
if (opts.planOnly) {
|
|
56664
|
+
const fs51 = await import('fs/promises');
|
|
56665
|
+
const path64 = await import('path');
|
|
56666
|
+
const spec = res?.specMarkdown;
|
|
56667
|
+
const lines = Array.isArray(res?.summaryLines) ? res.summaryLines : [];
|
|
56668
|
+
const planItems = [];
|
|
56669
|
+
for (const l of lines) {
|
|
56670
|
+
const s2 = String(l).trim();
|
|
56671
|
+
if (!s2) continue;
|
|
56672
|
+
if (/^Modified Artifacts/i.test(s2)) continue;
|
|
56673
|
+
if (/^OK:/i.test(s2)) continue;
|
|
56674
|
+
if (/^Next steps:/i.test(s2)) continue;
|
|
56675
|
+
const m2 = /^-\s+(create|modify)\s+(.+)$/i.exec(s2);
|
|
56676
|
+
if (m2) {
|
|
56677
|
+
planItems.push(`- [plan] ${m2[1].toLowerCase()} ${m2[2]}`);
|
|
56678
|
+
continue;
|
|
56679
|
+
}
|
|
56680
|
+
planItems.push(`- ${s2}`);
|
|
56681
|
+
}
|
|
56682
|
+
const md = [];
|
|
56683
|
+
if (spec && spec.trim()) {
|
|
56684
|
+
md.push(spec.trim());
|
|
56685
|
+
} else {
|
|
56686
|
+
md.push("# Code Plan");
|
|
56687
|
+
md.push("");
|
|
56688
|
+
md.push("## Request");
|
|
56689
|
+
md.push("");
|
|
56690
|
+
md.push("```");
|
|
56691
|
+
md.push(request);
|
|
56692
|
+
md.push("```");
|
|
56693
|
+
md.push("");
|
|
56694
|
+
md.push("## Proposed Changes");
|
|
56695
|
+
md.push("");
|
|
56696
|
+
if (planItems.length) md.push(...planItems);
|
|
56697
|
+
else md.push("- (no summary available)");
|
|
56698
|
+
}
|
|
56699
|
+
const plansDir = path64.join(root, ".maria", "plans");
|
|
56700
|
+
await fs51.mkdir(plansDir, { recursive: true });
|
|
56701
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
56702
|
+
const fileName = `code-plan-${ts}.md`;
|
|
56703
|
+
const outPath = path64.join(plansDir, fileName);
|
|
56704
|
+
await fs51.writeFile(outPath, md.join("\n") + "\n", "utf8");
|
|
56705
|
+
const rel = path64.relative(root, outPath);
|
|
56706
|
+
return this.success(`Code plan saved: ${rel}`);
|
|
56707
|
+
}
|
|
56708
|
+
const detail = res?.detailLines;
|
|
56709
|
+
if (opts.dryRun && Array.isArray(detail) && detail.length) {
|
|
56710
|
+
return this.success(detail.join("\n"));
|
|
56711
|
+
}
|
|
56712
|
+
const out = Array.isArray(res?.summaryLines) ? res.summaryLines.join("\n") : "";
|
|
56088
56713
|
return this.success(out);
|
|
56089
56714
|
} finally {
|
|
56090
56715
|
try {
|
|
@@ -56134,9 +56759,68 @@ ${pretty}`);
|
|
|
56134
56759
|
return this.error(parts.join("\n"));
|
|
56135
56760
|
}
|
|
56136
56761
|
}
|
|
56762
|
+
// Add default language hints when not specified by the user (LLM-assisted detection)
|
|
56763
|
+
async ensureLanguageDefaults(raw) {
|
|
56764
|
+
try {
|
|
56765
|
+
const system = [
|
|
56766
|
+
"You analyze a user's code-generation request.",
|
|
56767
|
+
"Decide if the user explicitly specified a programming language or framework/tooling (e.g., TypeScript, Python, Rust, Java, React, Vue, Node, etc.).",
|
|
56768
|
+
'Return ONLY compact JSON with shape {"explicitLanguage": boolean, "language"?: string}.',
|
|
56769
|
+
"Do not add any commentary."
|
|
56770
|
+
].join("\n");
|
|
56771
|
+
const user = `Request: ${raw}`;
|
|
56772
|
+
const resp = await callAPI("/v1/ai-proxy", {
|
|
56773
|
+
method: "POST",
|
|
56774
|
+
body: {
|
|
56775
|
+
provider: "google",
|
|
56776
|
+
model: "gemini-2.5-flash",
|
|
56777
|
+
taskType: "chat",
|
|
56778
|
+
prompt: `${system}
|
|
56779
|
+
|
|
56780
|
+
${user}`
|
|
56781
|
+
}
|
|
56782
|
+
});
|
|
56783
|
+
const content = (resp?.data?.content || resp?.content || "").trim();
|
|
56784
|
+
const extractFirstJson6 = (text) => {
|
|
56785
|
+
const fence = /```\s*json\s*\r?\n([\s\S]*?)```/i.exec(text);
|
|
56786
|
+
if (fence) return fence[1];
|
|
56787
|
+
const generic = /```\s*\r?\n([\s\S]*?)```/i.exec(text);
|
|
56788
|
+
if (generic) {
|
|
56789
|
+
try {
|
|
56790
|
+
JSON.parse(generic[1]);
|
|
56791
|
+
return generic[1];
|
|
56792
|
+
} catch {
|
|
56793
|
+
}
|
|
56794
|
+
}
|
|
56795
|
+
const start = text.indexOf("{");
|
|
56796
|
+
const end = text.lastIndexOf("}");
|
|
56797
|
+
if (start >= 0 && end > start) {
|
|
56798
|
+
const cand = text.slice(start, end + 1);
|
|
56799
|
+
try {
|
|
56800
|
+
JSON.parse(cand);
|
|
56801
|
+
return cand;
|
|
56802
|
+
} catch {
|
|
56803
|
+
}
|
|
56804
|
+
}
|
|
56805
|
+
return null;
|
|
56806
|
+
};
|
|
56807
|
+
const jsonText = extractFirstJson6(content) || content;
|
|
56808
|
+
let parsed = {};
|
|
56809
|
+
try {
|
|
56810
|
+
parsed = JSON.parse(jsonText);
|
|
56811
|
+
} catch {
|
|
56812
|
+
parsed.explicitLanguage = /```\s*[a-zA-Z]/.test(raw) || /\.(ts|tsx|js|jsx|py|java|kt|go|rs|rb|swift|cs|c|cpp|hpp|php|scala|hs|ex|exs|dart|lua|zig|sol|sql)\b/i.test(raw);
|
|
56813
|
+
}
|
|
56814
|
+
if (parsed && parsed.explicitLanguage) return raw;
|
|
56815
|
+
} catch {
|
|
56816
|
+
}
|
|
56817
|
+
const hint = " (Use TypeScript and React; prefer functional components and node)";
|
|
56818
|
+
return raw + hint;
|
|
56819
|
+
}
|
|
56137
56820
|
// v2.0 helpers
|
|
56138
56821
|
parseV2Options(raw) {
|
|
56139
|
-
const opts = { planOnly: false, apply: false, dryRun: false, interactive: false, yes: false, rollback: true, output: void 0, noCode: false, previewLines: 0, root: void 0, maxFiles: void 0, verbose: false, gitGuard: void 0, allowDotfiles: false, confirmOverwrites: [], gitCommit: void 0, gitBranch: void 0, gitTag: void 0, gitTagPrefix: void 0, gitPush: void 0, gitPushRemote: void 0, onlyAttached: false, attachMode: "assist", maxAttachments: 50, diffLines: void 0, diffBytes: void 0, diffHunks: void 0 };
|
|
56822
|
+
const opts = { planOnly: false, apply: false, dryRun: false, interactive: false, yes: false, rollback: true, output: void 0, noCode: false, previewLines: 0, root: void 0, maxFiles: void 0, verbose: false, gitGuard: void 0, allowDotfiles: false, confirmOverwrites: [], gitCommit: void 0, gitBranch: void 0, gitTag: void 0, gitTagPrefix: void 0, gitPush: void 0, gitPushRemote: void 0, onlyAttached: false, attachMode: "assist", maxAttachments: 50, diffLines: void 0, diffBytes: void 0, diffHunks: void 0, diffGlobalMaxFiles: void 0, diffGlobalMaxBytes: void 0 };
|
|
56823
|
+
const explicit = { apply: false, planOnly: false, dryRun: false };
|
|
56140
56824
|
const a = raw.slice();
|
|
56141
56825
|
while (a.length) {
|
|
56142
56826
|
const x2 = a.shift();
|
|
@@ -56146,12 +56830,15 @@ ${pretty}`);
|
|
|
56146
56830
|
case "plan-only":
|
|
56147
56831
|
case "sow":
|
|
56148
56832
|
opts.planOnly = true;
|
|
56833
|
+
explicit.planOnly = true;
|
|
56149
56834
|
break;
|
|
56150
56835
|
case "apply":
|
|
56151
56836
|
opts.apply = true;
|
|
56837
|
+
explicit.apply = true;
|
|
56152
56838
|
break;
|
|
56153
56839
|
case "dry-run":
|
|
56154
56840
|
opts.dryRun = true;
|
|
56841
|
+
explicit.dryRun = true;
|
|
56155
56842
|
break;
|
|
56156
56843
|
case "interactive":
|
|
56157
56844
|
opts.interactive = true;
|
|
@@ -56211,6 +56898,12 @@ ${pretty}`);
|
|
|
56211
56898
|
case "diff-hunks":
|
|
56212
56899
|
opts.diffHunks = Number(v || a.shift());
|
|
56213
56900
|
break;
|
|
56901
|
+
case "diff-global-max-files":
|
|
56902
|
+
opts.diffGlobalMaxFiles = Number(v || a.shift());
|
|
56903
|
+
break;
|
|
56904
|
+
case "diff-global-max-bytes":
|
|
56905
|
+
opts.diffGlobalMaxBytes = Number(v || a.shift());
|
|
56906
|
+
break;
|
|
56214
56907
|
case "confirm-overwrites": {
|
|
56215
56908
|
const list = (v || a.shift() || "").split(",").map((s2) => s2.trim()).filter(Boolean);
|
|
56216
56909
|
opts.confirmOverwrites = list;
|
|
@@ -56244,8 +56937,16 @@ ${pretty}`);
|
|
|
56244
56937
|
}
|
|
56245
56938
|
}
|
|
56246
56939
|
}
|
|
56247
|
-
if (
|
|
56248
|
-
opts.apply =
|
|
56940
|
+
if (explicit.planOnly || explicit.dryRun) {
|
|
56941
|
+
opts.apply = false;
|
|
56942
|
+
}
|
|
56943
|
+
if (explicit.planOnly) {
|
|
56944
|
+
opts.dryRun = false;
|
|
56945
|
+
}
|
|
56946
|
+
if (!explicit.apply && !explicit.planOnly && !explicit.dryRun) {
|
|
56947
|
+
if (!opts.apply && !opts.planOnly && !opts.dryRun) {
|
|
56948
|
+
opts.apply = true;
|
|
56949
|
+
}
|
|
56249
56950
|
}
|
|
56250
56951
|
return opts;
|
|
56251
56952
|
}
|
|
@@ -71083,7 +71784,7 @@ ${user}`,
|
|
|
71083
71784
|
};
|
|
71084
71785
|
}
|
|
71085
71786
|
});
|
|
71086
|
-
function
|
|
71787
|
+
function extractFirstJson5(text) {
|
|
71087
71788
|
const fence = /```json\r?\n([\s\S]*?)```/i.exec(text);
|
|
71088
71789
|
if (fence) return fence[1];
|
|
71089
71790
|
const start = text.indexOf("{");
|
|
@@ -71130,7 +71831,7 @@ ${user}`,
|
|
|
71130
71831
|
}
|
|
71131
71832
|
});
|
|
71132
71833
|
const raw = (response?.data?.content || response?.output || "").trim();
|
|
71133
|
-
const jsonText =
|
|
71834
|
+
const jsonText = extractFirstJson5(raw) || raw;
|
|
71134
71835
|
let parsed = {};
|
|
71135
71836
|
try {
|
|
71136
71837
|
parsed = JSON.parse(jsonText);
|
|
@@ -71151,7 +71852,7 @@ ${user}`,
|
|
|
71151
71852
|
}
|
|
71152
71853
|
return out;
|
|
71153
71854
|
}
|
|
71154
|
-
var
|
|
71855
|
+
var init_ArgumentInference2 = __esm({
|
|
71155
71856
|
"src/services/evaluation/ArgumentInference.ts"() {
|
|
71156
71857
|
init_api_caller();
|
|
71157
71858
|
}
|
|
@@ -71172,7 +71873,7 @@ var init_evaluate_command = __esm({
|
|
|
71172
71873
|
init_EvaluationOrchestrator();
|
|
71173
71874
|
init_api_caller();
|
|
71174
71875
|
init_animations();
|
|
71175
|
-
|
|
71876
|
+
init_ArgumentInference2();
|
|
71176
71877
|
EvaluateCommand = class extends BaseCommand {
|
|
71177
71878
|
name = "evaluate";
|
|
71178
71879
|
category = "evaluation";
|
|
@@ -71855,7 +72556,7 @@ __export(slash_commands_exports, {
|
|
|
71855
72556
|
MemoryStatusCommand: () => MemoryStatusCommand,
|
|
71856
72557
|
PermissionError: () => PermissionError,
|
|
71857
72558
|
PlanCommand: () => PlanCommand,
|
|
71858
|
-
RateLimitError: () =>
|
|
72559
|
+
RateLimitError: () => RateLimitError2,
|
|
71859
72560
|
RateLimitMiddleware: () => RateLimitMiddleware,
|
|
71860
72561
|
RecallCommand: () => RecallCommand,
|
|
71861
72562
|
RememberCommand: () => RememberCommand,
|
|
@@ -72417,6 +73118,17 @@ var init_slash_commands = __esm({
|
|
|
72417
73118
|
init_registry();
|
|
72418
73119
|
}
|
|
72419
73120
|
});
|
|
73121
|
+
|
|
73122
|
+
// src/cli/session-state.ts
|
|
73123
|
+
function clearSession() {
|
|
73124
|
+
while (session.length) session.pop();
|
|
73125
|
+
}
|
|
73126
|
+
var session;
|
|
73127
|
+
var init_session_state = __esm({
|
|
73128
|
+
"src/cli/session-state.ts"() {
|
|
73129
|
+
session = [];
|
|
73130
|
+
}
|
|
73131
|
+
});
|
|
72420
73132
|
async function handleSlash(input3) {
|
|
72421
73133
|
if (!input3.startsWith("/")) return false;
|
|
72422
73134
|
const { cmd, args: args2, options, flags } = parseSlash(input3);
|
|
@@ -72425,7 +73137,10 @@ async function handleSlash(input3) {
|
|
|
72425
73137
|
clearTerminal();
|
|
72426
73138
|
} catch {
|
|
72427
73139
|
}
|
|
72428
|
-
|
|
73140
|
+
try {
|
|
73141
|
+
clearSession();
|
|
73142
|
+
} catch {
|
|
73143
|
+
}
|
|
72429
73144
|
}
|
|
72430
73145
|
if (cmd === "doctor") {
|
|
72431
73146
|
console.log(chalk14__default.default.white("Run as subcommand: maria doctor"));
|
|
@@ -72477,6 +73192,7 @@ var init_handle_slash = __esm({
|
|
|
72477
73192
|
init_slash_commands();
|
|
72478
73193
|
init_cli_auth();
|
|
72479
73194
|
init_terminal();
|
|
73195
|
+
init_session_state();
|
|
72480
73196
|
}
|
|
72481
73197
|
});
|
|
72482
73198
|
function formatAnyError(err) {
|
|
@@ -74484,7 +75200,7 @@ var init_ai_response_service = __esm({
|
|
|
74484
75200
|
*/
|
|
74485
75201
|
async callLLM(prompt, opts = {}) {
|
|
74486
75202
|
const {
|
|
74487
|
-
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 named Maria. Always respond in English. Provide direct, production-quality answers. Make sure you answer in plain text, as a natural chat. When asked about the model (not your name or who you are, but the model), say you are a large language model fully trained by Bonginkan.",
|
|
75203
|
+
system = PLAIN_OUTPUT ? "Return ONLY the answer (or ONLY code). No menus, no lists, no guided flows. Always respond in English. If a local file path is provided, make sure you read the uploaded file before taking any actions." : "You are a helpful senior engineer named Maria. Always respond in English. Provide direct, production-quality answers. Make sure you answer in plain text, as a natural chat. When asked about the model (not your name or who you are, but the model), say you are a large language model fully trained by Bonginkan. If a path is provided, return the path as a string. If a local file path is provided, make sure you read the uploaded/attached file (which is likely equivalent to the path) before taking any actions.",
|
|
74488
75204
|
model = void 0,
|
|
74489
75205
|
provider = DEFAULT_PROVIDER2,
|
|
74490
75206
|
temperature = 0.2,
|
|
@@ -74492,14 +75208,63 @@ var init_ai_response_service = __esm({
|
|
|
74492
75208
|
} = opts;
|
|
74493
75209
|
process.env.MARIA_API_BASE || "https://api.maria-code.ai";
|
|
74494
75210
|
const preferApi = String(process.env.MARIA_USE_API || "1") === "1";
|
|
75211
|
+
let effectiveAttachments = Array.isArray(opts.attachments) ? opts.attachments.slice() : [];
|
|
74495
75212
|
if (preferApi) {
|
|
74496
75213
|
try {
|
|
74497
75214
|
const { callAPI: callAPI2 } = await Promise.resolve().then(() => (init_api_caller(), api_caller_exports));
|
|
75215
|
+
let autoAttachments = [];
|
|
75216
|
+
try {
|
|
75217
|
+
const pathPattern = /(?:^|\s)([\w\-\.\/\\:]+\.[A-Za-z0-9]{1,10})(?:\s|$)/gi;
|
|
75218
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
75219
|
+
let m2;
|
|
75220
|
+
const textToScan = `${prompt}`;
|
|
75221
|
+
while ((m2 = pathPattern.exec(textToScan)) !== null) {
|
|
75222
|
+
const p = (m2[1] || "").trim();
|
|
75223
|
+
if (p) candidates.add(p);
|
|
75224
|
+
}
|
|
75225
|
+
if (candidates.size > 0) {
|
|
75226
|
+
const fs51 = await import('fs/promises');
|
|
75227
|
+
const pathMod = await import('path');
|
|
75228
|
+
const cwd2 = process.cwd();
|
|
75229
|
+
for (const cand of candidates) {
|
|
75230
|
+
try {
|
|
75231
|
+
const normalized = cand.replace(/^"|"$/g, "").replace(/^'|'$/g, "");
|
|
75232
|
+
const abs = pathMod.isAbsolute(normalized) ? normalized : pathMod.join(cwd2, normalized);
|
|
75233
|
+
const st = await fs51.stat(abs).catch(() => null);
|
|
75234
|
+
if (!st || !st.isFile()) continue;
|
|
75235
|
+
const buf = await fs51.readFile(abs);
|
|
75236
|
+
const ext2 = (pathMod.extname(abs) || "").toLowerCase();
|
|
75237
|
+
const mime = ext2 === ".pdf" ? "application/pdf" : ext2 === ".png" ? "image/png" : ext2 === ".jpg" || ext2 === ".jpeg" ? "image/jpeg" : ext2 === ".webp" ? "image/webp" : ext2 === ".gif" ? "image/gif" : ext2 === ".bmp" ? "image/bmp" : ext2 === ".svg" ? "image/svg+xml" : ext2 === ".tif" || ext2 === ".tiff" ? "image/tiff" : ext2 === ".heic" ? "image/heic" : ext2 === ".heif" ? "image/heif" : "text/plain";
|
|
75238
|
+
autoAttachments.push({ name: pathMod.basename(abs), path: abs, mime, data_base64: buf.toString("base64") });
|
|
75239
|
+
} catch {
|
|
75240
|
+
}
|
|
75241
|
+
}
|
|
75242
|
+
}
|
|
75243
|
+
} catch {
|
|
75244
|
+
}
|
|
75245
|
+
if (autoAttachments.length > 0) {
|
|
75246
|
+
const existing = new Set(effectiveAttachments.map((a) => (a.path || a.name || "").toLowerCase()));
|
|
75247
|
+
for (const a of autoAttachments) {
|
|
75248
|
+
const key = (a.path || a.name || "").toLowerCase();
|
|
75249
|
+
if (!existing.has(key)) {
|
|
75250
|
+
effectiveAttachments.push(a);
|
|
75251
|
+
existing.add(key);
|
|
75252
|
+
}
|
|
75253
|
+
}
|
|
75254
|
+
}
|
|
75255
|
+
const inlineSection = "";
|
|
74498
75256
|
const r2 = await callAPI2("/v1/ai-proxy", {
|
|
74499
75257
|
method: "POST",
|
|
74500
|
-
body: {
|
|
75258
|
+
body: {
|
|
75259
|
+
// When attachments are present, force an attachments-capable route (mirror /evaluate)
|
|
75260
|
+
...effectiveAttachments.length ? { provider: "google", model: "gemini-2.5-flash" } : {},
|
|
75261
|
+
prompt: `${system}
|
|
74501
75262
|
|
|
74502
|
-
${prompt}`,
|
|
75263
|
+
${prompt}${inlineSection}`,
|
|
75264
|
+
taskType: "chat",
|
|
75265
|
+
// mirror /evaluate: include attachments in metadata
|
|
75266
|
+
...effectiveAttachments.length ? { metadata: { attachments: effectiveAttachments } } : {}
|
|
75267
|
+
}
|
|
74503
75268
|
});
|
|
74504
75269
|
const apiContent = r2?.data?.content || r2?.content;
|
|
74505
75270
|
if (apiContent) return apiContent;
|
|
@@ -74512,10 +75277,42 @@ ${prompt}`, taskType: "chat" }
|
|
|
74512
75277
|
} catch {
|
|
74513
75278
|
}
|
|
74514
75279
|
}
|
|
74515
|
-
|
|
74516
|
-
prompt: `${system}
|
|
75280
|
+
let fallbackPrompt = `${system}
|
|
74517
75281
|
|
|
74518
|
-
${prompt}
|
|
75282
|
+
${prompt}`;
|
|
75283
|
+
try {
|
|
75284
|
+
const attList = effectiveAttachments && effectiveAttachments.length ? effectiveAttachments : [];
|
|
75285
|
+
if (attList.length > 0) {
|
|
75286
|
+
const limitBytes = 128 * 1024;
|
|
75287
|
+
let used = 0;
|
|
75288
|
+
const sections = [];
|
|
75289
|
+
for (const a of attList) {
|
|
75290
|
+
if (!a?.data_base64) continue;
|
|
75291
|
+
try {
|
|
75292
|
+
const buf = Buffer.from(a.data_base64, "base64");
|
|
75293
|
+
const text = /^(application\/pdf)/i.test(String(a.mime || "")) ? "" : buf.toString("utf8");
|
|
75294
|
+
if (!text) continue;
|
|
75295
|
+
const remaining = Math.max(0, limitBytes - used);
|
|
75296
|
+
if (remaining <= 0) break;
|
|
75297
|
+
const slice = text.length > remaining ? text.slice(0, remaining) : text;
|
|
75298
|
+
used += Buffer.byteLength(slice, "utf8");
|
|
75299
|
+
sections.push(`[BEGIN file: ${a.path || a.name || "attachment.txt"}]
|
|
75300
|
+
${slice}
|
|
75301
|
+
[END]`);
|
|
75302
|
+
} catch {
|
|
75303
|
+
}
|
|
75304
|
+
}
|
|
75305
|
+
if (sections.length > 0) {
|
|
75306
|
+
fallbackPrompt = `${fallbackPrompt}
|
|
75307
|
+
|
|
75308
|
+
[ATTACHMENTS]
|
|
75309
|
+
${sections.join("\n\n")}`;
|
|
75310
|
+
}
|
|
75311
|
+
}
|
|
75312
|
+
} catch {
|
|
75313
|
+
}
|
|
75314
|
+
const res = await this.providerManager.complete({
|
|
75315
|
+
prompt: fallbackPrompt,
|
|
74519
75316
|
model,
|
|
74520
75317
|
temperature,
|
|
74521
75318
|
maxTokens
|
|
@@ -75760,7 +76557,7 @@ async function init2() {
|
|
|
75760
76557
|
ai = res.ai;
|
|
75761
76558
|
res.ctx;
|
|
75762
76559
|
store = res.store;
|
|
75763
|
-
|
|
76560
|
+
clearSession();
|
|
75764
76561
|
for (const m2 of res.session) session.push(m2);
|
|
75765
76562
|
await loadServices2();
|
|
75766
76563
|
}
|
|
@@ -75777,6 +76574,9 @@ async function streamAnswer(text, opts = {}) {
|
|
|
75777
76574
|
s2 = s2.replace(/\[BEGIN\s+file:[^\]]+\][\s\S]*?\[END\]/g, "");
|
|
75778
76575
|
return s2;
|
|
75779
76576
|
};
|
|
76577
|
+
const removeAttachmentSections = (s2) => {
|
|
76578
|
+
return s2.replace(/\[ATTACHMENTS\][\s\S]*$/i, "");
|
|
76579
|
+
};
|
|
75780
76580
|
const hasAnyCodeBlocks = (s2) => /```[\s\S]*?```|\[BEGIN\s+file:/i.test(s2);
|
|
75781
76581
|
const envInt = (name2, def) => {
|
|
75782
76582
|
const v = Number(process.env[name2]);
|
|
@@ -75802,10 +76602,11 @@ async function streamAnswer(text, opts = {}) {
|
|
|
75802
76602
|
model: process.env.MARIA_MODEL || "gemini-2.5-flash"
|
|
75803
76603
|
});
|
|
75804
76604
|
animation.stop();
|
|
75805
|
-
const
|
|
75806
|
-
|
|
76605
|
+
const respForArtifactCheck = removeAttachmentSections(resp || "");
|
|
76606
|
+
const containsCode = hasAnyCodeBlocks(respForArtifactCheck);
|
|
76607
|
+
if (containsCode && opts.triage && opts.triage.type === "route-code") {
|
|
75807
76608
|
try {
|
|
75808
|
-
const artifacts = extractAllCodeInfos(
|
|
76609
|
+
const artifacts = extractAllCodeInfos(respForArtifactCheck);
|
|
75809
76610
|
const savedFiles = [];
|
|
75810
76611
|
let okCount = 0, warnCount = 0, errCount = 0;
|
|
75811
76612
|
for (const { language, code, extension, filename: suggested } of artifacts) {
|
|
@@ -75830,7 +76631,7 @@ async function streamAnswer(text, opts = {}) {
|
|
|
75830
76631
|
console.log(chalk14__default.default.white(`ERROR: failed ${filepath} (${language}) - ${msg2}`));
|
|
75831
76632
|
}
|
|
75832
76633
|
}
|
|
75833
|
-
const prose = stripMarkdownForPlainChat(removeCodeBlocks(resp)).trim();
|
|
76634
|
+
const prose = stripMarkdownForPlainChat(removeCodeBlocks(removeAttachmentSections(resp))).trim();
|
|
75834
76635
|
if (prose) {
|
|
75835
76636
|
console.log(chalk14__default.default.white(""));
|
|
75836
76637
|
console.log(chalk14__default.default.white("Chat Response:"));
|
|
@@ -75909,44 +76710,23 @@ async function handleLine(line, options = {}) {
|
|
|
75909
76710
|
}
|
|
75910
76711
|
const consumed = await handleSlash(input3);
|
|
75911
76712
|
if (consumed) return;
|
|
75912
|
-
|
|
75913
|
-
|
|
75914
|
-
|
|
75915
|
-
|
|
75916
|
-
|
|
75917
|
-
|
|
75918
|
-
|
|
75919
|
-
|
|
75920
|
-
|
|
75921
|
-
|
|
75922
|
-
|
|
75923
|
-
|
|
75924
|
-
|
|
75925
|
-
|
|
75926
|
-
|
|
75927
|
-
skipChoiceResolution: true,
|
|
75928
|
-
skipTriage: true
|
|
75929
|
-
});
|
|
75930
|
-
console.log(chalk14__default.default.white(""));
|
|
75931
|
-
console.log(chalk14__default.default.white("Summary:"));
|
|
75932
|
-
if (triageResult.type === "route-code") {
|
|
75933
|
-
console.log(chalk14__default.default.white("OK: routed to /code plan-only"));
|
|
75934
|
-
console.log(chalk14__default.default.white("Next steps:"));
|
|
75935
|
-
console.log(chalk14__default.default.white("- Run /code --apply --yes after reviewing the plan"));
|
|
75936
|
-
} else if (triageResult.type === "route-image") {
|
|
75937
|
-
console.log(chalk14__default.default.white("OK: routed to /image"));
|
|
75938
|
-
console.log(chalk14__default.default.white("Next steps:"));
|
|
75939
|
-
console.log(chalk14__default.default.white("- Review generated images and iterate if needed"));
|
|
75940
|
-
} else if (triageResult.type === "route-video") {
|
|
75941
|
-
console.log(chalk14__default.default.white("OK: routed to /video"));
|
|
75942
|
-
console.log(chalk14__default.default.white("Next steps:"));
|
|
75943
|
-
console.log(chalk14__default.default.white("- Inspect the storyboard or render output"));
|
|
75944
|
-
} else {
|
|
75945
|
-
console.log(chalk14__default.default.white("OK: routed"));
|
|
75946
|
-
console.log(chalk14__default.default.white("Next steps:"));
|
|
75947
|
-
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
|
+
}
|
|
75948
76728
|
}
|
|
75949
|
-
|
|
76729
|
+
} finally {
|
|
75950
76730
|
}
|
|
75951
76731
|
}
|
|
75952
76732
|
const isAuthenticated = await authManager.isAuthenticated();
|
|
@@ -75959,73 +76739,7 @@ async function handleLine(line, options = {}) {
|
|
|
75959
76739
|
const user = { role: "user", content: input3, timestamp: /* @__PURE__ */ new Date() };
|
|
75960
76740
|
session.push(user);
|
|
75961
76741
|
if (store?.addMessage) await store.addMessage(user);
|
|
75962
|
-
|
|
75963
|
-
await handleComplexChat(input3, triageResult);
|
|
75964
|
-
return;
|
|
75965
|
-
}
|
|
75966
|
-
await streamAnswer(input3, { triage: triageResult });
|
|
75967
|
-
}
|
|
75968
|
-
async function handleComplexChat(request, triageResult) {
|
|
75969
|
-
const animation = new ProcessAnimation();
|
|
75970
|
-
animation.start();
|
|
75971
|
-
try {
|
|
75972
|
-
const authed = await authManager.isAuthenticated();
|
|
75973
|
-
let content = "";
|
|
75974
|
-
if (authed) {
|
|
75975
|
-
try {
|
|
75976
|
-
const resp = await callApiJson("/api/ai", {
|
|
75977
|
-
method: "POST",
|
|
75978
|
-
body: JSON.stringify({ prompt: request, taskType: "planning" }),
|
|
75979
|
-
headers: { "Content-Type": "application/json" }
|
|
75980
|
-
});
|
|
75981
|
-
content = resp?.data?.response || resp?.data?.content || "";
|
|
75982
|
-
} catch {
|
|
75983
|
-
}
|
|
75984
|
-
}
|
|
75985
|
-
if (!content) {
|
|
75986
|
-
animation.stop();
|
|
75987
|
-
await streamAnswer(request, { triage: triageResult });
|
|
75988
|
-
return;
|
|
75989
|
-
}
|
|
75990
|
-
animation.stop();
|
|
75991
|
-
const cleaned = content && typeof content === "string" ? content : buildComplexPlanSteps(request).join("\n");
|
|
75992
|
-
console.log(chalk14__default.default.white(cleaned));
|
|
75993
|
-
const planMessage = {
|
|
75994
|
-
role: "assistant",
|
|
75995
|
-
content: cleaned,
|
|
75996
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
75997
|
-
metadata: { tag: "complex-chat", triage: triageResult }
|
|
75998
|
-
};
|
|
75999
|
-
session.push(planMessage);
|
|
76000
|
-
if (store?.addMessage) await store.addMessage(planMessage);
|
|
76001
|
-
console.log(chalk14__default.default.white(""));
|
|
76002
|
-
console.log(chalk14__default.default.white("Summary:"));
|
|
76003
|
-
console.log(chalk14__default.default.white("OK: plan prepared"));
|
|
76004
|
-
console.log(chalk14__default.default.white("Next steps:"));
|
|
76005
|
-
console.log(chalk14__default.default.white("- Ask to apply or adjust the plan"));
|
|
76006
|
-
} finally {
|
|
76007
|
-
try {
|
|
76008
|
-
animation.stop();
|
|
76009
|
-
} catch {
|
|
76010
|
-
}
|
|
76011
|
-
}
|
|
76012
|
-
}
|
|
76013
|
-
function buildComplexPlanSteps(request) {
|
|
76014
|
-
const scoped = request.trim();
|
|
76015
|
-
const steps = [
|
|
76016
|
-
`Clarify scope, constraints, and success criteria for "${scoped}"`,
|
|
76017
|
-
`Review existing modules in src/ and docs/ for related work`,
|
|
76018
|
-
`Design the solution with safe defaults and feature flags if needed`,
|
|
76019
|
-
`Implement changes and document decisions`,
|
|
76020
|
-
`Validate with pnpm test and peer review artifacts`
|
|
76021
|
-
];
|
|
76022
|
-
if (/(test|spec|verify|検証)/i.test(scoped)) {
|
|
76023
|
-
steps.push("Extend or add Vitest coverage for new behaviour");
|
|
76024
|
-
}
|
|
76025
|
-
if (/(ui|frontend|component|画面)/i.test(scoped)) {
|
|
76026
|
-
steps.push("Capture CLI or UI snapshots to confirm UX changes");
|
|
76027
|
-
}
|
|
76028
|
-
return steps;
|
|
76742
|
+
await streamAnswer(input3, {});
|
|
76029
76743
|
}
|
|
76030
76744
|
async function tryResolveChoice(rawLine) {
|
|
76031
76745
|
const resolution = choiceMemory.resolve(rawLine);
|
|
@@ -76117,17 +76831,17 @@ MARIA v${getVersion()}
|
|
|
76117
76831
|
registerDoctorSubcommand(program2);
|
|
76118
76832
|
return program2;
|
|
76119
76833
|
}
|
|
76120
|
-
var InteractiveCLI, ai, store,
|
|
76834
|
+
var InteractiveCLI, ai, store, commandManager, startupDisplayed, program;
|
|
76121
76835
|
var init_cli = __esm({
|
|
76122
76836
|
"src/cli.ts"() {
|
|
76123
76837
|
init_env_loader();
|
|
76124
76838
|
init_version();
|
|
76125
76839
|
init_animations();
|
|
76126
76840
|
init_cli_auth();
|
|
76127
|
-
init_api_client();
|
|
76128
76841
|
init_choice_memory();
|
|
76129
|
-
|
|
76842
|
+
init_LlmTopLevelRouter();
|
|
76130
76843
|
init_handle_slash();
|
|
76844
|
+
init_session_state();
|
|
76131
76845
|
init_process_handlers();
|
|
76132
76846
|
init_doctor();
|
|
76133
76847
|
init_services_loader();
|
|
@@ -76135,7 +76849,6 @@ var init_cli = __esm({
|
|
|
76135
76849
|
init_interactive_session2();
|
|
76136
76850
|
init_server();
|
|
76137
76851
|
init_code_utils();
|
|
76138
|
-
session = [];
|
|
76139
76852
|
commandManager = null;
|
|
76140
76853
|
startupDisplayed = false;
|
|
76141
76854
|
if (!process.env.GOOGLE_AUTH_DISABLE_GCE_CHECK) {
|