@bonginkan/maria 4.3.38 → 4.3.39
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 +11 -3
- package/dist/bin/maria.cjs +1007 -364
- package/dist/bin/maria.cjs.map +1 -1
- package/dist/cli.cjs +1004 -361
- 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 +11 -3
package/dist/bin/maria.cjs
CHANGED
|
@@ -235,13 +235,13 @@ function getPackageJson() {
|
|
|
235
235
|
)
|
|
236
236
|
];
|
|
237
237
|
let packageJsonPath = null;
|
|
238
|
-
for (const
|
|
239
|
-
if (fs21.existsSync(
|
|
238
|
+
for (const path65 of possiblePaths) {
|
|
239
|
+
if (fs21.existsSync(path65)) {
|
|
240
240
|
try {
|
|
241
|
-
const content = fs21.readFileSync(
|
|
241
|
+
const content = fs21.readFileSync(path65, "utf-8");
|
|
242
242
|
const parsed = JSON.parse(content);
|
|
243
243
|
if (parsed.name === "@bonginkan/maria") {
|
|
244
|
-
packageJsonPath =
|
|
244
|
+
packageJsonPath = path65;
|
|
245
245
|
break;
|
|
246
246
|
}
|
|
247
247
|
} catch {
|
|
@@ -5314,22 +5314,22 @@ var init_from = __esm({
|
|
|
5314
5314
|
init_file();
|
|
5315
5315
|
init_fetch_blob();
|
|
5316
5316
|
({ stat } = fs21.promises);
|
|
5317
|
-
blobFromSync = (
|
|
5318
|
-
blobFrom = (
|
|
5319
|
-
fileFrom = (
|
|
5320
|
-
fileFromSync = (
|
|
5321
|
-
fromBlob = (stat13,
|
|
5322
|
-
path:
|
|
5317
|
+
blobFromSync = (path65, type) => fromBlob(fs21.statSync(path65), path65, type);
|
|
5318
|
+
blobFrom = (path65, type) => stat(path65).then((stat13) => fromBlob(stat13, path65, type));
|
|
5319
|
+
fileFrom = (path65, type) => stat(path65).then((stat13) => fromFile(stat13, path65, type));
|
|
5320
|
+
fileFromSync = (path65, type) => fromFile(fs21.statSync(path65), path65, type);
|
|
5321
|
+
fromBlob = (stat13, path65, type = "") => new fetch_blob_default([new BlobDataItem({
|
|
5322
|
+
path: path65,
|
|
5323
5323
|
size: stat13.size,
|
|
5324
5324
|
lastModified: stat13.mtimeMs,
|
|
5325
5325
|
start: 0
|
|
5326
5326
|
})], { type });
|
|
5327
|
-
fromFile = (stat13,
|
|
5328
|
-
path:
|
|
5327
|
+
fromFile = (stat13, path65, type = "") => new file_default([new BlobDataItem({
|
|
5328
|
+
path: path65,
|
|
5329
5329
|
size: stat13.size,
|
|
5330
5330
|
lastModified: stat13.mtimeMs,
|
|
5331
5331
|
start: 0
|
|
5332
|
-
})], path11.basename(
|
|
5332
|
+
})], path11.basename(path65), { type, lastModified: stat13.mtimeMs });
|
|
5333
5333
|
BlobDataItem = class _BlobDataItem {
|
|
5334
5334
|
#path;
|
|
5335
5335
|
#start;
|
|
@@ -9563,12 +9563,12 @@ ${this.toYamlLike(value, indent + 1)}`;
|
|
|
9563
9563
|
}
|
|
9564
9564
|
static async loadFromFile(configPath) {
|
|
9565
9565
|
const { importNodeBuiltin: importNodeBuiltin2 } = await Promise.resolve().then(() => (init_import_helper(), import_helper_exports));
|
|
9566
|
-
const
|
|
9566
|
+
const fs52 = await importNodeBuiltin2("fs");
|
|
9567
9567
|
const _path = await importNodeBuiltin2("_path");
|
|
9568
9568
|
const os23 = await importNodeBuiltin2("os");
|
|
9569
9569
|
const targetPath = configPath || _path.join(os23.homedir(), ".maria", "config.json");
|
|
9570
9570
|
try {
|
|
9571
|
-
const data = await
|
|
9571
|
+
const data = await fs52.promises.readFile(targetPath, "utf-8");
|
|
9572
9572
|
return JSON.parse(data);
|
|
9573
9573
|
} catch (innerError) {
|
|
9574
9574
|
if (innerError?.code === "ENOENT") {
|
|
@@ -9582,25 +9582,25 @@ ${this.toYamlLike(value, indent + 1)}`;
|
|
|
9582
9582
|
}
|
|
9583
9583
|
async save(configPath, options) {
|
|
9584
9584
|
const { importNodeBuiltin: importNodeBuiltin2 } = await Promise.resolve().then(() => (init_import_helper(), import_helper_exports));
|
|
9585
|
-
const
|
|
9585
|
+
const fs52 = await importNodeBuiltin2("fs");
|
|
9586
9586
|
const _path = await importNodeBuiltin2("_path");
|
|
9587
9587
|
const os23 = await importNodeBuiltin2("os");
|
|
9588
9588
|
const targetPath = configPath || _path.join(os23.homedir(), ".maria", "config.json");
|
|
9589
9589
|
try {
|
|
9590
9590
|
if (options?.backup) {
|
|
9591
9591
|
try {
|
|
9592
|
-
await
|
|
9592
|
+
await fs52.promises.access(targetPath);
|
|
9593
9593
|
const backupPath = `${targetPath}.backup.${Date.now()}`;
|
|
9594
|
-
await
|
|
9594
|
+
await fs52.promises.copyFile(targetPath, backupPath);
|
|
9595
9595
|
} catch {
|
|
9596
9596
|
}
|
|
9597
9597
|
}
|
|
9598
|
-
await
|
|
9598
|
+
await fs52.promises.mkdir(_path.dirname(targetPath), { recursive: true });
|
|
9599
9599
|
const dataToSave = this.getAll({
|
|
9600
9600
|
maskSensitive: options?.maskSensitive ?? true,
|
|
9601
9601
|
includeSourceMap: options?.includeSourceMap ?? false
|
|
9602
9602
|
});
|
|
9603
|
-
await
|
|
9603
|
+
await fs52.promises.writeFile(
|
|
9604
9604
|
targetPath,
|
|
9605
9605
|
JSON.stringify(dataToSave, null, 2),
|
|
9606
9606
|
{ mode: 384 }
|
|
@@ -9644,12 +9644,12 @@ ${this.toYamlLike(value, indent + 1)}`;
|
|
|
9644
9644
|
}
|
|
9645
9645
|
if (outputPath) {
|
|
9646
9646
|
const { importNodeBuiltin: importNodeBuiltin2 } = await Promise.resolve().then(() => (init_import_helper(), import_helper_exports));
|
|
9647
|
-
const
|
|
9647
|
+
const fs52 = await importNodeBuiltin2("fs");
|
|
9648
9648
|
const _path = await importNodeBuiltin2(
|
|
9649
9649
|
"_path"
|
|
9650
9650
|
);
|
|
9651
|
-
await
|
|
9652
|
-
await
|
|
9651
|
+
await fs52.promises.mkdir(_path.dirname(outputPath), { recursive: true });
|
|
9652
|
+
await fs52.promises.writeFile(outputPath, content, "utf-8");
|
|
9653
9653
|
console.log(`\u2705 Configuration exported to ${outputPath}`);
|
|
9654
9654
|
}
|
|
9655
9655
|
return content;
|
|
@@ -9958,13 +9958,13 @@ async function loadEnvironmentConfig() {
|
|
|
9958
9958
|
}
|
|
9959
9959
|
try {
|
|
9960
9960
|
const { importNodeBuiltin: importNodeBuiltin2, safeDynamicImport: safeDynamicImport2 } = await Promise.resolve().then(() => (init_import_helper(), import_helper_exports));
|
|
9961
|
-
const
|
|
9961
|
+
const fs52 = await safeDynamicImport2("fs-extra").catch(
|
|
9962
9962
|
() => importNodeBuiltin2("fs")
|
|
9963
9963
|
);
|
|
9964
9964
|
const _path = await importNodeBuiltin2("_path");
|
|
9965
9965
|
const _envPath = _path.join(process.cwd(), ".env.local");
|
|
9966
|
-
if (await
|
|
9967
|
-
const _envContent = await
|
|
9966
|
+
if (await fs52.pathExists(_envPath)) {
|
|
9967
|
+
const _envContent = await fs52.readFile(_envPath, "utf-8");
|
|
9968
9968
|
console.log("Loading environment from:", _envPath);
|
|
9969
9969
|
environmentLoaded = true;
|
|
9970
9970
|
const _lines = _envContent.split("\n");
|
|
@@ -19536,8 +19536,8 @@ var init_ConfigService = __esm({
|
|
|
19536
19536
|
/**
|
|
19537
19537
|
* ネストされた設定値の取得
|
|
19538
19538
|
*/
|
|
19539
|
-
getNestedValue(
|
|
19540
|
-
const keys =
|
|
19539
|
+
getNestedValue(path65) {
|
|
19540
|
+
const keys = path65.split(".");
|
|
19541
19541
|
let value = this._config;
|
|
19542
19542
|
for (const key of keys) {
|
|
19543
19543
|
if (value && typeof value === "object" && key in value) {
|
|
@@ -19567,8 +19567,8 @@ var init_ConfigService = __esm({
|
|
|
19567
19567
|
/**
|
|
19568
19568
|
* ネストされた設定値の更新
|
|
19569
19569
|
*/
|
|
19570
|
-
async setNestedValue(
|
|
19571
|
-
const keys =
|
|
19570
|
+
async setNestedValue(path65, value) {
|
|
19571
|
+
const keys = path65.split(".");
|
|
19572
19572
|
const lastKey = keys.pop();
|
|
19573
19573
|
let target = this._config;
|
|
19574
19574
|
for (const key of keys) {
|
|
@@ -19581,7 +19581,7 @@ var init_ConfigService = __esm({
|
|
|
19581
19581
|
target[lastKey] = value;
|
|
19582
19582
|
this.validateConfig();
|
|
19583
19583
|
this.emitChange({
|
|
19584
|
-
path:
|
|
19584
|
+
path: path65,
|
|
19585
19585
|
oldValue,
|
|
19586
19586
|
newValue: value,
|
|
19587
19587
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -19626,8 +19626,8 @@ var init_ConfigService = __esm({
|
|
|
19626
19626
|
setupAutoSave() {
|
|
19627
19627
|
process.on("exit", () => {
|
|
19628
19628
|
if (this._isDirty) {
|
|
19629
|
-
const
|
|
19630
|
-
|
|
19629
|
+
const fs52 = __require("fs");
|
|
19630
|
+
fs52.writeFileSync(
|
|
19631
19631
|
this._userConfigPath,
|
|
19632
19632
|
JSON.stringify(this._config, null, 2),
|
|
19633
19633
|
"utf-8"
|
|
@@ -19638,13 +19638,13 @@ var init_ConfigService = __esm({
|
|
|
19638
19638
|
/**
|
|
19639
19639
|
* 変更リスナーの登録
|
|
19640
19640
|
*/
|
|
19641
|
-
onChange(
|
|
19642
|
-
if (!this._listeners.has(
|
|
19643
|
-
this._listeners.set(
|
|
19641
|
+
onChange(path65, listener) {
|
|
19642
|
+
if (!this._listeners.has(path65)) {
|
|
19643
|
+
this._listeners.set(path65, []);
|
|
19644
19644
|
}
|
|
19645
|
-
this._listeners.get(
|
|
19645
|
+
this._listeners.get(path65).push(listener);
|
|
19646
19646
|
return () => {
|
|
19647
|
-
const listeners = this._listeners.get(
|
|
19647
|
+
const listeners = this._listeners.get(path65);
|
|
19648
19648
|
if (listeners) {
|
|
19649
19649
|
const index = listeners.indexOf(listener);
|
|
19650
19650
|
if (index !== -1) {
|
|
@@ -20133,7 +20133,7 @@ var init_ValidationService = __esm({
|
|
|
20133
20133
|
);
|
|
20134
20134
|
this._schemas.set(
|
|
20135
20135
|
"filePath",
|
|
20136
|
-
zod.z.string().min(1).max(this._config.maxFilePathLength).refine((
|
|
20136
|
+
zod.z.string().min(1).max(this._config.maxFilePathLength).refine((path65) => !this.containsPathTraversal(path65), {
|
|
20137
20137
|
message: "Path traversal detected"
|
|
20138
20138
|
})
|
|
20139
20139
|
);
|
|
@@ -20272,11 +20272,11 @@ var init_ValidationService = __esm({
|
|
|
20272
20272
|
/**
|
|
20273
20273
|
* ファイルパス検証
|
|
20274
20274
|
*/
|
|
20275
|
-
validateFilePath(
|
|
20275
|
+
validateFilePath(path65) {
|
|
20276
20276
|
try {
|
|
20277
20277
|
const schema = this._schemas.get("filePath");
|
|
20278
|
-
const result = schema.parse(
|
|
20279
|
-
if (this.isSystemPath(
|
|
20278
|
+
const result = schema.parse(path65);
|
|
20279
|
+
if (this.isSystemPath(path65)) {
|
|
20280
20280
|
return {
|
|
20281
20281
|
valid: false,
|
|
20282
20282
|
errors: [
|
|
@@ -20422,8 +20422,8 @@ var init_ValidationService = __esm({
|
|
|
20422
20422
|
/**
|
|
20423
20423
|
* パストラバーサルの検出
|
|
20424
20424
|
*/
|
|
20425
|
-
containsPathTraversal(
|
|
20426
|
-
return /\.\.[/\\]/.test(
|
|
20425
|
+
containsPathTraversal(path65) {
|
|
20426
|
+
return /\.\.[/\\]/.test(path65) || path65.includes("..\\") || path65.includes("../");
|
|
20427
20427
|
}
|
|
20428
20428
|
/**
|
|
20429
20429
|
* 危険なコマンドの判定
|
|
@@ -20450,7 +20450,7 @@ var init_ValidationService = __esm({
|
|
|
20450
20450
|
/**
|
|
20451
20451
|
* システムパスの判定
|
|
20452
20452
|
*/
|
|
20453
|
-
isSystemPath(
|
|
20453
|
+
isSystemPath(path65) {
|
|
20454
20454
|
const systemPaths = [
|
|
20455
20455
|
"/etc",
|
|
20456
20456
|
"/sys",
|
|
@@ -20464,7 +20464,7 @@ var init_ValidationService = __esm({
|
|
|
20464
20464
|
"/sbin"
|
|
20465
20465
|
];
|
|
20466
20466
|
return systemPaths.some(
|
|
20467
|
-
(sysPath) =>
|
|
20467
|
+
(sysPath) => path65.toLowerCase().startsWith(sysPath.toLowerCase())
|
|
20468
20468
|
);
|
|
20469
20469
|
}
|
|
20470
20470
|
/**
|
|
@@ -25440,10 +25440,10 @@ Run /doctor --fix to automatically fix ${fixableCount} issue(s)`
|
|
|
25440
25440
|
const finalize = async (text, data) => {
|
|
25441
25441
|
if (outputPath) {
|
|
25442
25442
|
try {
|
|
25443
|
-
const
|
|
25444
|
-
const
|
|
25445
|
-
const abs =
|
|
25446
|
-
await
|
|
25443
|
+
const fs52 = await import('fs/promises');
|
|
25444
|
+
const path65 = await import('path');
|
|
25445
|
+
const abs = path65.resolve(outputPath);
|
|
25446
|
+
await fs52.writeFile(abs, text, "utf-8");
|
|
25447
25447
|
const msg = `Saved doctor report to ${abs}`;
|
|
25448
25448
|
return { ok: true, message: msg, data: { path: abs, bytes: Buffer.byteLength(text, "utf-8") } };
|
|
25449
25449
|
} catch (e2) {
|
|
@@ -25533,10 +25533,10 @@ Run /doctor --fix to automatically fix ${fixableCount} issue(s)`
|
|
|
25533
25533
|
const finalize = async (text, data) => {
|
|
25534
25534
|
if (outputPath) {
|
|
25535
25535
|
try {
|
|
25536
|
-
const
|
|
25537
|
-
const
|
|
25538
|
-
const abs =
|
|
25539
|
-
await
|
|
25536
|
+
const fs52 = await import('fs/promises');
|
|
25537
|
+
const path65 = await import('path');
|
|
25538
|
+
const abs = path65.resolve(outputPath);
|
|
25539
|
+
await fs52.writeFile(abs, text, "utf-8");
|
|
25540
25540
|
const msg = `Saved metrics to ${abs}`;
|
|
25541
25541
|
return { ok: true, message: msg, data: { path: abs, bytes: Buffer.byteLength(text, "utf-8") } };
|
|
25542
25542
|
} catch (e2) {
|
|
@@ -25925,15 +25925,15 @@ var init_SessionOrchestrator = __esm({
|
|
|
25925
25925
|
/**
|
|
25926
25926
|
* 設定の取得
|
|
25927
25927
|
*/
|
|
25928
|
-
getConfig(
|
|
25929
|
-
return this._configService?.getNestedValue(
|
|
25928
|
+
getConfig(path65) {
|
|
25929
|
+
return this._configService?.getNestedValue(path65);
|
|
25930
25930
|
}
|
|
25931
25931
|
/**
|
|
25932
25932
|
* 設定の更新
|
|
25933
25933
|
*/
|
|
25934
|
-
async setConfig(
|
|
25934
|
+
async setConfig(path65, value) {
|
|
25935
25935
|
if (this._configService) {
|
|
25936
|
-
await this._configService.setNestedValue(
|
|
25936
|
+
await this._configService.setNestedValue(path65, value);
|
|
25937
25937
|
}
|
|
25938
25938
|
}
|
|
25939
25939
|
/**
|
|
@@ -26051,11 +26051,11 @@ var init_interactive_session = __esm({
|
|
|
26051
26051
|
getStats() {
|
|
26052
26052
|
return this.orchestrator.getSessionStats();
|
|
26053
26053
|
}
|
|
26054
|
-
getConfig(
|
|
26055
|
-
return this.orchestrator.getConfig(
|
|
26054
|
+
getConfig(path65) {
|
|
26055
|
+
return this.orchestrator.getConfig(path65);
|
|
26056
26056
|
}
|
|
26057
|
-
async setConfig(
|
|
26058
|
-
await this.orchestrator.setConfig(
|
|
26057
|
+
async setConfig(path65, value) {
|
|
26058
|
+
await this.orchestrator.setConfig(path65, value);
|
|
26059
26059
|
}
|
|
26060
26060
|
};
|
|
26061
26061
|
}
|
|
@@ -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.39",
|
|
26070
|
+
description: "\u{1F680} MARIA v4.3.39 - 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.39"}`
|
|
28108
28108
|
}
|
|
28109
28109
|
});
|
|
28110
28110
|
if (response.status === 401) {
|
|
@@ -28745,9 +28745,9 @@ function clientThrottle(endpoint) {
|
|
|
28745
28745
|
}
|
|
28746
28746
|
rateLimitMap.set(endpoint, now2);
|
|
28747
28747
|
}
|
|
28748
|
-
async function callApi(
|
|
28748
|
+
async function callApi(path65, init3 = {}) {
|
|
28749
28749
|
const apiBase = process.env.MARIA_API_BASE || "https://api.maria-code.ai";
|
|
28750
|
-
const fullUrl = `${apiBase}${
|
|
28750
|
+
const fullUrl = `${apiBase}${path65}`;
|
|
28751
28751
|
let tokens2 = await authManager.getValidTokens();
|
|
28752
28752
|
if (!tokens2) {
|
|
28753
28753
|
console.log(chalk14__default.default.red(ERR.AUTH_REQUIRED.msg));
|
|
@@ -28758,7 +28758,7 @@ async function callApi(path64, init3 = {}) {
|
|
|
28758
28758
|
"Authorization": `Bearer ${token}`,
|
|
28759
28759
|
"X-Device-Id": getDeviceId(),
|
|
28760
28760
|
"X-Session-Id": getSessionId() || "",
|
|
28761
|
-
"User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.
|
|
28761
|
+
"User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.39"}`,
|
|
28762
28762
|
"Content-Type": init3.headers?.["Content-Type"] || "application/json"
|
|
28763
28763
|
});
|
|
28764
28764
|
const doFetch = async (token) => {
|
|
@@ -28816,8 +28816,8 @@ async function callApi(path64, init3 = {}) {
|
|
|
28816
28816
|
}
|
|
28817
28817
|
return response;
|
|
28818
28818
|
}
|
|
28819
|
-
async function callApiJson(
|
|
28820
|
-
const response = await callApi(
|
|
28819
|
+
async function callApiJson(path65, init3 = {}) {
|
|
28820
|
+
const response = await callApi(path65, init3);
|
|
28821
28821
|
if (!response.ok) {
|
|
28822
28822
|
const error2 = await response.json().catch(() => ({
|
|
28823
28823
|
message: `API error: ${response.status} ${response.statusText}`
|
|
@@ -28826,8 +28826,8 @@ async function callApiJson(path64, init3 = {}) {
|
|
|
28826
28826
|
}
|
|
28827
28827
|
return response.json();
|
|
28828
28828
|
}
|
|
28829
|
-
async function* streamApi(
|
|
28830
|
-
const response = await callApi(
|
|
28829
|
+
async function* streamApi(path65, init3 = {}) {
|
|
28830
|
+
const response = await callApi(path65, {
|
|
28831
28831
|
...init3,
|
|
28832
28832
|
headers: {
|
|
28833
28833
|
...init3.headers,
|
|
@@ -28853,13 +28853,13 @@ async function* streamApi(path64, init3 = {}) {
|
|
|
28853
28853
|
reader.releaseLock();
|
|
28854
28854
|
}
|
|
28855
28855
|
}
|
|
28856
|
-
async function uploadFile(
|
|
28856
|
+
async function uploadFile(path65, file, metadata5 = {}) {
|
|
28857
28857
|
const formData = new FormData();
|
|
28858
28858
|
formData.append("file", new Blob([file]));
|
|
28859
28859
|
Object.entries(metadata5).forEach(([key, value]) => {
|
|
28860
28860
|
formData.append(key, String(value));
|
|
28861
28861
|
});
|
|
28862
|
-
return callApiJson(
|
|
28862
|
+
return callApiJson(path65, {
|
|
28863
28863
|
method: "POST",
|
|
28864
28864
|
body: formData,
|
|
28865
28865
|
headers: {
|
|
@@ -29175,7 +29175,7 @@ async function mapInputToTopLevelCommand(input3) {
|
|
|
29175
29175
|
const system = [
|
|
29176
29176
|
"You are a router for the MARIA CLI.",
|
|
29177
29177
|
"Decide the best command for a single user input.",
|
|
29178
|
-
"Allowed commands: /help, /image, /code, /video, /whoami, /login, /logout, /evaluate, /research, chat.",
|
|
29178
|
+
"Allowed commands: /help, /image, /code, /video, /whoami, /login, /logout, /evaluate, /research, /novel, chat.",
|
|
29179
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
29180
|
'Return JSON only with keys: { "command": string, "args"?: string[], "confidence": number }.',
|
|
29181
29181
|
"Select chat when the input is a general question or conversation rather than a specific slash command.",
|
|
@@ -29203,7 +29203,7 @@ ${input3}`,
|
|
|
29203
29203
|
}
|
|
29204
29204
|
if (!parsed || typeof parsed.command !== "string") return null;
|
|
29205
29205
|
const cmd = parsed.command;
|
|
29206
|
-
if (!["/help", "/image", "/code", "/video", "/whoami", "/login", "/logout", "/evaluate", "/research", "chat"].includes(cmd)) return null;
|
|
29206
|
+
if (!["/help", "/image", "/code", "/video", "/whoami", "/login", "/logout", "/evaluate", "/research", "/novel", "chat"].includes(cmd)) return null;
|
|
29207
29207
|
const out = { command: cmd };
|
|
29208
29208
|
if (Array.isArray(parsed.args)) {
|
|
29209
29209
|
out.args = parsed.args.filter((a) => typeof a === "string" && a.trim()).map((s2) => s2.trim());
|
|
@@ -33819,12 +33819,12 @@ var init_esm4 = __esm({
|
|
|
33819
33819
|
/**
|
|
33820
33820
|
* Get the Path object referenced by the string path, resolved from this Path
|
|
33821
33821
|
*/
|
|
33822
|
-
resolve(
|
|
33823
|
-
if (!
|
|
33822
|
+
resolve(path65) {
|
|
33823
|
+
if (!path65) {
|
|
33824
33824
|
return this;
|
|
33825
33825
|
}
|
|
33826
|
-
const rootPath = this.getRootString(
|
|
33827
|
-
const dir =
|
|
33826
|
+
const rootPath = this.getRootString(path65);
|
|
33827
|
+
const dir = path65.substring(rootPath.length);
|
|
33828
33828
|
const dirParts = dir.split(this.splitSep);
|
|
33829
33829
|
const result = rootPath ? this.getRoot(rootPath).#resolveParts(dirParts) : this.#resolveParts(dirParts);
|
|
33830
33830
|
return result;
|
|
@@ -34576,8 +34576,8 @@ var init_esm4 = __esm({
|
|
|
34576
34576
|
/**
|
|
34577
34577
|
* @internal
|
|
34578
34578
|
*/
|
|
34579
|
-
getRootString(
|
|
34580
|
-
return path11.win32.parse(
|
|
34579
|
+
getRootString(path65) {
|
|
34580
|
+
return path11.win32.parse(path65).root;
|
|
34581
34581
|
}
|
|
34582
34582
|
/**
|
|
34583
34583
|
* @internal
|
|
@@ -34623,8 +34623,8 @@ var init_esm4 = __esm({
|
|
|
34623
34623
|
/**
|
|
34624
34624
|
* @internal
|
|
34625
34625
|
*/
|
|
34626
|
-
getRootString(
|
|
34627
|
-
return
|
|
34626
|
+
getRootString(path65) {
|
|
34627
|
+
return path65.startsWith("/") ? "/" : "";
|
|
34628
34628
|
}
|
|
34629
34629
|
/**
|
|
34630
34630
|
* @internal
|
|
@@ -34673,8 +34673,8 @@ var init_esm4 = __esm({
|
|
|
34673
34673
|
*
|
|
34674
34674
|
* @internal
|
|
34675
34675
|
*/
|
|
34676
|
-
constructor(cwd2 = process.cwd(), pathImpl, sep4, { nocase, childrenCacheSize = 16 * 1024, fs:
|
|
34677
|
-
this.#fs = fsFromOption(
|
|
34676
|
+
constructor(cwd2 = process.cwd(), pathImpl, sep4, { nocase, childrenCacheSize = 16 * 1024, fs: fs52 = defaultFS } = {}) {
|
|
34677
|
+
this.#fs = fsFromOption(fs52);
|
|
34678
34678
|
if (cwd2 instanceof URL || cwd2.startsWith("file://")) {
|
|
34679
34679
|
cwd2 = url.fileURLToPath(cwd2);
|
|
34680
34680
|
}
|
|
@@ -34713,11 +34713,11 @@ var init_esm4 = __esm({
|
|
|
34713
34713
|
/**
|
|
34714
34714
|
* Get the depth of a provided path, string, or the cwd
|
|
34715
34715
|
*/
|
|
34716
|
-
depth(
|
|
34717
|
-
if (typeof
|
|
34718
|
-
|
|
34716
|
+
depth(path65 = this.cwd) {
|
|
34717
|
+
if (typeof path65 === "string") {
|
|
34718
|
+
path65 = this.cwd.resolve(path65);
|
|
34719
34719
|
}
|
|
34720
|
-
return
|
|
34720
|
+
return path65.depth();
|
|
34721
34721
|
}
|
|
34722
34722
|
/**
|
|
34723
34723
|
* Return the cache of child entries. Exposed so subclasses can create
|
|
@@ -35204,9 +35204,9 @@ var init_esm4 = __esm({
|
|
|
35204
35204
|
process11();
|
|
35205
35205
|
return results;
|
|
35206
35206
|
}
|
|
35207
|
-
chdir(
|
|
35207
|
+
chdir(path65 = this.cwd) {
|
|
35208
35208
|
const oldCwd = this.cwd;
|
|
35209
|
-
this.cwd = typeof
|
|
35209
|
+
this.cwd = typeof path65 === "string" ? this.cwd.resolve(path65) : path65;
|
|
35210
35210
|
this.cwd[setAsCwd](oldCwd);
|
|
35211
35211
|
}
|
|
35212
35212
|
};
|
|
@@ -35232,8 +35232,8 @@ var init_esm4 = __esm({
|
|
|
35232
35232
|
/**
|
|
35233
35233
|
* @internal
|
|
35234
35234
|
*/
|
|
35235
|
-
newRoot(
|
|
35236
|
-
return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs:
|
|
35235
|
+
newRoot(fs52) {
|
|
35236
|
+
return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs52 });
|
|
35237
35237
|
}
|
|
35238
35238
|
/**
|
|
35239
35239
|
* Return true if the provided path string is an absolute path
|
|
@@ -35261,8 +35261,8 @@ var init_esm4 = __esm({
|
|
|
35261
35261
|
/**
|
|
35262
35262
|
* @internal
|
|
35263
35263
|
*/
|
|
35264
|
-
newRoot(
|
|
35265
|
-
return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs:
|
|
35264
|
+
newRoot(fs52) {
|
|
35265
|
+
return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs52 });
|
|
35266
35266
|
}
|
|
35267
35267
|
/**
|
|
35268
35268
|
* Return true if the provided path string is an absolute path
|
|
@@ -35581,8 +35581,8 @@ var init_processor = __esm({
|
|
|
35581
35581
|
}
|
|
35582
35582
|
// match, absolute, ifdir
|
|
35583
35583
|
entries() {
|
|
35584
|
-
return [...this.store.entries()].map(([
|
|
35585
|
-
|
|
35584
|
+
return [...this.store.entries()].map(([path65, n]) => [
|
|
35585
|
+
path65,
|
|
35586
35586
|
!!(n & 2),
|
|
35587
35587
|
!!(n & 1)
|
|
35588
35588
|
]);
|
|
@@ -35795,9 +35795,9 @@ var init_walker = __esm({
|
|
|
35795
35795
|
signal;
|
|
35796
35796
|
maxDepth;
|
|
35797
35797
|
includeChildMatches;
|
|
35798
|
-
constructor(patterns,
|
|
35798
|
+
constructor(patterns, path65, opts) {
|
|
35799
35799
|
this.patterns = patterns;
|
|
35800
|
-
this.path =
|
|
35800
|
+
this.path = path65;
|
|
35801
35801
|
this.opts = opts;
|
|
35802
35802
|
this.#sep = !opts.posix && opts.platform === "win32" ? "\\" : "/";
|
|
35803
35803
|
this.includeChildMatches = opts.includeChildMatches !== false;
|
|
@@ -35816,11 +35816,11 @@ var init_walker = __esm({
|
|
|
35816
35816
|
});
|
|
35817
35817
|
}
|
|
35818
35818
|
}
|
|
35819
|
-
#ignored(
|
|
35820
|
-
return this.seen.has(
|
|
35819
|
+
#ignored(path65) {
|
|
35820
|
+
return this.seen.has(path65) || !!this.#ignore?.ignored?.(path65);
|
|
35821
35821
|
}
|
|
35822
|
-
#childrenIgnored(
|
|
35823
|
-
return !!this.#ignore?.childrenIgnored?.(
|
|
35822
|
+
#childrenIgnored(path65) {
|
|
35823
|
+
return !!this.#ignore?.childrenIgnored?.(path65);
|
|
35824
35824
|
}
|
|
35825
35825
|
// backpressure mechanism
|
|
35826
35826
|
pause() {
|
|
@@ -36035,8 +36035,8 @@ var init_walker = __esm({
|
|
|
36035
36035
|
};
|
|
36036
36036
|
GlobWalker = class extends GlobUtil {
|
|
36037
36037
|
matches = /* @__PURE__ */ new Set();
|
|
36038
|
-
constructor(patterns,
|
|
36039
|
-
super(patterns,
|
|
36038
|
+
constructor(patterns, path65, opts) {
|
|
36039
|
+
super(patterns, path65, opts);
|
|
36040
36040
|
}
|
|
36041
36041
|
matchEmit(e2) {
|
|
36042
36042
|
this.matches.add(e2);
|
|
@@ -36073,8 +36073,8 @@ var init_walker = __esm({
|
|
|
36073
36073
|
};
|
|
36074
36074
|
GlobStream = class extends GlobUtil {
|
|
36075
36075
|
results;
|
|
36076
|
-
constructor(patterns,
|
|
36077
|
-
super(patterns,
|
|
36076
|
+
constructor(patterns, path65, opts) {
|
|
36077
|
+
super(patterns, path65, opts);
|
|
36078
36078
|
this.results = new Minipass({
|
|
36079
36079
|
signal: this.signal,
|
|
36080
36080
|
objectMode: true
|
|
@@ -41909,9 +41909,9 @@ var init_SafetyGuard = __esm({
|
|
|
41909
41909
|
}
|
|
41910
41910
|
}
|
|
41911
41911
|
if (action.args.paths && Array.isArray(action.args.paths)) {
|
|
41912
|
-
for (const
|
|
41913
|
-
if (!this.validatePath(
|
|
41914
|
-
violations.push(`Invalid path: ${
|
|
41912
|
+
for (const path65 of action.args.paths) {
|
|
41913
|
+
if (!this.validatePath(path65)) {
|
|
41914
|
+
violations.push(`Invalid path: ${path65}`);
|
|
41915
41915
|
}
|
|
41916
41916
|
}
|
|
41917
41917
|
}
|
|
@@ -41967,15 +41967,15 @@ var init_SafetyGuard = __esm({
|
|
|
41967
41967
|
* Validate file path against allowed/blocked lists
|
|
41968
41968
|
*/
|
|
41969
41969
|
validatePath(filePath) {
|
|
41970
|
-
const
|
|
41971
|
-
const resolvedPath =
|
|
41970
|
+
const path65 = __require("path");
|
|
41971
|
+
const resolvedPath = path65.resolve(filePath);
|
|
41972
41972
|
for (const blockedPath of this.constraints.blockedPaths) {
|
|
41973
|
-
if (resolvedPath.startsWith(
|
|
41973
|
+
if (resolvedPath.startsWith(path65.resolve(blockedPath))) {
|
|
41974
41974
|
return false;
|
|
41975
41975
|
}
|
|
41976
41976
|
}
|
|
41977
41977
|
for (const allowedPath of this.constraints.allowedPaths) {
|
|
41978
|
-
if (resolvedPath.startsWith(
|
|
41978
|
+
if (resolvedPath.startsWith(path65.resolve(allowedPath))) {
|
|
41979
41979
|
return true;
|
|
41980
41980
|
}
|
|
41981
41981
|
}
|
|
@@ -42004,9 +42004,9 @@ var init_SafetyGuard = __esm({
|
|
|
42004
42004
|
violations.push(`Invalid path in ${action.type}: ${action.args.path}`);
|
|
42005
42005
|
}
|
|
42006
42006
|
if (action.args.paths && Array.isArray(action.args.paths)) {
|
|
42007
|
-
for (const
|
|
42008
|
-
if (!this.validatePath(
|
|
42009
|
-
violations.push(`Invalid path in ${action.type}: ${
|
|
42007
|
+
for (const path65 of action.args.paths) {
|
|
42008
|
+
if (!this.validatePath(path65)) {
|
|
42009
|
+
violations.push(`Invalid path in ${action.type}: ${path65}`);
|
|
42010
42010
|
}
|
|
42011
42011
|
}
|
|
42012
42012
|
}
|
|
@@ -42975,8 +42975,8 @@ var init_ConfigActionExecutor = __esm({
|
|
|
42975
42975
|
/**
|
|
42976
42976
|
* Set nested configuration value using dot notation
|
|
42977
42977
|
*/
|
|
42978
|
-
setNestedValue(obj,
|
|
42979
|
-
const keys =
|
|
42978
|
+
setNestedValue(obj, path65, value) {
|
|
42979
|
+
const keys = path65.split(".");
|
|
42980
42980
|
let current = obj;
|
|
42981
42981
|
for (let i2 = 0; i2 < keys.length - 1; i2++) {
|
|
42982
42982
|
const key = keys[i2];
|
|
@@ -51261,7 +51261,7 @@ var init_about_command = __esm({
|
|
|
51261
51261
|
async execute(args2, context2) {
|
|
51262
51262
|
const output3 = [];
|
|
51263
51263
|
output3.push("");
|
|
51264
|
-
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.39"));
|
|
51265
51265
|
output3.push(chalk14__default.default.gray("\u2550".repeat(40)));
|
|
51266
51266
|
output3.push("");
|
|
51267
51267
|
output3.push(chalk14__default.default.white.bold("MARIA - Minimal API, Maximum Power"));
|
|
@@ -54325,88 +54325,6 @@ var init_SystemCommandFactory = __esm({
|
|
|
54325
54325
|
};
|
|
54326
54326
|
}
|
|
54327
54327
|
});
|
|
54328
|
-
function handleRateLimitError(error2) {
|
|
54329
|
-
console.log();
|
|
54330
|
-
console.log(chalk14__default.default.yellow("\u23F1\uFE0F Rate Limit Exceeded"));
|
|
54331
|
-
console.log(chalk14__default.default.gray("\u2501".repeat(50)));
|
|
54332
|
-
const route = error2.route || error2.details?.endpoint || "API";
|
|
54333
|
-
const plan = error2.plan || error2.details?.plan || "Unknown";
|
|
54334
|
-
const limit = error2.limit || (error2.details?.limit ? parseInt(error2.details.limit) : null);
|
|
54335
|
-
const retryAfter = error2.retryAfter || error2.details?.retryAfterSeconds;
|
|
54336
|
-
const resetAt = error2.resetAt || (error2.details?.resetAt ? Date.parse(error2.details.resetAt) : null);
|
|
54337
|
-
const waitTime = Number.isFinite(retryAfter) ? `${retryAfter} second${retryAfter > 1 ? "s" : ""}` : "a few seconds";
|
|
54338
|
-
let resetTime = "";
|
|
54339
|
-
if (resetAt && Number.isFinite(resetAt)) {
|
|
54340
|
-
const resetDate = new Date(resetAt);
|
|
54341
|
-
const now2 = /* @__PURE__ */ new Date();
|
|
54342
|
-
const diffMs = resetDate.getTime() - now2.getTime();
|
|
54343
|
-
if (diffMs > 0 && diffMs < 6e4) {
|
|
54344
|
-
resetTime = `in ${Math.ceil(diffMs / 1e3)} seconds`;
|
|
54345
|
-
} else if (diffMs > 0) {
|
|
54346
|
-
resetTime = `at ${resetDate.toLocaleTimeString()}`;
|
|
54347
|
-
}
|
|
54348
|
-
}
|
|
54349
|
-
console.log(chalk14__default.default.white(`Plan: ${chalk14__default.default.bold(plan)}`));
|
|
54350
|
-
console.log(chalk14__default.default.white(`Endpoint: ${chalk14__default.default.bold(route)}`));
|
|
54351
|
-
if (limit !== null) {
|
|
54352
|
-
console.log(chalk14__default.default.white(`Limit: ${chalk14__default.default.bold(limit)} requests`));
|
|
54353
|
-
}
|
|
54354
|
-
if (error2.remaining !== void 0) {
|
|
54355
|
-
console.log(chalk14__default.default.white(`Remaining: ${chalk14__default.default.bold(error2.remaining)} requests`));
|
|
54356
|
-
}
|
|
54357
|
-
console.log();
|
|
54358
|
-
console.log(chalk14__default.default.cyan(`Please wait ${chalk14__default.default.bold(waitTime)} before trying again`));
|
|
54359
|
-
if (resetTime) {
|
|
54360
|
-
console.log(chalk14__default.default.gray(`Rate limit resets ${resetTime}`));
|
|
54361
|
-
}
|
|
54362
|
-
if (error2.hint) {
|
|
54363
|
-
console.log();
|
|
54364
|
-
console.log(chalk14__default.default.magenta("\u{1F4A1} " + error2.hint));
|
|
54365
|
-
}
|
|
54366
|
-
console.log(chalk14__default.default.gray("\u2501".repeat(50)));
|
|
54367
|
-
console.log();
|
|
54368
|
-
}
|
|
54369
|
-
async function parseRateLimitResponse(response) {
|
|
54370
|
-
if (response.status !== 429) {
|
|
54371
|
-
return null;
|
|
54372
|
-
}
|
|
54373
|
-
const rateLimitInfo = {
|
|
54374
|
-
limit: parseInt(response.headers.get("RateLimit-Limit") || "0") || void 0,
|
|
54375
|
-
remaining: parseInt(response.headers.get("RateLimit-Remaining") || "0") || void 0,
|
|
54376
|
-
resetAt: parseInt(response.headers.get("RateLimit-Reset") || "0") || void 0,
|
|
54377
|
-
retryAfter: parseInt(response.headers.get("Retry-After") || "0") || void 0
|
|
54378
|
-
};
|
|
54379
|
-
try {
|
|
54380
|
-
const data = await response.json();
|
|
54381
|
-
if (data.error === "rate_limited" || data.error === "rate_limit_exceeded") {
|
|
54382
|
-
return {
|
|
54383
|
-
...data,
|
|
54384
|
-
// Merge header info if not in body
|
|
54385
|
-
limit: data.limit || rateLimitInfo.limit,
|
|
54386
|
-
remaining: data.remaining || rateLimitInfo.remaining,
|
|
54387
|
-
resetAt: data.resetAt || rateLimitInfo.resetAt,
|
|
54388
|
-
retryAfter: data.retryAfter || rateLimitInfo.retryAfter
|
|
54389
|
-
};
|
|
54390
|
-
}
|
|
54391
|
-
return {
|
|
54392
|
-
error: "rate_limited",
|
|
54393
|
-
message: data.message || "Rate limit exceeded. Please wait and try again.",
|
|
54394
|
-
hint: data.hint || "Consider upgrading your plan for higher limits.",
|
|
54395
|
-
...rateLimitInfo
|
|
54396
|
-
};
|
|
54397
|
-
} catch {
|
|
54398
|
-
return {
|
|
54399
|
-
error: "rate_limited",
|
|
54400
|
-
message: "Rate limit exceeded. Please wait and try again.",
|
|
54401
|
-
hint: "Consider upgrading your plan for higher limits.",
|
|
54402
|
-
...rateLimitInfo
|
|
54403
|
-
};
|
|
54404
|
-
}
|
|
54405
|
-
}
|
|
54406
|
-
var init_rate_limit_handler = __esm({
|
|
54407
|
-
"src/services/api-client/rate-limit-handler.ts"() {
|
|
54408
|
-
}
|
|
54409
|
-
});
|
|
54410
54328
|
function extractCodeInfo(codeBlock) {
|
|
54411
54329
|
const match2 = codeBlock.match(/```([^\n]*)\n?([\s\S]*?)```/);
|
|
54412
54330
|
if (!match2) {
|
|
@@ -54651,8 +54569,408 @@ var init_code_utils = __esm({
|
|
|
54651
54569
|
}
|
|
54652
54570
|
});
|
|
54653
54571
|
|
|
54654
|
-
// src/services/
|
|
54572
|
+
// src/services/creative/NovelArgumentInference.ts
|
|
54655
54573
|
function extractFirstJson4(text) {
|
|
54574
|
+
if (!text) return null;
|
|
54575
|
+
const start = text.indexOf("{");
|
|
54576
|
+
const end = text.lastIndexOf("}");
|
|
54577
|
+
if (start !== -1 && end !== -1 && end > start) {
|
|
54578
|
+
const cand = text.slice(start, end + 1);
|
|
54579
|
+
try {
|
|
54580
|
+
JSON.parse(cand);
|
|
54581
|
+
return cand;
|
|
54582
|
+
} catch {
|
|
54583
|
+
}
|
|
54584
|
+
}
|
|
54585
|
+
return null;
|
|
54586
|
+
}
|
|
54587
|
+
async function inferNovelArgs(rawText) {
|
|
54588
|
+
const system = [
|
|
54589
|
+
"You extract structured options for a novel generation command.",
|
|
54590
|
+
'Return JSON ONLY with keys among: { "title"?: string, "lang"?: string, "format"?: "md"|"markdown"|"txt"|"plaintext", "genre"?: string, "planOnly"?: boolean, "chapters"?: number }.',
|
|
54591
|
+
'Infer reasonable values from natural language. Keep chapters between 3 and 50 if specified. If format suggests plain text, choose "plaintext".',
|
|
54592
|
+
"If the user requests outline only, set planOnly=true.",
|
|
54593
|
+
"Do not add commentary."
|
|
54594
|
+
].join("\n");
|
|
54595
|
+
const resp = await callAPI("/v1/ai-proxy", {
|
|
54596
|
+
method: "POST",
|
|
54597
|
+
body: {
|
|
54598
|
+
prompt: `${system}
|
|
54599
|
+
|
|
54600
|
+
---
|
|
54601
|
+
|
|
54602
|
+
${rawText}`,
|
|
54603
|
+
taskType: "creative"
|
|
54604
|
+
}
|
|
54605
|
+
});
|
|
54606
|
+
const raw = (resp?.data?.content || resp?.output || "").trim();
|
|
54607
|
+
const jsonText = extractFirstJson4(raw) || raw;
|
|
54608
|
+
let parsed = {};
|
|
54609
|
+
try {
|
|
54610
|
+
parsed = JSON.parse(jsonText);
|
|
54611
|
+
} catch {
|
|
54612
|
+
return {};
|
|
54613
|
+
}
|
|
54614
|
+
const out = {};
|
|
54615
|
+
if (typeof parsed.title === "string" && parsed.title.trim()) out.title = parsed.title.trim();
|
|
54616
|
+
if (typeof parsed.lang === "string" && parsed.lang.trim()) out.lang = parsed.lang.trim().toLowerCase();
|
|
54617
|
+
if (typeof parsed.format === "string") {
|
|
54618
|
+
const f3 = parsed.format.toLowerCase();
|
|
54619
|
+
if (f3 === "md" || f3 === "markdown") out.format = "md";
|
|
54620
|
+
else if (f3 === "txt" || f3 === "plaintext" || f3 === "text") out.format = "txt";
|
|
54621
|
+
}
|
|
54622
|
+
if (typeof parsed.genre === "string" && parsed.genre.trim()) out.genre = parsed.genre.trim();
|
|
54623
|
+
if (typeof parsed.planOnly === "boolean") out.planOnly = parsed.planOnly;
|
|
54624
|
+
if (typeof parsed.chapters === "number" && Number.isFinite(parsed.chapters)) {
|
|
54625
|
+
const n = Math.max(1, Math.min(100, Math.floor(parsed.chapters)));
|
|
54626
|
+
out.chapters = n;
|
|
54627
|
+
}
|
|
54628
|
+
return out;
|
|
54629
|
+
}
|
|
54630
|
+
var init_NovelArgumentInference = __esm({
|
|
54631
|
+
"src/services/creative/NovelArgumentInference.ts"() {
|
|
54632
|
+
init_api_caller();
|
|
54633
|
+
}
|
|
54634
|
+
});
|
|
54635
|
+
|
|
54636
|
+
// src/slash-commands/categories/creative/novel.command.ts
|
|
54637
|
+
var novel_command_exports = {};
|
|
54638
|
+
__export(novel_command_exports, {
|
|
54639
|
+
NovelCommand: () => NovelCommand,
|
|
54640
|
+
default: () => novel_command_default
|
|
54641
|
+
});
|
|
54642
|
+
function normalizeFormat(fmt) {
|
|
54643
|
+
const f3 = (fmt).toLowerCase();
|
|
54644
|
+
if (f3 === "txt" || f3 === "plaintext" || f3 === "text") return "txt";
|
|
54645
|
+
return "md";
|
|
54646
|
+
}
|
|
54647
|
+
function normalizeLang(lang) {
|
|
54648
|
+
const l = (lang).toLowerCase();
|
|
54649
|
+
if (!l) return "en";
|
|
54650
|
+
if (["en", "ja", "jp", "zh", "ko", "fr", "de", "es", "it", "pt"].includes(l)) {
|
|
54651
|
+
return l === "jp" ? "ja" : l;
|
|
54652
|
+
}
|
|
54653
|
+
return "en";
|
|
54654
|
+
}
|
|
54655
|
+
async function writeText(filePath, content) {
|
|
54656
|
+
const dir = path11__namespace.dirname(filePath);
|
|
54657
|
+
await fsp__namespace.mkdir(dir, { recursive: true });
|
|
54658
|
+
await fsp__namespace.writeFile(filePath, content, "utf8");
|
|
54659
|
+
}
|
|
54660
|
+
function extractFirstJsonArray(text) {
|
|
54661
|
+
if (!text) return null;
|
|
54662
|
+
const t2 = text.trim();
|
|
54663
|
+
const fenced = t2.match(/```json\s*([\s\S]*?)```/i) || t2.match(/```\s*([\s\S]*?)```/);
|
|
54664
|
+
if (fenced && fenced[1]) {
|
|
54665
|
+
const body = fenced[1].trim();
|
|
54666
|
+
try {
|
|
54667
|
+
const arr = JSON.parse(body);
|
|
54668
|
+
return Array.isArray(arr) ? arr : null;
|
|
54669
|
+
} catch {
|
|
54670
|
+
}
|
|
54671
|
+
}
|
|
54672
|
+
const defenced = t2.replace(/```json|```/gi, "").trim();
|
|
54673
|
+
try {
|
|
54674
|
+
const arr = JSON.parse(defenced);
|
|
54675
|
+
return Array.isArray(arr) ? arr : null;
|
|
54676
|
+
} catch {
|
|
54677
|
+
}
|
|
54678
|
+
const s2 = t2.indexOf("[");
|
|
54679
|
+
const e2 = t2.lastIndexOf("]");
|
|
54680
|
+
if (s2 !== -1 && e2 !== -1 && e2 > s2) {
|
|
54681
|
+
const slice = t2.slice(s2, e2 + 1);
|
|
54682
|
+
try {
|
|
54683
|
+
const arr = JSON.parse(slice);
|
|
54684
|
+
return Array.isArray(arr) ? arr : null;
|
|
54685
|
+
} catch {
|
|
54686
|
+
}
|
|
54687
|
+
}
|
|
54688
|
+
return null;
|
|
54689
|
+
}
|
|
54690
|
+
async function generatePlan(prompt, lang, title, genre) {
|
|
54691
|
+
const system = [
|
|
54692
|
+
"You generate a detailed novel outline (plot).",
|
|
54693
|
+
"Return Markdown with clear sections: Title, Logline, Themes, Characters, Chapter Outline.",
|
|
54694
|
+
"The language should match the requested language."
|
|
54695
|
+
].join("\n");
|
|
54696
|
+
const user = [
|
|
54697
|
+
`Language: ${lang}`,
|
|
54698
|
+
`Title: ${title}`,
|
|
54699
|
+
genre ? `Genre: ${genre}` : "",
|
|
54700
|
+
"Prompt:",
|
|
54701
|
+
prompt
|
|
54702
|
+
].filter(Boolean).join("\n");
|
|
54703
|
+
const resp = await callAPI("/v1/ai-proxy", { method: "POST", body: { prompt: `${system}
|
|
54704
|
+
|
|
54705
|
+
---
|
|
54706
|
+
|
|
54707
|
+
${user}`, taskType: "creative" } });
|
|
54708
|
+
const out = (resp?.data?.content || resp?.output || "").trim();
|
|
54709
|
+
return out;
|
|
54710
|
+
}
|
|
54711
|
+
async function generateChapters(planMarkdown, lang, chapters) {
|
|
54712
|
+
const system = [
|
|
54713
|
+
"You expand a novel outline into chapter texts.",
|
|
54714
|
+
"Return only JSON array: [{ index: number, title: string, content: string }].",
|
|
54715
|
+
"Write in the requested language and maintain consistency with the outline."
|
|
54716
|
+
].join("\n");
|
|
54717
|
+
const prompt = `${system}
|
|
54718
|
+
|
|
54719
|
+
LANG=${lang}
|
|
54720
|
+
CHAPTERS=${chapters}
|
|
54721
|
+
|
|
54722
|
+
OUTLINE:
|
|
54723
|
+
${planMarkdown}`;
|
|
54724
|
+
const resp = await callAPI("/v1/ai-proxy", { method: "POST", body: { prompt, taskType: "creative" } });
|
|
54725
|
+
const raw = (resp?.data?.content || resp?.output || "").trim();
|
|
54726
|
+
const arr = extractFirstJsonArray(raw);
|
|
54727
|
+
if (Array.isArray(arr)) {
|
|
54728
|
+
return arr.map((it, i2) => ({
|
|
54729
|
+
index: typeof it.index === "number" ? it.index : i2,
|
|
54730
|
+
title: typeof it.title === "string" ? it.title : `Chapter ${i2 + 1}`,
|
|
54731
|
+
content: typeof it.content === "string" ? it.content : ""
|
|
54732
|
+
}));
|
|
54733
|
+
}
|
|
54734
|
+
return [{ index: 0, title: "Chapter 1", content: raw }];
|
|
54735
|
+
}
|
|
54736
|
+
async function generateTitle(idea, lang, genre) {
|
|
54737
|
+
const system = [
|
|
54738
|
+
"You craft a concise, compelling novel title. Return only the title string.",
|
|
54739
|
+
"Consider the idea and genre. Use the requested language."
|
|
54740
|
+
].join("\n");
|
|
54741
|
+
const user = [
|
|
54742
|
+
`Language: ${lang}`,
|
|
54743
|
+
genre ? `Genre: ${genre}` : "",
|
|
54744
|
+
"Idea:",
|
|
54745
|
+
idea
|
|
54746
|
+
].filter(Boolean).join("\n");
|
|
54747
|
+
const resp = await callAPI("/v1/ai-proxy", { method: "POST", body: { prompt: `${system}
|
|
54748
|
+
|
|
54749
|
+
---
|
|
54750
|
+
|
|
54751
|
+
${user}`, taskType: "creative" } });
|
|
54752
|
+
const raw = (resp?.data?.content || resp?.output || "").trim();
|
|
54753
|
+
try {
|
|
54754
|
+
const obj = JSON.parse(raw);
|
|
54755
|
+
if (typeof obj?.title === "string") return obj.title.trim();
|
|
54756
|
+
} catch {
|
|
54757
|
+
}
|
|
54758
|
+
const matched = raw.match(/```[a-z]*\s*([\s\S]*?)```/i);
|
|
54759
|
+
const text = matched ? matched[1].trim() : raw;
|
|
54760
|
+
return text.split("\n")[0].trim();
|
|
54761
|
+
}
|
|
54762
|
+
var NovelCommand, novel_command_default;
|
|
54763
|
+
var init_novel_command = __esm({
|
|
54764
|
+
"src/slash-commands/categories/creative/novel.command.ts"() {
|
|
54765
|
+
init_base_command();
|
|
54766
|
+
init_code_utils();
|
|
54767
|
+
init_api_caller();
|
|
54768
|
+
init_NovelArgumentInference();
|
|
54769
|
+
init_animations();
|
|
54770
|
+
NovelCommand = class extends BaseCommand {
|
|
54771
|
+
name = "novel";
|
|
54772
|
+
category = "creative";
|
|
54773
|
+
description = "Generate a novel: outline plan and full chapters with language/format options";
|
|
54774
|
+
aliases = ["story"];
|
|
54775
|
+
usage = "<idea or title> [--lang <code>] [--format md|txt] [--genre <name>] [--plan-only] [--chapters <n>]";
|
|
54776
|
+
examples = [
|
|
54777
|
+
{ input: "/novel cyberpunk heist in Tokyo --lang ja", description: "\u65E5\u672C\u8A9E\u3067\u30B5\u30A4\u30D0\u30FC\u30D1\u30F3\u30AF\u5C0F\u8AAC\u3092\u751F\u6210" },
|
|
54778
|
+
{ input: '/novel "A voyage to Europa" --format txt --genre sci-fi', description: "\u82F1\u8A9E\u30FB\u30D7\u30EC\u30FC\u30F3\u30C6\u30AD\u30B9\u30C8\u3067\u751F\u6210" },
|
|
54779
|
+
{ input: "/novel detective mystery --plan-only", description: "\u30D7\u30ED\u30C3\u30C8\u306E\u307F\u3092\u4F5C\u6210\u3057\u3066\u4FDD\u5B58" }
|
|
54780
|
+
];
|
|
54781
|
+
async execute(args2, context2) {
|
|
54782
|
+
const raw = Array.isArray(args2.raw) ? args2.raw : [];
|
|
54783
|
+
const ideaText = raw.join(" ").trim();
|
|
54784
|
+
if (!ideaText) {
|
|
54785
|
+
return this.error("Usage: /novel <idea or title> [--lang <code>] [--format md|txt] [--genre <name>] [--plan-only] [--chapters <n>]");
|
|
54786
|
+
}
|
|
54787
|
+
const explicit = {
|
|
54788
|
+
lang: typeof args2.options["lang"] === "string" ? String(args2.options["lang"]) : void 0,
|
|
54789
|
+
format: typeof args2.options["format"] === "string" ? String(args2.options["format"]) : void 0,
|
|
54790
|
+
genre: typeof args2.options["genre"] === "string" ? String(args2.options["genre"]) : void 0,
|
|
54791
|
+
chapters: typeof args2.options["chapters"] === "string" ? Number(args2.options["chapters"]) : void 0,
|
|
54792
|
+
planOnly: args2.flags["plan-only"] === true || args2.flags["sow"] === true
|
|
54793
|
+
};
|
|
54794
|
+
let inferred = {};
|
|
54795
|
+
try {
|
|
54796
|
+
const spin = new ProcessAnimation();
|
|
54797
|
+
spin.start();
|
|
54798
|
+
try {
|
|
54799
|
+
inferred = await inferNovelArgs(ideaText);
|
|
54800
|
+
} finally {
|
|
54801
|
+
try {
|
|
54802
|
+
spin.stop();
|
|
54803
|
+
} catch {
|
|
54804
|
+
}
|
|
54805
|
+
}
|
|
54806
|
+
} catch {
|
|
54807
|
+
}
|
|
54808
|
+
const lang = normalizeLang(explicit.lang || inferred.lang || "en");
|
|
54809
|
+
const format = normalizeFormat(explicit.format || inferred.format || "md");
|
|
54810
|
+
const planOnly = explicit.planOnly || inferred.planOnly === true;
|
|
54811
|
+
const chapters = Number.isFinite(explicit.chapters) && explicit.chapters > 0 ? Math.floor(explicit.chapters) : typeof inferred.chapters === "number" && inferred.chapters > 0 ? Math.floor(inferred.chapters) : 8;
|
|
54812
|
+
const genre = explicit.genre || inferred.genre;
|
|
54813
|
+
let generatedTitle = inferred.title;
|
|
54814
|
+
if (!generatedTitle) {
|
|
54815
|
+
const spin = new ProcessAnimation();
|
|
54816
|
+
spin.start();
|
|
54817
|
+
try {
|
|
54818
|
+
generatedTitle = await generateTitle(ideaText, lang, genre);
|
|
54819
|
+
} finally {
|
|
54820
|
+
try {
|
|
54821
|
+
spin.stop();
|
|
54822
|
+
} catch {
|
|
54823
|
+
}
|
|
54824
|
+
}
|
|
54825
|
+
}
|
|
54826
|
+
const titleRaw = (generatedTitle || "novel").slice(0, 120);
|
|
54827
|
+
const title = sanitizeFilenameStrict(titleRaw);
|
|
54828
|
+
const root = process.cwd();
|
|
54829
|
+
const novelDir = await ensureUniquePath(safeResolve(root, path11__namespace.join("novel", title)));
|
|
54830
|
+
await fsp__namespace.mkdir(novelDir, { recursive: true });
|
|
54831
|
+
let plan = "";
|
|
54832
|
+
{
|
|
54833
|
+
const spin = new ProcessAnimation();
|
|
54834
|
+
spin.start();
|
|
54835
|
+
try {
|
|
54836
|
+
plan = await generatePlan(ideaText, lang, title, genre);
|
|
54837
|
+
} finally {
|
|
54838
|
+
try {
|
|
54839
|
+
spin.stop();
|
|
54840
|
+
} catch {
|
|
54841
|
+
}
|
|
54842
|
+
}
|
|
54843
|
+
}
|
|
54844
|
+
const planExt = format === "txt" ? ".txt" : ".md";
|
|
54845
|
+
const planPath = await ensureUniquePath(path11__namespace.join(novelDir, `00_plan${planExt}`));
|
|
54846
|
+
await writeText(planPath, plan);
|
|
54847
|
+
if (planOnly) {
|
|
54848
|
+
const msg2 = [`Saved plan to ${planPath}`, "", "Files:", `- ${planPath}`].join("\n");
|
|
54849
|
+
return this.success(msg2, { dir: novelDir, plan: planPath });
|
|
54850
|
+
}
|
|
54851
|
+
const chapterObjs = await (async () => {
|
|
54852
|
+
const spin = new ProcessAnimation();
|
|
54853
|
+
spin.start();
|
|
54854
|
+
try {
|
|
54855
|
+
return await generateChapters(plan, lang, chapters);
|
|
54856
|
+
} finally {
|
|
54857
|
+
try {
|
|
54858
|
+
spin.stop();
|
|
54859
|
+
} catch {
|
|
54860
|
+
}
|
|
54861
|
+
}
|
|
54862
|
+
})();
|
|
54863
|
+
let index = 1;
|
|
54864
|
+
const saved = [planPath];
|
|
54865
|
+
for (const ch of chapterObjs) {
|
|
54866
|
+
const num = String(index).padStart(2, "0");
|
|
54867
|
+
const chTitle = sanitizeFilenameStrict(ch.title || `chapter-${index}`);
|
|
54868
|
+
const file = path11__namespace.join(novelDir, `${num}_${chTitle}${planExt}`);
|
|
54869
|
+
const finalPath = await ensureUniquePath(file);
|
|
54870
|
+
const content = format === "md" ? `# ${ch.title}
|
|
54871
|
+
|
|
54872
|
+
${ch.content}` : ch.content;
|
|
54873
|
+
await writeText(finalPath, content);
|
|
54874
|
+
saved.push(finalPath);
|
|
54875
|
+
index++;
|
|
54876
|
+
}
|
|
54877
|
+
const msg = [
|
|
54878
|
+
`Saved novel to ${novelDir}`,
|
|
54879
|
+
"",
|
|
54880
|
+
"Files:",
|
|
54881
|
+
...saved.map((p) => `- ${p}`)
|
|
54882
|
+
].join("\n");
|
|
54883
|
+
return this.success(msg, { dir: novelDir, files: saved });
|
|
54884
|
+
}
|
|
54885
|
+
};
|
|
54886
|
+
novel_command_default = NovelCommand;
|
|
54887
|
+
}
|
|
54888
|
+
});
|
|
54889
|
+
function handleRateLimitError(error2) {
|
|
54890
|
+
console.log();
|
|
54891
|
+
console.log(chalk14__default.default.yellow("\u23F1\uFE0F Rate Limit Exceeded"));
|
|
54892
|
+
console.log(chalk14__default.default.gray("\u2501".repeat(50)));
|
|
54893
|
+
const route = error2.route || error2.details?.endpoint || "API";
|
|
54894
|
+
const plan = error2.plan || error2.details?.plan || "Unknown";
|
|
54895
|
+
const limit = error2.limit || (error2.details?.limit ? parseInt(error2.details.limit) : null);
|
|
54896
|
+
const retryAfter = error2.retryAfter || error2.details?.retryAfterSeconds;
|
|
54897
|
+
const resetAt = error2.resetAt || (error2.details?.resetAt ? Date.parse(error2.details.resetAt) : null);
|
|
54898
|
+
const waitTime = Number.isFinite(retryAfter) ? `${retryAfter} second${retryAfter > 1 ? "s" : ""}` : "a few seconds";
|
|
54899
|
+
let resetTime = "";
|
|
54900
|
+
if (resetAt && Number.isFinite(resetAt)) {
|
|
54901
|
+
const resetDate = new Date(resetAt);
|
|
54902
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
54903
|
+
const diffMs = resetDate.getTime() - now2.getTime();
|
|
54904
|
+
if (diffMs > 0 && diffMs < 6e4) {
|
|
54905
|
+
resetTime = `in ${Math.ceil(diffMs / 1e3)} seconds`;
|
|
54906
|
+
} else if (diffMs > 0) {
|
|
54907
|
+
resetTime = `at ${resetDate.toLocaleTimeString()}`;
|
|
54908
|
+
}
|
|
54909
|
+
}
|
|
54910
|
+
console.log(chalk14__default.default.white(`Plan: ${chalk14__default.default.bold(plan)}`));
|
|
54911
|
+
console.log(chalk14__default.default.white(`Endpoint: ${chalk14__default.default.bold(route)}`));
|
|
54912
|
+
if (limit !== null) {
|
|
54913
|
+
console.log(chalk14__default.default.white(`Limit: ${chalk14__default.default.bold(limit)} requests`));
|
|
54914
|
+
}
|
|
54915
|
+
if (error2.remaining !== void 0) {
|
|
54916
|
+
console.log(chalk14__default.default.white(`Remaining: ${chalk14__default.default.bold(error2.remaining)} requests`));
|
|
54917
|
+
}
|
|
54918
|
+
console.log();
|
|
54919
|
+
console.log(chalk14__default.default.cyan(`Please wait ${chalk14__default.default.bold(waitTime)} before trying again`));
|
|
54920
|
+
if (resetTime) {
|
|
54921
|
+
console.log(chalk14__default.default.gray(`Rate limit resets ${resetTime}`));
|
|
54922
|
+
}
|
|
54923
|
+
if (error2.hint) {
|
|
54924
|
+
console.log();
|
|
54925
|
+
console.log(chalk14__default.default.magenta("\u{1F4A1} " + error2.hint));
|
|
54926
|
+
}
|
|
54927
|
+
console.log(chalk14__default.default.gray("\u2501".repeat(50)));
|
|
54928
|
+
console.log();
|
|
54929
|
+
}
|
|
54930
|
+
async function parseRateLimitResponse(response) {
|
|
54931
|
+
if (response.status !== 429) {
|
|
54932
|
+
return null;
|
|
54933
|
+
}
|
|
54934
|
+
const rateLimitInfo = {
|
|
54935
|
+
limit: parseInt(response.headers.get("RateLimit-Limit") || "0") || void 0,
|
|
54936
|
+
remaining: parseInt(response.headers.get("RateLimit-Remaining") || "0") || void 0,
|
|
54937
|
+
resetAt: parseInt(response.headers.get("RateLimit-Reset") || "0") || void 0,
|
|
54938
|
+
retryAfter: parseInt(response.headers.get("Retry-After") || "0") || void 0
|
|
54939
|
+
};
|
|
54940
|
+
try {
|
|
54941
|
+
const data = await response.json();
|
|
54942
|
+
if (data.error === "rate_limited" || data.error === "rate_limit_exceeded") {
|
|
54943
|
+
return {
|
|
54944
|
+
...data,
|
|
54945
|
+
// Merge header info if not in body
|
|
54946
|
+
limit: data.limit || rateLimitInfo.limit,
|
|
54947
|
+
remaining: data.remaining || rateLimitInfo.remaining,
|
|
54948
|
+
resetAt: data.resetAt || rateLimitInfo.resetAt,
|
|
54949
|
+
retryAfter: data.retryAfter || rateLimitInfo.retryAfter
|
|
54950
|
+
};
|
|
54951
|
+
}
|
|
54952
|
+
return {
|
|
54953
|
+
error: "rate_limited",
|
|
54954
|
+
message: data.message || "Rate limit exceeded. Please wait and try again.",
|
|
54955
|
+
hint: data.hint || "Consider upgrading your plan for higher limits.",
|
|
54956
|
+
...rateLimitInfo
|
|
54957
|
+
};
|
|
54958
|
+
} catch {
|
|
54959
|
+
return {
|
|
54960
|
+
error: "rate_limited",
|
|
54961
|
+
message: "Rate limit exceeded. Please wait and try again.",
|
|
54962
|
+
hint: "Consider upgrading your plan for higher limits.",
|
|
54963
|
+
...rateLimitInfo
|
|
54964
|
+
};
|
|
54965
|
+
}
|
|
54966
|
+
}
|
|
54967
|
+
var init_rate_limit_handler = __esm({
|
|
54968
|
+
"src/services/api-client/rate-limit-handler.ts"() {
|
|
54969
|
+
}
|
|
54970
|
+
});
|
|
54971
|
+
|
|
54972
|
+
// src/services/code-orchestrator/ArgumentInference.ts
|
|
54973
|
+
function extractFirstJson5(text) {
|
|
54656
54974
|
const fence = /```json\r?\n([\s\S]*?)```/i.exec(text);
|
|
54657
54975
|
if (fence) return fence[1];
|
|
54658
54976
|
const start = text.indexOf("{");
|
|
@@ -54686,7 +55004,7 @@ ${rawText}`,
|
|
|
54686
55004
|
}
|
|
54687
55005
|
});
|
|
54688
55006
|
const raw = (resp?.data?.content || resp?.output || "").trim();
|
|
54689
|
-
const jsonText =
|
|
55007
|
+
const jsonText = extractFirstJson5(raw) || raw;
|
|
54690
55008
|
let parsed = {};
|
|
54691
55009
|
try {
|
|
54692
55010
|
parsed = JSON.parse(jsonText);
|
|
@@ -54798,10 +55116,10 @@ function suggestName(fp, p) {
|
|
|
54798
55116
|
const base = (fp.description || "file").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
54799
55117
|
return base || "file";
|
|
54800
55118
|
}
|
|
54801
|
-
function guessKindByPath(
|
|
54802
|
-
if (/__tests__|\.spec\.(t|j)sx?$|^tests\//.test(
|
|
54803
|
-
if (/^docs\//.test(
|
|
54804
|
-
if (/\.(json|cjs|js|ts)$/.test(
|
|
55119
|
+
function guessKindByPath(path65) {
|
|
55120
|
+
if (/__tests__|\.spec\.(t|j)sx?$|^tests\//.test(path65)) return "test";
|
|
55121
|
+
if (/^docs\//.test(path65) || /\.md$/.test(path65)) return "doc";
|
|
55122
|
+
if (/\.(json|cjs|js|ts)$/.test(path65) && !/src\//.test(path65)) return "config";
|
|
54805
55123
|
return "source";
|
|
54806
55124
|
}
|
|
54807
55125
|
var init_PathInferencer = __esm({
|
|
@@ -55065,9 +55383,9 @@ function formatPlanAsDiff(files, opts) {
|
|
|
55065
55383
|
function readCurrentFileSafe(root, rel, abs) {
|
|
55066
55384
|
if (!root && !abs) return "";
|
|
55067
55385
|
try {
|
|
55068
|
-
const
|
|
55386
|
+
const fs52 = __require("fs");
|
|
55069
55387
|
const p = abs ? abs : __require("path").join(root, rel);
|
|
55070
|
-
return
|
|
55388
|
+
return fs52.existsSync(p) ? fs52.readFileSync(p, "utf8") : "";
|
|
55071
55389
|
} catch {
|
|
55072
55390
|
return "";
|
|
55073
55391
|
}
|
|
@@ -55402,7 +55720,8 @@ async function listRepoFiles(root) {
|
|
|
55402
55720
|
}
|
|
55403
55721
|
for (const e2 of entries) {
|
|
55404
55722
|
const name2 = e2.name;
|
|
55405
|
-
if (name2 === ".git" || name2 === "node_modules" || name2 === "dist" || name2 === ".maria"
|
|
55723
|
+
if (name2 === ".git" || name2 === "node_modules" || name2 === "dist" || name2 === ".maria" || // macOS system/hidden dirs that shouldn't be scanned
|
|
55724
|
+
name2 === ".DS_Store" || name2 === ".Spotlight-V100" || name2 === ".Trashes" || name2 === ".fseventsd" || name2 === ".TemporaryItems") continue;
|
|
55406
55725
|
const full = path11__namespace.default.join(dir, name2);
|
|
55407
55726
|
const rel = path11__namespace.default.relative(root, full).replace(/\\/g, "/");
|
|
55408
55727
|
if (e2.isDirectory()) {
|
|
@@ -55655,6 +55974,60 @@ var Orchestrator_exports = {};
|
|
|
55655
55974
|
__export(Orchestrator_exports, {
|
|
55656
55975
|
orchestrate: () => orchestrate
|
|
55657
55976
|
});
|
|
55977
|
+
async function getRepoFiles(root) {
|
|
55978
|
+
if (_repoFileIndexCache && _repoFileIndexCache.root === root) return _repoFileIndexCache.files;
|
|
55979
|
+
const fs52 = await import('fs/promises');
|
|
55980
|
+
const pathMod = await import('path');
|
|
55981
|
+
const ignoreDir = /* @__PURE__ */ new Set([
|
|
55982
|
+
".git",
|
|
55983
|
+
"node_modules",
|
|
55984
|
+
"dist",
|
|
55985
|
+
"build",
|
|
55986
|
+
".maria",
|
|
55987
|
+
".next",
|
|
55988
|
+
"coverage",
|
|
55989
|
+
".DS_Store",
|
|
55990
|
+
".Spotlight-V100",
|
|
55991
|
+
".Trashes",
|
|
55992
|
+
".fseventsd",
|
|
55993
|
+
".TemporaryItems"
|
|
55994
|
+
]);
|
|
55995
|
+
const out = [];
|
|
55996
|
+
async function walk2(dir) {
|
|
55997
|
+
let entries = [];
|
|
55998
|
+
try {
|
|
55999
|
+
entries = await fs52.readdir(dir, { withFileTypes: true });
|
|
56000
|
+
} catch {
|
|
56001
|
+
return;
|
|
56002
|
+
}
|
|
56003
|
+
for (const e2 of entries) {
|
|
56004
|
+
const name2 = e2.name;
|
|
56005
|
+
if (ignoreDir.has(name2)) continue;
|
|
56006
|
+
const full = pathMod.join(dir, name2);
|
|
56007
|
+
if (e2.isDirectory()) {
|
|
56008
|
+
await walk2(full);
|
|
56009
|
+
continue;
|
|
56010
|
+
}
|
|
56011
|
+
out.push(pathMod.relative(root, full).replace(/\\/g, "/"));
|
|
56012
|
+
}
|
|
56013
|
+
}
|
|
56014
|
+
await walk2(root);
|
|
56015
|
+
_repoFileIndexCache = { root, files: out };
|
|
56016
|
+
return out;
|
|
56017
|
+
}
|
|
56018
|
+
function languageFromExt(ext2) {
|
|
56019
|
+
const e2 = ext2.toLowerCase().replace(/^\./, "");
|
|
56020
|
+
if (e2 === "ts") return "typescript";
|
|
56021
|
+
if (e2 === "tsx") return "tsx";
|
|
56022
|
+
if (e2 === "js" || e2 === "mjs" || e2 === "cjs") return "javascript";
|
|
56023
|
+
if (e2 === "jsx") return "jsx";
|
|
56024
|
+
if (e2 === "json") return "json";
|
|
56025
|
+
if (e2 === "html") return "html";
|
|
56026
|
+
if (e2 === "css" || e2 === "scss") return "css";
|
|
56027
|
+
if (e2 === "md") return "markdown";
|
|
56028
|
+
if (e2 === "yaml" || e2 === "yml") return "yaml";
|
|
56029
|
+
return void 0;
|
|
56030
|
+
}
|
|
55658
56031
|
async function ensureCodeFallbackManager() {
|
|
55659
56032
|
const policy = await loadFallbackPolicy().catch(() => getDefaultFallbackPolicy());
|
|
55660
56033
|
const signature = JSON.stringify(policy);
|
|
@@ -55693,11 +56066,19 @@ async function orchestrate(request, opts) {
|
|
|
55693
56066
|
explicitAbsMap[rel] = pathMod.join(opts.root, rel);
|
|
55694
56067
|
}
|
|
55695
56068
|
}
|
|
55696
|
-
const isEditIntent =
|
|
56069
|
+
const isEditIntent = await detectEditIntentEnhanced(opts.root, request, {
|
|
55697
56070
|
hasAttachments: !!(opts.attachedFiles && opts.attachedFiles.length > 0),
|
|
55698
|
-
|
|
55699
|
-
|
|
55700
|
-
|
|
56071
|
+
explicitFiles});
|
|
56072
|
+
let editTargets = explicitFiles;
|
|
56073
|
+
if (isEditIntent && editTargets.length === 0) {
|
|
56074
|
+
try {
|
|
56075
|
+
const repoFiles = await getRepoFiles(opts.root);
|
|
56076
|
+
const likely = repoFiles.filter((p) => /\.(ts|tsx|js|jsx|html|css|scss|json|md)$/i.test(p));
|
|
56077
|
+
editTargets = likely.slice(0, 20);
|
|
56078
|
+
} catch {
|
|
56079
|
+
}
|
|
56080
|
+
}
|
|
56081
|
+
const editContext = isEditIntent && editTargets.length > 0 ? await buildEditContext(opts.root, editTargets, 200, 512 * 1024) : "";
|
|
55701
56082
|
if (opts.attachedFiles && opts.attachedFiles.length > 0) {
|
|
55702
56083
|
const mapRes = await mapAttachmentsToTargets(opts.attachedFiles, {
|
|
55703
56084
|
root: opts.root,
|
|
@@ -55756,14 +56137,14 @@ ${editContext}`;
|
|
|
55756
56137
|
const pathAttachments = [];
|
|
55757
56138
|
if (explicitFiles.length > 0) {
|
|
55758
56139
|
try {
|
|
55759
|
-
const
|
|
56140
|
+
const fs52 = await import('fs/promises');
|
|
55760
56141
|
const pathMod = await import('path');
|
|
55761
56142
|
for (const rel of explicitFiles) {
|
|
55762
56143
|
try {
|
|
55763
56144
|
const full = explicitAbsMap[rel] || pathMod.join(opts.root, rel);
|
|
55764
|
-
const stat13 = await
|
|
56145
|
+
const stat13 = await fs52.stat(full).catch(() => null);
|
|
55765
56146
|
if (!stat13 || !stat13.isFile()) continue;
|
|
55766
|
-
const buf = await
|
|
56147
|
+
const buf = await fs52.readFile(full);
|
|
55767
56148
|
const ext2 = (pathMod.extname(full) || "").toLowerCase();
|
|
55768
56149
|
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
56150
|
pathAttachments.push({
|
|
@@ -55781,7 +56162,7 @@ ${editContext}`;
|
|
|
55781
56162
|
const hydratedCtx = [];
|
|
55782
56163
|
if (ctxAttachments.length > 0) {
|
|
55783
56164
|
try {
|
|
55784
|
-
const
|
|
56165
|
+
const fs52 = await import('fs/promises');
|
|
55785
56166
|
for (const a of ctxAttachments) {
|
|
55786
56167
|
if (a.data_base64) {
|
|
55787
56168
|
hydratedCtx.push(a);
|
|
@@ -55792,12 +56173,12 @@ ${editContext}`;
|
|
|
55792
56173
|
continue;
|
|
55793
56174
|
}
|
|
55794
56175
|
try {
|
|
55795
|
-
const stat13 = await
|
|
56176
|
+
const stat13 = await fs52.stat(p).catch(() => null);
|
|
55796
56177
|
if (!stat13 || !stat13.isFile()) {
|
|
55797
56178
|
hydratedCtx.push(a);
|
|
55798
56179
|
continue;
|
|
55799
56180
|
}
|
|
55800
|
-
const buf = await
|
|
56181
|
+
const buf = await fs52.readFile(p);
|
|
55801
56182
|
hydratedCtx.push({ ...a, data_base64: buf.toString("base64") });
|
|
55802
56183
|
} catch {
|
|
55803
56184
|
hydratedCtx.push(a);
|
|
@@ -55847,40 +56228,44 @@ ${editContext}`;
|
|
|
55847
56228
|
codeOutput = outcome.data?.output || "";
|
|
55848
56229
|
}
|
|
55849
56230
|
const blocks = extractBlocks(codeOutput);
|
|
55850
|
-
if (explicitFiles.length > 0) {
|
|
56231
|
+
if (explicitFiles.length > 0 || isEditIntent && editTargets.length > 0) {
|
|
55851
56232
|
const mapped = /* @__PURE__ */ new Set();
|
|
56233
|
+
const targets = explicitFiles.length > 0 ? explicitFiles : editTargets;
|
|
56234
|
+
const absMap = explicitFiles.length > 0 ? explicitAbsMap : /* @__PURE__ */ Object.create(null);
|
|
55852
56235
|
const htmlIdx = blocks.findIndex((b) => /html/i.test(b.language));
|
|
55853
|
-
const htmlFile =
|
|
56236
|
+
const htmlFile = targets.find((f3) => f3.toLowerCase().endsWith(".html"));
|
|
55854
56237
|
if (htmlIdx >= 0 && htmlFile) {
|
|
55855
|
-
initial.push({ path: htmlFile, absPath:
|
|
56238
|
+
initial.push({ path: htmlFile, absPath: absMap[htmlFile], noNormalize: true, kind: "source", action: "modify", description: "HTML page", language: "html", preview: blocks[htmlIdx].code });
|
|
55856
56239
|
mapped.add(htmlFile);
|
|
55857
56240
|
}
|
|
55858
56241
|
const jsIdx = blocks.findIndex((b) => /(ts|tsx|jsx|javascript|js)/i.test(b.language));
|
|
55859
|
-
const jsFile =
|
|
56242
|
+
const jsFile = targets.find((f3) => f3.toLowerCase().endsWith(".js"));
|
|
55860
56243
|
if (jsIdx >= 0 && jsFile && !mapped.has(jsFile)) {
|
|
55861
|
-
initial.push({ path: jsFile, absPath:
|
|
56244
|
+
initial.push({ path: jsFile, absPath: absMap[jsFile], noNormalize: true, kind: "source", action: "modify", description: "Script", language: "javascript", preview: blocks[jsIdx].code });
|
|
55862
56245
|
mapped.add(jsFile);
|
|
55863
56246
|
}
|
|
55864
56247
|
const cssIdx = blocks.findIndex((b) => /css/i.test(b.language));
|
|
55865
|
-
const cssFile =
|
|
56248
|
+
const cssFile = targets.find((f3) => f3.toLowerCase().endsWith(".css"));
|
|
55866
56249
|
if (cssIdx >= 0 && cssFile && !mapped.has(cssFile)) {
|
|
55867
|
-
initial.push({ path: cssFile, absPath:
|
|
56250
|
+
initial.push({ path: cssFile, absPath: absMap[cssFile], noNormalize: true, kind: "source", action: "modify", description: "Stylesheet", language: "css", preview: blocks[cssIdx].code });
|
|
55868
56251
|
mapped.add(cssFile);
|
|
55869
56252
|
}
|
|
55870
|
-
for (const f3 of
|
|
56253
|
+
for (const f3 of targets) {
|
|
55871
56254
|
if (mapped.has(f3)) continue;
|
|
55872
|
-
const
|
|
55873
|
-
|
|
55874
|
-
|
|
55875
|
-
|
|
56255
|
+
const ext2 = (() => {
|
|
56256
|
+
const m2 = f3.lastIndexOf(".");
|
|
56257
|
+
return m2 >= 0 ? f3.slice(m2) : "";
|
|
56258
|
+
})();
|
|
56259
|
+
const lang = languageFromExt(ext2);
|
|
56260
|
+
initial.push({ path: f3, absPath: absMap[f3], noNormalize: true, kind: "source", action: "modify", description: "Edit target", language: lang, preview: "" });
|
|
55876
56261
|
}
|
|
55877
56262
|
} else {
|
|
55878
56263
|
for (let i2 = 0; i2 < blocks.length; i2++) {
|
|
55879
56264
|
const b = blocks[i2];
|
|
55880
56265
|
const desired = typeof b.filename === "string" && b.filename.trim() ? b.filename.trim() : null;
|
|
55881
|
-
const
|
|
56266
|
+
const path65 = desired || suggestName2(request, b.language, i2);
|
|
55882
56267
|
initial.push({
|
|
55883
|
-
path:
|
|
56268
|
+
path: path65,
|
|
55884
56269
|
kind: "source",
|
|
55885
56270
|
action: "create",
|
|
55886
56271
|
description: describe2(b.language, ""),
|
|
@@ -55911,13 +56296,13 @@ ${editContext}`;
|
|
|
55911
56296
|
{ root: opts.root }
|
|
55912
56297
|
);
|
|
55913
56298
|
try {
|
|
55914
|
-
const [{ access: access18 },
|
|
56299
|
+
const [{ access: access18 }, path65] = await Promise.all([
|
|
55915
56300
|
import('fs/promises'),
|
|
55916
56301
|
import('path')
|
|
55917
56302
|
]);
|
|
55918
56303
|
for (const p of normalized) {
|
|
55919
56304
|
try {
|
|
55920
|
-
const absCandidate = p.absPath ? p.absPath :
|
|
56305
|
+
const absCandidate = p.absPath ? p.absPath : path65.join(opts.root, p.path);
|
|
55921
56306
|
await access18(absCandidate);
|
|
55922
56307
|
p.action = "modify";
|
|
55923
56308
|
if (isEditIntent) {
|
|
@@ -56155,12 +56540,12 @@ function languageExt(lang) {
|
|
|
56155
56540
|
}
|
|
56156
56541
|
async function journalResume(root, request, files) {
|
|
56157
56542
|
try {
|
|
56158
|
-
const
|
|
56543
|
+
const fs52 = await import('fs/promises');
|
|
56159
56544
|
const dir = path11__namespace.default.join(root, ".maria", "memory");
|
|
56160
|
-
await
|
|
56545
|
+
await fs52.mkdir(dir, { recursive: true });
|
|
56161
56546
|
const out = path11__namespace.default.join(dir, "resume-plan.json");
|
|
56162
56547
|
const payload = { request, createdAt: (/* @__PURE__ */ new Date()).toISOString(), files };
|
|
56163
|
-
await
|
|
56548
|
+
await fs52.writeFile(out, JSON.stringify(payload, null, 2), "utf8");
|
|
56164
56549
|
} catch {
|
|
56165
56550
|
}
|
|
56166
56551
|
}
|
|
@@ -56288,6 +56673,68 @@ function detectEditIntent(request, ctx2) {
|
|
|
56288
56673
|
const mentionsEdit = editKeywords.some((k) => r2.includes(k));
|
|
56289
56674
|
return ctx2.hasAttachments || ctx2.explicitFilesCount > 0 || mentionsEdit;
|
|
56290
56675
|
}
|
|
56676
|
+
async function detectEditIntentEnhanced(root, request, ctx2) {
|
|
56677
|
+
const baseline = detectEditIntent(request, { hasAttachments: ctx2.hasAttachments, explicitFilesCount: ctx2.explicitFiles.length });
|
|
56678
|
+
if (baseline) return true;
|
|
56679
|
+
const r2 = request.toLowerCase();
|
|
56680
|
+
const softHints = ["improve", "enhance", "make it", "change the", "adjust", "tweak", "rework", "revamp", "retro", "modernize", "clean up", "polish"];
|
|
56681
|
+
const hasSoftHint = softHints.some((k) => r2.includes(k));
|
|
56682
|
+
if (!hasSoftHint) return false;
|
|
56683
|
+
try {
|
|
56684
|
+
const fs52 = await import('fs/promises');
|
|
56685
|
+
const pathMod = await import('path');
|
|
56686
|
+
const { loadGlobby: loadGlobby2 } = await Promise.resolve().then(() => (init_esm_compat(), esm_compat_exports));
|
|
56687
|
+
const globby = await loadGlobby2();
|
|
56688
|
+
const ignore = [
|
|
56689
|
+
"**/node_modules/**",
|
|
56690
|
+
"**/.git/**",
|
|
56691
|
+
"**/dist/**",
|
|
56692
|
+
"**/build/**",
|
|
56693
|
+
"**/.maria/**",
|
|
56694
|
+
"**/.next/**",
|
|
56695
|
+
"**/coverage/**",
|
|
56696
|
+
"**/.DS_Store/**",
|
|
56697
|
+
"**/.DS_Store",
|
|
56698
|
+
"**/.Spotlight-V100/**",
|
|
56699
|
+
"**/.Spotlight-V100",
|
|
56700
|
+
"**/.Trashes/**",
|
|
56701
|
+
"**/.Trashes",
|
|
56702
|
+
"**/.fseventsd/**",
|
|
56703
|
+
"**/.fseventsd",
|
|
56704
|
+
"**/.TemporaryItems/**",
|
|
56705
|
+
"**/.TemporaryItems"
|
|
56706
|
+
];
|
|
56707
|
+
const candidates = await globby(["**/*.{html,css,js,ts,tsx}"], { cwd: root, absolute: true, gitignore: true, ignore, deep: 3 });
|
|
56708
|
+
if (candidates && candidates.length > 0) return true;
|
|
56709
|
+
} catch {
|
|
56710
|
+
}
|
|
56711
|
+
try {
|
|
56712
|
+
const short = request.trim().length <= 160;
|
|
56713
|
+
if (!short) return false;
|
|
56714
|
+
const system = [
|
|
56715
|
+
"You are classifying whether the user intends to EDIT existing files vs CREATE a new project.",
|
|
56716
|
+
'Return JSON: { "edit": true|false } only.'
|
|
56717
|
+
].join("\n");
|
|
56718
|
+
const user = `Instruction: ${request}`;
|
|
56719
|
+
const resp = await executeChat([
|
|
56720
|
+
{ role: "system", content: system },
|
|
56721
|
+
{ role: "user", content: user }
|
|
56722
|
+
]);
|
|
56723
|
+
const raw = (resp?.output || "").trim();
|
|
56724
|
+
const jsonText = (() => {
|
|
56725
|
+
try {
|
|
56726
|
+
const m2 = raw.match(/\{[\s\S]*\}/);
|
|
56727
|
+
return m2 ? m2[0] : raw;
|
|
56728
|
+
} catch {
|
|
56729
|
+
return raw;
|
|
56730
|
+
}
|
|
56731
|
+
})();
|
|
56732
|
+
const parsed = JSON.parse(jsonText);
|
|
56733
|
+
if (typeof parsed?.edit === "boolean") return !!parsed.edit;
|
|
56734
|
+
} catch {
|
|
56735
|
+
}
|
|
56736
|
+
return false;
|
|
56737
|
+
}
|
|
56291
56738
|
function sanitizeFolderName(name2) {
|
|
56292
56739
|
const base = name2.toLowerCase().replace(/[`~!@#$%^&*()+=\[\]{}|;:'",<>/?\\]/g, " ").replace(/\s+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
56293
56740
|
return base || "project";
|
|
@@ -56320,14 +56767,14 @@ async function ensureTopFolder(root, proposed, plans) {
|
|
|
56320
56767
|
return { folderName: unique };
|
|
56321
56768
|
}
|
|
56322
56769
|
async function ensureUniqueFolder(root, base) {
|
|
56323
|
-
const
|
|
56770
|
+
const fs52 = await import('fs/promises');
|
|
56324
56771
|
const pathMod = await import('path');
|
|
56325
56772
|
let name2 = sanitizeFolderName(base);
|
|
56326
56773
|
let suffix = 0;
|
|
56327
56774
|
for (; suffix < Number.MAX_SAFE_INTEGER; ) {
|
|
56328
56775
|
const candidate = suffix === 0 ? name2 : `${name2}-${String(suffix).padStart(2, "0")}`;
|
|
56329
56776
|
try {
|
|
56330
|
-
await
|
|
56777
|
+
await fs52.access(pathMod.join(root, candidate));
|
|
56331
56778
|
suffix += 1;
|
|
56332
56779
|
} catch {
|
|
56333
56780
|
return candidate;
|
|
@@ -56337,13 +56784,13 @@ async function ensureUniqueFolder(root, base) {
|
|
|
56337
56784
|
}
|
|
56338
56785
|
async function buildEditContext(root, files, maxLines, maxBytes) {
|
|
56339
56786
|
try {
|
|
56340
|
-
const
|
|
56787
|
+
const fs52 = await import('fs/promises');
|
|
56341
56788
|
const pathMod = await import('path');
|
|
56342
56789
|
const sections = [];
|
|
56343
56790
|
for (const rel of files) {
|
|
56344
56791
|
const full = pathMod.join(root, rel);
|
|
56345
56792
|
try {
|
|
56346
|
-
const buf = await
|
|
56793
|
+
const buf = await fs52.readFile(full);
|
|
56347
56794
|
const clipped = buf.length > maxBytes ? buf.subarray(0, maxBytes) : buf;
|
|
56348
56795
|
const text = clipped.toString("utf8").replace(/\r\n/g, "\n");
|
|
56349
56796
|
const lines = text.split("\n").slice(0, maxLines).join("\n");
|
|
@@ -56360,84 +56807,58 @@ ${lines}
|
|
|
56360
56807
|
}
|
|
56361
56808
|
}
|
|
56362
56809
|
async function resolveExplicitPaths(root, files, hintText) {
|
|
56363
|
-
const
|
|
56810
|
+
const fs52 = await import('fs/promises');
|
|
56364
56811
|
const pathMod = await import('path');
|
|
56365
|
-
const
|
|
56366
|
-
|
|
56367
|
-
|
|
56368
|
-
"
|
|
56369
|
-
"
|
|
56370
|
-
"
|
|
56371
|
-
"
|
|
56372
|
-
"
|
|
56373
|
-
"
|
|
56374
|
-
"
|
|
56375
|
-
|
|
56376
|
-
|
|
56377
|
-
|
|
56378
|
-
|
|
56379
|
-
|
|
56380
|
-
|
|
56381
|
-
|
|
56382
|
-
|
|
56383
|
-
|
|
56812
|
+
const ignoreDir = /* @__PURE__ */ new Set([
|
|
56813
|
+
".git",
|
|
56814
|
+
"node_modules",
|
|
56815
|
+
"dist",
|
|
56816
|
+
"build",
|
|
56817
|
+
".maria",
|
|
56818
|
+
".next",
|
|
56819
|
+
"coverage",
|
|
56820
|
+
".DS_Store",
|
|
56821
|
+
".Spotlight-V100",
|
|
56822
|
+
".Trashes",
|
|
56823
|
+
".fseventsd",
|
|
56824
|
+
".TemporaryItems"
|
|
56825
|
+
]);
|
|
56826
|
+
async function buildRepoIndex() {
|
|
56827
|
+
if (_repoFileIndexCache && _repoFileIndexCache.root === root) return _repoFileIndexCache.files;
|
|
56828
|
+
const out2 = [];
|
|
56829
|
+
async function walk2(dir) {
|
|
56830
|
+
let entries = [];
|
|
56831
|
+
try {
|
|
56832
|
+
entries = await fs52.readdir(dir, { withFileTypes: true });
|
|
56833
|
+
} catch {
|
|
56834
|
+
return;
|
|
56835
|
+
}
|
|
56836
|
+
for (const e2 of entries) {
|
|
56837
|
+
const name2 = e2.name;
|
|
56838
|
+
if (ignoreDir.has(name2)) continue;
|
|
56839
|
+
const full = pathMod.join(dir, name2);
|
|
56840
|
+
if (e2.isDirectory()) {
|
|
56841
|
+
await walk2(full);
|
|
56842
|
+
continue;
|
|
56843
|
+
}
|
|
56844
|
+
out2.push(pathMod.relative(root, full).replace(/\\/g, "/"));
|
|
56845
|
+
}
|
|
56384
56846
|
}
|
|
56847
|
+
await walk2(root);
|
|
56848
|
+
_repoFileIndexCache = { root, files: out2 };
|
|
56849
|
+
return out2;
|
|
56850
|
+
}
|
|
56851
|
+
const allFiles = await buildRepoIndex();
|
|
56852
|
+
const hintTokens = Array.from(new Set(hintText.toLowerCase().replace(/[^a-z0-9_/.-]+/g, " ").split(/\s+/).filter(Boolean)));
|
|
56853
|
+
async function rankCandidates(candidates, desired) {
|
|
56854
|
+
const normalized = desired.replace(/^\/+/, "").replace(/\\/g, "/");
|
|
56385
56855
|
const lowerRel = normalized.toLowerCase();
|
|
56386
56856
|
const ext2 = (pathMod.extname(normalized) || "").toLowerCase();
|
|
56387
56857
|
const base = pathMod.basename(normalized);
|
|
56388
|
-
|
|
56858
|
+
base.replace(/\.[^.]+$/, "").toLowerCase();
|
|
56389
56859
|
const parentPath = pathMod.dirname(normalized);
|
|
56390
56860
|
const parent = parentPath.split("/").pop() || "";
|
|
56391
56861
|
const dirParts = parentPath === "." ? [] : parentPath.split("/").filter(Boolean).map((s2) => s2.toLowerCase());
|
|
56392
|
-
const patterns = [];
|
|
56393
|
-
patterns.push(`**/${normalized}`);
|
|
56394
|
-
if (parent && parent !== "." && parent !== "/") patterns.push(`**/${parent}/${base}`);
|
|
56395
|
-
if (base) patterns.push(`**/${base}`);
|
|
56396
|
-
patterns.push(`**/*${base}`);
|
|
56397
|
-
if (!ext2) {
|
|
56398
|
-
patterns.push(`**/${nameNoExt}.*`);
|
|
56399
|
-
}
|
|
56400
|
-
const uniqPatterns = Array.from(new Set(patterns));
|
|
56401
|
-
const candidatesSet = /* @__PURE__ */ new Set();
|
|
56402
|
-
for (const pat of uniqPatterns) {
|
|
56403
|
-
const found = await globby(pat, { cwd: root, absolute: false, gitignore: true, ignore });
|
|
56404
|
-
for (const f3 of found) {
|
|
56405
|
-
candidatesSet.add(f3.replace(/\\/g, "/"));
|
|
56406
|
-
}
|
|
56407
|
-
if (candidatesSet.size > 200) break;
|
|
56408
|
-
}
|
|
56409
|
-
let candidates = Array.from(candidatesSet);
|
|
56410
|
-
if (dirParts.length > 0) {
|
|
56411
|
-
const filtered = candidates.filter((relp) => {
|
|
56412
|
-
const segs = relp.toLowerCase().split("/");
|
|
56413
|
-
let pos = -1;
|
|
56414
|
-
for (const part of dirParts) {
|
|
56415
|
-
const next = segs.indexOf(part, pos + 1);
|
|
56416
|
-
if (next === -1) return false;
|
|
56417
|
-
pos = next;
|
|
56418
|
-
}
|
|
56419
|
-
return true;
|
|
56420
|
-
});
|
|
56421
|
-
if (filtered.length > 0) candidates = filtered;
|
|
56422
|
-
}
|
|
56423
|
-
if (candidates.length === 0) {
|
|
56424
|
-
const prefixes = ["", "src/", "app/", "pages/"];
|
|
56425
|
-
for (const pre of prefixes) {
|
|
56426
|
-
const cand = pathMod.join(root, pre + normalized);
|
|
56427
|
-
try {
|
|
56428
|
-
await fs51.access(cand);
|
|
56429
|
-
return (pre + normalized).replace(/^\/+/, "");
|
|
56430
|
-
} catch {
|
|
56431
|
-
}
|
|
56432
|
-
}
|
|
56433
|
-
if (dirParts.length > 0) {
|
|
56434
|
-
if (/^(src|app|pages)\//i.test(normalized)) return normalized;
|
|
56435
|
-
const pref = await pickExistingFolderPrefix(root, parentPath);
|
|
56436
|
-
const combined = (pref + normalized).replace(/^\/+/, "").replace(/^(src\/)src\//i, "$1");
|
|
56437
|
-
return combined;
|
|
56438
|
-
}
|
|
56439
|
-
return normalized.replace(/^(src\/)src\//i, "$1");
|
|
56440
|
-
}
|
|
56441
56862
|
function score(relPath) {
|
|
56442
56863
|
const lower2 = relPath.toLowerCase();
|
|
56443
56864
|
let s2 = 0;
|
|
@@ -56461,10 +56882,36 @@ async function resolveExplicitPaths(root, files, hintText) {
|
|
|
56461
56882
|
s2 -= Math.min(10, Math.floor(relPath.length / 80));
|
|
56462
56883
|
return s2;
|
|
56463
56884
|
}
|
|
56464
|
-
|
|
56885
|
+
const limited = candidates.slice(0, Math.min(50, candidates.length));
|
|
56886
|
+
if (limited.length > 1) {
|
|
56887
|
+
try {
|
|
56888
|
+
const ranked = limited.map((p) => ({ p, s: score(p) })).sort((a, b) => b.s - a.s).slice(0, 5).map((x2) => x2.p);
|
|
56889
|
+
const system = [
|
|
56890
|
+
"You are helping choose the most relevant target file path for an edit operation.",
|
|
56891
|
+
"Given a user request and several candidate repo-relative paths, pick ONE best path.",
|
|
56892
|
+
"Return ONLY the raw path text. No code blocks. No explanations."
|
|
56893
|
+
].join("\n");
|
|
56894
|
+
const user = [
|
|
56895
|
+
`User request: ${hintText}`,
|
|
56896
|
+
"Candidates:",
|
|
56897
|
+
...ranked.map((r2, i2) => `${i2 + 1}. ${r2}`),
|
|
56898
|
+
"",
|
|
56899
|
+
"Answer with exactly one of the candidate paths."
|
|
56900
|
+
].join("\n");
|
|
56901
|
+
const chat = await executeChat([
|
|
56902
|
+
{ role: "system", content: system },
|
|
56903
|
+
{ role: "user", content: user }
|
|
56904
|
+
]);
|
|
56905
|
+
const raw = (chat.output || "").trim();
|
|
56906
|
+
const pick = ranked.find((r2) => r2 === raw) || ranked.find((r2) => raw.includes(r2)) || ranked[0];
|
|
56907
|
+
return pick.replace(/^\/+/, "");
|
|
56908
|
+
} catch {
|
|
56909
|
+
}
|
|
56910
|
+
}
|
|
56911
|
+
let best = limited[0];
|
|
56465
56912
|
let bestScore = score(best);
|
|
56466
|
-
for (let i2 = 1; i2 <
|
|
56467
|
-
const c =
|
|
56913
|
+
for (let i2 = 1; i2 < limited.length; i2++) {
|
|
56914
|
+
const c = limited[i2];
|
|
56468
56915
|
const sc = score(c);
|
|
56469
56916
|
if (sc > bestScore) {
|
|
56470
56917
|
best = c;
|
|
@@ -56474,20 +56921,41 @@ async function resolveExplicitPaths(root, files, hintText) {
|
|
|
56474
56921
|
return best.replace(/^\/+/, "");
|
|
56475
56922
|
}
|
|
56476
56923
|
const out = [];
|
|
56477
|
-
for (const
|
|
56478
|
-
|
|
56924
|
+
for (const desired of files) {
|
|
56925
|
+
const normalized = desired.replace(/^\/+/, "").replace(/\\/g, "/");
|
|
56926
|
+
if (allFiles.includes(normalized)) {
|
|
56927
|
+
out.push(normalized);
|
|
56928
|
+
continue;
|
|
56929
|
+
}
|
|
56930
|
+
const base = pathMod.basename(normalized).toLowerCase();
|
|
56931
|
+
const nameNoExt = base.replace(/\.[^.]+$/, "");
|
|
56932
|
+
const candidates = allFiles.filter((p) => {
|
|
56933
|
+
const b = pathMod.basename(p).toLowerCase();
|
|
56934
|
+
return b === base || b.includes(base) || !base.includes(".") && (b === `${nameNoExt}.ts` || b === `${nameNoExt}.js` || b.startsWith(nameNoExt));
|
|
56935
|
+
});
|
|
56936
|
+
if (candidates.length === 0) {
|
|
56937
|
+
const parentPath = pathMod.dirname(normalized);
|
|
56938
|
+
if (parentPath && parentPath !== ".") {
|
|
56939
|
+
const pref = await pickExistingFolderPrefix(root, parentPath);
|
|
56940
|
+
out.push((pref + normalized).replace(/^\/+/, "").replace(/^(src\/)src\//i, "$1"));
|
|
56941
|
+
} else {
|
|
56942
|
+
out.push(normalized.replace(/^(src\/)src\//i, "$1"));
|
|
56943
|
+
}
|
|
56944
|
+
continue;
|
|
56945
|
+
}
|
|
56946
|
+
out.push(await rankCandidates(candidates, normalized));
|
|
56479
56947
|
}
|
|
56480
56948
|
return out;
|
|
56481
56949
|
}
|
|
56482
56950
|
async function pickExistingFolderPrefix(root, parentPath) {
|
|
56483
|
-
const
|
|
56951
|
+
const fs52 = await import('fs/promises');
|
|
56484
56952
|
const pathMod = await import('path');
|
|
56485
56953
|
const parts = parentPath.replace(/^\/+/, "").split("/").filter(Boolean);
|
|
56486
56954
|
const prefixes = ["src", "app", "pages", ""];
|
|
56487
56955
|
for (const pre of prefixes) {
|
|
56488
56956
|
const test = pre ? pathMod.join(root, pre, ...parts) : pathMod.join(root, ...parts);
|
|
56489
56957
|
try {
|
|
56490
|
-
await
|
|
56958
|
+
await fs52.access(test);
|
|
56491
56959
|
return pre ? `${pre}/` : "";
|
|
56492
56960
|
} catch {
|
|
56493
56961
|
}
|
|
@@ -56534,7 +57002,7 @@ requestAnimationFrame(step);`;
|
|
|
56534
57002
|
}
|
|
56535
57003
|
return { path: filename, kind: "source", action: "create", description: "Source file", preview: "" };
|
|
56536
57004
|
}
|
|
56537
|
-
var codeFallbackManager, codeFallbackPolicySignature;
|
|
57005
|
+
var codeFallbackManager, _repoFileIndexCache, codeFallbackPolicySignature;
|
|
56538
57006
|
var init_Orchestrator = __esm({
|
|
56539
57007
|
"src/services/code-orchestrator/Orchestrator.ts"() {
|
|
56540
57008
|
init_RepoScanner();
|
|
@@ -56549,6 +57017,7 @@ var init_Orchestrator = __esm({
|
|
|
56549
57017
|
init_FallbackManager();
|
|
56550
57018
|
init_policy();
|
|
56551
57019
|
codeFallbackManager = null;
|
|
57020
|
+
_repoFileIndexCache = null;
|
|
56552
57021
|
codeFallbackPolicySignature = null;
|
|
56553
57022
|
}
|
|
56554
57023
|
});
|
|
@@ -56661,8 +57130,8 @@ var init_code_command = __esm({
|
|
|
56661
57130
|
try {
|
|
56662
57131
|
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
57132
|
if (opts.planOnly) {
|
|
56664
|
-
const
|
|
56665
|
-
const
|
|
57133
|
+
const fs52 = await import('fs/promises');
|
|
57134
|
+
const path65 = await import('path');
|
|
56666
57135
|
const spec = res?.specMarkdown;
|
|
56667
57136
|
const lines = Array.isArray(res?.summaryLines) ? res.summaryLines : [];
|
|
56668
57137
|
const planItems = [];
|
|
@@ -56696,13 +57165,13 @@ var init_code_command = __esm({
|
|
|
56696
57165
|
if (planItems.length) md.push(...planItems);
|
|
56697
57166
|
else md.push("- (no summary available)");
|
|
56698
57167
|
}
|
|
56699
|
-
const plansDir =
|
|
56700
|
-
await
|
|
57168
|
+
const plansDir = path65.join(root, ".maria", "plans");
|
|
57169
|
+
await fs52.mkdir(plansDir, { recursive: true });
|
|
56701
57170
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
56702
57171
|
const fileName = `code-plan-${ts}.md`;
|
|
56703
|
-
const outPath =
|
|
56704
|
-
await
|
|
56705
|
-
const rel =
|
|
57172
|
+
const outPath = path65.join(plansDir, fileName);
|
|
57173
|
+
await fs52.writeFile(outPath, md.join("\n") + "\n", "utf8");
|
|
57174
|
+
const rel = path65.relative(root, outPath);
|
|
56706
57175
|
return this.success(`Code plan saved: ${rel}`);
|
|
56707
57176
|
}
|
|
56708
57177
|
const detail = res?.detailLines;
|
|
@@ -56762,6 +57231,97 @@ ${pretty}`);
|
|
|
56762
57231
|
// Add default language hints when not specified by the user (LLM-assisted detection)
|
|
56763
57232
|
async ensureLanguageDefaults(raw) {
|
|
56764
57233
|
try {
|
|
57234
|
+
const fs52 = await import('fs/promises');
|
|
57235
|
+
const pathMod = await import('path');
|
|
57236
|
+
const cwd2 = process.cwd();
|
|
57237
|
+
const ignoreDir = /* @__PURE__ */ new Set([".git", "node_modules", "dist", "build", ".maria", ".next", "coverage", ".DS_Store", ".Spotlight-V100", ".Trashes", ".fseventsd", ".TemporaryItems"]);
|
|
57238
|
+
const pathTokens = /* @__PURE__ */ new Set();
|
|
57239
|
+
const fileLike = raw.match(/([\w\-./\\:]+\.[A-Za-z0-9]{1,10})/g) || [];
|
|
57240
|
+
for (const t2 of fileLike) pathTokens.add(t2);
|
|
57241
|
+
const slashLike = raw.match(/[^\s"']*[\\/][^\s"']+/g) || [];
|
|
57242
|
+
for (const t2 of slashLike) pathTokens.add(t2);
|
|
57243
|
+
const listFilesUnder = async (dir, maxCount) => {
|
|
57244
|
+
const out = [];
|
|
57245
|
+
const walk2 = async (d) => {
|
|
57246
|
+
if (out.length >= maxCount) return;
|
|
57247
|
+
let entries = [];
|
|
57248
|
+
try {
|
|
57249
|
+
entries = await fs52.readdir(d, { withFileTypes: true });
|
|
57250
|
+
} catch {
|
|
57251
|
+
return;
|
|
57252
|
+
}
|
|
57253
|
+
for (const e2 of entries) {
|
|
57254
|
+
const name2 = e2.name;
|
|
57255
|
+
if (ignoreDir.has(name2)) continue;
|
|
57256
|
+
const full = pathMod.join(d, name2);
|
|
57257
|
+
if (e2.isDirectory()) {
|
|
57258
|
+
await walk2(full);
|
|
57259
|
+
if (out.length >= maxCount) break;
|
|
57260
|
+
continue;
|
|
57261
|
+
}
|
|
57262
|
+
if (/\.(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|html|css|scss|md|json)$/i.test(name2)) {
|
|
57263
|
+
out.push(full);
|
|
57264
|
+
if (out.length >= maxCount) break;
|
|
57265
|
+
}
|
|
57266
|
+
}
|
|
57267
|
+
};
|
|
57268
|
+
await walk2(dir);
|
|
57269
|
+
return out;
|
|
57270
|
+
};
|
|
57271
|
+
const readHead = async (full, lines) => {
|
|
57272
|
+
try {
|
|
57273
|
+
const buf = await fs52.readFile(full, "utf8");
|
|
57274
|
+
return buf.split(/\r?\n/).slice(0, lines).join("\n");
|
|
57275
|
+
} catch {
|
|
57276
|
+
return "";
|
|
57277
|
+
}
|
|
57278
|
+
};
|
|
57279
|
+
const samples = [];
|
|
57280
|
+
for (const tok of Array.from(pathTokens)) {
|
|
57281
|
+
const abs = pathMod.isAbsolute(tok) ? tok : pathMod.join(cwd2, tok);
|
|
57282
|
+
try {
|
|
57283
|
+
const st = await fs52.stat(abs);
|
|
57284
|
+
if (st.isFile()) {
|
|
57285
|
+
samples.push(await readHead(abs, 10));
|
|
57286
|
+
} else if (st.isDirectory()) {
|
|
57287
|
+
const files = await listFilesUnder(abs, 25);
|
|
57288
|
+
for (const f3 of files) samples.push(await readHead(f3, 10));
|
|
57289
|
+
}
|
|
57290
|
+
} catch {
|
|
57291
|
+
}
|
|
57292
|
+
if (samples.length >= 50) break;
|
|
57293
|
+
}
|
|
57294
|
+
if (samples.length > 0) {
|
|
57295
|
+
const preSpin = new ProcessAnimation();
|
|
57296
|
+
preSpin.start();
|
|
57297
|
+
let llmLang = null;
|
|
57298
|
+
try {
|
|
57299
|
+
llmLang = await this.detectLanguageLLMFromSamples(samples);
|
|
57300
|
+
} finally {
|
|
57301
|
+
try {
|
|
57302
|
+
preSpin.stop();
|
|
57303
|
+
} catch {
|
|
57304
|
+
}
|
|
57305
|
+
}
|
|
57306
|
+
if (llmLang) {
|
|
57307
|
+
const hint2 = (() => {
|
|
57308
|
+
const l = llmLang.toLowerCase();
|
|
57309
|
+
if (l === "tsx") return "TypeScript (React/TSX)";
|
|
57310
|
+
if (l === "jsx") return "JavaScript (React/JSX)";
|
|
57311
|
+
if (l === "typescript") return "TypeScript";
|
|
57312
|
+
if (l === "javascript") return "JavaScript";
|
|
57313
|
+
if (l === "html") return "HTML";
|
|
57314
|
+
if (l === "css") return "CSS";
|
|
57315
|
+
return llmLang;
|
|
57316
|
+
})();
|
|
57317
|
+
return raw + ` (Use ${hint2})`;
|
|
57318
|
+
}
|
|
57319
|
+
}
|
|
57320
|
+
} catch {
|
|
57321
|
+
}
|
|
57322
|
+
try {
|
|
57323
|
+
const preSpin = new ProcessAnimation();
|
|
57324
|
+
preSpin.start();
|
|
56765
57325
|
const system = [
|
|
56766
57326
|
"You analyze a user's code-generation request.",
|
|
56767
57327
|
"Decide if the user explicitly specified a programming language or framework/tooling (e.g., TypeScript, Python, Rust, Java, React, Vue, Node, etc.).",
|
|
@@ -56780,8 +57340,12 @@ ${pretty}`);
|
|
|
56780
57340
|
${user}`
|
|
56781
57341
|
}
|
|
56782
57342
|
});
|
|
57343
|
+
try {
|
|
57344
|
+
preSpin.stop();
|
|
57345
|
+
} catch {
|
|
57346
|
+
}
|
|
56783
57347
|
const content = (resp?.data?.content || resp?.content || "").trim();
|
|
56784
|
-
const
|
|
57348
|
+
const extractFirstJson7 = (text) => {
|
|
56785
57349
|
const fence = /```\s*json\s*\r?\n([\s\S]*?)```/i.exec(text);
|
|
56786
57350
|
if (fence) return fence[1];
|
|
56787
57351
|
const generic = /```\s*\r?\n([\s\S]*?)```/i.exec(text);
|
|
@@ -56804,7 +57368,7 @@ ${user}`
|
|
|
56804
57368
|
}
|
|
56805
57369
|
return null;
|
|
56806
57370
|
};
|
|
56807
|
-
const jsonText =
|
|
57371
|
+
const jsonText = extractFirstJson7(content) || content;
|
|
56808
57372
|
let parsed = {};
|
|
56809
57373
|
try {
|
|
56810
57374
|
parsed = JSON.parse(jsonText);
|
|
@@ -56817,6 +57381,76 @@ ${user}`
|
|
|
56817
57381
|
const hint = " (Use TypeScript and React; prefer functional components and node)";
|
|
56818
57382
|
return raw + hint;
|
|
56819
57383
|
}
|
|
57384
|
+
// LLM-based language detection from sample code heads (top-10 lines per file)
|
|
57385
|
+
async detectLanguageLLMFromSamples(samples) {
|
|
57386
|
+
try {
|
|
57387
|
+
const system = [
|
|
57388
|
+
"You are a programming language classifier.",
|
|
57389
|
+
"Given multiple short code excerpts, determine the dominant language across them.",
|
|
57390
|
+
"Respond with ONLY a single token language name from this set:",
|
|
57391
|
+
"[typescript, tsx, javascript, jsx, python, java, go, rust, php, cpp, c, swift, kotlin, ruby, csharp, html, css, scss, json, yaml, markdown].",
|
|
57392
|
+
"If unsure between tsx and jsx, choose tsx if TypeScript types appear, else jsx."
|
|
57393
|
+
].join("\n");
|
|
57394
|
+
const joined = samples.slice(0, 20).map((s2, i2) => `// sample ${i2 + 1}
|
|
57395
|
+
${s2}`).join("\n\n");
|
|
57396
|
+
const { callAPI: callAPI2 } = await Promise.resolve().then(() => (init_api_caller(), api_caller_exports));
|
|
57397
|
+
const resp = await callAPI2("/v1/ai-proxy", {
|
|
57398
|
+
method: "POST",
|
|
57399
|
+
body: {
|
|
57400
|
+
provider: "google",
|
|
57401
|
+
model: "gemini-2.5-flash",
|
|
57402
|
+
taskType: "chat",
|
|
57403
|
+
prompt: `${system}
|
|
57404
|
+
|
|
57405
|
+
${joined}`
|
|
57406
|
+
}
|
|
57407
|
+
});
|
|
57408
|
+
const content = (resp?.data?.content || resp?.content || "").trim();
|
|
57409
|
+
const token = content.replace(/```[\s\S]*?```/g, "").trim().toLowerCase();
|
|
57410
|
+
const norm = this.normalizeLanguageName(token);
|
|
57411
|
+
return norm || null;
|
|
57412
|
+
} catch {
|
|
57413
|
+
return null;
|
|
57414
|
+
}
|
|
57415
|
+
}
|
|
57416
|
+
normalizeLanguageName(lang) {
|
|
57417
|
+
const l = (lang || "").toLowerCase().trim();
|
|
57418
|
+
if (!l) return null;
|
|
57419
|
+
const map = {
|
|
57420
|
+
"ts": "typescript",
|
|
57421
|
+
"typescript": "typescript",
|
|
57422
|
+
"tsx": "tsx",
|
|
57423
|
+
"jsx": "jsx",
|
|
57424
|
+
"js": "javascript",
|
|
57425
|
+
"javascript": "javascript",
|
|
57426
|
+
"py": "python",
|
|
57427
|
+
"python": "python",
|
|
57428
|
+
"java": "java",
|
|
57429
|
+
"go": "go",
|
|
57430
|
+
"rust": "rust",
|
|
57431
|
+
"rs": "rust",
|
|
57432
|
+
"php": "php",
|
|
57433
|
+
"c++": "cpp",
|
|
57434
|
+
"cpp": "cpp",
|
|
57435
|
+
"c": "c",
|
|
57436
|
+
"swift": "swift",
|
|
57437
|
+
"kotlin": "kotlin",
|
|
57438
|
+
"rb": "ruby",
|
|
57439
|
+
"ruby": "ruby",
|
|
57440
|
+
"cs": "csharp",
|
|
57441
|
+
"c#": "csharp",
|
|
57442
|
+
"csharp": "csharp",
|
|
57443
|
+
"html": "html",
|
|
57444
|
+
"css": "css",
|
|
57445
|
+
"scss": "scss",
|
|
57446
|
+
"json": "json",
|
|
57447
|
+
"yaml": "yaml",
|
|
57448
|
+
"yml": "yaml",
|
|
57449
|
+
"markdown": "markdown",
|
|
57450
|
+
"md": "markdown"
|
|
57451
|
+
};
|
|
57452
|
+
return map[l] || null;
|
|
57453
|
+
}
|
|
56820
57454
|
// v2.0 helpers
|
|
56821
57455
|
parseV2Options(raw) {
|
|
56822
57456
|
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 };
|
|
@@ -57012,16 +57646,16 @@ ${user}`
|
|
|
57012
57646
|
}
|
|
57013
57647
|
async persistLastPlan(root, plans) {
|
|
57014
57648
|
try {
|
|
57015
|
-
const
|
|
57649
|
+
const fs52 = await import('fs/promises');
|
|
57016
57650
|
const p = path11__namespace.join(root, ".maria");
|
|
57017
|
-
await
|
|
57651
|
+
await fs52.mkdir(p, { recursive: true });
|
|
57018
57652
|
const out = path11__namespace.join(p, "last-plan.json");
|
|
57019
|
-
await
|
|
57653
|
+
await fs52.writeFile(out, JSON.stringify({ createdAt: (/* @__PURE__ */ new Date()).toISOString(), plans }, null, 2), "utf8");
|
|
57020
57654
|
} catch {
|
|
57021
57655
|
}
|
|
57022
57656
|
}
|
|
57023
57657
|
async applyPlan(plans, options) {
|
|
57024
|
-
const
|
|
57658
|
+
const fs52 = await import('fs/promises');
|
|
57025
57659
|
const created = [];
|
|
57026
57660
|
const modified = [];
|
|
57027
57661
|
const skipped = [];
|
|
@@ -57040,9 +57674,9 @@ ${user}`
|
|
|
57040
57674
|
continue;
|
|
57041
57675
|
}
|
|
57042
57676
|
const tmp = full + `.tmp-${process.pid}-${Date.now()}`;
|
|
57043
|
-
await
|
|
57044
|
-
await
|
|
57045
|
-
await
|
|
57677
|
+
await fs52.mkdir(path11__namespace.dirname(full), { recursive: true });
|
|
57678
|
+
await fs52.writeFile(tmp, plan.preview || "", "utf8");
|
|
57679
|
+
await fs52.rename(tmp, full);
|
|
57046
57680
|
if (exists2) modified.push(plan.path);
|
|
57047
57681
|
else created.push(plan.path);
|
|
57048
57682
|
written++;
|
|
@@ -57053,7 +57687,7 @@ ${user}`
|
|
|
57053
57687
|
if (options.rollback) {
|
|
57054
57688
|
for (const p of [...created, ...modified]) {
|
|
57055
57689
|
try {
|
|
57056
|
-
await
|
|
57690
|
+
await fs52.unlink(path11__namespace.join(options.root, p));
|
|
57057
57691
|
} catch {
|
|
57058
57692
|
}
|
|
57059
57693
|
}
|
|
@@ -57063,8 +57697,8 @@ ${user}`
|
|
|
57063
57697
|
}
|
|
57064
57698
|
async pathExists(p) {
|
|
57065
57699
|
try {
|
|
57066
|
-
const
|
|
57067
|
-
await
|
|
57700
|
+
const fs52 = await import('fs/promises');
|
|
57701
|
+
await fs52.access(p);
|
|
57068
57702
|
return true;
|
|
57069
57703
|
} catch {
|
|
57070
57704
|
return false;
|
|
@@ -57175,17 +57809,17 @@ ${user}`
|
|
|
57175
57809
|
// Attempt to collect attached files from context; map to AttachedFileContext
|
|
57176
57810
|
async collectAttachedFiles(context2) {
|
|
57177
57811
|
const list = [];
|
|
57178
|
-
const
|
|
57179
|
-
const
|
|
57812
|
+
const fs52 = await import('fs/promises');
|
|
57813
|
+
const path65 = await import('path');
|
|
57180
57814
|
const att = context2 && (context2.attachments || context2.input?.attachments) || [];
|
|
57181
57815
|
for (const a of att) {
|
|
57182
57816
|
try {
|
|
57183
57817
|
const p = a.path || a.filePath || a.name || "";
|
|
57184
|
-
const originalName = a.name ||
|
|
57818
|
+
const originalName = a.name || path65.basename(p || `attachment_${Date.now().toString(36)}`);
|
|
57185
57819
|
let content = a.content;
|
|
57186
57820
|
if (!content && p) {
|
|
57187
|
-
const abs =
|
|
57188
|
-
content = await
|
|
57821
|
+
const abs = path65.isAbsolute(p) ? p : path65.join(process.cwd(), p);
|
|
57822
|
+
content = await fs52.readFile(abs, "utf8");
|
|
57189
57823
|
}
|
|
57190
57824
|
if (!content) continue;
|
|
57191
57825
|
list.push({ originalName, pathHint: p || void 0, content, size: Buffer.byteLength(content, "utf8"), mime: a.mime || a.type });
|
|
@@ -63874,17 +64508,17 @@ var init_GraphEngine = __esm({
|
|
|
63874
64508
|
const visited = /* @__PURE__ */ new Set();
|
|
63875
64509
|
const queue = [{ id: from, path: [from] }];
|
|
63876
64510
|
while (queue.length) {
|
|
63877
|
-
const { id, path:
|
|
64511
|
+
const { id, path: path65 } = queue.shift();
|
|
63878
64512
|
if (visited.has(id)) continue;
|
|
63879
64513
|
visited.add(id);
|
|
63880
64514
|
const neighbors = this.edges.get(id) || /* @__PURE__ */ new Set();
|
|
63881
64515
|
for (const e2 of neighbors) {
|
|
63882
64516
|
if (e2.to === to) {
|
|
63883
|
-
const res = [...
|
|
64517
|
+
const res = [...path65, to];
|
|
63884
64518
|
this.recordQueryTime(Date.now() - start);
|
|
63885
64519
|
return res;
|
|
63886
64520
|
}
|
|
63887
|
-
if (!visited.has(e2.to)) queue.push({ id: e2.to, path: [...
|
|
64521
|
+
if (!visited.has(e2.to)) queue.push({ id: e2.to, path: [...path65, e2.to] });
|
|
63888
64522
|
}
|
|
63889
64523
|
}
|
|
63890
64524
|
this.recordQueryTime(Date.now() - start);
|
|
@@ -66551,12 +67185,12 @@ This will:
|
|
|
66551
67185
|
};
|
|
66552
67186
|
const result = await this.deltaDetector.detectDelta(root, deltaOptions);
|
|
66553
67187
|
const files = [
|
|
66554
|
-
...result.changed.map((
|
|
66555
|
-
_path:
|
|
66556
|
-
type: previousState?.fileHashes?.[
|
|
67188
|
+
...result.changed.map((path65) => ({
|
|
67189
|
+
_path: path65,
|
|
67190
|
+
type: previousState?.fileHashes?.[path65] ? "modified" : "added"
|
|
66557
67191
|
})),
|
|
66558
|
-
...result.deleted.map((
|
|
66559
|
-
_path:
|
|
67192
|
+
...result.deleted.map((path65) => ({
|
|
67193
|
+
_path: path65,
|
|
66560
67194
|
type: "deleted"
|
|
66561
67195
|
}))
|
|
66562
67196
|
];
|
|
@@ -69992,13 +70626,13 @@ async function checkShield(commandName, userPlan = "free") {
|
|
|
69992
70626
|
}
|
|
69993
70627
|
async function loadManifest() {
|
|
69994
70628
|
try {
|
|
69995
|
-
const
|
|
69996
|
-
const
|
|
69997
|
-
const manifestPath =
|
|
70629
|
+
const fs52 = await import('fs');
|
|
70630
|
+
const path65 = await import('path');
|
|
70631
|
+
const manifestPath = path65.join(
|
|
69998
70632
|
__dirname,
|
|
69999
70633
|
"../command-manifest-v2.1.json"
|
|
70000
70634
|
);
|
|
70001
|
-
const content =
|
|
70635
|
+
const content = fs52.readFileSync(manifestPath, "utf-8");
|
|
70002
70636
|
return JSON.parse(content);
|
|
70003
70637
|
} catch {
|
|
70004
70638
|
return { commands: [] };
|
|
@@ -71493,7 +72127,7 @@ ${user}`,
|
|
|
71493
72127
|
};
|
|
71494
72128
|
}
|
|
71495
72129
|
});
|
|
71496
|
-
function
|
|
72130
|
+
function extractFirstJson6(text) {
|
|
71497
72131
|
const fence = /```json\r?\n([\s\S]*?)```/i.exec(text);
|
|
71498
72132
|
if (fence) return fence[1];
|
|
71499
72133
|
const start = text.indexOf("{");
|
|
@@ -71540,7 +72174,7 @@ ${user}`,
|
|
|
71540
72174
|
}
|
|
71541
72175
|
});
|
|
71542
72176
|
const raw = (response?.data?.content || response?.output || "").trim();
|
|
71543
|
-
const jsonText =
|
|
72177
|
+
const jsonText = extractFirstJson6(raw) || raw;
|
|
71544
72178
|
let parsed = {};
|
|
71545
72179
|
try {
|
|
71546
72180
|
parsed = JSON.parse(jsonText);
|
|
@@ -72400,6 +73034,15 @@ async function registerBuiltInCommands() {
|
|
|
72400
73034
|
} catch (error2) {
|
|
72401
73035
|
console.error("Failed to register media commands:", error2);
|
|
72402
73036
|
}
|
|
73037
|
+
try {
|
|
73038
|
+
const NovelModule = await Promise.resolve().then(() => (init_novel_command(), novel_command_exports));
|
|
73039
|
+
const NovelClass = NovelModule.NovelCommand || NovelModule.default;
|
|
73040
|
+
const novel = new NovelClass();
|
|
73041
|
+
if (novel.initialize) await novel.initialize();
|
|
73042
|
+
commandRegistry.register(novel);
|
|
73043
|
+
} catch (error2) {
|
|
73044
|
+
console.error("Failed to register novel command:", error2);
|
|
73045
|
+
}
|
|
72403
73046
|
try {
|
|
72404
73047
|
const { codeCommand: codeCommand2 } = await Promise.resolve().then(() => (init_code_command(), code_command_exports));
|
|
72405
73048
|
try {
|
|
@@ -74932,16 +75575,16 @@ var init_ai_response_service = __esm({
|
|
|
74932
75575
|
if (p) candidates.add(p);
|
|
74933
75576
|
}
|
|
74934
75577
|
if (candidates.size > 0) {
|
|
74935
|
-
const
|
|
75578
|
+
const fs52 = await import('fs/promises');
|
|
74936
75579
|
const pathMod = await import('path');
|
|
74937
75580
|
const cwd2 = process.cwd();
|
|
74938
75581
|
for (const cand of candidates) {
|
|
74939
75582
|
try {
|
|
74940
75583
|
const normalized = cand.replace(/^"|"$/g, "").replace(/^'|'$/g, "");
|
|
74941
75584
|
const abs = pathMod.isAbsolute(normalized) ? normalized : pathMod.join(cwd2, normalized);
|
|
74942
|
-
const st = await
|
|
75585
|
+
const st = await fs52.stat(abs).catch(() => null);
|
|
74943
75586
|
if (!st || !st.isFile()) continue;
|
|
74944
|
-
const buf = await
|
|
75587
|
+
const buf = await fs52.readFile(abs);
|
|
74945
75588
|
const ext2 = (pathMod.extname(abs) || "").toLowerCase();
|
|
74946
75589
|
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";
|
|
74947
75590
|
autoAttachments.push({ name: pathMod.basename(abs), path: abs, mime, data_base64: buf.toString("base64") });
|