@bonginkan/maria 4.3.30 → 4.3.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/READY.manifest.json +1 -1
- package/dist/bin/maria.cjs +1349 -202
- package/dist/bin/maria.cjs.map +1 -1
- package/dist/cli.cjs +1346 -199
- package/dist/cli.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/server/express-server.cjs +1 -1
- package/dist/server/express-server.js +1 -1
- package/dist/server-express.cjs +1 -1
- package/dist/server-express.cjs.map +1 -1
- package/package.json +2 -2
- package/src/slash-commands/READY.manifest.json +1 -1
package/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 path64 of possiblePaths) {
|
|
239
|
+
if (fs21.existsSync(path64)) {
|
|
240
240
|
try {
|
|
241
|
-
const content = fs21.readFileSync(
|
|
241
|
+
const content = fs21.readFileSync(path64, "utf-8");
|
|
242
242
|
const parsed = JSON.parse(content);
|
|
243
243
|
if (parsed.name === "@bonginkan/maria") {
|
|
244
|
-
packageJsonPath =
|
|
244
|
+
packageJsonPath = path64;
|
|
245
245
|
break;
|
|
246
246
|
}
|
|
247
247
|
} catch {
|
|
@@ -525,22 +525,22 @@ function dataUriToBuffer(uri) {
|
|
|
525
525
|
if (firstComma === -1 || firstComma <= 4) {
|
|
526
526
|
throw new TypeError("malformed data: URI");
|
|
527
527
|
}
|
|
528
|
-
const
|
|
528
|
+
const meta27 = uri.substring(5, firstComma).split(";");
|
|
529
529
|
let charset = "";
|
|
530
530
|
let base64 = false;
|
|
531
|
-
const type =
|
|
531
|
+
const type = meta27[0] || "text/plain";
|
|
532
532
|
let typeFull = type;
|
|
533
|
-
for (let i2 = 1; i2 <
|
|
534
|
-
if (
|
|
533
|
+
for (let i2 = 1; i2 < meta27.length; i2++) {
|
|
534
|
+
if (meta27[i2] === "base64") {
|
|
535
535
|
base64 = true;
|
|
536
|
-
} else if (
|
|
537
|
-
typeFull += `;${
|
|
538
|
-
if (
|
|
539
|
-
charset =
|
|
536
|
+
} else if (meta27[i2]) {
|
|
537
|
+
typeFull += `;${meta27[i2]}`;
|
|
538
|
+
if (meta27[i2].indexOf("charset=") === 0) {
|
|
539
|
+
charset = meta27[i2].substring(8);
|
|
540
540
|
}
|
|
541
541
|
}
|
|
542
542
|
}
|
|
543
|
-
if (!
|
|
543
|
+
if (!meta27[0] && !charset.length) {
|
|
544
544
|
typeFull += ";charset=US-ASCII";
|
|
545
545
|
charset = "US-ASCII";
|
|
546
546
|
}
|
|
@@ -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 = (path64, type) => fromBlob(fs21.statSync(path64), path64, type);
|
|
5318
|
+
blobFrom = (path64, type) => stat(path64).then((stat13) => fromBlob(stat13, path64, type));
|
|
5319
|
+
fileFrom = (path64, type) => stat(path64).then((stat13) => fromFile(stat13, path64, type));
|
|
5320
|
+
fileFromSync = (path64, type) => fromFile(fs21.statSync(path64), path64, type);
|
|
5321
|
+
fromBlob = (stat13, path64, type = "") => new fetch_blob_default([new BlobDataItem({
|
|
5322
|
+
path: path64,
|
|
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, path64, type = "") => new file_default([new BlobDataItem({
|
|
5328
|
+
path: path64,
|
|
5329
5329
|
size: stat13.size,
|
|
5330
5330
|
lastModified: stat13.mtimeMs,
|
|
5331
5331
|
start: 0
|
|
5332
|
-
})], path11.basename(
|
|
5332
|
+
})], path11.basename(path64), { 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 fs51 = 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 fs51.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 fs51 = 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 fs51.promises.access(targetPath);
|
|
9593
9593
|
const backupPath = `${targetPath}.backup.${Date.now()}`;
|
|
9594
|
-
await
|
|
9594
|
+
await fs51.promises.copyFile(targetPath, backupPath);
|
|
9595
9595
|
} catch {
|
|
9596
9596
|
}
|
|
9597
9597
|
}
|
|
9598
|
-
await
|
|
9598
|
+
await fs51.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 fs51.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 fs51 = await importNodeBuiltin2("fs");
|
|
9648
9648
|
const _path = await importNodeBuiltin2(
|
|
9649
9649
|
"_path"
|
|
9650
9650
|
);
|
|
9651
|
-
await
|
|
9652
|
-
await
|
|
9651
|
+
await fs51.promises.mkdir(_path.dirname(outputPath), { recursive: true });
|
|
9652
|
+
await fs51.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 fs51 = 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 fs51.pathExists(_envPath)) {
|
|
9967
|
+
const _envContent = await fs51.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(path64) {
|
|
19540
|
+
const keys = path64.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(path64, value) {
|
|
19571
|
+
const keys = path64.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: path64,
|
|
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 fs51 = __require("fs");
|
|
19630
|
+
fs51.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(path64, listener) {
|
|
19642
|
+
if (!this._listeners.has(path64)) {
|
|
19643
|
+
this._listeners.set(path64, []);
|
|
19644
19644
|
}
|
|
19645
|
-
this._listeners.get(
|
|
19645
|
+
this._listeners.get(path64).push(listener);
|
|
19646
19646
|
return () => {
|
|
19647
|
-
const listeners = this._listeners.get(
|
|
19647
|
+
const listeners = this._listeners.get(path64);
|
|
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((path64) => !this.containsPathTraversal(path64), {
|
|
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(path64) {
|
|
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(path64);
|
|
20279
|
+
if (this.isSystemPath(path64)) {
|
|
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(path64) {
|
|
20426
|
+
return /\.\.[/\\]/.test(path64) || path64.includes("..\\") || path64.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(path64) {
|
|
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) => path64.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 fs51 = await import('fs/promises');
|
|
25444
|
+
const path64 = await import('path');
|
|
25445
|
+
const abs = path64.resolve(outputPath);
|
|
25446
|
+
await fs51.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 fs51 = await import('fs/promises');
|
|
25537
|
+
const path64 = await import('path');
|
|
25538
|
+
const abs = path64.resolve(outputPath);
|
|
25539
|
+
await fs51.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(path64) {
|
|
25929
|
+
return this._configService?.getNestedValue(path64);
|
|
25930
25930
|
}
|
|
25931
25931
|
/**
|
|
25932
25932
|
* 設定の更新
|
|
25933
25933
|
*/
|
|
25934
|
-
async setConfig(
|
|
25934
|
+
async setConfig(path64, value) {
|
|
25935
25935
|
if (this._configService) {
|
|
25936
|
-
await this._configService.setNestedValue(
|
|
25936
|
+
await this._configService.setNestedValue(path64, 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(path64) {
|
|
26055
|
+
return this.orchestrator.getConfig(path64);
|
|
26056
26056
|
}
|
|
26057
|
-
async setConfig(
|
|
26058
|
-
await this.orchestrator.setConfig(
|
|
26057
|
+
async setConfig(path64, value) {
|
|
26058
|
+
await this.orchestrator.setConfig(path64, 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.32",
|
|
26070
|
+
description: "\u{1F680} MARIA v4.3.32 - Enterprise AI Development Platform with identity system and character voice implementation. Features 74 production-ready commands with comprehensive fallback implementation, local LLM support, and zero external dependencies. Includes natural language coding, AI safety evaluation, intelligent evolution system, episodic memory with PII masking, and real-time monitoring dashboard. Built with TypeScript AST-powered code generation, OAuth2.0 + PKCE authentication, quantum-resistant cryptography, and enterprise-grade performance.",
|
|
26071
26071
|
keywords: [
|
|
26072
26072
|
"ai",
|
|
26073
26073
|
"cli",
|
|
@@ -28099,7 +28099,7 @@ var init_AuthenticationManager = __esm({
|
|
|
28099
28099
|
const response = await fetch(`${this.apiBase}/api/user/profile`, {
|
|
28100
28100
|
headers: {
|
|
28101
28101
|
"Authorization": `Bearer ${tokens2.accessToken}`,
|
|
28102
|
-
"User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.
|
|
28102
|
+
"User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.32"}`
|
|
28103
28103
|
}
|
|
28104
28104
|
});
|
|
28105
28105
|
if (response.status === 401) {
|
|
@@ -28718,9 +28718,9 @@ function getDeviceId() {
|
|
|
28718
28718
|
function getSessionId() {
|
|
28719
28719
|
return global.MARIA_SESSION_ID;
|
|
28720
28720
|
}
|
|
28721
|
-
async function callApi(
|
|
28721
|
+
async function callApi(path64, init3 = {}) {
|
|
28722
28722
|
const apiBase = process.env.MARIA_API_BASE || "https://api.maria-code.ai";
|
|
28723
|
-
const fullUrl = `${apiBase}${
|
|
28723
|
+
const fullUrl = `${apiBase}${path64}`;
|
|
28724
28724
|
let tokens2 = await authManager.getValidTokens();
|
|
28725
28725
|
if (!tokens2) {
|
|
28726
28726
|
console.log(chalk14__default.default.red(ERR.AUTH_REQUIRED.msg));
|
|
@@ -28731,7 +28731,7 @@ async function callApi(path60, init3 = {}) {
|
|
|
28731
28731
|
"Authorization": `Bearer ${token}`,
|
|
28732
28732
|
"X-Device-Id": getDeviceId(),
|
|
28733
28733
|
"X-Session-Id": getSessionId() || "",
|
|
28734
|
-
"User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.
|
|
28734
|
+
"User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.32"}`,
|
|
28735
28735
|
"Content-Type": init3.headers?.["Content-Type"] || "application/json"
|
|
28736
28736
|
});
|
|
28737
28737
|
const doFetch = async (token) => {
|
|
@@ -28789,8 +28789,8 @@ async function callApi(path60, init3 = {}) {
|
|
|
28789
28789
|
}
|
|
28790
28790
|
return response;
|
|
28791
28791
|
}
|
|
28792
|
-
async function callApiJson(
|
|
28793
|
-
const response = await callApi(
|
|
28792
|
+
async function callApiJson(path64, init3 = {}) {
|
|
28793
|
+
const response = await callApi(path64, init3);
|
|
28794
28794
|
if (!response.ok) {
|
|
28795
28795
|
const error2 = await response.json().catch(() => ({
|
|
28796
28796
|
message: `API error: ${response.status} ${response.statusText}`
|
|
@@ -33659,12 +33659,12 @@ var init_esm4 = __esm({
|
|
|
33659
33659
|
/**
|
|
33660
33660
|
* Get the Path object referenced by the string path, resolved from this Path
|
|
33661
33661
|
*/
|
|
33662
|
-
resolve(
|
|
33663
|
-
if (!
|
|
33662
|
+
resolve(path64) {
|
|
33663
|
+
if (!path64) {
|
|
33664
33664
|
return this;
|
|
33665
33665
|
}
|
|
33666
|
-
const rootPath = this.getRootString(
|
|
33667
|
-
const dir =
|
|
33666
|
+
const rootPath = this.getRootString(path64);
|
|
33667
|
+
const dir = path64.substring(rootPath.length);
|
|
33668
33668
|
const dirParts = dir.split(this.splitSep);
|
|
33669
33669
|
const result = rootPath ? this.getRoot(rootPath).#resolveParts(dirParts) : this.#resolveParts(dirParts);
|
|
33670
33670
|
return result;
|
|
@@ -34416,8 +34416,8 @@ var init_esm4 = __esm({
|
|
|
34416
34416
|
/**
|
|
34417
34417
|
* @internal
|
|
34418
34418
|
*/
|
|
34419
|
-
getRootString(
|
|
34420
|
-
return path11.win32.parse(
|
|
34419
|
+
getRootString(path64) {
|
|
34420
|
+
return path11.win32.parse(path64).root;
|
|
34421
34421
|
}
|
|
34422
34422
|
/**
|
|
34423
34423
|
* @internal
|
|
@@ -34463,8 +34463,8 @@ var init_esm4 = __esm({
|
|
|
34463
34463
|
/**
|
|
34464
34464
|
* @internal
|
|
34465
34465
|
*/
|
|
34466
|
-
getRootString(
|
|
34467
|
-
return
|
|
34466
|
+
getRootString(path64) {
|
|
34467
|
+
return path64.startsWith("/") ? "/" : "";
|
|
34468
34468
|
}
|
|
34469
34469
|
/**
|
|
34470
34470
|
* @internal
|
|
@@ -34513,8 +34513,8 @@ var init_esm4 = __esm({
|
|
|
34513
34513
|
*
|
|
34514
34514
|
* @internal
|
|
34515
34515
|
*/
|
|
34516
|
-
constructor(cwd2 = process.cwd(), pathImpl, sep4, { nocase, childrenCacheSize = 16 * 1024, fs:
|
|
34517
|
-
this.#fs = fsFromOption(
|
|
34516
|
+
constructor(cwd2 = process.cwd(), pathImpl, sep4, { nocase, childrenCacheSize = 16 * 1024, fs: fs51 = defaultFS } = {}) {
|
|
34517
|
+
this.#fs = fsFromOption(fs51);
|
|
34518
34518
|
if (cwd2 instanceof URL || cwd2.startsWith("file://")) {
|
|
34519
34519
|
cwd2 = url.fileURLToPath(cwd2);
|
|
34520
34520
|
}
|
|
@@ -34553,11 +34553,11 @@ var init_esm4 = __esm({
|
|
|
34553
34553
|
/**
|
|
34554
34554
|
* Get the depth of a provided path, string, or the cwd
|
|
34555
34555
|
*/
|
|
34556
|
-
depth(
|
|
34557
|
-
if (typeof
|
|
34558
|
-
|
|
34556
|
+
depth(path64 = this.cwd) {
|
|
34557
|
+
if (typeof path64 === "string") {
|
|
34558
|
+
path64 = this.cwd.resolve(path64);
|
|
34559
34559
|
}
|
|
34560
|
-
return
|
|
34560
|
+
return path64.depth();
|
|
34561
34561
|
}
|
|
34562
34562
|
/**
|
|
34563
34563
|
* Return the cache of child entries. Exposed so subclasses can create
|
|
@@ -35044,9 +35044,9 @@ var init_esm4 = __esm({
|
|
|
35044
35044
|
process11();
|
|
35045
35045
|
return results;
|
|
35046
35046
|
}
|
|
35047
|
-
chdir(
|
|
35047
|
+
chdir(path64 = this.cwd) {
|
|
35048
35048
|
const oldCwd = this.cwd;
|
|
35049
|
-
this.cwd = typeof
|
|
35049
|
+
this.cwd = typeof path64 === "string" ? this.cwd.resolve(path64) : path64;
|
|
35050
35050
|
this.cwd[setAsCwd](oldCwd);
|
|
35051
35051
|
}
|
|
35052
35052
|
};
|
|
@@ -35072,8 +35072,8 @@ var init_esm4 = __esm({
|
|
|
35072
35072
|
/**
|
|
35073
35073
|
* @internal
|
|
35074
35074
|
*/
|
|
35075
|
-
newRoot(
|
|
35076
|
-
return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs:
|
|
35075
|
+
newRoot(fs51) {
|
|
35076
|
+
return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs51 });
|
|
35077
35077
|
}
|
|
35078
35078
|
/**
|
|
35079
35079
|
* Return true if the provided path string is an absolute path
|
|
@@ -35101,8 +35101,8 @@ var init_esm4 = __esm({
|
|
|
35101
35101
|
/**
|
|
35102
35102
|
* @internal
|
|
35103
35103
|
*/
|
|
35104
|
-
newRoot(
|
|
35105
|
-
return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs:
|
|
35104
|
+
newRoot(fs51) {
|
|
35105
|
+
return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs51 });
|
|
35106
35106
|
}
|
|
35107
35107
|
/**
|
|
35108
35108
|
* Return true if the provided path string is an absolute path
|
|
@@ -35421,8 +35421,8 @@ var init_processor = __esm({
|
|
|
35421
35421
|
}
|
|
35422
35422
|
// match, absolute, ifdir
|
|
35423
35423
|
entries() {
|
|
35424
|
-
return [...this.store.entries()].map(([
|
|
35425
|
-
|
|
35424
|
+
return [...this.store.entries()].map(([path64, n]) => [
|
|
35425
|
+
path64,
|
|
35426
35426
|
!!(n & 2),
|
|
35427
35427
|
!!(n & 1)
|
|
35428
35428
|
]);
|
|
@@ -35635,9 +35635,9 @@ var init_walker = __esm({
|
|
|
35635
35635
|
signal;
|
|
35636
35636
|
maxDepth;
|
|
35637
35637
|
includeChildMatches;
|
|
35638
|
-
constructor(patterns,
|
|
35638
|
+
constructor(patterns, path64, opts) {
|
|
35639
35639
|
this.patterns = patterns;
|
|
35640
|
-
this.path =
|
|
35640
|
+
this.path = path64;
|
|
35641
35641
|
this.opts = opts;
|
|
35642
35642
|
this.#sep = !opts.posix && opts.platform === "win32" ? "\\" : "/";
|
|
35643
35643
|
this.includeChildMatches = opts.includeChildMatches !== false;
|
|
@@ -35656,11 +35656,11 @@ var init_walker = __esm({
|
|
|
35656
35656
|
});
|
|
35657
35657
|
}
|
|
35658
35658
|
}
|
|
35659
|
-
#ignored(
|
|
35660
|
-
return this.seen.has(
|
|
35659
|
+
#ignored(path64) {
|
|
35660
|
+
return this.seen.has(path64) || !!this.#ignore?.ignored?.(path64);
|
|
35661
35661
|
}
|
|
35662
|
-
#childrenIgnored(
|
|
35663
|
-
return !!this.#ignore?.childrenIgnored?.(
|
|
35662
|
+
#childrenIgnored(path64) {
|
|
35663
|
+
return !!this.#ignore?.childrenIgnored?.(path64);
|
|
35664
35664
|
}
|
|
35665
35665
|
// backpressure mechanism
|
|
35666
35666
|
pause() {
|
|
@@ -35875,8 +35875,8 @@ var init_walker = __esm({
|
|
|
35875
35875
|
};
|
|
35876
35876
|
GlobWalker = class extends GlobUtil {
|
|
35877
35877
|
matches = /* @__PURE__ */ new Set();
|
|
35878
|
-
constructor(patterns,
|
|
35879
|
-
super(patterns,
|
|
35878
|
+
constructor(patterns, path64, opts) {
|
|
35879
|
+
super(patterns, path64, opts);
|
|
35880
35880
|
}
|
|
35881
35881
|
matchEmit(e2) {
|
|
35882
35882
|
this.matches.add(e2);
|
|
@@ -35913,8 +35913,8 @@ var init_walker = __esm({
|
|
|
35913
35913
|
};
|
|
35914
35914
|
GlobStream = class extends GlobUtil {
|
|
35915
35915
|
results;
|
|
35916
|
-
constructor(patterns,
|
|
35917
|
-
super(patterns,
|
|
35916
|
+
constructor(patterns, path64, opts) {
|
|
35917
|
+
super(patterns, path64, opts);
|
|
35918
35918
|
this.results = new Minipass({
|
|
35919
35919
|
signal: this.signal,
|
|
35920
35920
|
objectMode: true
|
|
@@ -41648,9 +41648,9 @@ var init_SafetyGuard = __esm({
|
|
|
41648
41648
|
}
|
|
41649
41649
|
}
|
|
41650
41650
|
if (action.args.paths && Array.isArray(action.args.paths)) {
|
|
41651
|
-
for (const
|
|
41652
|
-
if (!this.validatePath(
|
|
41653
|
-
violations.push(`Invalid path: ${
|
|
41651
|
+
for (const path64 of action.args.paths) {
|
|
41652
|
+
if (!this.validatePath(path64)) {
|
|
41653
|
+
violations.push(`Invalid path: ${path64}`);
|
|
41654
41654
|
}
|
|
41655
41655
|
}
|
|
41656
41656
|
}
|
|
@@ -41706,15 +41706,15 @@ var init_SafetyGuard = __esm({
|
|
|
41706
41706
|
* Validate file path against allowed/blocked lists
|
|
41707
41707
|
*/
|
|
41708
41708
|
validatePath(filePath) {
|
|
41709
|
-
const
|
|
41710
|
-
const resolvedPath =
|
|
41709
|
+
const path64 = __require("path");
|
|
41710
|
+
const resolvedPath = path64.resolve(filePath);
|
|
41711
41711
|
for (const blockedPath of this.constraints.blockedPaths) {
|
|
41712
|
-
if (resolvedPath.startsWith(
|
|
41712
|
+
if (resolvedPath.startsWith(path64.resolve(blockedPath))) {
|
|
41713
41713
|
return false;
|
|
41714
41714
|
}
|
|
41715
41715
|
}
|
|
41716
41716
|
for (const allowedPath of this.constraints.allowedPaths) {
|
|
41717
|
-
if (resolvedPath.startsWith(
|
|
41717
|
+
if (resolvedPath.startsWith(path64.resolve(allowedPath))) {
|
|
41718
41718
|
return true;
|
|
41719
41719
|
}
|
|
41720
41720
|
}
|
|
@@ -41743,9 +41743,9 @@ var init_SafetyGuard = __esm({
|
|
|
41743
41743
|
violations.push(`Invalid path in ${action.type}: ${action.args.path}`);
|
|
41744
41744
|
}
|
|
41745
41745
|
if (action.args.paths && Array.isArray(action.args.paths)) {
|
|
41746
|
-
for (const
|
|
41747
|
-
if (!this.validatePath(
|
|
41748
|
-
violations.push(`Invalid path in ${action.type}: ${
|
|
41746
|
+
for (const path64 of action.args.paths) {
|
|
41747
|
+
if (!this.validatePath(path64)) {
|
|
41748
|
+
violations.push(`Invalid path in ${action.type}: ${path64}`);
|
|
41749
41749
|
}
|
|
41750
41750
|
}
|
|
41751
41751
|
}
|
|
@@ -42714,8 +42714,8 @@ var init_ConfigActionExecutor = __esm({
|
|
|
42714
42714
|
/**
|
|
42715
42715
|
* Set nested configuration value using dot notation
|
|
42716
42716
|
*/
|
|
42717
|
-
setNestedValue(obj,
|
|
42718
|
-
const keys =
|
|
42717
|
+
setNestedValue(obj, path64, value) {
|
|
42718
|
+
const keys = path64.split(".");
|
|
42719
42719
|
let current = obj;
|
|
42720
42720
|
for (let i2 = 0; i2 < keys.length - 1; i2++) {
|
|
42721
42721
|
const key = keys[i2];
|
|
@@ -50689,7 +50689,7 @@ var init_about_command = __esm({
|
|
|
50689
50689
|
async execute(args2, context2) {
|
|
50690
50690
|
const output3 = [];
|
|
50691
50691
|
output3.push("");
|
|
50692
|
-
output3.push(chalk14__default.default.cyan.bold("\u{1F916} About MARIA v4.3.
|
|
50692
|
+
output3.push(chalk14__default.default.cyan.bold("\u{1F916} About MARIA v4.3.32"));
|
|
50693
50693
|
output3.push(chalk14__default.default.gray("\u2550".repeat(40)));
|
|
50694
50694
|
output3.push("");
|
|
50695
50695
|
output3.push(chalk14__default.default.white.bold("MARIA - Minimal API, Maximum Power"));
|
|
@@ -54170,10 +54170,10 @@ function suggestName(fp, p) {
|
|
|
54170
54170
|
const base = (fp.description || "file").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
54171
54171
|
return base || "file";
|
|
54172
54172
|
}
|
|
54173
|
-
function guessKindByPath(
|
|
54174
|
-
if (/__tests__|\.spec\.(t|j)sx?$|^tests\//.test(
|
|
54175
|
-
if (/^docs\//.test(
|
|
54176
|
-
if (/\.(json|cjs|js|ts)$/.test(
|
|
54173
|
+
function guessKindByPath(path64) {
|
|
54174
|
+
if (/__tests__|\.spec\.(t|j)sx?$|^tests\//.test(path64)) return "test";
|
|
54175
|
+
if (/^docs\//.test(path64) || /\.md$/.test(path64)) return "doc";
|
|
54176
|
+
if (/\.(json|cjs|js|ts)$/.test(path64) && !/src\//.test(path64)) return "config";
|
|
54177
54177
|
return "source";
|
|
54178
54178
|
}
|
|
54179
54179
|
var init_PathInferencer = __esm({
|
|
@@ -54433,9 +54433,9 @@ function formatPlanAsDiff(files, opts) {
|
|
|
54433
54433
|
function readCurrentFileSafe(root, rel, abs) {
|
|
54434
54434
|
if (!root && !abs) return "";
|
|
54435
54435
|
try {
|
|
54436
|
-
const
|
|
54436
|
+
const fs51 = __require("fs");
|
|
54437
54437
|
const p = abs ? abs : __require("path").join(root, rel);
|
|
54438
|
-
return
|
|
54438
|
+
return fs51.existsSync(p) ? fs51.readFileSync(p, "utf8") : "";
|
|
54439
54439
|
} catch {
|
|
54440
54440
|
return "";
|
|
54441
54441
|
}
|
|
@@ -55308,9 +55308,9 @@ ${editContext}`;
|
|
|
55308
55308
|
for (let i2 = 0; i2 < blocks.length; i2++) {
|
|
55309
55309
|
const b = blocks[i2];
|
|
55310
55310
|
const desired = typeof b.filename === "string" && b.filename.trim() ? b.filename.trim() : null;
|
|
55311
|
-
const
|
|
55311
|
+
const path64 = desired || suggestName2(request, b.language, i2);
|
|
55312
55312
|
initial.push({
|
|
55313
|
-
path:
|
|
55313
|
+
path: path64,
|
|
55314
55314
|
kind: "source",
|
|
55315
55315
|
action: "create",
|
|
55316
55316
|
description: describe2(b.language, ""),
|
|
@@ -55341,13 +55341,13 @@ ${editContext}`;
|
|
|
55341
55341
|
{ root: opts.root }
|
|
55342
55342
|
);
|
|
55343
55343
|
try {
|
|
55344
|
-
const [{ access: access18 },
|
|
55344
|
+
const [{ access: access18 }, path64] = await Promise.all([
|
|
55345
55345
|
import('fs/promises'),
|
|
55346
55346
|
import('path')
|
|
55347
55347
|
]);
|
|
55348
55348
|
for (const p of normalized) {
|
|
55349
55349
|
try {
|
|
55350
|
-
const absCandidate = p.absPath ? p.absPath :
|
|
55350
|
+
const absCandidate = p.absPath ? p.absPath : path64.join(opts.root, p.path);
|
|
55351
55351
|
await access18(absCandidate);
|
|
55352
55352
|
p.action = "modify";
|
|
55353
55353
|
if (isEditIntent) {
|
|
@@ -55539,12 +55539,12 @@ function languageExt(lang) {
|
|
|
55539
55539
|
}
|
|
55540
55540
|
async function journalResume(root, request, files) {
|
|
55541
55541
|
try {
|
|
55542
|
-
const
|
|
55542
|
+
const fs51 = await import('fs/promises');
|
|
55543
55543
|
const dir = path11__namespace.default.join(root, ".maria", "memory");
|
|
55544
|
-
await
|
|
55544
|
+
await fs51.mkdir(dir, { recursive: true });
|
|
55545
55545
|
const out = path11__namespace.default.join(dir, "resume-plan.json");
|
|
55546
55546
|
const payload = { request, createdAt: (/* @__PURE__ */ new Date()).toISOString(), files };
|
|
55547
|
-
await
|
|
55547
|
+
await fs51.writeFile(out, JSON.stringify(payload, null, 2), "utf8");
|
|
55548
55548
|
} catch {
|
|
55549
55549
|
}
|
|
55550
55550
|
}
|
|
@@ -55704,14 +55704,14 @@ async function ensureTopFolder(root, proposed, plans) {
|
|
|
55704
55704
|
return { folderName: unique };
|
|
55705
55705
|
}
|
|
55706
55706
|
async function ensureUniqueFolder(root, base) {
|
|
55707
|
-
const
|
|
55707
|
+
const fs51 = await import('fs/promises');
|
|
55708
55708
|
const pathMod = await import('path');
|
|
55709
55709
|
let name2 = sanitizeFolderName(base);
|
|
55710
55710
|
let suffix = 0;
|
|
55711
55711
|
for (; suffix < Number.MAX_SAFE_INTEGER; ) {
|
|
55712
55712
|
const candidate = suffix === 0 ? name2 : `${name2}-${String(suffix).padStart(2, "0")}`;
|
|
55713
55713
|
try {
|
|
55714
|
-
await
|
|
55714
|
+
await fs51.access(pathMod.join(root, candidate));
|
|
55715
55715
|
suffix += 1;
|
|
55716
55716
|
} catch {
|
|
55717
55717
|
return candidate;
|
|
@@ -55721,13 +55721,13 @@ async function ensureUniqueFolder(root, base) {
|
|
|
55721
55721
|
}
|
|
55722
55722
|
async function buildEditContext(root, files, maxLines, maxBytes) {
|
|
55723
55723
|
try {
|
|
55724
|
-
const
|
|
55724
|
+
const fs51 = await import('fs/promises');
|
|
55725
55725
|
const pathMod = await import('path');
|
|
55726
55726
|
const sections = [];
|
|
55727
55727
|
for (const rel of files) {
|
|
55728
55728
|
const full = pathMod.join(root, rel);
|
|
55729
55729
|
try {
|
|
55730
|
-
const buf = await
|
|
55730
|
+
const buf = await fs51.readFile(full);
|
|
55731
55731
|
const clipped = buf.length > maxBytes ? buf.subarray(0, maxBytes) : buf;
|
|
55732
55732
|
const text = clipped.toString("utf8").replace(/\r\n/g, "\n");
|
|
55733
55733
|
const lines = text.split("\n").slice(0, maxLines).join("\n");
|
|
@@ -55744,7 +55744,7 @@ ${lines}
|
|
|
55744
55744
|
}
|
|
55745
55745
|
}
|
|
55746
55746
|
async function resolveExplicitPaths(root, files, hintText) {
|
|
55747
|
-
const
|
|
55747
|
+
const fs51 = await import('fs/promises');
|
|
55748
55748
|
const pathMod = await import('path');
|
|
55749
55749
|
const { loadGlobby: loadGlobby2 } = await Promise.resolve().then(() => (init_esm_compat(), esm_compat_exports));
|
|
55750
55750
|
const globby = await loadGlobby2();
|
|
@@ -55762,7 +55762,7 @@ async function resolveExplicitPaths(root, files, hintText) {
|
|
|
55762
55762
|
const normalized = rel.replace(/^\/+/, "").replace(/\\/g, "/");
|
|
55763
55763
|
const fullExact = pathMod.join(root, normalized);
|
|
55764
55764
|
try {
|
|
55765
|
-
await
|
|
55765
|
+
await fs51.access(fullExact);
|
|
55766
55766
|
return normalized;
|
|
55767
55767
|
} catch {
|
|
55768
55768
|
}
|
|
@@ -55809,7 +55809,7 @@ async function resolveExplicitPaths(root, files, hintText) {
|
|
|
55809
55809
|
for (const pre of prefixes) {
|
|
55810
55810
|
const cand = pathMod.join(root, pre + normalized);
|
|
55811
55811
|
try {
|
|
55812
|
-
await
|
|
55812
|
+
await fs51.access(cand);
|
|
55813
55813
|
return (pre + normalized).replace(/^\/+/, "");
|
|
55814
55814
|
} catch {
|
|
55815
55815
|
}
|
|
@@ -55864,14 +55864,14 @@ async function resolveExplicitPaths(root, files, hintText) {
|
|
|
55864
55864
|
return out;
|
|
55865
55865
|
}
|
|
55866
55866
|
async function pickExistingFolderPrefix(root, parentPath) {
|
|
55867
|
-
const
|
|
55867
|
+
const fs51 = await import('fs/promises');
|
|
55868
55868
|
const pathMod = await import('path');
|
|
55869
55869
|
const parts = parentPath.replace(/^\/+/, "").split("/").filter(Boolean);
|
|
55870
55870
|
const prefixes = ["src", "app", "pages", ""];
|
|
55871
55871
|
for (const pre of prefixes) {
|
|
55872
55872
|
const test = pre ? pathMod.join(root, pre, ...parts) : pathMod.join(root, ...parts);
|
|
55873
55873
|
try {
|
|
55874
|
-
await
|
|
55874
|
+
await fs51.access(test);
|
|
55875
55875
|
return pre ? `${pre}/` : "";
|
|
55876
55876
|
} catch {
|
|
55877
55877
|
}
|
|
@@ -56231,16 +56231,16 @@ ${pretty}`);
|
|
|
56231
56231
|
}
|
|
56232
56232
|
async persistLastPlan(root, plans) {
|
|
56233
56233
|
try {
|
|
56234
|
-
const
|
|
56234
|
+
const fs51 = await import('fs/promises');
|
|
56235
56235
|
const p = path11__namespace.join(root, ".maria");
|
|
56236
|
-
await
|
|
56236
|
+
await fs51.mkdir(p, { recursive: true });
|
|
56237
56237
|
const out = path11__namespace.join(p, "last-plan.json");
|
|
56238
|
-
await
|
|
56238
|
+
await fs51.writeFile(out, JSON.stringify({ createdAt: (/* @__PURE__ */ new Date()).toISOString(), plans }, null, 2), "utf8");
|
|
56239
56239
|
} catch {
|
|
56240
56240
|
}
|
|
56241
56241
|
}
|
|
56242
56242
|
async applyPlan(plans, options) {
|
|
56243
|
-
const
|
|
56243
|
+
const fs51 = await import('fs/promises');
|
|
56244
56244
|
const created = [];
|
|
56245
56245
|
const modified = [];
|
|
56246
56246
|
const skipped = [];
|
|
@@ -56259,9 +56259,9 @@ ${pretty}`);
|
|
|
56259
56259
|
continue;
|
|
56260
56260
|
}
|
|
56261
56261
|
const tmp = full + `.tmp-${process.pid}-${Date.now()}`;
|
|
56262
|
-
await
|
|
56263
|
-
await
|
|
56264
|
-
await
|
|
56262
|
+
await fs51.mkdir(path11__namespace.dirname(full), { recursive: true });
|
|
56263
|
+
await fs51.writeFile(tmp, plan.preview || "", "utf8");
|
|
56264
|
+
await fs51.rename(tmp, full);
|
|
56265
56265
|
if (exists2) modified.push(plan.path);
|
|
56266
56266
|
else created.push(plan.path);
|
|
56267
56267
|
written++;
|
|
@@ -56272,7 +56272,7 @@ ${pretty}`);
|
|
|
56272
56272
|
if (options.rollback) {
|
|
56273
56273
|
for (const p of [...created, ...modified]) {
|
|
56274
56274
|
try {
|
|
56275
|
-
await
|
|
56275
|
+
await fs51.unlink(path11__namespace.join(options.root, p));
|
|
56276
56276
|
} catch {
|
|
56277
56277
|
}
|
|
56278
56278
|
}
|
|
@@ -56282,8 +56282,8 @@ ${pretty}`);
|
|
|
56282
56282
|
}
|
|
56283
56283
|
async pathExists(p) {
|
|
56284
56284
|
try {
|
|
56285
|
-
const
|
|
56286
|
-
await
|
|
56285
|
+
const fs51 = await import('fs/promises');
|
|
56286
|
+
await fs51.access(p);
|
|
56287
56287
|
return true;
|
|
56288
56288
|
} catch {
|
|
56289
56289
|
return false;
|
|
@@ -56394,17 +56394,17 @@ ${pretty}`);
|
|
|
56394
56394
|
// Attempt to collect attached files from context; map to AttachedFileContext
|
|
56395
56395
|
async collectAttachedFiles(context2) {
|
|
56396
56396
|
const list = [];
|
|
56397
|
-
const
|
|
56398
|
-
const
|
|
56397
|
+
const fs51 = await import('fs/promises');
|
|
56398
|
+
const path64 = await import('path');
|
|
56399
56399
|
const att = context2 && (context2.attachments || context2.input?.attachments) || [];
|
|
56400
56400
|
for (const a of att) {
|
|
56401
56401
|
try {
|
|
56402
56402
|
const p = a.path || a.filePath || a.name || "";
|
|
56403
|
-
const originalName = a.name ||
|
|
56403
|
+
const originalName = a.name || path64.basename(p || `attachment_${Date.now().toString(36)}`);
|
|
56404
56404
|
let content = a.content;
|
|
56405
56405
|
if (!content && p) {
|
|
56406
|
-
const abs =
|
|
56407
|
-
content = await
|
|
56406
|
+
const abs = path64.isAbsolute(p) ? p : path64.join(process.cwd(), p);
|
|
56407
|
+
content = await fs51.readFile(abs, "utf8");
|
|
56408
56408
|
}
|
|
56409
56409
|
if (!content) continue;
|
|
56410
56410
|
list.push({ originalName, pathHint: p || void 0, content, size: Buffer.byteLength(content, "utf8"), mime: a.mime || a.type });
|
|
@@ -56970,12 +56970,12 @@ async function scanRoot(opts) {
|
|
|
56970
56970
|
const filepath = path11__namespace.join(cwd2, name2);
|
|
56971
56971
|
const result = await safeRead(filepath, 512 * 1024, maxLines, signal);
|
|
56972
56972
|
if (result.head || result.meta) {
|
|
56973
|
-
let
|
|
56973
|
+
let meta27 = result.meta || object;
|
|
56974
56974
|
if (name2 === "package.json" && result.head) {
|
|
56975
56975
|
try {
|
|
56976
56976
|
const pkg = JSON.parse(result.head);
|
|
56977
|
-
|
|
56978
|
-
...
|
|
56977
|
+
meta27 = {
|
|
56978
|
+
...meta27,
|
|
56979
56979
|
name: pkg.name,
|
|
56980
56980
|
version: pkg.version,
|
|
56981
56981
|
type: pkg.type,
|
|
@@ -56988,14 +56988,14 @@ async function scanRoot(opts) {
|
|
|
56988
56988
|
workspaces: pkg.workspaces
|
|
56989
56989
|
};
|
|
56990
56990
|
} catch (e2) {
|
|
56991
|
-
|
|
56991
|
+
meta27.parseError = true;
|
|
56992
56992
|
}
|
|
56993
56993
|
}
|
|
56994
56994
|
findings.push({
|
|
56995
56995
|
file: name2,
|
|
56996
56996
|
kind: "read",
|
|
56997
56997
|
head: result.head,
|
|
56998
|
-
meta:
|
|
56998
|
+
meta: meta27,
|
|
56999
56999
|
truncated: result.truncated
|
|
57000
57000
|
});
|
|
57001
57001
|
}
|
|
@@ -57333,19 +57333,19 @@ function extractPackageInfo(findings) {
|
|
|
57333
57333
|
hasPostinstall: false
|
|
57334
57334
|
};
|
|
57335
57335
|
}
|
|
57336
|
-
const
|
|
57336
|
+
const meta27 = pkgFinding.meta;
|
|
57337
57337
|
return {
|
|
57338
|
-
name:
|
|
57339
|
-
version:
|
|
57340
|
-
type:
|
|
57341
|
-
scripts:
|
|
57342
|
-
hasPostinstall: !!
|
|
57343
|
-
bin:
|
|
57344
|
-
main:
|
|
57345
|
-
exports:
|
|
57346
|
-
dependencies:
|
|
57347
|
-
devDependencies:
|
|
57348
|
-
workspaces:
|
|
57338
|
+
name: meta27.name,
|
|
57339
|
+
version: meta27.version,
|
|
57340
|
+
type: meta27.type,
|
|
57341
|
+
scripts: meta27.scripts ? Object.keys(meta27.scripts) : [],
|
|
57342
|
+
hasPostinstall: !!meta27.scripts?.postinstall,
|
|
57343
|
+
bin: meta27.bin,
|
|
57344
|
+
main: meta27.main,
|
|
57345
|
+
exports: meta27.exports,
|
|
57346
|
+
dependencies: meta27.dependencies || [],
|
|
57347
|
+
devDependencies: meta27.devDependencies || [],
|
|
57348
|
+
workspaces: meta27.workspaces
|
|
57349
57349
|
};
|
|
57350
57350
|
}
|
|
57351
57351
|
function collectWarnings(pkg, findings, cwd2) {
|
|
@@ -57496,9 +57496,9 @@ function calculateMetrics(findings, startTime) {
|
|
|
57496
57496
|
}
|
|
57497
57497
|
function renderFinding(f3) {
|
|
57498
57498
|
const title = `### ${f3.kind.toUpperCase()} \u2014 ${f3.file}`;
|
|
57499
|
-
let
|
|
57499
|
+
let meta27 = "";
|
|
57500
57500
|
if (f3.meta && Object.keys(f3.meta).length > 0) {
|
|
57501
|
-
|
|
57501
|
+
meta27 = `
|
|
57502
57502
|
<details><summary>meta</summary>
|
|
57503
57503
|
|
|
57504
57504
|
\`\`\`json
|
|
@@ -57519,7 +57519,7 @@ ${f3.head.trim()}
|
|
|
57519
57519
|
}
|
|
57520
57520
|
const truncInfo = f3.truncated ? `
|
|
57521
57521
|
> _truncated preview_` : "";
|
|
57522
|
-
return [title,
|
|
57522
|
+
return [title, meta27, content, truncInfo, ""].join("\n");
|
|
57523
57523
|
}
|
|
57524
57524
|
function safeJsonStringify(obj) {
|
|
57525
57525
|
try {
|
|
@@ -63093,17 +63093,17 @@ var init_GraphEngine = __esm({
|
|
|
63093
63093
|
const visited = /* @__PURE__ */ new Set();
|
|
63094
63094
|
const queue = [{ id: from, path: [from] }];
|
|
63095
63095
|
while (queue.length) {
|
|
63096
|
-
const { id, path:
|
|
63096
|
+
const { id, path: path64 } = queue.shift();
|
|
63097
63097
|
if (visited.has(id)) continue;
|
|
63098
63098
|
visited.add(id);
|
|
63099
63099
|
const neighbors = this.edges.get(id) || /* @__PURE__ */ new Set();
|
|
63100
63100
|
for (const e2 of neighbors) {
|
|
63101
63101
|
if (e2.to === to) {
|
|
63102
|
-
const res = [...
|
|
63102
|
+
const res = [...path64, to];
|
|
63103
63103
|
this.recordQueryTime(Date.now() - start);
|
|
63104
63104
|
return res;
|
|
63105
63105
|
}
|
|
63106
|
-
if (!visited.has(e2.to)) queue.push({ id: e2.to, path: [...
|
|
63106
|
+
if (!visited.has(e2.to)) queue.push({ id: e2.to, path: [...path64, e2.to] });
|
|
63107
63107
|
}
|
|
63108
63108
|
}
|
|
63109
63109
|
this.recordQueryTime(Date.now() - start);
|
|
@@ -65770,12 +65770,12 @@ This will:
|
|
|
65770
65770
|
};
|
|
65771
65771
|
const result = await this.deltaDetector.detectDelta(root, deltaOptions);
|
|
65772
65772
|
const files = [
|
|
65773
|
-
...result.changed.map((
|
|
65774
|
-
_path:
|
|
65775
|
-
type: previousState?.fileHashes?.[
|
|
65773
|
+
...result.changed.map((path64) => ({
|
|
65774
|
+
_path: path64,
|
|
65775
|
+
type: previousState?.fileHashes?.[path64] ? "modified" : "added"
|
|
65776
65776
|
})),
|
|
65777
|
-
...result.deleted.map((
|
|
65778
|
-
_path:
|
|
65777
|
+
...result.deleted.map((path64) => ({
|
|
65778
|
+
_path: path64,
|
|
65779
65779
|
type: "deleted"
|
|
65780
65780
|
}))
|
|
65781
65781
|
];
|
|
@@ -69502,13 +69502,13 @@ async function checkShield(commandName, userPlan = "free") {
|
|
|
69502
69502
|
}
|
|
69503
69503
|
async function loadManifest() {
|
|
69504
69504
|
try {
|
|
69505
|
-
const
|
|
69506
|
-
const
|
|
69507
|
-
const manifestPath =
|
|
69505
|
+
const fs51 = await import('fs');
|
|
69506
|
+
const path64 = await import('path');
|
|
69507
|
+
const manifestPath = path64.join(
|
|
69508
69508
|
__dirname,
|
|
69509
69509
|
"../command-manifest-v2.1.json"
|
|
69510
69510
|
);
|
|
69511
|
-
const content =
|
|
69511
|
+
const content = fs51.readFileSync(manifestPath, "utf-8");
|
|
69512
69512
|
return JSON.parse(content);
|
|
69513
69513
|
} catch {
|
|
69514
69514
|
return { commands: [] };
|
|
@@ -70602,6 +70602,1145 @@ var init_gpu_command = __esm({
|
|
|
70602
70602
|
gpu_command_default = GPUCommand;
|
|
70603
70603
|
}
|
|
70604
70604
|
});
|
|
70605
|
+
var CriteriaManager;
|
|
70606
|
+
var init_CriteriaManager = __esm({
|
|
70607
|
+
"src/services/evaluation/CriteriaManager.ts"() {
|
|
70608
|
+
CriteriaManager = class {
|
|
70609
|
+
constructor(projectRoot) {
|
|
70610
|
+
this.projectRoot = projectRoot;
|
|
70611
|
+
}
|
|
70612
|
+
getDefaultPath() {
|
|
70613
|
+
return path11__namespace.default.join(this.projectRoot, ".maria", "evaluation.criteria.json");
|
|
70614
|
+
}
|
|
70615
|
+
async ensureCriteriaFile(customPath) {
|
|
70616
|
+
const criteriaPath = customPath ? path11__namespace.default.isAbsolute(customPath) ? customPath : path11__namespace.default.join(this.projectRoot, customPath) : this.getDefaultPath();
|
|
70617
|
+
const dir = path11__namespace.default.dirname(criteriaPath);
|
|
70618
|
+
await fs21.promises.mkdir(dir, { recursive: true });
|
|
70619
|
+
try {
|
|
70620
|
+
await fs21.promises.access(criteriaPath);
|
|
70621
|
+
return criteriaPath;
|
|
70622
|
+
} catch {
|
|
70623
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
70624
|
+
const payload = {
|
|
70625
|
+
version: "1.0.0",
|
|
70626
|
+
project: path11__namespace.default.basename(this.projectRoot) || "project",
|
|
70627
|
+
createdAt: now2,
|
|
70628
|
+
updatedAt: now2,
|
|
70629
|
+
items: this.createDefaultCriteria()
|
|
70630
|
+
};
|
|
70631
|
+
await fs21.promises.writeFile(criteriaPath, JSON.stringify(payload, null, 2), "utf8");
|
|
70632
|
+
return criteriaPath;
|
|
70633
|
+
}
|
|
70634
|
+
}
|
|
70635
|
+
async loadCriteria(criteriaPath) {
|
|
70636
|
+
const buf = await fs21.promises.readFile(criteriaPath, "utf8");
|
|
70637
|
+
const json = JSON.parse(buf);
|
|
70638
|
+
if (!Array.isArray(json.items)) {
|
|
70639
|
+
throw new Error("Invalid criteria file: items missing");
|
|
70640
|
+
}
|
|
70641
|
+
return json;
|
|
70642
|
+
}
|
|
70643
|
+
async updateCriteria(criteriaPath, updater) {
|
|
70644
|
+
const current = await this.loadCriteria(criteriaPath);
|
|
70645
|
+
const next = updater({ ...current, updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
70646
|
+
await fs21.promises.writeFile(criteriaPath, JSON.stringify(next, null, 2), "utf8");
|
|
70647
|
+
}
|
|
70648
|
+
createDefaultCriteria() {
|
|
70649
|
+
const items = [
|
|
70650
|
+
["clarity", "Clarity: Clear goals and requirements", 0.15, "Are requirements, specs, and assumptions explicitly stated?"],
|
|
70651
|
+
["feasibility", "Feasibility: Realistic scope and timeline", 0.15, "Are dependencies, risks, and alternatives considered?"],
|
|
70652
|
+
["maintainability", "Maintainability: Structure and reuse", 0.15, "Does design follow separation of concerns and sound naming?"],
|
|
70653
|
+
["testability", "Testability: Strategy and coverage", 0.1, "Are unit/integration/regression test approaches considered?"],
|
|
70654
|
+
["security", "Security: Validation and secret handling", 0.1, "Are input validation, authz, and secret management addressed?"],
|
|
70655
|
+
["performance", "Performance: Efficiency and scalability", 0.1, "Are data volume, I/O, and bottlenecks considered?"],
|
|
70656
|
+
["alignment", "Project Alignment: Conventions and structure", 0.15, "Does it follow folder structure, naming, and tooling?"],
|
|
70657
|
+
["completeness", "Completeness: Edge cases and failures", 0.1, "Are inputs/outputs/errors/logging/edge cases covered?"]
|
|
70658
|
+
];
|
|
70659
|
+
return items.map(([id, name2, weight, rubric]) => ({ id, name: name2, weight, rubric, description: name2 }));
|
|
70660
|
+
}
|
|
70661
|
+
};
|
|
70662
|
+
}
|
|
70663
|
+
});
|
|
70664
|
+
|
|
70665
|
+
// src/services/evaluation/ScoringEngine.ts
|
|
70666
|
+
var ScoringEngine;
|
|
70667
|
+
var init_ScoringEngine = __esm({
|
|
70668
|
+
"src/services/evaluation/ScoringEngine.ts"() {
|
|
70669
|
+
ScoringEngine = class {
|
|
70670
|
+
async evaluate(input3, criteria) {
|
|
70671
|
+
const textBundle = this.joinInput(input3);
|
|
70672
|
+
const details = [];
|
|
70673
|
+
for (const item of criteria.items) {
|
|
70674
|
+
const score = this.heuristicScore(textBundle, item.id);
|
|
70675
|
+
const reason = this.generateReason(textBundle, item.id);
|
|
70676
|
+
details.push({ id: item.id, name: item.name, weight: item.weight, score, reason });
|
|
70677
|
+
}
|
|
70678
|
+
const totalWeight = details.reduce((s2, d) => s2 + d.weight, 0) || 1;
|
|
70679
|
+
const totalScore = details.reduce((s2, d) => s2 + d.score * d.weight, 0) / totalWeight;
|
|
70680
|
+
return { totalScore, details };
|
|
70681
|
+
}
|
|
70682
|
+
joinInput(input3) {
|
|
70683
|
+
const parts = [];
|
|
70684
|
+
if (input3.idea) parts.push(`IDEA:
|
|
70685
|
+
${input3.idea}`);
|
|
70686
|
+
if (input3.code) parts.push(`CODE:
|
|
70687
|
+
${input3.code}`);
|
|
70688
|
+
if (input3.files && input3.files.length) {
|
|
70689
|
+
for (const f3 of input3.files) {
|
|
70690
|
+
parts.push(`FILE ${f3.path}:
|
|
70691
|
+
${f3.content}`);
|
|
70692
|
+
}
|
|
70693
|
+
}
|
|
70694
|
+
return parts.join("\n\n");
|
|
70695
|
+
}
|
|
70696
|
+
heuristicScore(bundle, aspect) {
|
|
70697
|
+
const lower2 = bundle.toLowerCase();
|
|
70698
|
+
const checks = {
|
|
70699
|
+
clarity: ["objective", "\u76EE\u7684", "\u8981\u4EF6", "spec", "\u4ED5\u69D8"],
|
|
70700
|
+
feasibility: ["risk", "\u30EA\u30B9\u30AF", "plan", "\u8A08\u753B", "timeline"],
|
|
70701
|
+
maintainability: ["function", "class", "interface", "\u5206\u5272", "\u30E2\u30B8\u30E5\u30FC\u30EB"],
|
|
70702
|
+
testability: ["test", "spec", "vitest", "jest", "coverage"],
|
|
70703
|
+
security: ["secret", "env", "sanitize", "validation", "\u6A29\u9650"],
|
|
70704
|
+
performance: ["cache", "\u6027\u80FD", "optimiz", "stream", "memo"],
|
|
70705
|
+
alignment: ["src/", "pnpm", "eslint", "prettier", "convention"],
|
|
70706
|
+
completeness: ["edge case", "\u7570\u5E38\u7CFB", "\u30A8\u30E9\u30FC", "fallback", "retry"]
|
|
70707
|
+
};
|
|
70708
|
+
const words = checks[aspect] || [];
|
|
70709
|
+
const hits = words.reduce((c, w) => c + (lower2.includes(w) ? 1 : 0), 0);
|
|
70710
|
+
if (hits === 0) return 0.3;
|
|
70711
|
+
if (hits === 1) return 0.55;
|
|
70712
|
+
if (hits === 2) return 0.75;
|
|
70713
|
+
return 0.9;
|
|
70714
|
+
}
|
|
70715
|
+
generateReason(bundle, aspect) {
|
|
70716
|
+
switch (aspect) {
|
|
70717
|
+
case "clarity":
|
|
70718
|
+
return "\u8981\u6C42\u3084\u4ED5\u69D8\u306E\u660E\u793A\u5EA6\u304B\u3089\u6982\u7B97";
|
|
70719
|
+
case "feasibility":
|
|
70720
|
+
return "\u30EA\u30B9\u30AF\u30FB\u8A08\u753B\u306E\u8A18\u8F09\u6709\u7121\u304B\u3089\u6982\u7B97";
|
|
70721
|
+
case "maintainability":
|
|
70722
|
+
return "\u69CB\u9020\u5316\u30FB\u518D\u5229\u7528\u6027\u306E\u5146\u5019\u304B\u3089\u6982\u7B97";
|
|
70723
|
+
case "testability":
|
|
70724
|
+
return "\u30C6\u30B9\u30C8\u95A2\u9023\u306E\u8A00\u53CA\u304B\u3089\u6982\u7B97";
|
|
70725
|
+
case "security":
|
|
70726
|
+
return "\u79D8\u5BC6\u7BA1\u7406\u30FB\u5165\u529B\u691C\u8A3C\u306E\u8A00\u53CA\u304B\u3089\u6982\u7B97";
|
|
70727
|
+
case "performance":
|
|
70728
|
+
return "\u6027\u80FD\u6700\u9069\u5316\u306E\u793A\u5506\u304B\u3089\u6982\u7B97";
|
|
70729
|
+
case "alignment":
|
|
70730
|
+
return "\u30EA\u30DD\u30B8\u30C8\u30EA\u898F\u7D04\u3078\u306E\u8A00\u53CA\u304B\u3089\u6982\u7B97";
|
|
70731
|
+
case "completeness":
|
|
70732
|
+
return "\u7570\u5E38\u7CFB\u30FB\u30A8\u30C3\u30B8\u30B1\u30FC\u30B9\u306E\u7DB2\u7F85\u5EA6\u304B\u3089\u6982\u7B97";
|
|
70733
|
+
default:
|
|
70734
|
+
return "\u30D2\u30E5\u30FC\u30EA\u30B9\u30C6\u30A3\u30C3\u30AF\u8A55\u4FA1";
|
|
70735
|
+
}
|
|
70736
|
+
}
|
|
70737
|
+
};
|
|
70738
|
+
}
|
|
70739
|
+
});
|
|
70740
|
+
var EvaluationOrchestrator;
|
|
70741
|
+
var init_EvaluationOrchestrator = __esm({
|
|
70742
|
+
"src/services/evaluation/EvaluationOrchestrator.ts"() {
|
|
70743
|
+
init_CriteriaManager();
|
|
70744
|
+
init_ScoringEngine();
|
|
70745
|
+
init_api_caller();
|
|
70746
|
+
EvaluationOrchestrator = class {
|
|
70747
|
+
constructor(projectRoot) {
|
|
70748
|
+
this.projectRoot = projectRoot;
|
|
70749
|
+
this.criteriaManager = new CriteriaManager(projectRoot);
|
|
70750
|
+
this.engine = new ScoringEngine();
|
|
70751
|
+
}
|
|
70752
|
+
criteriaManager;
|
|
70753
|
+
engine;
|
|
70754
|
+
async assess(options) {
|
|
70755
|
+
const criteriaPath = options.criteria ? path11__namespace.default.isAbsolute(options.criteria) ? options.criteria : path11__namespace.default.join(this.projectRoot, options.criteria) : this.criteriaManager.getDefaultPath();
|
|
70756
|
+
const needGenerate = !!options.regenerateCriteria || !await this.exists(criteriaPath);
|
|
70757
|
+
if (needGenerate) {
|
|
70758
|
+
try {
|
|
70759
|
+
await this.generateCriteriaWithLLM(criteriaPath, {
|
|
70760
|
+
idea: options.idea,
|
|
70761
|
+
code: options.code,
|
|
70762
|
+
files: options.files || []
|
|
70763
|
+
});
|
|
70764
|
+
} catch {
|
|
70765
|
+
await this.criteriaManager.ensureCriteriaFile(criteriaPath);
|
|
70766
|
+
}
|
|
70767
|
+
} else {
|
|
70768
|
+
await this.criteriaManager.ensureCriteriaFile(criteriaPath);
|
|
70769
|
+
}
|
|
70770
|
+
const criteria = await this.criteriaManager.loadCriteria(criteriaPath);
|
|
70771
|
+
if (options.criteriaOnly) {
|
|
70772
|
+
return { criteriaPath, result: null };
|
|
70773
|
+
}
|
|
70774
|
+
const files = await this.readFiles(options.files || []);
|
|
70775
|
+
const input3 = {
|
|
70776
|
+
idea: options.idea,
|
|
70777
|
+
code: options.code,
|
|
70778
|
+
files
|
|
70779
|
+
};
|
|
70780
|
+
const result = await this.scoreWithLLM(input3, criteria);
|
|
70781
|
+
result.files = input3.files || [];
|
|
70782
|
+
return { criteriaPath, result };
|
|
70783
|
+
}
|
|
70784
|
+
async exists(p) {
|
|
70785
|
+
try {
|
|
70786
|
+
await fs21.promises.stat(p);
|
|
70787
|
+
return true;
|
|
70788
|
+
} catch {
|
|
70789
|
+
return false;
|
|
70790
|
+
}
|
|
70791
|
+
}
|
|
70792
|
+
async generateCriteriaWithLLM(criteriaPath, context2) {
|
|
70793
|
+
const relPath = path11__namespace.default.relative(this.projectRoot, criteriaPath).replace(/\\/g, "/");
|
|
70794
|
+
const targetPath = relPath.startsWith(".") ? relPath : relPath;
|
|
70795
|
+
const dir = path11__namespace.default.dirname(criteriaPath);
|
|
70796
|
+
await fs21.promises.mkdir(dir, { recursive: true });
|
|
70797
|
+
const system = [
|
|
70798
|
+
"You are an expert evaluation designer.",
|
|
70799
|
+
"Create a JSON criteria file for evaluating the given idea/code/files. If a local file path is provided, make sure you read the uploaded file before taking any actions.",
|
|
70800
|
+
"Respond ONLY with a single multi-file section in this exact format:",
|
|
70801
|
+
`[BEGIN file: ${targetPath}]`,
|
|
70802
|
+
"{JSON}",
|
|
70803
|
+
"[END]",
|
|
70804
|
+
"Do not include any other text or markdown.",
|
|
70805
|
+
"JSON schema:",
|
|
70806
|
+
'{ "version": "1.0.0", "project": string, "createdAt": ISO string, "updatedAt": ISO string, "items": [{ "id": string, "name": string, "description": string, "weight": number (0..1), "rubric": string }] }',
|
|
70807
|
+
"Total weight across items should be ~1. Use concise English labels and rubrics tailored to the input."
|
|
70808
|
+
].join("\n");
|
|
70809
|
+
const user = [
|
|
70810
|
+
`Project: ${path11__namespace.default.basename(this.projectRoot)}`,
|
|
70811
|
+
context2.idea ? `Idea:
|
|
70812
|
+
${context2.idea}` : void 0,
|
|
70813
|
+
context2.code ? `Code snippet:
|
|
70814
|
+
${context2.code}` : void 0,
|
|
70815
|
+
context2.files.length ? `Files:
|
|
70816
|
+
${context2.files.map((f3) => `- ${f3}`).join("\n")}` : void 0
|
|
70817
|
+
].filter(Boolean).join("\n\n");
|
|
70818
|
+
const response = await callAPI("/v1/ai-proxy", {
|
|
70819
|
+
method: "POST",
|
|
70820
|
+
body: {
|
|
70821
|
+
prompt: `${system}
|
|
70822
|
+
|
|
70823
|
+
---
|
|
70824
|
+
|
|
70825
|
+
${user}`,
|
|
70826
|
+
taskType: "evaluation"
|
|
70827
|
+
}
|
|
70828
|
+
});
|
|
70829
|
+
const content = (response?.data?.content || response?.output || "").trim();
|
|
70830
|
+
if (!content) throw new Error("Empty LLM response");
|
|
70831
|
+
const fileMap = this.parseFileSections(content);
|
|
70832
|
+
let payload;
|
|
70833
|
+
if (fileMap.size > 0) {
|
|
70834
|
+
payload = fileMap.get(targetPath) || Array.from(fileMap.values())[0];
|
|
70835
|
+
} else {
|
|
70836
|
+
payload = this.extractFirstJsonObject(content) || content;
|
|
70837
|
+
}
|
|
70838
|
+
try {
|
|
70839
|
+
JSON.parse(payload);
|
|
70840
|
+
} catch {
|
|
70841
|
+
throw new Error("Invalid JSON in generated criteria");
|
|
70842
|
+
}
|
|
70843
|
+
await fs21.promises.writeFile(criteriaPath, payload, "utf8");
|
|
70844
|
+
}
|
|
70845
|
+
parseFileSections(text) {
|
|
70846
|
+
const map = /* @__PURE__ */ new Map();
|
|
70847
|
+
const regex2 = /\[BEGIN\s+file:\s*([^\]]+)\]\r?\n([\s\S]*?)\[END\]/gi;
|
|
70848
|
+
let m2;
|
|
70849
|
+
while ((m2 = regex2.exec(text)) !== null) {
|
|
70850
|
+
const file = m2[1].trim();
|
|
70851
|
+
const body = m2[2];
|
|
70852
|
+
map.set(file, body);
|
|
70853
|
+
}
|
|
70854
|
+
return map;
|
|
70855
|
+
}
|
|
70856
|
+
extractFirstJsonObject(text) {
|
|
70857
|
+
const fenceJson = /```\s*json\s*\r?\n([\s\S]*?)```/i.exec(text);
|
|
70858
|
+
if (fenceJson) return fenceJson[1];
|
|
70859
|
+
const fencePlain = /```\s*\r?\n([\s\S]*?)```/i.exec(text);
|
|
70860
|
+
if (fencePlain) {
|
|
70861
|
+
const body = fencePlain[1];
|
|
70862
|
+
try {
|
|
70863
|
+
JSON.parse(body);
|
|
70864
|
+
return body;
|
|
70865
|
+
} catch {
|
|
70866
|
+
}
|
|
70867
|
+
}
|
|
70868
|
+
const defenced = text.replace(/```[a-zA-Z]*\s*\r?\n([\s\S]*?)```/g, "$1");
|
|
70869
|
+
const start = defenced.indexOf("{");
|
|
70870
|
+
const end = defenced.lastIndexOf("}");
|
|
70871
|
+
if (start >= 0 && end > start) {
|
|
70872
|
+
const cand = defenced.slice(start, end + 1);
|
|
70873
|
+
try {
|
|
70874
|
+
JSON.parse(cand);
|
|
70875
|
+
return cand;
|
|
70876
|
+
} catch {
|
|
70877
|
+
}
|
|
70878
|
+
}
|
|
70879
|
+
return null;
|
|
70880
|
+
}
|
|
70881
|
+
async scoreWithLLM(input3, criteria) {
|
|
70882
|
+
const criteriaPreview = criteria.items.map((it) => ({ id: it.id, name: it.name, weight: it.weight, rubric: it.rubric })).slice(0, 20);
|
|
70883
|
+
const parts = [];
|
|
70884
|
+
if (input3.idea) parts.push(`Idea:
|
|
70885
|
+
${input3.idea}`);
|
|
70886
|
+
if (input3.code) parts.push(`Code:
|
|
70887
|
+
${input3.code}`);
|
|
70888
|
+
const files = input3.files || [];
|
|
70889
|
+
if (files.length) {
|
|
70890
|
+
parts.push(`Files attached:
|
|
70891
|
+
${files.slice(0, 20).map((f3) => `- ${f3.path}`).join("\n")}`);
|
|
70892
|
+
}
|
|
70893
|
+
const bundle = parts.join("\n\n");
|
|
70894
|
+
const system = [
|
|
70895
|
+
"You are an impartial evaluator. Score each criterion between 0 and 1.",
|
|
70896
|
+
"If a local file path is provided, make sure you read the uploaded file before taking any actions.",
|
|
70897
|
+
"Return JSON only in the following schema:",
|
|
70898
|
+
'{ "totalScore": number (0..1), "details": [{ "id": string, "score": number (0..1), "reason": string }] }',
|
|
70899
|
+
"Keep reasons short (<= 120 chars)."
|
|
70900
|
+
].join("\n");
|
|
70901
|
+
const user = [
|
|
70902
|
+
`Criteria: ${JSON.stringify(criteriaPreview)}`,
|
|
70903
|
+
"Input to evaluate:",
|
|
70904
|
+
bundle
|
|
70905
|
+
].join("\n\n");
|
|
70906
|
+
(input3.files || []).some((f3) => f3.mime && f3.mime !== "text/plain");
|
|
70907
|
+
const provider = "google";
|
|
70908
|
+
const model = "gemini-2.5-flash";
|
|
70909
|
+
const response = await callAPI("/v1/ai-proxy", {
|
|
70910
|
+
method: "POST",
|
|
70911
|
+
body: {
|
|
70912
|
+
provider,
|
|
70913
|
+
model,
|
|
70914
|
+
prompt: `${system}
|
|
70915
|
+
|
|
70916
|
+
---
|
|
70917
|
+
|
|
70918
|
+
${user}`,
|
|
70919
|
+
taskType: "evaluation",
|
|
70920
|
+
metadata: {
|
|
70921
|
+
attachments: (input3.files || []).map((f3) => this.toAttachmentPayload(f3))
|
|
70922
|
+
}
|
|
70923
|
+
}
|
|
70924
|
+
});
|
|
70925
|
+
const raw = (response?.data?.content || response?.output || "").trim();
|
|
70926
|
+
if (!raw) throw new Error("Empty LLM scoring response");
|
|
70927
|
+
let jsonText = this.extractFirstJsonObject(raw) || raw;
|
|
70928
|
+
const sections = this.parseFileSections(raw);
|
|
70929
|
+
if (sections.size > 0) {
|
|
70930
|
+
jsonText = Array.from(sections.values())[0];
|
|
70931
|
+
}
|
|
70932
|
+
let parsed;
|
|
70933
|
+
try {
|
|
70934
|
+
parsed = JSON.parse(jsonText);
|
|
70935
|
+
} catch {
|
|
70936
|
+
return { totalScore: 0, details: criteria.items.map((it) => ({ id: it.id, name: it.name, weight: it.weight, score: 0, reason: "" })), passThroughText: raw };
|
|
70937
|
+
}
|
|
70938
|
+
const details = criteria.items.map((it) => {
|
|
70939
|
+
const found = parsed.details.find((d) => d.id === it.id);
|
|
70940
|
+
const score = Math.max(0, Math.min(1, found?.score ?? 0));
|
|
70941
|
+
return { id: it.id, name: it.name, weight: it.weight, score, reason: found?.reason || "" };
|
|
70942
|
+
});
|
|
70943
|
+
const totalWeight = details.reduce((s2, d) => s2 + d.weight, 0) || 1;
|
|
70944
|
+
const weighted = details.reduce((s2, d) => s2 + d.score * d.weight, 0) / totalWeight;
|
|
70945
|
+
const totalScore = Number.isFinite(parsed.totalScore) ? Math.max(0, Math.min(1, parsed.totalScore)) : weighted;
|
|
70946
|
+
return { totalScore, details };
|
|
70947
|
+
}
|
|
70948
|
+
toAttachmentPayload(file) {
|
|
70949
|
+
const ext2 = path11__namespace.default.extname(file.path).toLowerCase();
|
|
70950
|
+
const mime = file.mime || (ext2 === ".pdf" ? "application/pdf" : "text/plain");
|
|
70951
|
+
const b64 = file.binaryBase64 || Buffer.from(file.content || "", "utf8").toString("base64");
|
|
70952
|
+
return { name: path11__namespace.default.basename(file.path), path: file.path, mime, data_base64: b64 };
|
|
70953
|
+
}
|
|
70954
|
+
async readFiles(pathsInput) {
|
|
70955
|
+
const out = [];
|
|
70956
|
+
for (const p of pathsInput) {
|
|
70957
|
+
const normalized = p.replace(/^"|"$/g, "").replace(/^'|'$/g, "");
|
|
70958
|
+
const abs = path11__namespace.default.isAbsolute(normalized) ? normalized : path11__namespace.default.join(this.projectRoot, normalized);
|
|
70959
|
+
try {
|
|
70960
|
+
const stat13 = await fs21.promises.stat(abs);
|
|
70961
|
+
if (stat13.isDirectory()) {
|
|
70962
|
+
continue;
|
|
70963
|
+
}
|
|
70964
|
+
const ext2 = path11__namespace.default.extname(abs).toLowerCase();
|
|
70965
|
+
const raw = await fs21.promises.readFile(abs);
|
|
70966
|
+
let content = "";
|
|
70967
|
+
if (/\.pdf$/i.test(abs)) {
|
|
70968
|
+
content = await this.tryExtractPdfText(abs);
|
|
70969
|
+
} else {
|
|
70970
|
+
try {
|
|
70971
|
+
content = raw.toString("utf8");
|
|
70972
|
+
} catch {
|
|
70973
|
+
content = "";
|
|
70974
|
+
}
|
|
70975
|
+
}
|
|
70976
|
+
const mime = ext2 === ".pdf" ? "application/pdf" : "text/plain";
|
|
70977
|
+
const binaryBase64 = raw.toString("base64");
|
|
70978
|
+
out.push({ path: abs, content, binaryBase64, mime });
|
|
70979
|
+
} catch {
|
|
70980
|
+
}
|
|
70981
|
+
}
|
|
70982
|
+
return out;
|
|
70983
|
+
}
|
|
70984
|
+
async tryExtractPdfText(absPath) {
|
|
70985
|
+
try {
|
|
70986
|
+
const buf = await fs21.promises.readFile(absPath);
|
|
70987
|
+
try {
|
|
70988
|
+
const mod = await import('pdf-parse');
|
|
70989
|
+
const pdfParse = mod?.default || mod;
|
|
70990
|
+
if (typeof pdfParse === "function") {
|
|
70991
|
+
const res = await pdfParse(buf);
|
|
70992
|
+
const text = (res?.text || "").trim();
|
|
70993
|
+
if (text) return text;
|
|
70994
|
+
}
|
|
70995
|
+
} catch {
|
|
70996
|
+
}
|
|
70997
|
+
const kb = Math.round(buf.byteLength / 1024);
|
|
70998
|
+
return `[[PDF ${absPath} (${kb} KB) \u2014 text extraction unavailable in this environment]]`;
|
|
70999
|
+
} catch {
|
|
71000
|
+
return "[[PDF read error]]";
|
|
71001
|
+
}
|
|
71002
|
+
}
|
|
71003
|
+
};
|
|
71004
|
+
}
|
|
71005
|
+
});
|
|
71006
|
+
function extractFirstJson(text) {
|
|
71007
|
+
const fence = /```json\r?\n([\s\S]*?)```/i.exec(text);
|
|
71008
|
+
if (fence) return fence[1];
|
|
71009
|
+
const start = text.indexOf("{");
|
|
71010
|
+
const end = text.lastIndexOf("}");
|
|
71011
|
+
if (start >= 0 && end > start) {
|
|
71012
|
+
const cand = text.slice(start, end + 1);
|
|
71013
|
+
try {
|
|
71014
|
+
JSON.parse(cand);
|
|
71015
|
+
return cand;
|
|
71016
|
+
} catch {
|
|
71017
|
+
}
|
|
71018
|
+
}
|
|
71019
|
+
return null;
|
|
71020
|
+
}
|
|
71021
|
+
function sanitizePath(candidate, cwd2) {
|
|
71022
|
+
const normalized = path11__namespace.default.normalize(candidate);
|
|
71023
|
+
const absolute = path11__namespace.default.isAbsolute(normalized) ? normalized : path11__namespace.default.join(cwd2, normalized);
|
|
71024
|
+
const resolved = path11__namespace.default.resolve(absolute);
|
|
71025
|
+
const root = path11__namespace.default.resolve(cwd2);
|
|
71026
|
+
if (!resolved.startsWith(root)) return void 0;
|
|
71027
|
+
return resolved;
|
|
71028
|
+
}
|
|
71029
|
+
async function inferAssessParams(rawText, cwd2) {
|
|
71030
|
+
const system = [
|
|
71031
|
+
"You extract structured options for an evaluation command.",
|
|
71032
|
+
'Return JSON only with keys: { "criteriaPath"?: string, "regenerate"?: boolean, "criteriaOnly"?: boolean, "files"?: string[], "idea"?: string, "code"?: string }.',
|
|
71033
|
+
'Prefer concise relative paths for criteria (e.g., "AGI-hackathon-ideathon/evaluation.criteria.json").',
|
|
71034
|
+
'If the text says "do not regenerate" or "DO NOT regenerate", set regenerate=false (override any other hint).',
|
|
71035
|
+
"If the text asks to create/save criteria/rubric (without asking for evaluation), set criteriaOnly=true.",
|
|
71036
|
+
"If the text mentions saving criteria to a folder, set criteriaPath accordingly and regenerate=true.",
|
|
71037
|
+
"If it references files or folders, include them in files[] (relative to cwd).",
|
|
71038
|
+
"If idea content is present, place in idea; do not paraphrase."
|
|
71039
|
+
].join("\n");
|
|
71040
|
+
const user = rawText;
|
|
71041
|
+
const response = await callAPI("/v1/ai-proxy", {
|
|
71042
|
+
method: "POST",
|
|
71043
|
+
body: {
|
|
71044
|
+
prompt: `${system}
|
|
71045
|
+
|
|
71046
|
+
---
|
|
71047
|
+
|
|
71048
|
+
${user}`,
|
|
71049
|
+
taskType: "evaluation"
|
|
71050
|
+
}
|
|
71051
|
+
});
|
|
71052
|
+
const raw = (response?.data?.content || response?.output || "").trim();
|
|
71053
|
+
const jsonText = extractFirstJson(raw) || raw;
|
|
71054
|
+
let parsed = {};
|
|
71055
|
+
try {
|
|
71056
|
+
parsed = JSON.parse(jsonText);
|
|
71057
|
+
} catch {
|
|
71058
|
+
return {};
|
|
71059
|
+
}
|
|
71060
|
+
const out = {};
|
|
71061
|
+
if (typeof parsed.idea === "string" && parsed.idea.trim()) out.idea = parsed.idea.trim();
|
|
71062
|
+
if (typeof parsed.code === "string" && parsed.code.trim()) out.code = parsed.code.trim();
|
|
71063
|
+
if (typeof parsed.regenerate === "boolean") out.regenerate = parsed.regenerate;
|
|
71064
|
+
if (typeof parsed.criteriaOnly === "boolean") out.criteriaOnly = parsed.criteriaOnly;
|
|
71065
|
+
if (typeof parsed.criteriaPath === "string" && parsed.criteriaPath.trim()) {
|
|
71066
|
+
const safe = sanitizePath(parsed.criteriaPath.trim(), cwd2);
|
|
71067
|
+
if (safe) out.criteriaPath = safe;
|
|
71068
|
+
}
|
|
71069
|
+
if (Array.isArray(parsed.files)) {
|
|
71070
|
+
out.files = parsed.files.filter((f3) => typeof f3 === "string" && f3.trim()).map((f3) => sanitizePath(f3.trim(), cwd2)).filter((x2) => Boolean(x2));
|
|
71071
|
+
}
|
|
71072
|
+
return out;
|
|
71073
|
+
}
|
|
71074
|
+
var init_ArgumentInference = __esm({
|
|
71075
|
+
"src/services/evaluation/ArgumentInference.ts"() {
|
|
71076
|
+
init_api_caller();
|
|
71077
|
+
}
|
|
71078
|
+
});
|
|
71079
|
+
|
|
71080
|
+
// src/slash-commands/categories/evaluation/evaluate.command.ts
|
|
71081
|
+
var evaluate_command_exports = {};
|
|
71082
|
+
__export(evaluate_command_exports, {
|
|
71083
|
+
EvaluateCommand: () => EvaluateCommand,
|
|
71084
|
+
default: () => evaluate_command_default,
|
|
71085
|
+
meta: () => meta26
|
|
71086
|
+
});
|
|
71087
|
+
var EvaluateCommand, meta26, evaluate_command_default;
|
|
71088
|
+
var init_evaluate_command = __esm({
|
|
71089
|
+
"src/slash-commands/categories/evaluation/evaluate.command.ts"() {
|
|
71090
|
+
init_base_command();
|
|
71091
|
+
init_logger();
|
|
71092
|
+
init_EvaluationOrchestrator();
|
|
71093
|
+
init_api_caller();
|
|
71094
|
+
init_animations();
|
|
71095
|
+
init_ArgumentInference();
|
|
71096
|
+
EvaluateCommand = class extends BaseCommand {
|
|
71097
|
+
name = "evaluate";
|
|
71098
|
+
category = "evaluation";
|
|
71099
|
+
description = "\u{1F9EA} Run A/B tests and quality evaluations using the Phase 4 framework";
|
|
71100
|
+
aliases = ["eval", "test", "ab"];
|
|
71101
|
+
usage = "[run|status|results|stop|assess] [--config <path>] [--dataset <path>] [--format <format>] [--compare-baseline] [--idea <text>] [--code <text>] [--file <path> ...] [--criteria <path>]";
|
|
71102
|
+
examples = [
|
|
71103
|
+
{
|
|
71104
|
+
input: "/evaluate run --config tests/golden/config.json",
|
|
71105
|
+
description: "Run A/B evaluation with specified configuration",
|
|
71106
|
+
output: "Started evaluation test with nDCG and MRR metrics"
|
|
71107
|
+
},
|
|
71108
|
+
{
|
|
71109
|
+
input: "/evaluate status",
|
|
71110
|
+
description: "Show current evaluation status and active tests",
|
|
71111
|
+
output: "Evaluation system status with running/completed tests"
|
|
71112
|
+
},
|
|
71113
|
+
{
|
|
71114
|
+
input: "/evaluate results --format table",
|
|
71115
|
+
description: "Display latest evaluation results in table format",
|
|
71116
|
+
output: "Formatted table with quality metrics and improvements"
|
|
71117
|
+
},
|
|
71118
|
+
{
|
|
71119
|
+
input: "/evaluate run --dataset golden/sharepoint.json --compare-baseline",
|
|
71120
|
+
description: "Run evaluation against custom dataset with baseline comparison",
|
|
71121
|
+
output: "A/B test results with statistical significance analysis"
|
|
71122
|
+
},
|
|
71123
|
+
{
|
|
71124
|
+
input: "/evaluate assess --idea 'CLI\u306E\u8A2D\u8A08\u65B9\u91DD' --file src/cli.ts",
|
|
71125
|
+
description: "Generate criteria if missing and assess idea/files",
|
|
71126
|
+
output: "Weighted score and per-criterion breakdown"
|
|
71127
|
+
}
|
|
71128
|
+
];
|
|
71129
|
+
permissions = {
|
|
71130
|
+
requiresAuth: false,
|
|
71131
|
+
role: void 0
|
|
71132
|
+
};
|
|
71133
|
+
rateLimit = {
|
|
71134
|
+
requests: 10,
|
|
71135
|
+
window: "5m"
|
|
71136
|
+
};
|
|
71137
|
+
async execute(args2, context2) {
|
|
71138
|
+
try {
|
|
71139
|
+
const { options, parsed } = args2;
|
|
71140
|
+
const positional = parsed["positional"] || [];
|
|
71141
|
+
const candidate = positional[0];
|
|
71142
|
+
const hasFreeText = Array.isArray(args2.raw) && args2.raw.length > 0;
|
|
71143
|
+
const subcommand = candidate ? candidate : hasFreeText ? "assess" : "status";
|
|
71144
|
+
const normalized = subcommand.toLowerCase();
|
|
71145
|
+
const allowed = /* @__PURE__ */ new Set(["run", "status", "results", "stop", "assess"]);
|
|
71146
|
+
if (!allowed.has(normalized)) {
|
|
71147
|
+
const idea = (args2.raw || []).join(" ").trim();
|
|
71148
|
+
return await this.assessInput({ ...options, idea }, context2, args2);
|
|
71149
|
+
}
|
|
71150
|
+
switch (normalized) {
|
|
71151
|
+
case "run":
|
|
71152
|
+
return await this.runEvaluation(options, context2);
|
|
71153
|
+
case "status":
|
|
71154
|
+
return await this.getEvaluationStatus(options);
|
|
71155
|
+
case "results":
|
|
71156
|
+
return await this.getEvaluationResults(options);
|
|
71157
|
+
case "stop":
|
|
71158
|
+
return await this.stopEvaluation(options);
|
|
71159
|
+
case "assess":
|
|
71160
|
+
return await this.assessInput(options, context2, args2);
|
|
71161
|
+
default:
|
|
71162
|
+
return await this.assessInput(options, context2, args2);
|
|
71163
|
+
}
|
|
71164
|
+
} catch (error2) {
|
|
71165
|
+
logger.error("Evaluation command failed:", error2);
|
|
71166
|
+
return this.error(
|
|
71167
|
+
"Evaluation execution failed",
|
|
71168
|
+
"EVALUATION_ERROR",
|
|
71169
|
+
error2 instanceof Error ? error2.message : "Unknown error occurred"
|
|
71170
|
+
);
|
|
71171
|
+
}
|
|
71172
|
+
}
|
|
71173
|
+
/**
|
|
71174
|
+
* Assess idea/code/files using criteria (creates default criteria if missing)
|
|
71175
|
+
*/
|
|
71176
|
+
async assessInput(options, context2, commandArgs) {
|
|
71177
|
+
const root = context2.environment?.cwd || process.cwd();
|
|
71178
|
+
const rawText = (commandArgs?.raw || []).join(" ");
|
|
71179
|
+
const cwd2 = root;
|
|
71180
|
+
let inferred = {};
|
|
71181
|
+
try {
|
|
71182
|
+
const inferSpin = new ProcessAnimation();
|
|
71183
|
+
inferSpin.start();
|
|
71184
|
+
try {
|
|
71185
|
+
inferred = await inferAssessParams(rawText, cwd2);
|
|
71186
|
+
} finally {
|
|
71187
|
+
try {
|
|
71188
|
+
inferSpin.stop();
|
|
71189
|
+
} catch {
|
|
71190
|
+
}
|
|
71191
|
+
}
|
|
71192
|
+
} catch {
|
|
71193
|
+
}
|
|
71194
|
+
const filesOption = options["file"];
|
|
71195
|
+
const filesFromFlags = Array.isArray(filesOption) ? filesOption : filesOption ? [filesOption] : [];
|
|
71196
|
+
const detectedFromText = Array.from(rawText.match(/[A-Za-z]:\\[^\r\n]+/g) || []).map((s2) => s2.trim().replace(/[\s\.,;\)]*$/, ""));
|
|
71197
|
+
const noRegen = /\bdo\s*not\s*regenerate\b|\bdo\s*not\s*re\s*gen\b|\bdo\s*not\s*re\s*create\b|\bno\s*regen\b|\bDO\s*NOT\s*REGENERATE\b/i.test(rawText);
|
|
71198
|
+
const files = Array.from(/* @__PURE__ */ new Set([...inferred.files || [], ...filesFromFlags, ...detectedFromText]));
|
|
71199
|
+
const orchestrator = new EvaluationOrchestrator(root);
|
|
71200
|
+
const spinner = new ProcessAnimation();
|
|
71201
|
+
spinner.start();
|
|
71202
|
+
let criteriaPath;
|
|
71203
|
+
let result;
|
|
71204
|
+
try {
|
|
71205
|
+
const assessed = await orchestrator.assess({
|
|
71206
|
+
root,
|
|
71207
|
+
criteria: options["criteria"] || inferred.criteriaPath || void 0,
|
|
71208
|
+
files,
|
|
71209
|
+
idea: options["idea"] || inferred.idea || void 0,
|
|
71210
|
+
code: options["code"] || inferred.code || void 0,
|
|
71211
|
+
regenerateCriteria: noRegen ? false : !!options["regenerate"] || !!options["regen"] || !options["criteria"] || !!inferred.regenerate,
|
|
71212
|
+
llmScoring: options["no-llm-scoring"] ? false : true,
|
|
71213
|
+
criteriaOnly: !!options["criteria-only"] || !!inferred.criteriaOnly
|
|
71214
|
+
});
|
|
71215
|
+
criteriaPath = assessed.criteriaPath;
|
|
71216
|
+
result = assessed.result;
|
|
71217
|
+
} finally {
|
|
71218
|
+
try {
|
|
71219
|
+
spinner.stop();
|
|
71220
|
+
} catch {
|
|
71221
|
+
}
|
|
71222
|
+
}
|
|
71223
|
+
const system = [
|
|
71224
|
+
"You are an expert evaluator.",
|
|
71225
|
+
"Return a concise English assessment with:",
|
|
71226
|
+
"- A one-line overall verdict",
|
|
71227
|
+
"- A weighted score (0-100)",
|
|
71228
|
+
"- A short bullet breakdown per criterion (name: score/100 - brief reason)",
|
|
71229
|
+
"Be direct and professional.",
|
|
71230
|
+
// Strong guard: attachments are uploaded; do not ask for local file content
|
|
71231
|
+
"The input files are already uploaded and referenced via file URIs.",
|
|
71232
|
+
"Use the provided attachments; do not ask the user to paste file contents.",
|
|
71233
|
+
"Do not claim you cannot access local file paths."
|
|
71234
|
+
].join("\n");
|
|
71235
|
+
if (result === null) {
|
|
71236
|
+
const rel = path11__namespace.default.relative(root, criteriaPath);
|
|
71237
|
+
return this.success(`Criteria file created: ${rel}`);
|
|
71238
|
+
}
|
|
71239
|
+
if (result?.passThroughText) {
|
|
71240
|
+
return this.success(result.passThroughText, {
|
|
71241
|
+
type: "evaluation-assess-passthrough",
|
|
71242
|
+
total: 0
|
|
71243
|
+
});
|
|
71244
|
+
}
|
|
71245
|
+
const breakdown = result.details.map((d) => `- ${d.name} (${Math.round(d.weight * 100)}%): ${Math.round(d.score * 100)}/100 - ${d.reason}`).join("\n");
|
|
71246
|
+
const user = [
|
|
71247
|
+
`Project root: ${path11__namespace.default.basename(root)}`,
|
|
71248
|
+
`Criteria file: ${path11__namespace.default.relative(root, criteriaPath)}`,
|
|
71249
|
+
`Weighted total: ${Math.round(result.totalScore * 100)}/100`,
|
|
71250
|
+
`Breakdown:
|
|
71251
|
+
${breakdown}`,
|
|
71252
|
+
options["idea"] || inferred.idea ? `Idea:
|
|
71253
|
+
${options["idea"] || inferred.idea}` : void 0,
|
|
71254
|
+
options["code"] || inferred.code ? `Code snippet:
|
|
71255
|
+
${options["code"] || inferred.code}` : void 0
|
|
71256
|
+
// No inline file contents; rely on attachments only
|
|
71257
|
+
].filter(Boolean).join("\n\n");
|
|
71258
|
+
const llmSpinner = new ProcessAnimation();
|
|
71259
|
+
llmSpinner.start();
|
|
71260
|
+
try {
|
|
71261
|
+
const enriched = [
|
|
71262
|
+
system,
|
|
71263
|
+
"\n---\n",
|
|
71264
|
+
user
|
|
71265
|
+
].join("\n");
|
|
71266
|
+
const attachments = Array.isArray(result?.files) ? result.files.map((f3) => ({
|
|
71267
|
+
name: path11__namespace.default.basename(String(f3.path || "attachment.txt")),
|
|
71268
|
+
path: String(f3.path || ""),
|
|
71269
|
+
mime: String(f3.mime || "text/plain"),
|
|
71270
|
+
data_base64: f3.binaryBase64 ? String(f3.binaryBase64) : f3.content ? Buffer.from(f3.content, "utf8").toString("base64") : void 0
|
|
71271
|
+
})).filter((a) => !!a.data_base64) : [];
|
|
71272
|
+
const response = await callAPI("/v1/ai-proxy", {
|
|
71273
|
+
method: "POST",
|
|
71274
|
+
body: {
|
|
71275
|
+
// Force Google route and always use the attachments-capable model
|
|
71276
|
+
provider: "google",
|
|
71277
|
+
model: "gemini-2.5-flash",
|
|
71278
|
+
prompt: enriched,
|
|
71279
|
+
taskType: "evaluation",
|
|
71280
|
+
metadata: attachments.length ? { attachments } : void 0
|
|
71281
|
+
}
|
|
71282
|
+
});
|
|
71283
|
+
const routedModel = response?.data?.routedModel;
|
|
71284
|
+
const content = (response?.data?.content || response?.output || "").trim();
|
|
71285
|
+
const uploads = response?.data?.uploads || [];
|
|
71286
|
+
if (content) {
|
|
71287
|
+
const uploadNote = uploads.length ? `Attached ${uploads.length} file(s) uploaded and referenced.` : attachments.length ? `Attached ${attachments.length} local file(s).` : void 0;
|
|
71288
|
+
const finalText = uploadNote ? `${uploadNote}
|
|
71289
|
+
|
|
71290
|
+
${content}` : content;
|
|
71291
|
+
return this.success(finalText, {
|
|
71292
|
+
type: "evaluation-assess",
|
|
71293
|
+
total: result.totalScore,
|
|
71294
|
+
details: result.details,
|
|
71295
|
+
routedModel,
|
|
71296
|
+
uploads
|
|
71297
|
+
});
|
|
71298
|
+
}
|
|
71299
|
+
} catch (e2) {
|
|
71300
|
+
try {
|
|
71301
|
+
llmSpinner.stop();
|
|
71302
|
+
} catch {
|
|
71303
|
+
}
|
|
71304
|
+
const msg = e2?.message || "LLM scoring failed";
|
|
71305
|
+
return this.error(`Evaluation failed: ${msg}`, "EVALUATION_ERROR", "LLM scoring is required and fallback is disabled");
|
|
71306
|
+
} finally {
|
|
71307
|
+
try {
|
|
71308
|
+
llmSpinner.stop();
|
|
71309
|
+
} catch {
|
|
71310
|
+
}
|
|
71311
|
+
}
|
|
71312
|
+
return this.error("Evaluation failed: unknown state", "EVALUATION_ERROR");
|
|
71313
|
+
}
|
|
71314
|
+
/**
|
|
71315
|
+
* Run A/B evaluation test
|
|
71316
|
+
*/
|
|
71317
|
+
async runEvaluation(options, context2) {
|
|
71318
|
+
const config2 = this.parseEvaluationConfig(options);
|
|
71319
|
+
const validation = await this.validateConfig(config2);
|
|
71320
|
+
if (!validation.success) {
|
|
71321
|
+
return this.error(
|
|
71322
|
+
validation.error || "Invalid configuration",
|
|
71323
|
+
"CONFIG_ERROR"
|
|
71324
|
+
);
|
|
71325
|
+
}
|
|
71326
|
+
logger.info("Starting A/B evaluation test", {
|
|
71327
|
+
config: config2,
|
|
71328
|
+
user: context2.user?.id
|
|
71329
|
+
});
|
|
71330
|
+
const testResult = await this.executeEvaluation(config2);
|
|
71331
|
+
const formattedOutput = this.formatEvaluationStart(testResult);
|
|
71332
|
+
return this.success(formattedOutput, {
|
|
71333
|
+
testId: testResult.testId,
|
|
71334
|
+
status: testResult.status,
|
|
71335
|
+
type: "evaluation-started"
|
|
71336
|
+
});
|
|
71337
|
+
}
|
|
71338
|
+
/**
|
|
71339
|
+
* Get evaluation system status
|
|
71340
|
+
*/
|
|
71341
|
+
async getEvaluationStatus(_options) {
|
|
71342
|
+
const status = await this.fetchEvaluationStatus();
|
|
71343
|
+
const formattedOutput = this.formatEvaluationStatus(status);
|
|
71344
|
+
return this.success(formattedOutput, {
|
|
71345
|
+
activeTests: status.activeTests.length,
|
|
71346
|
+
completedTests: status.completedTests.length,
|
|
71347
|
+
systemHealth: status.systemHealth,
|
|
71348
|
+
type: "evaluation-status"
|
|
71349
|
+
});
|
|
71350
|
+
}
|
|
71351
|
+
/**
|
|
71352
|
+
* Get evaluation results
|
|
71353
|
+
*/
|
|
71354
|
+
async getEvaluationResults(options) {
|
|
71355
|
+
const format = options["format"] || "table";
|
|
71356
|
+
const results = await this.fetchLatestResults();
|
|
71357
|
+
const formattedOutput = this.formatEvaluationResults(results, format);
|
|
71358
|
+
return this.success(formattedOutput, {
|
|
71359
|
+
resultCount: results.length,
|
|
71360
|
+
format,
|
|
71361
|
+
type: "evaluation-results"
|
|
71362
|
+
});
|
|
71363
|
+
}
|
|
71364
|
+
/**
|
|
71365
|
+
* Stop running evaluation
|
|
71366
|
+
*/
|
|
71367
|
+
async stopEvaluation(options) {
|
|
71368
|
+
const testId = options["test-id"];
|
|
71369
|
+
if (!testId) {
|
|
71370
|
+
return this.error(
|
|
71371
|
+
"Test ID is required to stop evaluation",
|
|
71372
|
+
"MISSING_TEST_ID",
|
|
71373
|
+
"Use --test-id <id> to specify which test to stop"
|
|
71374
|
+
);
|
|
71375
|
+
}
|
|
71376
|
+
await this.terminateEvaluation(testId);
|
|
71377
|
+
return this.success(`Evaluation test ${testId} stopped successfully`, {
|
|
71378
|
+
testId,
|
|
71379
|
+
type: "evaluation-stopped"
|
|
71380
|
+
});
|
|
71381
|
+
}
|
|
71382
|
+
/**
|
|
71383
|
+
* Parse evaluation configuration
|
|
71384
|
+
*/
|
|
71385
|
+
parseEvaluationConfig(options) {
|
|
71386
|
+
return {
|
|
71387
|
+
datasetPath: options["dataset"] || options["config"],
|
|
71388
|
+
testName: options["name"] || `eval_${Date.now()}`,
|
|
71389
|
+
maxQueries: parseInt(options["max-queries"] || "100", 10),
|
|
71390
|
+
metrics: (options["metrics"] || "nDCG,MRR,precision").split(","),
|
|
71391
|
+
outputFormat: options["format"] || "table",
|
|
71392
|
+
compareBaseline: options["compare-baseline"] || false
|
|
71393
|
+
};
|
|
71394
|
+
}
|
|
71395
|
+
/**
|
|
71396
|
+
* Validate evaluation configuration
|
|
71397
|
+
*/
|
|
71398
|
+
async validateConfig(config2) {
|
|
71399
|
+
if (config2.datasetPath && !config2.datasetPath.endsWith(".json")) {
|
|
71400
|
+
return { success: false, error: "Dataset must be a JSON file" };
|
|
71401
|
+
}
|
|
71402
|
+
if (config2.maxQueries && (config2.maxQueries < 1 || config2.maxQueries > 1e4)) {
|
|
71403
|
+
return {
|
|
71404
|
+
success: false,
|
|
71405
|
+
error: "Max queries must be between 1 and 10000"
|
|
71406
|
+
};
|
|
71407
|
+
}
|
|
71408
|
+
const validMetrics = ["nDCG", "MRR", "precision", "recall", "latency"];
|
|
71409
|
+
if (config2.metrics && !config2.metrics.every((m2) => validMetrics.includes(m2))) {
|
|
71410
|
+
return {
|
|
71411
|
+
success: false,
|
|
71412
|
+
error: `Invalid metrics. Valid options: ${validMetrics.join(", ")}`
|
|
71413
|
+
};
|
|
71414
|
+
}
|
|
71415
|
+
const validFormats = ["table", "json", "csv"];
|
|
71416
|
+
if (config2.outputFormat && !validFormats.includes(config2.outputFormat)) {
|
|
71417
|
+
return {
|
|
71418
|
+
success: false,
|
|
71419
|
+
error: `Invalid format. Valid options: ${validFormats.join(", ")}`
|
|
71420
|
+
};
|
|
71421
|
+
}
|
|
71422
|
+
return { success: true };
|
|
71423
|
+
}
|
|
71424
|
+
/**
|
|
71425
|
+
* Execute evaluation (mock implementation)
|
|
71426
|
+
*/
|
|
71427
|
+
async executeEvaluation(config2) {
|
|
71428
|
+
await new Promise((resolve19) => setTimeout(resolve19, 500));
|
|
71429
|
+
return {
|
|
71430
|
+
testId: `eval_${Math.random().toString(36).substr(2, 9)}`,
|
|
71431
|
+
testName: config2.testName || "Unnamed Test",
|
|
71432
|
+
timestamp: Date.now(),
|
|
71433
|
+
status: "running",
|
|
71434
|
+
metrics: {
|
|
71435
|
+
nDCG_at_1: 0,
|
|
71436
|
+
nDCG_at_5: 0,
|
|
71437
|
+
nDCG_at_10: 0,
|
|
71438
|
+
MRR: 0,
|
|
71439
|
+
precision_at_1: 0,
|
|
71440
|
+
precision_at_5: 0,
|
|
71441
|
+
recall_at_10: 0,
|
|
71442
|
+
latency_p50: 0,
|
|
71443
|
+
latency_p95: 0
|
|
71444
|
+
},
|
|
71445
|
+
queryCount: 0,
|
|
71446
|
+
duration: 0
|
|
71447
|
+
};
|
|
71448
|
+
}
|
|
71449
|
+
/**
|
|
71450
|
+
* Fetch evaluation system status
|
|
71451
|
+
*/
|
|
71452
|
+
async fetchEvaluationStatus() {
|
|
71453
|
+
return {
|
|
71454
|
+
activeTests: [
|
|
71455
|
+
{
|
|
71456
|
+
testId: "eval_abc123",
|
|
71457
|
+
testName: "SharePoint RAG Evaluation",
|
|
71458
|
+
timestamp: Date.now() - 3e5,
|
|
71459
|
+
// 5 minutes ago
|
|
71460
|
+
status: "running",
|
|
71461
|
+
metrics: {
|
|
71462
|
+
nDCG_at_1: 0.75,
|
|
71463
|
+
nDCG_at_5: 0.68,
|
|
71464
|
+
nDCG_at_10: 0.64,
|
|
71465
|
+
MRR: 0.72,
|
|
71466
|
+
precision_at_1: 0.75,
|
|
71467
|
+
precision_at_5: 0.68,
|
|
71468
|
+
recall_at_10: 0.85,
|
|
71469
|
+
latency_p50: 245.5,
|
|
71470
|
+
latency_p95: 520.2
|
|
71471
|
+
},
|
|
71472
|
+
queryCount: 45,
|
|
71473
|
+
duration: 300
|
|
71474
|
+
}
|
|
71475
|
+
],
|
|
71476
|
+
completedTests: [
|
|
71477
|
+
{
|
|
71478
|
+
testId: "eval_xyz789",
|
|
71479
|
+
testName: "Baseline Comparison Test",
|
|
71480
|
+
timestamp: Date.now() - 36e5,
|
|
71481
|
+
// 1 hour ago
|
|
71482
|
+
status: "completed",
|
|
71483
|
+
metrics: {
|
|
71484
|
+
nDCG_at_1: 0.82,
|
|
71485
|
+
nDCG_at_5: 0.74,
|
|
71486
|
+
nDCG_at_10: 0.69,
|
|
71487
|
+
MRR: 0.79,
|
|
71488
|
+
precision_at_1: 0.82,
|
|
71489
|
+
precision_at_5: 0.74,
|
|
71490
|
+
recall_at_10: 0.89,
|
|
71491
|
+
latency_p50: 189.3,
|
|
71492
|
+
latency_p95: 445.8
|
|
71493
|
+
},
|
|
71494
|
+
queryCount: 100,
|
|
71495
|
+
duration: 1247,
|
|
71496
|
+
baselineComparison: {
|
|
71497
|
+
improvement: {
|
|
71498
|
+
nDCG_at_1: 0.08,
|
|
71499
|
+
nDCG_at_5: 0.12,
|
|
71500
|
+
MRR: 0.15,
|
|
71501
|
+
latency_p50: -0.22
|
|
71502
|
+
},
|
|
71503
|
+
significant: {
|
|
71504
|
+
nDCG_at_1: true,
|
|
71505
|
+
nDCG_at_5: true,
|
|
71506
|
+
MRR: true,
|
|
71507
|
+
latency_p50: true
|
|
71508
|
+
}
|
|
71509
|
+
}
|
|
71510
|
+
}
|
|
71511
|
+
],
|
|
71512
|
+
systemHealth: {
|
|
71513
|
+
evaluationService: "healthy",
|
|
71514
|
+
datasetAccess: "available",
|
|
71515
|
+
metricsCollection: "active"
|
|
71516
|
+
}
|
|
71517
|
+
};
|
|
71518
|
+
}
|
|
71519
|
+
/**
|
|
71520
|
+
* Fetch latest evaluation results
|
|
71521
|
+
*/
|
|
71522
|
+
async fetchLatestResults() {
|
|
71523
|
+
const status = await this.fetchEvaluationStatus();
|
|
71524
|
+
return [...status.activeTests, ...status.completedTests].slice(0, 5);
|
|
71525
|
+
}
|
|
71526
|
+
/**
|
|
71527
|
+
* Terminate evaluation
|
|
71528
|
+
*/
|
|
71529
|
+
async terminateEvaluation(_testId) {
|
|
71530
|
+
await new Promise((resolve19) => setTimeout(resolve19, 200));
|
|
71531
|
+
return true;
|
|
71532
|
+
}
|
|
71533
|
+
/**
|
|
71534
|
+
* Format evaluation start message
|
|
71535
|
+
*/
|
|
71536
|
+
formatEvaluationStart(_result) {
|
|
71537
|
+
const lines = [];
|
|
71538
|
+
lines.push("");
|
|
71539
|
+
lines.push("\u{1F9EA} A/B EVALUATION STARTED");
|
|
71540
|
+
lines.push("\u2550".repeat(40));
|
|
71541
|
+
lines.push("");
|
|
71542
|
+
lines.push(`Test ID: ${_result.testId}`);
|
|
71543
|
+
lines.push(`Test Name: ${_result.testName}`);
|
|
71544
|
+
lines.push(`Status: ${_result.status.toUpperCase()}`);
|
|
71545
|
+
lines.push(`Started: ${new Date(_result.timestamp).toLocaleString()}`);
|
|
71546
|
+
lines.push("");
|
|
71547
|
+
lines.push("\u{1F4CA} **Metrics to Collect:**");
|
|
71548
|
+
lines.push(" \u2022 nDCG@1, nDCG@5, nDCG@10");
|
|
71549
|
+
lines.push(" \u2022 Mean Reciprocal Rank (MRR)");
|
|
71550
|
+
lines.push(" \u2022 Precision@1, Precision@5");
|
|
71551
|
+
lines.push(" \u2022 Recall@10");
|
|
71552
|
+
lines.push(" \u2022 Latency (p50, p95)");
|
|
71553
|
+
lines.push("");
|
|
71554
|
+
lines.push("\u{1F4A1} **Monitor Progress:**");
|
|
71555
|
+
lines.push(" Use `/evaluate status` to check progress");
|
|
71556
|
+
lines.push(" Use `/evaluate results` to see latest metrics");
|
|
71557
|
+
return lines.join("\n");
|
|
71558
|
+
}
|
|
71559
|
+
/**
|
|
71560
|
+
* Format evaluation status
|
|
71561
|
+
*/
|
|
71562
|
+
formatEvaluationStatus(status) {
|
|
71563
|
+
const lines = [];
|
|
71564
|
+
lines.push("");
|
|
71565
|
+
lines.push("\u{1F4CA} EVALUATION SYSTEM STATUS");
|
|
71566
|
+
lines.push("\u2550".repeat(40));
|
|
71567
|
+
lines.push("");
|
|
71568
|
+
lines.push("\u{1F527} **System Health:**");
|
|
71569
|
+
lines.push(
|
|
71570
|
+
` Evaluation Service: ${this.getHealthIcon(status.systemHealth.evaluationService)} ${status.systemHealth.evaluationService}`
|
|
71571
|
+
);
|
|
71572
|
+
lines.push(
|
|
71573
|
+
` Dataset Access: ${this.getHealthIcon(status.systemHealth.datasetAccess)} ${status.systemHealth.datasetAccess}`
|
|
71574
|
+
);
|
|
71575
|
+
lines.push(
|
|
71576
|
+
` Metrics Collection: ${this.getHealthIcon(status.systemHealth.metricsCollection)} ${status.systemHealth.metricsCollection}`
|
|
71577
|
+
);
|
|
71578
|
+
lines.push("");
|
|
71579
|
+
if (status.activeTests.length > 0) {
|
|
71580
|
+
lines.push(`\u26A1 **Active Tests (${status.activeTests.length}):**`);
|
|
71581
|
+
for (const test of status.activeTests) {
|
|
71582
|
+
lines.push(` \u2022 ${test.testName} (${test.testId})`);
|
|
71583
|
+
lines.push(
|
|
71584
|
+
` Progress: ${test.queryCount} queries, ${Math.round(test.duration / 60)}m elapsed`
|
|
71585
|
+
);
|
|
71586
|
+
lines.push(` Current nDCG@5: ${test.metrics.nDCG_at_5.toFixed(3)}`);
|
|
71587
|
+
}
|
|
71588
|
+
lines.push("");
|
|
71589
|
+
}
|
|
71590
|
+
if (status.completedTests.length > 0) {
|
|
71591
|
+
lines.push(
|
|
71592
|
+
`\u2705 **Recent Completed Tests (${status.completedTests.length}):**`
|
|
71593
|
+
);
|
|
71594
|
+
for (const test of status.completedTests.slice(0, 3)) {
|
|
71595
|
+
const timeAgo = Math.round((Date.now() - test.timestamp) / 6e4);
|
|
71596
|
+
lines.push(` \u2022 ${test.testName} - ${timeAgo}m ago`);
|
|
71597
|
+
lines.push(
|
|
71598
|
+
` nDCG@5: ${test.metrics.nDCG_at_5.toFixed(3)}, MRR: ${test.metrics.MRR.toFixed(3)}`
|
|
71599
|
+
);
|
|
71600
|
+
if (test.baselineComparison) {
|
|
71601
|
+
const improvement = (test.baselineComparison.improvement.nDCG_at_5 * 100).toFixed(1);
|
|
71602
|
+
lines.push(` Improvement: +${improvement}% vs baseline`);
|
|
71603
|
+
}
|
|
71604
|
+
}
|
|
71605
|
+
}
|
|
71606
|
+
return lines.join("\n");
|
|
71607
|
+
}
|
|
71608
|
+
/**
|
|
71609
|
+
* Format evaluation results
|
|
71610
|
+
*/
|
|
71611
|
+
formatEvaluationResults(results, format) {
|
|
71612
|
+
if (format === "json") {
|
|
71613
|
+
return JSON.stringify(results, null, 2);
|
|
71614
|
+
}
|
|
71615
|
+
if (format === "csv") {
|
|
71616
|
+
const headers = [
|
|
71617
|
+
"Test ID",
|
|
71618
|
+
"Name",
|
|
71619
|
+
"Status",
|
|
71620
|
+
"nDCG@5",
|
|
71621
|
+
"MRR",
|
|
71622
|
+
"P@1",
|
|
71623
|
+
"Latency P50"
|
|
71624
|
+
];
|
|
71625
|
+
const rows = results.map((r2) => [
|
|
71626
|
+
r2.testId,
|
|
71627
|
+
r2.testName,
|
|
71628
|
+
r2.status,
|
|
71629
|
+
r2.metrics.nDCG_at_5.toFixed(3),
|
|
71630
|
+
r2.metrics.MRR.toFixed(3),
|
|
71631
|
+
r2.metrics.precision_at_1.toFixed(3),
|
|
71632
|
+
r2.metrics.latency_p50.toFixed(1)
|
|
71633
|
+
]);
|
|
71634
|
+
return [headers.join(","), ...rows.map((row) => row.join(","))].join(
|
|
71635
|
+
"\n"
|
|
71636
|
+
);
|
|
71637
|
+
}
|
|
71638
|
+
const lines = [];
|
|
71639
|
+
lines.push("");
|
|
71640
|
+
lines.push("\u{1F4C8} EVALUATION RESULTS");
|
|
71641
|
+
lines.push("\u2550".repeat(60));
|
|
71642
|
+
lines.push("");
|
|
71643
|
+
for (const _result of results) {
|
|
71644
|
+
lines.push(`**${_result.testName}** (${_result.testId})`);
|
|
71645
|
+
lines.push(
|
|
71646
|
+
`Status: ${_result.status.toUpperCase()} | Queries: ${_result.queryCount} | Duration: ${Math.round(_result.duration / 60)}m`
|
|
71647
|
+
);
|
|
71648
|
+
lines.push("");
|
|
71649
|
+
lines.push("\u{1F4CA} **Quality Metrics:**");
|
|
71650
|
+
lines.push(
|
|
71651
|
+
` nDCG@1: ${_result.metrics.nDCG_at_1.toFixed(3)} nDCG@5: ${_result.metrics.nDCG_at_5.toFixed(3)} nDCG@10: ${_result.metrics.nDCG_at_10.toFixed(3)}`
|
|
71652
|
+
);
|
|
71653
|
+
lines.push(
|
|
71654
|
+
` MRR: ${_result.metrics.MRR.toFixed(3)} P@1: ${_result.metrics.precision_at_1.toFixed(3)} P@5: ${_result.metrics.precision_at_5.toFixed(3)}`
|
|
71655
|
+
);
|
|
71656
|
+
lines.push(` Recall@10: ${_result.metrics.recall_at_10.toFixed(3)}`);
|
|
71657
|
+
lines.push("");
|
|
71658
|
+
lines.push("\u26A1 **Performance:**");
|
|
71659
|
+
lines.push(
|
|
71660
|
+
` Latency P50: ${_result.metrics.latency_p50.toFixed(1)}ms P95: ${_result.metrics.latency_p95.toFixed(1)}ms`
|
|
71661
|
+
);
|
|
71662
|
+
if (_result.baselineComparison) {
|
|
71663
|
+
lines.push("");
|
|
71664
|
+
lines.push("\u{1F504} **vs Baseline:**");
|
|
71665
|
+
const improvement = _result.baselineComparison.improvement;
|
|
71666
|
+
const significant = _result.baselineComparison.significant;
|
|
71667
|
+
lines.push(
|
|
71668
|
+
` nDCG@5: ${improvement.nDCG_at_5 >= 0 ? "+" : ""}${(improvement.nDCG_at_5 * 100).toFixed(1)}% ${significant.nDCG_at_5 ? "\u2713" : "\u2717"}`
|
|
71669
|
+
);
|
|
71670
|
+
lines.push(
|
|
71671
|
+
` MRR: ${improvement.MRR >= 0 ? "+" : ""}${(improvement.MRR * 100).toFixed(1)}% ${significant.MRR ? "\u2713" : "\u2717"}`
|
|
71672
|
+
);
|
|
71673
|
+
lines.push(
|
|
71674
|
+
` Latency: ${improvement.latency_p50 >= 0 ? "+" : ""}${(improvement.latency_p50 * 100).toFixed(1)}% ${significant.latency_p50 ? "\u2713" : "\u2717"}`
|
|
71675
|
+
);
|
|
71676
|
+
}
|
|
71677
|
+
lines.push("");
|
|
71678
|
+
lines.push("\u2500".repeat(40));
|
|
71679
|
+
lines.push("");
|
|
71680
|
+
}
|
|
71681
|
+
return lines.join("\n");
|
|
71682
|
+
}
|
|
71683
|
+
/**
|
|
71684
|
+
* Get health status icon
|
|
71685
|
+
*/
|
|
71686
|
+
getHealthIcon(status) {
|
|
71687
|
+
switch (status) {
|
|
71688
|
+
case "healthy":
|
|
71689
|
+
case "available":
|
|
71690
|
+
case "active":
|
|
71691
|
+
return "\u{1F7E2}";
|
|
71692
|
+
case "degraded":
|
|
71693
|
+
case "limited":
|
|
71694
|
+
return "\u{1F7E1}";
|
|
71695
|
+
case "down":
|
|
71696
|
+
case "unavailable":
|
|
71697
|
+
case "inactive":
|
|
71698
|
+
return "\u{1F534}";
|
|
71699
|
+
default:
|
|
71700
|
+
return "\u26AA";
|
|
71701
|
+
}
|
|
71702
|
+
}
|
|
71703
|
+
/**
|
|
71704
|
+
* Command validation
|
|
71705
|
+
*/
|
|
71706
|
+
async validate(args2) {
|
|
71707
|
+
const { parsed, options } = args2;
|
|
71708
|
+
const positional = parsed["positional"] || [];
|
|
71709
|
+
const subcommand = positional[0];
|
|
71710
|
+
if (subcommand === "run") {
|
|
71711
|
+
if (options["max-queries"] && isNaN(parseInt(options["max-queries"], 10))) {
|
|
71712
|
+
return {
|
|
71713
|
+
success: false,
|
|
71714
|
+
error: "max-queries must be a number"
|
|
71715
|
+
};
|
|
71716
|
+
}
|
|
71717
|
+
}
|
|
71718
|
+
if (subcommand === "stop" && !options["test-id"]) {
|
|
71719
|
+
return {
|
|
71720
|
+
success: false,
|
|
71721
|
+
error: "stop command requires --test-id parameter"
|
|
71722
|
+
};
|
|
71723
|
+
}
|
|
71724
|
+
return { success: true };
|
|
71725
|
+
}
|
|
71726
|
+
};
|
|
71727
|
+
meta26 = {
|
|
71728
|
+
name: "evaluate",
|
|
71729
|
+
category: "evaluation",
|
|
71730
|
+
description: "A/B testing and quality evaluation framework",
|
|
71731
|
+
aliases: ["eval", "test", "ab"],
|
|
71732
|
+
usage: "/evaluate [run|status|results|stop] [options]",
|
|
71733
|
+
examples: [
|
|
71734
|
+
"/evaluate run --dataset data.json",
|
|
71735
|
+
"/evaluate status",
|
|
71736
|
+
"/evaluate results --format table",
|
|
71737
|
+
"/evaluate stop --test-id eval_abc123"
|
|
71738
|
+
],
|
|
71739
|
+
deps: []
|
|
71740
|
+
};
|
|
71741
|
+
evaluate_command_default = EvaluateCommand;
|
|
71742
|
+
}
|
|
71743
|
+
});
|
|
70605
71744
|
|
|
70606
71745
|
// src/slash-commands/index.ts
|
|
70607
71746
|
var slash_commands_exports = {};
|
|
@@ -71091,15 +72230,23 @@ async function registerBuiltInCommands() {
|
|
|
71091
72230
|
initialize: async () => {
|
|
71092
72231
|
}
|
|
71093
72232
|
});
|
|
71094
|
-
|
|
71095
|
-
|
|
71096
|
-
|
|
71097
|
-
|
|
71098
|
-
|
|
71099
|
-
|
|
71100
|
-
|
|
71101
|
-
|
|
71102
|
-
|
|
72233
|
+
try {
|
|
72234
|
+
const EvaluateModule = await Promise.resolve().then(() => (init_evaluate_command(), evaluate_command_exports));
|
|
72235
|
+
const EvaluateClass = EvaluateModule.EvaluateCommand || EvaluateModule.default;
|
|
72236
|
+
const evaluate = new EvaluateClass();
|
|
72237
|
+
if (evaluate.initialize) await evaluate.initialize();
|
|
72238
|
+
commandRegistry.register(evaluate);
|
|
72239
|
+
} catch {
|
|
72240
|
+
commandRegistry.register({
|
|
72241
|
+
name: "evaluate",
|
|
72242
|
+
category: "evaluation",
|
|
72243
|
+
description: "Evaluation system",
|
|
72244
|
+
aliases: [],
|
|
72245
|
+
execute: async () => shield2({ message: "\u{1F512} Not available in this build" }),
|
|
72246
|
+
initialize: async () => {
|
|
72247
|
+
}
|
|
72248
|
+
});
|
|
72249
|
+
}
|
|
71103
72250
|
commandRegistry.register({
|
|
71104
72251
|
name: "multimodal",
|
|
71105
72252
|
category: "multimodal",
|