@bonginkan/maria 4.3.27 → 4.3.28
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 +1 -1
- package/dist/bin/maria.cjs +326 -43
- package/dist/bin/maria.cjs.map +1 -1
- package/dist/cli.cjs +326 -43
- 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 +1 -1
- package/dist/server/express-server.js +1 -1
- package/dist/server-express.cjs +1 -1
- package/dist/server-express.cjs.map +1 -1
- package/package.json +2 -2
- package/src/slash-commands/READY.manifest.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# MARIA - AI Development Platform v4.3.
|
|
1
|
+
# MARIA - AI Development Platform v4.3.28
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@bonginkan/maria)
|
|
4
4
|
[](LICENSE)
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
> **Enterprise-grade AI development platform with 100% command availability and comprehensive fallback support**
|
|
12
12
|
|
|
13
|
-
## 🚀 What's New in v4.3.
|
|
13
|
+
## 🚀 What's New in v4.3.28 (September 16, 2025)
|
|
14
14
|
|
|
15
15
|
### 🎯 Interactive Improvements & Choice Memory
|
|
16
16
|
- **Choice Memory System**: Smart persistence of user selections across sessions
|
|
@@ -922,7 +922,7 @@ await secureWorkflow.executeWithAuth(workflowDefinition, securityContext);
|
|
|
922
922
|
### Quick Installation
|
|
923
923
|
```bash
|
|
924
924
|
# Install globally (recommended)
|
|
925
|
-
npm install -g @bonginkan/maria@4.3.
|
|
925
|
+
npm install -g @bonginkan/maria@4.3.28
|
|
926
926
|
|
|
927
927
|
# Verify installation
|
|
928
928
|
maria --version # Should show v4.3.9
|
|
@@ -1126,7 +1126,7 @@ MARIA CODE is distributed under a comprehensive licensing system designed for in
|
|
|
1126
1126
|
|
|
1127
1127
|
*MARIA v4.1.4 represents the pinnacle of multimodal AI development platform evolution - combining revolutionary voice-to-code capabilities, advanced memory systems, and comprehensive command ecosystems with enterprise-grade security and performance. This release establishes MARIA as the definitive choice for developers and Fortune 500 enterprises seeking intelligent, multimodal development experiences with GraphRAG intelligence, multilingual support, and zero-anxiety coding workflows.*
|
|
1128
1128
|
|
|
1129
|
-
**Transform your development experience today**: `npm install -g @bonginkan/maria@4.3.
|
|
1129
|
+
**Transform your development experience today**: `npm install -g @bonginkan/maria@4.3.28`
|
|
1130
1130
|
|
|
1131
1131
|
🌐 **Official Website**: [https://maria-code.ai](https://maria-code.ai)
|
|
1132
1132
|
💬 **Community**: [https://discord.gg/SMSmSGcEQy](https://discord.gg/SMSmSGcEQy)
|
package/dist/READY.manifest.json
CHANGED
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.28",
|
|
26070
|
+
description: "\u{1F680} MARIA v4.3.28 - 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",
|
|
@@ -28099,7 +28099,7 @@ var init_AuthenticationManager = __esm({
|
|
|
28099
28099
|
const response = await fetch(`${this.apiBase}/api/user/profile`, {
|
|
28100
28100
|
headers: {
|
|
28101
28101
|
"Authorization": `Bearer ${tokens2.accessToken}`,
|
|
28102
|
-
"User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.
|
|
28102
|
+
"User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.28"}`
|
|
28103
28103
|
}
|
|
28104
28104
|
});
|
|
28105
28105
|
if (response.status === 401) {
|
|
@@ -28731,7 +28731,7 @@ async function callApi(path60, init3 = {}) {
|
|
|
28731
28731
|
"Authorization": `Bearer ${token}`,
|
|
28732
28732
|
"X-Device-Id": getDeviceId(),
|
|
28733
28733
|
"X-Session-Id": getSessionId() || "",
|
|
28734
|
-
"User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.
|
|
28734
|
+
"User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.28"}`,
|
|
28735
28735
|
"Content-Type": init3.headers?.["Content-Type"] || "application/json"
|
|
28736
28736
|
});
|
|
28737
28737
|
const doFetch = async (token) => {
|
|
@@ -44443,7 +44443,7 @@ async function applyPlans(plans, opts) {
|
|
|
44443
44443
|
try {
|
|
44444
44444
|
for (const plan of plans) {
|
|
44445
44445
|
if (opts.signal?.aborted) throw abortErr();
|
|
44446
|
-
const target = path11__namespace.default.join(opts.root, plan.path);
|
|
44446
|
+
const target = plan.absPath ? plan.absPath : path11__namespace.default.join(opts.root, plan.path);
|
|
44447
44447
|
const dir = path11__namespace.default.dirname(target);
|
|
44448
44448
|
await fs21.promises.mkdir(dir, { recursive: true });
|
|
44449
44449
|
const exists2 = await fileExists(target);
|
|
@@ -50625,7 +50625,7 @@ var init_about_command = __esm({
|
|
|
50625
50625
|
async execute(args2, context2) {
|
|
50626
50626
|
const output3 = [];
|
|
50627
50627
|
output3.push("");
|
|
50628
|
-
output3.push(chalk14__default.default.cyan.bold("\u{1F916} About MARIA v4.3.
|
|
50628
|
+
output3.push(chalk14__default.default.cyan.bold("\u{1F916} About MARIA v4.3.28"));
|
|
50629
50629
|
output3.push(chalk14__default.default.gray("\u2550".repeat(40)));
|
|
50630
50630
|
output3.push("");
|
|
50631
50631
|
output3.push(chalk14__default.default.white.bold("MARIA - Minimal API, Maximum Power"));
|
|
@@ -54127,6 +54127,10 @@ async function normalizePlans(plans, opts) {
|
|
|
54127
54127
|
const profile = await scanRepo(opts.root);
|
|
54128
54128
|
const out = [];
|
|
54129
54129
|
for (const fp of plans) {
|
|
54130
|
+
if (fp.noNormalize) {
|
|
54131
|
+
out.push(fp);
|
|
54132
|
+
continue;
|
|
54133
|
+
}
|
|
54130
54134
|
const n = normalizePlanItem(fp, profile);
|
|
54131
54135
|
if (!n.kind) n.kind = guessKindByPath(n.path);
|
|
54132
54136
|
out.push(n);
|
|
@@ -54171,7 +54175,7 @@ async function validatePlan(plans, opts) {
|
|
|
54171
54175
|
skipped.push(fp.path);
|
|
54172
54176
|
continue;
|
|
54173
54177
|
}
|
|
54174
|
-
const full = path11__namespace.default.join(opts.root, rel);
|
|
54178
|
+
const full = fp.absPath ? fp.absPath : path11__namespace.default.join(opts.root, rel);
|
|
54175
54179
|
if (!full.startsWith(path11__namespace.default.resolve(opts.root))) {
|
|
54176
54180
|
warnings.push(`Outside root denied: ${fp.path}`);
|
|
54177
54181
|
skipped.push(fp.path);
|
|
@@ -54302,10 +54306,10 @@ function formatPlan(summary, opts) {
|
|
|
54302
54306
|
budget.diffLines = Math.min(budget.diffLines, 20);
|
|
54303
54307
|
lines.push("", `Diff preview (truncated to ${budget.diffLines} lines per file):`);
|
|
54304
54308
|
for (const f3 of summary.files) {
|
|
54305
|
-
if (f3.action
|
|
54306
|
-
const before = readCurrentFileSafe(opts.root, f3.path);
|
|
54309
|
+
if (f3.action !== "modify") continue;
|
|
54310
|
+
const before = readCurrentFileSafe(opts.root, f3.path, f3.absPath);
|
|
54307
54311
|
const after = f3.preview || "";
|
|
54308
|
-
const diff = buildUnifiedDiff(f3.path, before, after, budget);
|
|
54312
|
+
const diff = buildUnifiedDiff(f3.path, before, after, budget, f3.absPath);
|
|
54309
54313
|
lines.push(diff, "");
|
|
54310
54314
|
}
|
|
54311
54315
|
}
|
|
@@ -54342,9 +54346,10 @@ function formatPlanAsDiff(files, opts) {
|
|
|
54342
54346
|
let shownFiles = 0;
|
|
54343
54347
|
for (const f3 of files) {
|
|
54344
54348
|
if (budget.globalMaxFiles !== void 0 && shownFiles >= budget.globalMaxFiles) break;
|
|
54345
|
-
|
|
54349
|
+
if (f3.action !== "modify") continue;
|
|
54350
|
+
const before = readCurrentFileSafe(opts.root, f3.path, f3.absPath);
|
|
54346
54351
|
const after = f3.preview || "";
|
|
54347
|
-
const diff = buildUnifiedDiff(f3.path, before, after, budget);
|
|
54352
|
+
const diff = buildUnifiedDiff(f3.path, before, after, budget, f3.absPath);
|
|
54348
54353
|
const diffBytes = Buffer.byteLength(diff, "utf8");
|
|
54349
54354
|
if (budget.globalMaxBytes !== void 0 && bytesUsed + diffBytes > budget.globalMaxBytes && shownFiles > 0) {
|
|
54350
54355
|
lines.push(`
|
|
@@ -54361,11 +54366,11 @@ function formatPlanAsDiff(files, opts) {
|
|
|
54361
54366
|
}
|
|
54362
54367
|
return lines.join("\n");
|
|
54363
54368
|
}
|
|
54364
|
-
function readCurrentFileSafe(root, rel) {
|
|
54365
|
-
if (!root) return "";
|
|
54369
|
+
function readCurrentFileSafe(root, rel, abs) {
|
|
54370
|
+
if (!root && !abs) return "";
|
|
54366
54371
|
try {
|
|
54367
54372
|
const fs49 = __require("fs");
|
|
54368
|
-
const p = __require("path").join(root, rel);
|
|
54373
|
+
const p = abs ? abs : __require("path").join(root, rel);
|
|
54369
54374
|
return fs49.existsSync(p) ? fs49.readFileSync(p, "utf8") : "";
|
|
54370
54375
|
} catch {
|
|
54371
54376
|
return "";
|
|
@@ -54382,7 +54387,7 @@ function normalizeDiffBudget(b) {
|
|
|
54382
54387
|
globalMaxFiles: Number.isFinite(b?.globalMaxFiles) ? b.globalMaxFiles : envGlobalFiles
|
|
54383
54388
|
};
|
|
54384
54389
|
}
|
|
54385
|
-
function buildUnifiedDiff(relPath, before, after, b) {
|
|
54390
|
+
function buildUnifiedDiff(relPath, before, after, b, abs) {
|
|
54386
54391
|
const beforeLines = before.split(/\r?\n/);
|
|
54387
54392
|
const afterLines = after.split(/\r?\n/);
|
|
54388
54393
|
let i2 = 0;
|
|
@@ -54391,14 +54396,15 @@ function buildUnifiedDiff(relPath, before, after, b) {
|
|
|
54391
54396
|
while (j < beforeLines.length - i2 && j < afterLines.length - i2 && beforeLines[beforeLines.length - 1 - j] === afterLines[afterLines.length - 1 - j]) j++;
|
|
54392
54397
|
const oldMid = beforeLines.slice(i2, beforeLines.length - j);
|
|
54393
54398
|
const newMid = afterLines.slice(i2, afterLines.length - j);
|
|
54394
|
-
const
|
|
54399
|
+
const headerPath = abs ? abs : relPath;
|
|
54400
|
+
const header = [`--- ${headerPath}`, `+++ ${headerPath}`];
|
|
54395
54401
|
const body = [];
|
|
54396
54402
|
const ctxPrefix = Math.max(0, i2 - 3);
|
|
54397
54403
|
Math.min(beforeLines.length, beforeLines.length - j + 3);
|
|
54398
54404
|
const preCtx = beforeLines.slice(ctxPrefix, i2).map((l) => ` ${l}`);
|
|
54399
54405
|
const postCtx = beforeLines.slice(beforeLines.length - j, Math.min(beforeLines.length - j + 3, beforeLines.length)).map((l) => ` ${l}`);
|
|
54400
|
-
const del = oldMid.map((l) => `-${l}`);
|
|
54401
|
-
const add = newMid.map((l) => `+${l}`);
|
|
54406
|
+
const del = oldMid.map((l) => colorRed(`-${l}`));
|
|
54407
|
+
const add = newMid.map((l) => colorGreen(`+${l}`));
|
|
54402
54408
|
body.push(...preCtx);
|
|
54403
54409
|
body.push(...del);
|
|
54404
54410
|
body.push(...add);
|
|
@@ -54415,6 +54421,22 @@ function buildUnifiedDiff(relPath, before, after, b) {
|
|
|
54415
54421
|
}
|
|
54416
54422
|
return out;
|
|
54417
54423
|
}
|
|
54424
|
+
function colorGreen(s2) {
|
|
54425
|
+
try {
|
|
54426
|
+
const chalk44 = __require("chalk");
|
|
54427
|
+
return chalk44.green(s2);
|
|
54428
|
+
} catch {
|
|
54429
|
+
return s2;
|
|
54430
|
+
}
|
|
54431
|
+
}
|
|
54432
|
+
function colorRed(s2) {
|
|
54433
|
+
try {
|
|
54434
|
+
const chalk44 = __require("chalk");
|
|
54435
|
+
return chalk44.red(s2);
|
|
54436
|
+
} catch {
|
|
54437
|
+
return s2;
|
|
54438
|
+
}
|
|
54439
|
+
}
|
|
54418
54440
|
function languageLabel(lang, filePath) {
|
|
54419
54441
|
if (lang) {
|
|
54420
54442
|
const l = lang.toLowerCase();
|
|
@@ -55041,6 +55063,20 @@ var init_policy = __esm({
|
|
|
55041
55063
|
}
|
|
55042
55064
|
});
|
|
55043
55065
|
|
|
55066
|
+
// src/utils/esm-compat.ts
|
|
55067
|
+
var esm_compat_exports = {};
|
|
55068
|
+
__export(esm_compat_exports, {
|
|
55069
|
+
loadGlobby: () => loadGlobby
|
|
55070
|
+
});
|
|
55071
|
+
async function loadGlobby() {
|
|
55072
|
+
const mod = await import('globby');
|
|
55073
|
+
return mod?.globby ?? mod?.default ?? mod;
|
|
55074
|
+
}
|
|
55075
|
+
var init_esm_compat = __esm({
|
|
55076
|
+
"src/utils/esm-compat.ts"() {
|
|
55077
|
+
}
|
|
55078
|
+
});
|
|
55079
|
+
|
|
55044
55080
|
// src/services/code-orchestrator/Orchestrator.ts
|
|
55045
55081
|
var Orchestrator_exports = {};
|
|
55046
55082
|
__export(Orchestrator_exports, {
|
|
@@ -55075,6 +55111,20 @@ async function orchestrate(request, opts) {
|
|
|
55075
55111
|
const initial = [];
|
|
55076
55112
|
const fallbackNotices = [];
|
|
55077
55113
|
const withNotices = (base) => fallbackNotices.length > 0 ? [...fallbackNotices, ...base] : base;
|
|
55114
|
+
const explicitFilesRaw = parseExplicitFilenames(request);
|
|
55115
|
+
const explicitFiles = explicitFilesRaw.length > 0 ? await resolveExplicitPaths(opts.root, explicitFilesRaw, request) : [];
|
|
55116
|
+
const explicitAbsMap = /* @__PURE__ */ Object.create(null);
|
|
55117
|
+
if (explicitFiles.length > 0) {
|
|
55118
|
+
const pathMod = await import('path');
|
|
55119
|
+
for (const rel of explicitFiles) {
|
|
55120
|
+
explicitAbsMap[rel] = pathMod.join(opts.root, rel);
|
|
55121
|
+
}
|
|
55122
|
+
}
|
|
55123
|
+
const isEditIntent = detectEditIntent(request, {
|
|
55124
|
+
hasAttachments: !!(opts.attachedFiles && opts.attachedFiles.length > 0),
|
|
55125
|
+
explicitFilesCount: explicitFiles.length
|
|
55126
|
+
});
|
|
55127
|
+
const editContext = isEditIntent && explicitFiles.length > 0 ? await buildEditContext(opts.root, explicitFiles, 200, 512 * 1024) : "";
|
|
55078
55128
|
if (opts.attachedFiles && opts.attachedFiles.length > 0) {
|
|
55079
55129
|
const mapRes = await mapAttachmentsToTargets(opts.attachedFiles, {
|
|
55080
55130
|
root: opts.root,
|
|
@@ -55094,7 +55144,6 @@ async function orchestrate(request, opts) {
|
|
|
55094
55144
|
}
|
|
55095
55145
|
}
|
|
55096
55146
|
const onlyAttached = !!opts.flags.onlyAttached;
|
|
55097
|
-
const explicitFiles = parseExplicitFilenames(request);
|
|
55098
55147
|
if (!onlyAttached) {
|
|
55099
55148
|
let codeOutput = "";
|
|
55100
55149
|
if (process.env.MARIA_E2E_FAKE_CODE === "1") {
|
|
@@ -55114,9 +55163,17 @@ async function orchestrate(request, opts) {
|
|
|
55114
55163
|
"[BEGIN file: path]\n<content>\n[END]",
|
|
55115
55164
|
"Do not include any prose before/after; no menus/questions/suggestions; start immediately with ``` or [BEGIN file: ...]."
|
|
55116
55165
|
].join("\n");
|
|
55166
|
+
const requestPreamble = isEditIntent ? [
|
|
55167
|
+
"// EDIT MODE: modify existing files, preserve unrelated content.",
|
|
55168
|
+
"// Follow existing structure and only touch requested files.",
|
|
55169
|
+
editContext ? "// Current file snapshots provided below." : ""
|
|
55170
|
+
].filter(Boolean).join("\n") : "";
|
|
55117
55171
|
const enriched = `${FILE_FORMAT_INSTRUCTIONS}
|
|
55118
55172
|
|
|
55119
|
-
${
|
|
55173
|
+
${requestPreamble}
|
|
55174
|
+
${request}
|
|
55175
|
+
|
|
55176
|
+
${editContext}`;
|
|
55120
55177
|
const response = await executeCode(enriched);
|
|
55121
55178
|
const raw = (response.output || response?.data?.content || "").trim();
|
|
55122
55179
|
if (!raw) {
|
|
@@ -55161,24 +55218,27 @@ ${request}`;
|
|
|
55161
55218
|
const htmlIdx = blocks.findIndex((b) => /html/i.test(b.language));
|
|
55162
55219
|
const htmlFile = explicitFiles.find((f3) => f3.toLowerCase().endsWith(".html"));
|
|
55163
55220
|
if (htmlIdx >= 0 && htmlFile) {
|
|
55164
|
-
initial.push({ path: htmlFile, kind: "source", action: "create", description: "HTML page", language: "html", preview: blocks[htmlIdx].code });
|
|
55221
|
+
initial.push({ path: htmlFile, absPath: explicitAbsMap[htmlFile], noNormalize: true, kind: "source", action: "create", description: "HTML page", language: "html", preview: blocks[htmlIdx].code });
|
|
55165
55222
|
mapped.add(htmlFile);
|
|
55166
55223
|
}
|
|
55167
55224
|
const jsIdx = blocks.findIndex((b) => /(ts|tsx|jsx|javascript|js)/i.test(b.language));
|
|
55168
55225
|
const jsFile = explicitFiles.find((f3) => f3.toLowerCase().endsWith(".js"));
|
|
55169
55226
|
if (jsIdx >= 0 && jsFile && !mapped.has(jsFile)) {
|
|
55170
|
-
initial.push({ path: jsFile, kind: "source", action: "create", description: "Script", language: "javascript", preview: blocks[jsIdx].code });
|
|
55227
|
+
initial.push({ path: jsFile, absPath: explicitAbsMap[jsFile], noNormalize: true, kind: "source", action: "create", description: "Script", language: "javascript", preview: blocks[jsIdx].code });
|
|
55171
55228
|
mapped.add(jsFile);
|
|
55172
55229
|
}
|
|
55173
55230
|
const cssIdx = blocks.findIndex((b) => /css/i.test(b.language));
|
|
55174
55231
|
const cssFile = explicitFiles.find((f3) => f3.toLowerCase().endsWith(".css"));
|
|
55175
55232
|
if (cssIdx >= 0 && cssFile && !mapped.has(cssFile)) {
|
|
55176
|
-
initial.push({ path: cssFile, kind: "source", action: "create", description: "Stylesheet", language: "css", preview: blocks[cssIdx].code });
|
|
55233
|
+
initial.push({ path: cssFile, absPath: explicitAbsMap[cssFile], noNormalize: true, kind: "source", action: "create", description: "Stylesheet", language: "css", preview: blocks[cssIdx].code });
|
|
55177
55234
|
mapped.add(cssFile);
|
|
55178
55235
|
}
|
|
55179
55236
|
for (const f3 of explicitFiles) {
|
|
55180
55237
|
if (mapped.has(f3)) continue;
|
|
55181
|
-
|
|
55238
|
+
const plan = scaffoldForFilename(f3, explicitFiles);
|
|
55239
|
+
plan.absPath = explicitAbsMap[f3];
|
|
55240
|
+
plan.noNormalize = true;
|
|
55241
|
+
initial.push(plan);
|
|
55182
55242
|
}
|
|
55183
55243
|
} else {
|
|
55184
55244
|
for (let i2 = 0; i2 < blocks.length; i2++) {
|
|
@@ -55196,12 +55256,26 @@ ${request}`;
|
|
|
55196
55256
|
}
|
|
55197
55257
|
}
|
|
55198
55258
|
}
|
|
55259
|
+
if (!isEditIntent) {
|
|
55260
|
+
const proposedTop = deriveProjectFolderName(request);
|
|
55261
|
+
const { folderName, detectedTop } = await ensureTopFolder(opts.root, proposedTop, initial);
|
|
55262
|
+
if (folderName) {
|
|
55263
|
+
for (const p of initial) {
|
|
55264
|
+
if (!startsWithTopFolder(p.path, detectedTop || folderName)) {
|
|
55265
|
+
p.path = prefixWithTopFolder(p.path, folderName);
|
|
55266
|
+
}
|
|
55267
|
+
}
|
|
55268
|
+
}
|
|
55269
|
+
}
|
|
55199
55270
|
if (explicitFiles.length > 0 && initial.filter((f3) => !!f3.preview).length === 0) {
|
|
55200
55271
|
for (const f3 of explicitFiles) {
|
|
55201
55272
|
initial.push(scaffoldForFilename(f3, explicitFiles));
|
|
55202
55273
|
}
|
|
55203
55274
|
}
|
|
55204
|
-
const normalized = await normalizePlans(
|
|
55275
|
+
const normalized = await normalizePlans(
|
|
55276
|
+
initial.map((p) => p.noNormalize ? p : p),
|
|
55277
|
+
{ root: opts.root }
|
|
55278
|
+
);
|
|
55205
55279
|
try {
|
|
55206
55280
|
const [{ access: access18 }, path60] = await Promise.all([
|
|
55207
55281
|
import('fs/promises'),
|
|
@@ -55209,8 +55283,12 @@ ${request}`;
|
|
|
55209
55283
|
]);
|
|
55210
55284
|
for (const p of normalized) {
|
|
55211
55285
|
try {
|
|
55212
|
-
|
|
55286
|
+
const absCandidate = p.absPath ? p.absPath : path60.join(opts.root, p.path);
|
|
55287
|
+
await access18(absCandidate);
|
|
55213
55288
|
p.action = "modify";
|
|
55289
|
+
if (isEditIntent) {
|
|
55290
|
+
p.overwritePolicy = "allow";
|
|
55291
|
+
}
|
|
55214
55292
|
} catch {
|
|
55215
55293
|
p.action = "create";
|
|
55216
55294
|
}
|
|
@@ -55218,10 +55296,12 @@ ${request}`;
|
|
|
55218
55296
|
} catch {
|
|
55219
55297
|
}
|
|
55220
55298
|
const validated = await validatePlan(normalized, { root: opts.root, profile, flags: { maxFiles: opts.flags.maxFiles, yes: opts.flags.yes, interactive: !!opts.flags.interactive, ...opts.flags } });
|
|
55221
|
-
const
|
|
55222
|
-
const
|
|
55223
|
-
|
|
55224
|
-
);
|
|
55299
|
+
const hasAnyModify = validated.files.some((f3) => f3.action === "modify") || isEditIntent;
|
|
55300
|
+
const outputMode = !opts.flags.hideCode && hasAnyModify ? "diff" : resolveOutputMode(opts.flags.output, validated.files.length, !!opts.flags.hideCode);
|
|
55301
|
+
const skippedSetForLookup = new Set(validated.skipped || []);
|
|
55302
|
+
const skippedPlans = normalized.filter((f3) => skippedSetForLookup.has(f3.path));
|
|
55303
|
+
const remainingSkipped = (validated.skipped || []).filter((p) => !skippedPlans.some((sp) => sp.path === p)).map((p) => ({ path: p, kind: "source", action: "skip", description: "" }));
|
|
55304
|
+
const displayFiles = validated.files.concat(skippedPlans).concat(remainingSkipped);
|
|
55225
55305
|
const summary = summarizePlan(displayFiles);
|
|
55226
55306
|
const lines = [
|
|
55227
55307
|
formatPlan(summary, {
|
|
@@ -55259,6 +55339,7 @@ ${request}`;
|
|
|
55259
55339
|
if (softIssues.hasTrailingWhitespace) lines.push(warnLine("Proposed changes contain trailing whitespace"));
|
|
55260
55340
|
if (softIssues.hasConflictMarkers) lines.push(warnLine("Proposed changes contain conflict markers"));
|
|
55261
55341
|
}
|
|
55342
|
+
const preApplyOutput = withNotices(lines);
|
|
55262
55343
|
let appliedCount = 0;
|
|
55263
55344
|
let durationMs = 0;
|
|
55264
55345
|
let rolledBack = false;
|
|
@@ -55270,7 +55351,7 @@ ${request}`;
|
|
|
55270
55351
|
return { plan: normalized, validated, summaryLines: withNotices([errorLine("working tree not clean (commit or stash first). Re-run after cleaning your git status.")]) };
|
|
55271
55352
|
}
|
|
55272
55353
|
}
|
|
55273
|
-
const allowOverwrite = opts.flags.overwriteAllowed === true || !!opts.flags.yes;
|
|
55354
|
+
const allowOverwrite = opts.flags.overwriteAllowed === true || !!opts.flags.yes || isEditIntent;
|
|
55274
55355
|
const applyRes = await applyPlans(approved, { root: opts.root, overwriteAllowed: allowOverwrite, rollback: opts.flags.rollback !== false, signal: opts.abortSignal, onProgress: (w, t2) => {
|
|
55275
55356
|
}, eol: profile.eol });
|
|
55276
55357
|
appliedCount = applyRes.appliedCount;
|
|
@@ -55300,7 +55381,7 @@ ${request}`;
|
|
|
55300
55381
|
const savedList = [].concat(applyRes.created, applyRes.modified);
|
|
55301
55382
|
const savedAbs = savedList.map((rel) => path11__namespace.default.resolve(opts.root, rel));
|
|
55302
55383
|
const footer = savedAbs.length > 0 ? ["Saved files (full paths):", ...savedAbs.map((p) => `- ${p}`)] : [];
|
|
55303
|
-
return { plan: normalized, validated, applied: { count: appliedCount, durationMs, rolledBack }, summaryLines:
|
|
55384
|
+
return { plan: normalized, validated, applied: { count: appliedCount, durationMs, rolledBack }, summaryLines: [...preApplyOutput, "", msg, ...footer] };
|
|
55304
55385
|
} catch (e2) {
|
|
55305
55386
|
if (e2?.name === "AbortError") {
|
|
55306
55387
|
await journalResume(opts.root, request, validated.files);
|
|
@@ -55521,6 +55602,218 @@ function parseExplicitFilenames(request) {
|
|
|
55521
55602
|
}
|
|
55522
55603
|
return out;
|
|
55523
55604
|
}
|
|
55605
|
+
function detectEditIntent(request, ctx2) {
|
|
55606
|
+
const r2 = request.toLowerCase();
|
|
55607
|
+
const editKeywords = ["modify", "edit", "update", "fix", "refactor", "change", "patch", "\u5DEE\u5206", "\u4FEE\u6B63", "\u5909\u66F4", "\u65E2\u5B58", "\u8FFD\u8A18"];
|
|
55608
|
+
const mentionsEdit = editKeywords.some((k) => r2.includes(k));
|
|
55609
|
+
return ctx2.hasAttachments || ctx2.explicitFilesCount > 0 || mentionsEdit;
|
|
55610
|
+
}
|
|
55611
|
+
function sanitizeFolderName(name2) {
|
|
55612
|
+
const base = name2.toLowerCase().replace(/[`~!@#$%^&*()+=\[\]{}|;:'",<>/?\\]/g, " ").replace(/\s+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
55613
|
+
return base || "project";
|
|
55614
|
+
}
|
|
55615
|
+
function deriveProjectFolderName(request) {
|
|
55616
|
+
const words = request.toLowerCase().replace(/[^a-z0-9\s-]/g, " ").split(/\s+/).filter((w) => w.length > 2).slice(0, 4).join("-");
|
|
55617
|
+
return sanitizeFolderName(words || "project");
|
|
55618
|
+
}
|
|
55619
|
+
function startsWithTopFolder(p, folder) {
|
|
55620
|
+
if (!folder) return false;
|
|
55621
|
+
const seg = p.replace(/^\/+/, "").split("/")[0];
|
|
55622
|
+
return seg.toLowerCase() === folder.toLowerCase();
|
|
55623
|
+
}
|
|
55624
|
+
function prefixWithTopFolder(p, folder) {
|
|
55625
|
+
const rel = p.replace(/^\/+/, "");
|
|
55626
|
+
return `${folder}/${rel}`;
|
|
55627
|
+
}
|
|
55628
|
+
async function ensureTopFolder(root, proposed, plans) {
|
|
55629
|
+
const tops = /* @__PURE__ */ new Set();
|
|
55630
|
+
for (const p of plans) {
|
|
55631
|
+
const seg = p.path.replace(/^\/+/, "").split("/")[0] || "";
|
|
55632
|
+
if (seg) tops.add(seg);
|
|
55633
|
+
}
|
|
55634
|
+
if (tops.size === 1) {
|
|
55635
|
+
const only = Array.from(tops)[0];
|
|
55636
|
+
const unique2 = await ensureUniqueFolder(root, only);
|
|
55637
|
+
return { folderName: unique2, detectedTop: only };
|
|
55638
|
+
}
|
|
55639
|
+
const unique = await ensureUniqueFolder(root, proposed);
|
|
55640
|
+
return { folderName: unique };
|
|
55641
|
+
}
|
|
55642
|
+
async function ensureUniqueFolder(root, base) {
|
|
55643
|
+
const fs49 = await import('fs/promises');
|
|
55644
|
+
const pathMod = await import('path');
|
|
55645
|
+
let name2 = sanitizeFolderName(base);
|
|
55646
|
+
let suffix = 0;
|
|
55647
|
+
for (; suffix < Number.MAX_SAFE_INTEGER; ) {
|
|
55648
|
+
const candidate = suffix === 0 ? name2 : `${name2}-${String(suffix).padStart(2, "0")}`;
|
|
55649
|
+
try {
|
|
55650
|
+
await fs49.access(pathMod.join(root, candidate));
|
|
55651
|
+
suffix += 1;
|
|
55652
|
+
} catch {
|
|
55653
|
+
return candidate;
|
|
55654
|
+
}
|
|
55655
|
+
}
|
|
55656
|
+
throw new Error("ensureUniqueFolder: exhausted attempts to find a unique folder name");
|
|
55657
|
+
}
|
|
55658
|
+
async function buildEditContext(root, files, maxLines, maxBytes) {
|
|
55659
|
+
try {
|
|
55660
|
+
const fs49 = await import('fs/promises');
|
|
55661
|
+
const pathMod = await import('path');
|
|
55662
|
+
const sections = [];
|
|
55663
|
+
for (const rel of files) {
|
|
55664
|
+
const full = pathMod.join(root, rel);
|
|
55665
|
+
try {
|
|
55666
|
+
const buf = await fs49.readFile(full);
|
|
55667
|
+
const clipped = buf.length > maxBytes ? buf.subarray(0, maxBytes) : buf;
|
|
55668
|
+
const text = clipped.toString("utf8").replace(/\r\n/g, "\n");
|
|
55669
|
+
const lines = text.split("\n").slice(0, maxLines).join("\n");
|
|
55670
|
+
sections.push(`[BEGIN file: ${rel}]
|
|
55671
|
+
${lines}
|
|
55672
|
+
[END]`);
|
|
55673
|
+
} catch {
|
|
55674
|
+
}
|
|
55675
|
+
}
|
|
55676
|
+
if (sections.length === 0) return "";
|
|
55677
|
+
return ["// Current repository files (read-only context):", ...sections].join("\n");
|
|
55678
|
+
} catch {
|
|
55679
|
+
return "";
|
|
55680
|
+
}
|
|
55681
|
+
}
|
|
55682
|
+
async function resolveExplicitPaths(root, files, hintText) {
|
|
55683
|
+
const fs49 = await import('fs/promises');
|
|
55684
|
+
const pathMod = await import('path');
|
|
55685
|
+
const { loadGlobby: loadGlobby2 } = await Promise.resolve().then(() => (init_esm_compat(), esm_compat_exports));
|
|
55686
|
+
const globby = await loadGlobby2();
|
|
55687
|
+
const ignore = [
|
|
55688
|
+
"**/node_modules/**",
|
|
55689
|
+
"**/.git/**",
|
|
55690
|
+
"**/dist/**",
|
|
55691
|
+
"**/build/**",
|
|
55692
|
+
"**/.maria/**",
|
|
55693
|
+
"**/.next/**",
|
|
55694
|
+
"**/coverage/**"
|
|
55695
|
+
];
|
|
55696
|
+
const hintTokens = Array.from(new Set(hintText.toLowerCase().replace(/[^a-z0-9_/.-]+/g, " ").split(/\s+/).filter(Boolean)));
|
|
55697
|
+
async function findBest(rel) {
|
|
55698
|
+
const normalized = rel.replace(/^\/+/, "").replace(/\\/g, "/");
|
|
55699
|
+
const fullExact = pathMod.join(root, normalized);
|
|
55700
|
+
try {
|
|
55701
|
+
await fs49.access(fullExact);
|
|
55702
|
+
return normalized;
|
|
55703
|
+
} catch {
|
|
55704
|
+
}
|
|
55705
|
+
const lowerRel = normalized.toLowerCase();
|
|
55706
|
+
const ext2 = (pathMod.extname(normalized) || "").toLowerCase();
|
|
55707
|
+
const base = pathMod.basename(normalized);
|
|
55708
|
+
const nameNoExt = base.replace(/\.[^.]+$/, "").toLowerCase();
|
|
55709
|
+
const parentPath = pathMod.dirname(normalized);
|
|
55710
|
+
const parent = parentPath.split("/").pop() || "";
|
|
55711
|
+
const dirParts = parentPath === "." ? [] : parentPath.split("/").filter(Boolean).map((s2) => s2.toLowerCase());
|
|
55712
|
+
const patterns = [];
|
|
55713
|
+
patterns.push(`**/${normalized}`);
|
|
55714
|
+
if (parent && parent !== "." && parent !== "/") patterns.push(`**/${parent}/${base}`);
|
|
55715
|
+
if (base) patterns.push(`**/${base}`);
|
|
55716
|
+
patterns.push(`**/*${base}`);
|
|
55717
|
+
if (!ext2) {
|
|
55718
|
+
patterns.push(`**/${nameNoExt}.*`);
|
|
55719
|
+
}
|
|
55720
|
+
const uniqPatterns = Array.from(new Set(patterns));
|
|
55721
|
+
const candidatesSet = /* @__PURE__ */ new Set();
|
|
55722
|
+
for (const pat of uniqPatterns) {
|
|
55723
|
+
const found = await globby(pat, { cwd: root, absolute: false, gitignore: true, ignore });
|
|
55724
|
+
for (const f3 of found) {
|
|
55725
|
+
candidatesSet.add(f3.replace(/\\/g, "/"));
|
|
55726
|
+
}
|
|
55727
|
+
if (candidatesSet.size > 200) break;
|
|
55728
|
+
}
|
|
55729
|
+
let candidates = Array.from(candidatesSet);
|
|
55730
|
+
if (dirParts.length > 0) {
|
|
55731
|
+
const filtered = candidates.filter((relp) => {
|
|
55732
|
+
const segs = relp.toLowerCase().split("/");
|
|
55733
|
+
let pos = -1;
|
|
55734
|
+
for (const part of dirParts) {
|
|
55735
|
+
const next = segs.indexOf(part, pos + 1);
|
|
55736
|
+
if (next === -1) return false;
|
|
55737
|
+
pos = next;
|
|
55738
|
+
}
|
|
55739
|
+
return true;
|
|
55740
|
+
});
|
|
55741
|
+
if (filtered.length > 0) candidates = filtered;
|
|
55742
|
+
}
|
|
55743
|
+
if (candidates.length === 0) {
|
|
55744
|
+
const prefixes = ["", "src/", "app/", "pages/"];
|
|
55745
|
+
for (const pre of prefixes) {
|
|
55746
|
+
const cand = pathMod.join(root, pre + normalized);
|
|
55747
|
+
try {
|
|
55748
|
+
await fs49.access(cand);
|
|
55749
|
+
return (pre + normalized).replace(/^\/+/, "");
|
|
55750
|
+
} catch {
|
|
55751
|
+
}
|
|
55752
|
+
}
|
|
55753
|
+
if (dirParts.length > 0) {
|
|
55754
|
+
if (/^(src|app|pages)\//i.test(normalized)) return normalized;
|
|
55755
|
+
const pref = await pickExistingFolderPrefix(root, parentPath);
|
|
55756
|
+
const combined = (pref + normalized).replace(/^\/+/, "").replace(/^(src\/)src\//i, "$1");
|
|
55757
|
+
return combined;
|
|
55758
|
+
}
|
|
55759
|
+
return normalized.replace(/^(src\/)src\//i, "$1");
|
|
55760
|
+
}
|
|
55761
|
+
function score(relPath) {
|
|
55762
|
+
const lower2 = relPath.toLowerCase();
|
|
55763
|
+
let s2 = 0;
|
|
55764
|
+
if (lower2.endsWith(lowerRel)) s2 += 80;
|
|
55765
|
+
if (lower2.split("/").pop() === base.toLowerCase()) s2 += 40;
|
|
55766
|
+
if (ext2 && lower2.endsWith(ext2)) s2 += 10;
|
|
55767
|
+
if (lower2.startsWith("src/")) s2 += 18;
|
|
55768
|
+
if (parent && lower2.includes(`/${parent.toLowerCase()}/`)) s2 += 15;
|
|
55769
|
+
if (parentPath && lower2.endsWith(`/${parentPath.toLowerCase()}/${base.toLowerCase()}`)) s2 += 40;
|
|
55770
|
+
if (dirParts.length > 0) {
|
|
55771
|
+
for (const part of dirParts) {
|
|
55772
|
+
if (lower2.includes(`/${part}/`)) s2 += 20;
|
|
55773
|
+
else s2 -= 120;
|
|
55774
|
+
}
|
|
55775
|
+
}
|
|
55776
|
+
for (const t2 of hintTokens) {
|
|
55777
|
+
if (t2.length >= 3 && lower2.includes(`/${t2}/`)) {
|
|
55778
|
+
s2 += 2;
|
|
55779
|
+
}
|
|
55780
|
+
}
|
|
55781
|
+
s2 -= Math.min(10, Math.floor(relPath.length / 80));
|
|
55782
|
+
return s2;
|
|
55783
|
+
}
|
|
55784
|
+
let best = candidates[0];
|
|
55785
|
+
let bestScore = score(best);
|
|
55786
|
+
for (let i2 = 1; i2 < candidates.length; i2++) {
|
|
55787
|
+
const c = candidates[i2];
|
|
55788
|
+
const sc = score(c);
|
|
55789
|
+
if (sc > bestScore) {
|
|
55790
|
+
best = c;
|
|
55791
|
+
bestScore = sc;
|
|
55792
|
+
}
|
|
55793
|
+
}
|
|
55794
|
+
return best.replace(/^\/+/, "");
|
|
55795
|
+
}
|
|
55796
|
+
const out = [];
|
|
55797
|
+
for (const f3 of files) {
|
|
55798
|
+
out.push(await findBest(f3));
|
|
55799
|
+
}
|
|
55800
|
+
return out;
|
|
55801
|
+
}
|
|
55802
|
+
async function pickExistingFolderPrefix(root, parentPath) {
|
|
55803
|
+
const fs49 = await import('fs/promises');
|
|
55804
|
+
const pathMod = await import('path');
|
|
55805
|
+
const parts = parentPath.replace(/^\/+/, "").split("/").filter(Boolean);
|
|
55806
|
+
const prefixes = ["src", "app", "pages", ""];
|
|
55807
|
+
for (const pre of prefixes) {
|
|
55808
|
+
const test = pre ? pathMod.join(root, pre, ...parts) : pathMod.join(root, ...parts);
|
|
55809
|
+
try {
|
|
55810
|
+
await fs49.access(test);
|
|
55811
|
+
return pre ? `${pre}/` : "";
|
|
55812
|
+
} catch {
|
|
55813
|
+
}
|
|
55814
|
+
}
|
|
55815
|
+
return "src/";
|
|
55816
|
+
}
|
|
55524
55817
|
function scaffoldForFilename(filename, all) {
|
|
55525
55818
|
const lower2 = filename.toLowerCase();
|
|
55526
55819
|
if (lower2.endsWith(".html")) {
|
|
@@ -56495,16 +56788,6 @@ var init_resume_command = __esm({
|
|
|
56495
56788
|
}
|
|
56496
56789
|
});
|
|
56497
56790
|
|
|
56498
|
-
// src/utils/esm-compat.ts
|
|
56499
|
-
async function loadGlobby() {
|
|
56500
|
-
const mod = await import('globby');
|
|
56501
|
-
return mod?.globby ?? mod?.default ?? mod;
|
|
56502
|
-
}
|
|
56503
|
-
var init_esm_compat = __esm({
|
|
56504
|
-
"src/utils/esm-compat.ts"() {
|
|
56505
|
-
}
|
|
56506
|
-
});
|
|
56507
|
-
|
|
56508
56791
|
// src/services/init/scanner.ts
|
|
56509
56792
|
var scanner_exports = {};
|
|
56510
56793
|
__export(scanner_exports, {
|