flowseeker 0.1.8 → 0.1.9
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/CHANGELOG.md +12 -0
- package/dist/chat/nativeChatParticipant.js +1 -1
- package/dist/cli/main.js +19 -3
- package/dist/cli/runEvaluation.js +103 -0
- package/dist/eval/accuracyV2.js +483 -0
- package/dist/eval/goldenTask.js +192 -0
- package/dist/framework/laravel.js +177 -0
- package/dist/index/semanticChunkIndex.js +388 -0
- package/dist/index/workspaceIndex.js +339 -29
- package/dist/mcp/mcpTools.js +1627 -2
- package/dist/pipeline/contextBlueprint.js +15 -2
- package/dist/pipeline/fileScanner.js +116 -1
- package/dist/pipeline/fusionTrace.js +149 -0
- package/dist/pipeline/nodeScan.js +13 -2
- package/dist/pipeline/roleRefinement.js +62 -0
- package/dist/pipeline/runHeadless.js +25 -5
- package/dist/pipeline/runPipeline.js +2 -2
- package/dist/pipeline/solvePacket.js +112 -6
- package/dist/pipeline/taskUnderstanding.js +2 -2
- package/dist/ui/chatViewProvider.js +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# FlowSeeker Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.9 - Accuracy Gates, Semantic Diagnostics, And Release Hygiene
|
|
4
|
+
|
|
5
|
+
- Added semantic-only diagnostic/report-only mode for MCP context output so semantic experiments can be inspected without changing deterministic ranking or primary edit candidates.
|
|
6
|
+
- Hardened MCP context smoke coverage across JSON, human, agent, and compact output profiles, including semantic-only warning checks and default-mode purity checks.
|
|
7
|
+
- Added multi-framework golden accuracy harnesses for Laravel, NestJS, Next.js, and Django with label-quality checks, must-not guards, and reproducible edit-recall metrics.
|
|
8
|
+
- Added Phase 20 deterministic accuracy improvements through guarded `framework_convention` and `role_intent` signals, improving NestJS edit recall at 1 from 0% to 67% with must-not violations still at 0%.
|
|
9
|
+
- Added top1 gap, residual triage, signal simulation, import-graph reality, hard-residual strategy, and closeout reports to document what improved and where simple deterministic boosts are exhausted.
|
|
10
|
+
- Closed Phase 20 with documented limitations: three remaining hard top1 misses require future cross-file workflow/domain evidence infrastructure rather than another blind weight tweak.
|
|
11
|
+
- Added closeout/release-readiness artifacts for the 0.1.9 accuracy work, including final matrix metrics and rejected/unsafe target documentation.
|
|
12
|
+
- Refreshed FlowSeeker logo assets across extension, chat/webview, activity bar, and landing-page public assets.
|
|
13
|
+
- Tightened release hygiene so internal PDF/export artifacts are excluded from git, npm, and VSIX packages.
|
|
14
|
+
|
|
3
15
|
## 0.1.8 - Local Semantic, One-Command MCP, And Solve Packet UX
|
|
4
16
|
|
|
5
17
|
- Added full CLI entry points: `flowseeker`, `fs-guide`, `fs-auto`, `fs-files`, `fs-retrieve`, and `fs-mcp`.
|
|
@@ -170,7 +170,7 @@ function registerNativeChatParticipant(context, resultProvider, gateway, editSto
|
|
|
170
170
|
}
|
|
171
171
|
};
|
|
172
172
|
const participant = vscode.chat.createChatParticipant(participantId, handler);
|
|
173
|
-
participant.iconPath = vscode.Uri.joinPath(context.extensionUri, "resources", "flowseeker-logo
|
|
173
|
+
participant.iconPath = vscode.Uri.joinPath(context.extensionUri, "resources", "flowseeker-logo.png");
|
|
174
174
|
participant.followupProvider = {
|
|
175
175
|
provideFollowups(result) {
|
|
176
176
|
const metadata = result.metadata;
|
package/dist/cli/main.js
CHANGED
|
@@ -471,6 +471,13 @@ async function runDoctorCommand(args) {
|
|
|
471
471
|
const hasGuide = stdout.includes("flowseeker_guide");
|
|
472
472
|
const hasAuto = stdout.includes("flowseeker_auto");
|
|
473
473
|
const hasFiles = stdout.includes("flowseeker_files");
|
|
474
|
+
const hasValidatePlan = stdout.includes("flowseeker_validate_plan");
|
|
475
|
+
const hasContext = stdout.includes("flowseeker_context");
|
|
476
|
+
const hasInspect = stdout.includes("flowseeker_inspect");
|
|
477
|
+
const hasExpand = stdout.includes("flowseeker_expand");
|
|
478
|
+
const hasStatus = stdout.includes("flowseeker_status");
|
|
479
|
+
const hasIndex = stdout.includes("flowseeker_index");
|
|
480
|
+
const hasFeedback = stdout.includes("flowseeker_feedback");
|
|
474
481
|
mcpStatus = {
|
|
475
482
|
checked: true,
|
|
476
483
|
initializeOk: stdout.includes('"id":0'),
|
|
@@ -478,10 +485,19 @@ async function runDoctorCommand(args) {
|
|
|
478
485
|
toolsIncludesGuide: hasGuide,
|
|
479
486
|
toolsIncludesAuto: hasAuto,
|
|
480
487
|
toolsIncludesFiles: hasFiles,
|
|
488
|
+
toolsIncludesValidatePlan: hasValidatePlan,
|
|
489
|
+
toolsIncludesContext: hasContext,
|
|
490
|
+
toolsIncludesInspect: hasInspect,
|
|
491
|
+
toolsIncludesExpand: hasExpand,
|
|
492
|
+
toolsIncludesStatus: hasStatus,
|
|
493
|
+
toolsIncludesIndex: hasIndex,
|
|
494
|
+
toolsIncludesFeedback: hasFeedback,
|
|
481
495
|
promptsIncludeRetrieve: stdout.includes('"retrieve"'),
|
|
482
496
|
promptsIncludeGuide: stdout.includes('"guide"'),
|
|
483
497
|
promptsIncludeAuto: stdout.includes('"auto"'),
|
|
484
|
-
promptsIncludeFiles: stdout.includes('"files"')
|
|
498
|
+
promptsIncludeFiles: stdout.includes('"files"'),
|
|
499
|
+
promptsIncludeValidatePlan: stdout.includes('"validate-plan"'),
|
|
500
|
+
promptsIncludeContext: stdout.includes('"context"'),
|
|
485
501
|
};
|
|
486
502
|
if (!hasRetrieve)
|
|
487
503
|
nextActions.push("MCP tools/list missing flowseeker_retrieve. Check MCP server startup.");
|
|
@@ -545,8 +561,8 @@ async function runDoctorCommand(args) {
|
|
|
545
561
|
lines.push(" Self-check: " + (mcp.checked ? (mcp.initializeOk ? "pass" : "init failed") : "not run"));
|
|
546
562
|
if (mcp.checked) {
|
|
547
563
|
const toolIcons = (name) => mcp[name] ? "present" : "MISSING";
|
|
548
|
-
lines.push(" Tools: retrieve=" + toolIcons("toolsIncludesRetrieve") + " guide=" + toolIcons("toolsIncludesGuide") + " auto=" + toolIcons("toolsIncludesAuto") + " files=" + toolIcons("toolsIncludesFiles"));
|
|
549
|
-
lines.push(" Prompts: retrieve=" + toolIcons("promptsIncludeRetrieve") + " guide=" + toolIcons("promptsIncludeGuide") + " auto=" + toolIcons("promptsIncludeAuto") + " files=" + toolIcons("promptsIncludeFiles"));
|
|
564
|
+
lines.push(" Tools: retrieve=" + toolIcons("toolsIncludesRetrieve") + " guide=" + toolIcons("toolsIncludesGuide") + " auto=" + toolIcons("toolsIncludesAuto") + " files=" + toolIcons("toolsIncludesFiles") + " validate_plan=" + toolIcons("toolsIncludesValidatePlan") + " context=" + toolIcons("toolsIncludesContext") + " inspect=" + toolIcons("toolsIncludesInspect") + " expand=" + toolIcons("toolsIncludesExpand") + " status=" + toolIcons("toolsIncludesStatus") + " index=" + toolIcons("toolsIncludesIndex") + " feedback=" + toolIcons("toolsIncludesFeedback"));
|
|
565
|
+
lines.push(" Prompts: retrieve=" + toolIcons("promptsIncludeRetrieve") + " guide=" + toolIcons("promptsIncludeGuide") + " auto=" + toolIcons("promptsIncludeAuto") + " files=" + toolIcons("promptsIncludeFiles") + " validate-plan=" + toolIcons("promptsIncludeValidatePlan") + " context=" + toolIcons("promptsIncludeContext"));
|
|
550
566
|
}
|
|
551
567
|
lines.push(" Server command: flowseeker");
|
|
552
568
|
lines.push(" Server args: mcp --workspace " + resolved + "");
|
|
@@ -41,8 +41,11 @@ const defaultConfig_1 = require("../config/defaultConfig");
|
|
|
41
41
|
const evaluationMetrics_1 = require("../pipeline/evaluationMetrics");
|
|
42
42
|
const fileGroups_1 = require("../pipeline/fileGroups");
|
|
43
43
|
const runHeadless_1 = require("../pipeline/runHeadless");
|
|
44
|
+
const fileScanner_1 = require("../pipeline/fileScanner");
|
|
44
45
|
const tokenSavings_1 = require("../pipeline/tokenSavings");
|
|
45
46
|
const text_1 = require("../utils/text");
|
|
47
|
+
const goldenTask_1 = require("../eval/goldenTask");
|
|
48
|
+
const accuracyV2_1 = require("../eval/accuracyV2");
|
|
46
49
|
void main().catch((error) => {
|
|
47
50
|
const message = error instanceof Error ? error.stack ?? error.message : String(error);
|
|
48
51
|
console.error(message);
|
|
@@ -50,6 +53,11 @@ void main().catch((error) => {
|
|
|
50
53
|
});
|
|
51
54
|
async function main() {
|
|
52
55
|
const options = parseArgs(process.argv.slice(2));
|
|
56
|
+
// Golden-manifest-only mode: skip regular eval
|
|
57
|
+
if (options.goldenManifestPath && !options.manifestPath && !options.workspacePath) {
|
|
58
|
+
await runGoldenEval(options.goldenManifestPath, options.goldenReportPath);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
53
61
|
const loaded = await loadManifest(options);
|
|
54
62
|
const manifest = loaded.manifest;
|
|
55
63
|
validateManifest(manifest, loaded.source);
|
|
@@ -114,6 +122,9 @@ async function main() {
|
|
|
114
122
|
if (options.failOnMiss && results.some((result) => result.pass === false)) {
|
|
115
123
|
process.exitCode = 1;
|
|
116
124
|
}
|
|
125
|
+
if (options.goldenManifestPath) {
|
|
126
|
+
await runGoldenEval(options.goldenManifestPath, options.goldenReportPath);
|
|
127
|
+
}
|
|
117
128
|
}
|
|
118
129
|
function parseArgs(args) {
|
|
119
130
|
const options = {
|
|
@@ -198,6 +209,16 @@ function parseArgs(args) {
|
|
|
198
209
|
options.dumpFailureAnalysis = true;
|
|
199
210
|
continue;
|
|
200
211
|
}
|
|
212
|
+
if (arg === "--golden-manifest") {
|
|
213
|
+
options.goldenManifestPath = requireValue(args, index, arg);
|
|
214
|
+
index += 1;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (arg === "--golden-report") {
|
|
218
|
+
options.goldenReportPath = requireValue(args, index, arg);
|
|
219
|
+
index += 1;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
201
222
|
if (arg === "--help" || arg === "-h") {
|
|
202
223
|
printUsage();
|
|
203
224
|
process.exit(0);
|
|
@@ -962,4 +983,86 @@ function formatTaskAwareGuardSummary(results) {
|
|
|
962
983
|
const consistency = (scanned === candidates + blockedSlot + blockedExpected) && (candidates === demoted + promoted + noSafeReplacement);
|
|
963
984
|
return `taskAwareAvoidGuard: scanned=${scanned}, candidates=${candidates}, demoted=${demoted}, promoted=${promoted}, blockedSlot=${blockedSlot}, blockedExpected=${blockedExpected}, noSafeReplacement=${noSafeReplacement}\ntaskAwareAvoidGuardConsistency: ${consistency ? "PASS" : "FAIL"}`;
|
|
964
985
|
}
|
|
986
|
+
async function runGoldenEval(goldenManifestPath, goldenReportPath) {
|
|
987
|
+
const manifestPath = path.resolve(goldenManifestPath);
|
|
988
|
+
const manifest = await readJson(manifestPath);
|
|
989
|
+
const workspacePath = typeof manifest.workspace === "string" && manifest.workspace.trim()
|
|
990
|
+
? path.resolve(manifest.workspace)
|
|
991
|
+
: "";
|
|
992
|
+
const issues = (0, goldenTask_1.validateGoldenManifest)(manifest, workspacePath || undefined);
|
|
993
|
+
if (issues.length > 0) {
|
|
994
|
+
console.error(`Golden manifest validation failed with ${issues.length} issue(s):`);
|
|
995
|
+
for (const issue of issues)
|
|
996
|
+
console.error(` - ${issue}`);
|
|
997
|
+
process.exitCode = 1;
|
|
998
|
+
return;
|
|
999
|
+
}
|
|
1000
|
+
const config = (0, defaultConfig_1.mergeConfig)(await (0, loadConfigFromPath_1.loadConfigFromPath)(workspacePath), {});
|
|
1001
|
+
console.log(`\nGolden Eval: ${manifest.name}`);
|
|
1002
|
+
console.log(`Workspace: ${workspacePath}`);
|
|
1003
|
+
console.log(`Tasks: ${manifest.tasks.length}`);
|
|
1004
|
+
const perTaskResults = [];
|
|
1005
|
+
const flowResults = [];
|
|
1006
|
+
const taskGuardReasons = {};
|
|
1007
|
+
for (const goldenTask of manifest.tasks) {
|
|
1008
|
+
const taskStart = Date.now();
|
|
1009
|
+
console.log(`- ${goldenTask.id}: ${goldenTask.task}`);
|
|
1010
|
+
(0, fileScanner_1.clearGuardReasons)();
|
|
1011
|
+
const result = await (0, runHeadless_1.runFlowSeekerHeadless)(workspacePath, goldenTask.task, config);
|
|
1012
|
+
const gr = (0, fileScanner_1.getGuardReasons)();
|
|
1013
|
+
if (gr.size > 0) {
|
|
1014
|
+
const plain = {};
|
|
1015
|
+
for (const [fp, cat] of gr)
|
|
1016
|
+
plain[fp] = cat;
|
|
1017
|
+
taskGuardReasons[String(perTaskResults.length)] = plain;
|
|
1018
|
+
}
|
|
1019
|
+
flowResults.push(result);
|
|
1020
|
+
const metrics = (0, accuracyV2_1.computeAccuracyV2)(result, goldenTask);
|
|
1021
|
+
perTaskResults.push(metrics);
|
|
1022
|
+
const dur = ((Date.now() - taskStart) / 1000).toFixed(2);
|
|
1023
|
+
console.log(` editR@1=${metrics.editRecall1} editR@3=${metrics.editRecall3} editR@10=${metrics.editRecall10} first3Hit=${metrics.first3Hit} mustNotViolation=${metrics.mustNotEditViolation} ${dur}s`);
|
|
1024
|
+
}
|
|
1025
|
+
// Compute failure analysis for each task
|
|
1026
|
+
const failureAnalysis = manifest.tasks.map((goldenTask, i) => (0, accuracyV2_1.computeFailureAnalysis)(flowResults[i], goldenTask, perTaskResults[i]));
|
|
1027
|
+
// Compute semantic contribution
|
|
1028
|
+
const semPerTask = flowResults.map((r) => (0, accuracyV2_1.computeSemanticContribution)(r));
|
|
1029
|
+
const semanticContribution = (0, accuracyV2_1.aggregateSemanticContribution)(semPerTask, flowResults);
|
|
1030
|
+
// Compute role classifier report
|
|
1031
|
+
const roleConfusionMatrix = (0, accuracyV2_1.computeRoleConfusionMatrix)(flowResults, manifest.tasks, "balanced");
|
|
1032
|
+
const roleClassifierReport = (0, accuracyV2_1.computeRoleClassifierReport)(flowResults, manifest.tasks);
|
|
1033
|
+
const report = (0, accuracyV2_1.aggregateAccuracyV2)(perTaskResults, failureAnalysis, semanticContribution, roleConfusionMatrix, roleClassifierReport, manifest.name);
|
|
1034
|
+
// Write JSON report
|
|
1035
|
+
const reportPath = path.resolve(goldenReportPath ?? path.join(".flowseeker", "reports", `golden-eval-${slugify(manifest.name)}.json`));
|
|
1036
|
+
await fs.mkdir(path.dirname(reportPath), { recursive: true });
|
|
1037
|
+
await fs.writeFile(reportPath, JSON.stringify({ ...report, guardReasons: taskGuardReasons }, null, 2), "utf8");
|
|
1038
|
+
console.log(`\nGolden JSON: ${reportPath}`);
|
|
1039
|
+
// Write markdown report
|
|
1040
|
+
const mdPath = reportPath.replace(/\.json$/, ".md");
|
|
1041
|
+
const mdLines = [
|
|
1042
|
+
"# FlowSeeker Accuracy V2 Report",
|
|
1043
|
+
"",
|
|
1044
|
+
`Generated: ${new Date().toISOString()}`,
|
|
1045
|
+
`Manifest: ${manifest.name}`,
|
|
1046
|
+
`Workspace: ${workspacePath}`,
|
|
1047
|
+
`Tasks: ${report.taskCount}`,
|
|
1048
|
+
"",
|
|
1049
|
+
...(0, accuracyV2_1.renderAccuracyV2Markdown)(report),
|
|
1050
|
+
];
|
|
1051
|
+
await fs.writeFile(mdPath, mdLines.join("\n"), "utf8");
|
|
1052
|
+
console.log(`Golden Markdown: ${mdPath}`);
|
|
1053
|
+
// Print summary
|
|
1054
|
+
console.log(`\nAccuracy V2 Summary:`);
|
|
1055
|
+
console.log(` edit_recall@1: ${(report.editRecall1 * 100).toFixed(1)}%`);
|
|
1056
|
+
console.log(` edit_recall@3: ${(report.editRecall3 * 100).toFixed(1)}%`);
|
|
1057
|
+
console.log(` edit_recall@5: ${(report.editRecall5 * 100).toFixed(1)}%`);
|
|
1058
|
+
console.log(` edit_recall@10: ${(report.editRecall10 * 100).toFixed(1)}%`);
|
|
1059
|
+
console.log(` primary_edit_precision@3: ${(report.primaryEditPrecision3 * 100).toFixed(1)}%`);
|
|
1060
|
+
console.log(` read_context_recall@10: ${(report.readContextRecall10 * 100).toFixed(1)}%`);
|
|
1061
|
+
console.log(` test_recall@10: ${(report.testRecall10 * 100).toFixed(1)}%`);
|
|
1062
|
+
console.log(` must_not_edit_violation_rate: ${(report.mustNotEditViolationRate * 100).toFixed(1)}%`);
|
|
1063
|
+
console.log(` noise_promoted_as_edit_rate: ${(report.noisePromotedAsEditRate * 100).toFixed(1)}%`);
|
|
1064
|
+
console.log(` required_slot_coverage: ${(report.requiredSlotCoverage * 100).toFixed(1)}%`);
|
|
1065
|
+
console.log(` missing_slot_rate: ${(report.missingSlotRate * 100).toFixed(1)}%`);
|
|
1066
|
+
console.log(` first3_hit_rate: ${(report.first3HitRate * 100).toFixed(1)}%`);
|
|
1067
|
+
}
|
|
965
1068
|
//# sourceMappingURL=runEvaluation.js.map
|