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 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-vector-v2.svg");
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