@hassangameryt/freeflow 0.2.0 → 0.4.0
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/.agents/plugins/marketplace.json +1 -1
- package/.claude-plugin/marketplace.json +4 -4
- package/{plugins/freeflow/.claude-plugin → .claude-plugin}/plugin.json +5 -2
- package/{plugins/freeflow/.codex-plugin → .codex-plugin}/plugin.json +8 -9
- package/README.md +194 -127
- package/assets/feedback-loop.png +0 -0
- package/assets/freeflow-plugin-icon.png +0 -0
- package/assets/freeflow_workflow_map.png +0 -0
- package/assets/workflow.png +0 -0
- package/command-surface.json +129 -0
- package/hooks/freeflow-runtime-context.mjs +419 -0
- package/hooks/tests/check-runtime-context-hook.sh +223 -0
- package/package.json +41 -22
- package/pi-extension/dist/index.js +269 -0
- package/pi-extension/dist/integrations/mcp-config.js +29 -0
- package/pi-extension/dist/output-router/host-producer-identification.js +232 -0
- package/pi-extension/dist/output-router/native-safety-net.js +216 -0
- package/pi-extension/dist/output-router/observed-tool-routing.js +122 -0
- package/pi-extension/dist/output-router/renderers.js +1023 -0
- package/pi-extension/dist/output-router/router-tools.js +554 -0
- package/pi-extension/dist/output-router/schemas.js +383 -0
- package/pi-extension/dist/output-router/status.js +744 -0
- package/pi-extension/dist/output-router/utils.js +502 -0
- package/pi-extension/dist/runtime/runtime-context.js +798 -0
- package/pi-extension/dist/settings/settings-tui.js +314 -0
- package/pi-extension/dist/settings/settings-ui.js +1487 -0
- package/pi-extension/freeflow/index.js +1 -0
- package/pi-extension/src/index.ts +295 -0
- package/pi-extension/src/integrations/mcp-config.ts +32 -0
- package/pi-extension/src/output-router/host-producer-identification.ts +256 -0
- package/pi-extension/src/output-router/native-safety-net.ts +248 -0
- package/pi-extension/src/output-router/observed-tool-routing.ts +134 -0
- package/pi-extension/src/output-router/renderers.ts +1108 -0
- package/pi-extension/src/output-router/router-tools.ts +579 -0
- package/pi-extension/src/output-router/schemas.ts +387 -0
- package/pi-extension/src/output-router/status.ts +791 -0
- package/pi-extension/src/output-router/utils.ts +554 -0
- package/pi-extension/src/runtime/runtime-context.ts +895 -0
- package/pi-extension/src/settings/settings-tui.ts +408 -0
- package/pi-extension/src/settings/settings-ui.ts +1730 -0
- package/pi-extension/tests/integration/pi-extension.test.js +4018 -0
- package/pi-extension/tests/output-router/observed-producers.test.js +132 -0
- package/pi-extension/tests/output-router/search.test.js +722 -0
- package/pi-extension/tests/settings/settings-tui.test.js +243 -0
- package/pi-extension/tsconfig.json +16 -0
- package/{plugins/freeflow/router/dist → router/dist/benchmarks}/benchmark-harness.d.ts +16 -13
- package/router/dist/benchmarks/benchmark-harness.js +92 -0
- package/router/dist/benchmarks/benchmarks.d.ts +109 -0
- package/router/dist/benchmarks/benchmarks.js +979 -0
- package/router/dist/benchmarks/codex-qa-benchmarks.d.ts +95 -0
- package/router/dist/benchmarks/codex-qa-benchmarks.js +500 -0
- package/router/dist/benchmarks/command-benchmarks.d.ts +143 -0
- package/router/dist/benchmarks/command-benchmarks.js +698 -0
- package/router/dist/benchmarks/context-mode-normalized-benchmarks.d.ts +82 -0
- package/router/dist/benchmarks/context-mode-normalized-benchmarks.js +773 -0
- package/router/dist/benchmarks/context-mode-real-deep-benchmark.d.ts +132 -0
- package/router/dist/benchmarks/context-mode-real-deep-benchmark.js +1380 -0
- package/router/dist/benchmarks/context-saving-baseline.d.ts +60 -0
- package/router/dist/benchmarks/context-saving-baseline.js +470 -0
- package/router/dist/benchmarks/index-benchmarks.d.ts +103 -0
- package/router/dist/benchmarks/index-benchmarks.js +862 -0
- package/router/dist/benchmarks/storage-policy-benchmarks.d.ts +101 -0
- package/router/dist/benchmarks/storage-policy-benchmarks.js +618 -0
- package/router/dist/benchmarks/vault-index-benchmarks.d.ts +56 -0
- package/router/dist/benchmarks/vault-index-benchmarks.js +322 -0
- package/router/dist/config/config.d.ts +103 -0
- package/router/dist/config/config.js +632 -0
- package/{plugins/freeflow/router/dist → router/dist/config}/router-contract.d.ts +2 -2
- package/router/dist/config/router-contract.js +54 -0
- package/{plugins/freeflow/router/dist → router/dist/config}/schema.d.ts +19 -10
- package/router/dist/config/schema.js +648 -0
- package/router/dist/config/types.d.ts +573 -0
- package/router/dist/config/types.js +41 -0
- package/router/dist/evidence/bounded-evidence.d.ts +40 -0
- package/router/dist/evidence/bounded-evidence.js +323 -0
- package/router/dist/evidence/evidence-range-selector.d.ts +24 -0
- package/router/dist/evidence/evidence-range-selector.js +232 -0
- package/router/dist/evidence/evidence-search.d.ts +27 -0
- package/router/dist/evidence/evidence-search.js +490 -0
- package/{plugins/freeflow/router/dist → router/dist/evidence}/evidence.d.ts +18 -18
- package/router/dist/evidence/evidence.js +200 -0
- package/router/dist/evidence/failure-contracts.d.ts +37 -0
- package/router/dist/evidence/failure-contracts.js +166 -0
- package/router/dist/evidence/line-ranges.d.ts +24 -0
- package/router/dist/evidence/line-ranges.js +22 -0
- package/router/dist/experiments/local-index.d.ts +64 -0
- package/router/dist/experiments/local-index.js +581 -0
- package/router/dist/index.d.ts +30 -0
- package/router/dist/index.js +32 -0
- package/router/dist/local/local-traversal.d.ts +18 -0
- package/router/dist/local/local-traversal.js +334 -0
- package/router/dist/processing/engine.d.ts +132 -0
- package/router/dist/processing/engine.js +533 -0
- package/router/dist/processing/reducers.d.ts +280 -0
- package/router/dist/processing/reducers.js +1673 -0
- package/router/dist/processing/renderers.d.ts +31 -0
- package/router/dist/processing/renderers.js +195 -0
- package/router/dist/processing/scripts.d.ts +91 -0
- package/router/dist/processing/scripts.js +386 -0
- package/{plugins/freeflow/router/dist → router/dist/repo}/repo-traversal.d.ts +9 -9
- package/router/dist/repo/repo-traversal.js +245 -0
- package/router/dist/routing/observed-reducers.d.ts +41 -0
- package/router/dist/routing/observed-reducers.js +661 -0
- package/router/dist/routing/observed-routing.d.ts +26 -0
- package/router/dist/routing/observed-routing.js +378 -0
- package/router/dist/routing/parsers.d.ts +16 -0
- package/router/dist/routing/parsers.js +521 -0
- package/router/dist/routing/run-filters.d.ts +60 -0
- package/router/dist/routing/run-filters.js +238 -0
- package/router/dist/routing/run-reducers.d.ts +49 -0
- package/router/dist/routing/run-reducers.js +122 -0
- package/router/dist/sandbox/adapter-roots.d.ts +46 -0
- package/router/dist/sandbox/adapter-roots.js +66 -0
- package/router/dist/sandbox/eryx-python-adapter.d.ts +13 -0
- package/router/dist/sandbox/eryx-python-adapter.js +868 -0
- package/router/dist/sandbox/jq-wasm-adapter.d.ts +9 -0
- package/router/dist/sandbox/jq-wasm-adapter.js +429 -0
- package/router/dist/sandbox/quickjs-wasi-adapter.d.ts +13 -0
- package/router/dist/sandbox/quickjs-wasi-adapter.js +384 -0
- package/router/dist/sandbox/script-sandbox.d.ts +134 -0
- package/router/dist/sandbox/script-sandbox.js +337 -0
- package/router/dist/setup/script-transform-adapters.d.ts +32 -0
- package/router/dist/setup/script-transform-adapters.js +278 -0
- package/router/dist/tools/batch.d.ts +33 -0
- package/router/dist/tools/batch.js +586 -0
- package/router/dist/tools/run.d.ts +62 -0
- package/router/dist/tools/run.js +1304 -0
- package/router/dist/tools/search.d.ts +66 -0
- package/router/dist/tools/search.js +1364 -0
- package/router/dist/transform/engine.d.ts +168 -0
- package/router/dist/transform/engine.js +2072 -0
- package/router/dist/vault/vault-index.d.ts +125 -0
- package/router/dist/vault/vault-index.js +416 -0
- package/router/dist/vault/vault.d.ts +138 -0
- package/router/dist/vault/vault.js +630 -0
- package/runtime/interaction-contract.md +16 -0
- package/skills/bypass/SKILL.md +82 -0
- package/skills/commit-work/SKILL.md +106 -0
- package/skills/commit-work/references/staging-decisions.md +73 -0
- package/skills/decision-gate/SKILL.md +48 -0
- package/skills/design-for-depth/SKILL.md +106 -0
- package/skills/design-for-depth/references/design-pressure-signals.md +314 -0
- package/skills/design-for-depth/references/interface-design-loop.md +156 -0
- package/skills/design-for-depth/references/software-design-philosophy.md +248 -0
- package/skills/diagnose-failure/SKILL.md +105 -0
- package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +36 -0
- package/skills/diagnose-failure/references/flaky-and-performance.md +43 -0
- package/skills/discuss/SKILL.md +121 -0
- package/skills/discuss/references/checkpoints.md +66 -0
- package/skills/evaluate-skill/SKILL.md +105 -0
- package/skills/evaluate-skill/references/definition-schema.md +345 -0
- package/skills/evaluate-skill/references/evaluation-design.md +86 -0
- package/skills/evaluate-skill/references/execution-and-evidence.md +85 -0
- package/skills/evaluate-skill/references/review-and-revision.md +51 -0
- package/skills/evaluate-skill/scripts/lib/definitions.mjs +296 -0
- package/skills/evaluate-skill/scripts/lib/evidence.mjs +46 -0
- package/skills/evaluate-skill/scripts/lib/grade-comparison.mjs +60 -0
- package/skills/evaluate-skill/scripts/lib/grade-interaction.mjs +148 -0
- package/skills/evaluate-skill/scripts/lib/grade-support.mjs +126 -0
- package/skills/evaluate-skill/scripts/lib/grade-workspace.mjs +192 -0
- package/skills/evaluate-skill/scripts/lib/grade.mjs +56 -0
- package/skills/evaluate-skill/scripts/lib/pi.mjs +489 -0
- package/skills/evaluate-skill/scripts/lib/process.mjs +79 -0
- package/skills/evaluate-skill/scripts/lib/rpc.mjs +444 -0
- package/skills/evaluate-skill/scripts/lib/runner.mjs +346 -0
- package/skills/evaluate-skill/scripts/lib/sandbox.mjs +409 -0
- package/skills/evaluate-skill/scripts/lib/view.mjs +337 -0
- package/skills/evaluate-skill/scripts/pi-guard.mjs +164 -0
- package/skills/evaluate-skill/scripts/skill-eval.mjs +101 -0
- package/skills/execute-work/SKILL.md +99 -0
- package/skills/execute-work/references/code-practices.md +78 -0
- package/skills/execute-work/references/execution-loop.md +77 -0
- package/skills/finish-branch/SKILL.md +117 -0
- package/skills/finish-branch/references/integration-options.md +80 -0
- package/skills/handoff/SKILL.md +92 -0
- package/skills/handoff/references/templates.md +141 -0
- package/skills/launch-work/SKILL.md +116 -0
- package/skills/launch-work/references/launch-readiness.md +85 -0
- package/skills/migration-work/SKILL.md +115 -0
- package/skills/migration-work/references/migration-lifecycle.md +82 -0
- package/skills/mode-contract/SKILL.md +82 -0
- package/skills/output-router/SKILL.md +206 -0
- package/skills/output-router/references/safety-policy.md +40 -0
- package/skills/release-work/SKILL.md +118 -0
- package/skills/release-work/references/release-evidence.md +78 -0
- package/skills/review-artifact/SKILL.md +126 -0
- package/skills/review-artifact/references/reviewer-prompt.md +148 -0
- package/skills/review-work/SKILL.md +126 -0
- package/skills/review-work/references/reviewer-prompt.md +134 -0
- package/skills/review-work/references/security-risk-lens.md +67 -0
- package/skills/setup-freeflow/SKILL.md +98 -0
- package/skills/setup-freeflow/references/activation-contract.md +120 -0
- package/skills/setup-freeflow/references/host-setup.md +72 -0
- package/skills/setup-freeflow/references/output-router-setup.md +110 -0
- package/skills/simplify-code/SKILL.md +80 -0
- package/skills/simplify-code/references/simplification-patterns.md +70 -0
- package/skills/tdd/SKILL.md +96 -0
- package/skills/tdd/references/test-design.md +96 -0
- package/skills/track-work/SKILL.md +84 -0
- package/skills/track-work/references/working-record-schema.md +378 -0
- package/skills/verify-work/SKILL.md +85 -0
- package/skills/verify-work/references/browser-runtime-evidence.md +55 -0
- package/skills/verify-work/references/integration-evidence.md +51 -0
- package/skills/verify-work/references/performance-evidence.md +57 -0
- package/skills/workflow/SKILL.md +91 -0
- package/skills/workflow/references/domain-skill-composition.md +57 -0
- package/skills/workflow/references/workflow-loop.md +92 -0
- package/skills/write-plan/SKILL.md +123 -0
- package/skills/write-plan/references/plan-shapes.md +156 -0
- package/skills/write-skill/SKILL.md +119 -0
- package/skills/write-skill/references/activation-boundaries.md +62 -0
- package/skills/write-skill/references/agent-first-instructions.md +87 -0
- package/skills/write-skill/references/progressive-disclosure.md +63 -0
- package/skills/write-skill/scripts/lib/skill-author.mjs +653 -0
- package/skills/write-skill/scripts/skill-author.mjs +104 -0
- package/skills/write-spec/SKILL.md +104 -0
- package/skills/write-spec/references/artifact-standards.md +86 -0
- package/skills/write-spec/references/decision-records.md +77 -0
- package/skills/write-spec/references/spec-shapes.md +128 -0
- package/plugins/freeflow/command-surface.json +0 -77
- package/plugins/freeflow/docs/README.md +0 -40
- package/plugins/freeflow/docs/adr/0001-three-modes.md +0 -27
- package/plugins/freeflow/docs/adr/0002-evals-before-hooks.md +0 -17
- package/plugins/freeflow/docs/adr/0003-release-boundary.md +0 -21
- package/plugins/freeflow/docs/adr/0004-research-replaces-shallow-discovery-skills.md +0 -26
- package/plugins/freeflow/docs/adr/README.md +0 -8
- package/plugins/freeflow/docs/architecture.md +0 -86
- package/plugins/freeflow/docs/output-router.md +0 -212
- package/plugins/freeflow/docs/release-evidence.md +0 -69
- package/plugins/freeflow/docs/skills.md +0 -43
- package/plugins/freeflow/docs/workflow.md +0 -57
- package/plugins/freeflow/hooks/freeflow-runtime-context.mjs +0 -257
- package/plugins/freeflow/pi-extension/index.js +0 -1176
- package/plugins/freeflow/router/dist/benchmark-harness.js +0 -92
- package/plugins/freeflow/router/dist/benchmarks.d.ts +0 -102
- package/plugins/freeflow/router/dist/benchmarks.js +0 -880
- package/plugins/freeflow/router/dist/bounded-evidence.d.ts +0 -40
- package/plugins/freeflow/router/dist/bounded-evidence.js +0 -310
- package/plugins/freeflow/router/dist/codex-qa-benchmarks.d.ts +0 -91
- package/plugins/freeflow/router/dist/codex-qa-benchmarks.js +0 -461
- package/plugins/freeflow/router/dist/command-benchmarks.d.ts +0 -128
- package/plugins/freeflow/router/dist/command-benchmarks.js +0 -652
- package/plugins/freeflow/router/dist/config.d.ts +0 -22
- package/plugins/freeflow/router/dist/config.js +0 -114
- package/plugins/freeflow/router/dist/evidence-range-selector.d.ts +0 -22
- package/plugins/freeflow/router/dist/evidence-range-selector.js +0 -180
- package/plugins/freeflow/router/dist/evidence-search.d.ts +0 -25
- package/plugins/freeflow/router/dist/evidence-search.js +0 -450
- package/plugins/freeflow/router/dist/evidence.js +0 -196
- package/plugins/freeflow/router/dist/experimental-local-index.d.ts +0 -1
- package/plugins/freeflow/router/dist/experimental-local-index.js +0 -1
- package/plugins/freeflow/router/dist/experiments/local-index.d.ts +0 -58
- package/plugins/freeflow/router/dist/experiments/local-index.js +0 -562
- package/plugins/freeflow/router/dist/index-benchmarks.d.ts +0 -84
- package/plugins/freeflow/router/dist/index-benchmarks.js +0 -458
- package/plugins/freeflow/router/dist/index.d.ts +0 -12
- package/plugins/freeflow/router/dist/index.js +0 -12
- package/plugins/freeflow/router/dist/line-ranges.d.ts +0 -22
- package/plugins/freeflow/router/dist/line-ranges.js +0 -22
- package/plugins/freeflow/router/dist/parsers.d.ts +0 -16
- package/plugins/freeflow/router/dist/parsers.js +0 -473
- package/plugins/freeflow/router/dist/repo-traversal.js +0 -242
- package/plugins/freeflow/router/dist/retrieve.d.ts +0 -33
- package/plugins/freeflow/router/dist/retrieve.js +0 -855
- package/plugins/freeflow/router/dist/router-contract.js +0 -54
- package/plugins/freeflow/router/dist/run.d.ts +0 -26
- package/plugins/freeflow/router/dist/run.js +0 -356
- package/plugins/freeflow/router/dist/schema.js +0 -354
- package/plugins/freeflow/router/dist/types.d.ts +0 -234
- package/plugins/freeflow/router/dist/types.js +0 -9
- package/plugins/freeflow/router/dist/vault.d.ts +0 -80
- package/plugins/freeflow/router/dist/vault.js +0 -484
- package/plugins/freeflow/skills/bypass/SKILL.md +0 -68
- package/plugins/freeflow/skills/commit-work/SKILL.md +0 -98
- package/plugins/freeflow/skills/commit-work/references/staging-decisions.md +0 -51
- package/plugins/freeflow/skills/diagnose-failure/SKILL.md +0 -95
- package/plugins/freeflow/skills/diagnose-failure/references/feedback-loop-catalog.md +0 -25
- package/plugins/freeflow/skills/diagnose-failure/references/flaky-and-performance.md +0 -31
- package/plugins/freeflow/skills/evaluate-skill/SKILL.md +0 -96
- package/plugins/freeflow/skills/evaluate-skill/references/eval-patterns.md +0 -41
- package/plugins/freeflow/skills/evaluate-skill/references/grading-priority.md +0 -33
- package/plugins/freeflow/skills/execute-plan/SKILL.md +0 -132
- package/plugins/freeflow/skills/execute-plan/references/execution-map.md +0 -122
- package/plugins/freeflow/skills/handoff/SKILL.md +0 -66
- package/plugins/freeflow/skills/handoff/references/templates.md +0 -64
- package/plugins/freeflow/skills/interview-gate/SKILL.md +0 -90
- package/plugins/freeflow/skills/mode-contract/SKILL.md +0 -79
- package/plugins/freeflow/skills/output-router/SKILL.md +0 -69
- package/plugins/freeflow/skills/output-router/references/safety-policy.md +0 -33
- package/plugins/freeflow/skills/research/ARTIFACT-DESTINATIONS.md +0 -58
- package/plugins/freeflow/skills/research/CHECKPOINTS.md +0 -74
- package/plugins/freeflow/skills/research/LANGUAGE.md +0 -61
- package/plugins/freeflow/skills/research/SKILL.md +0 -128
- package/plugins/freeflow/skills/review-artifact/SKILL.md +0 -115
- package/plugins/freeflow/skills/review-artifact/references/reviewer-prompt.md +0 -56
- package/plugins/freeflow/skills/review-work/SKILL.md +0 -96
- package/plugins/freeflow/skills/review-work/references/reviewer-prompt.md +0 -97
- package/plugins/freeflow/skills/setup-freeflow/SKILL.md +0 -94
- package/plugins/freeflow/skills/setup-freeflow/references/activation-contract.md +0 -99
- package/plugins/freeflow/skills/setup-freeflow/references/host-setup.md +0 -35
- package/plugins/freeflow/skills/setup-freeflow/references/output-router-setup.md +0 -52
- package/plugins/freeflow/skills/verify-work/SKILL.md +0 -62
- package/plugins/freeflow/skills/workflow/SKILL.md +0 -95
- package/plugins/freeflow/skills/workflow/references/workflow-map.md +0 -102
- package/plugins/freeflow/skills/write-plan/SKILL.md +0 -88
- package/plugins/freeflow/skills/write-plan/references/plan-shapes.md +0 -70
- package/plugins/freeflow/skills/write-skill/SKILL.md +0 -88
- package/plugins/freeflow/skills/write-spec/SKILL.md +0 -90
- package/plugins/freeflow/skills/write-spec/references/artifact-standards.md +0 -67
- package/plugins/freeflow/skills/write-spec/references/spec-shapes.md +0 -69
- /package/{plugins/freeflow/assets → assets}/freeflow-plugin-icon-transparent.png +0 -0
- /package/{plugins/freeflow/hooks → hooks}/hooks.json +0 -0
|
@@ -1,458 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { mkdir, mkdtemp, readdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { dirname, resolve } from "node:path";
|
|
5
|
-
import { fileURLToPath } from "node:url";
|
|
6
|
-
import { performance } from "node:perf_hooks";
|
|
7
|
-
import { defaultJsonRunReportPath, escapeMarkdownTableCell as escapeTable, formatPercent, latencySummary, normalizeIterations, parseBenchmarkCliArgs, reductionPercent, writeBenchmarkReportPair, } from "./benchmark-harness.js";
|
|
8
|
-
import { freeflowRetrieve } from "./retrieve.js";
|
|
9
|
-
import { buildOrLoadExperimentalRepoIndex, queryExperimentalRepoIndex, } from "./experiments/local-index.js";
|
|
10
|
-
const DEFAULT_ITERATIONS = 3;
|
|
11
|
-
export async function runIndexBenchmarks(options = {}) {
|
|
12
|
-
const iterations = normalizeIterations(options.iterations, DEFAULT_ITERATIONS);
|
|
13
|
-
const fixtures = indexFixtureDefinitions();
|
|
14
|
-
const fixtureResults = [];
|
|
15
|
-
for (const fixture of fixtures) {
|
|
16
|
-
const results = [];
|
|
17
|
-
for (const mode of indexBenchmarkModes()) {
|
|
18
|
-
results.push(await runIndexFixtureMode(fixture, mode, iterations));
|
|
19
|
-
}
|
|
20
|
-
fixtureResults.push({ id: fixture.id, title: fixture.title, expected: fixtureExpectedForMode(fixture, "index-warm"), results });
|
|
21
|
-
}
|
|
22
|
-
return {
|
|
23
|
-
generatedAt: options.generatedAt ?? new Date().toISOString(),
|
|
24
|
-
iterations,
|
|
25
|
-
summary: summarizeIndexReport(fixtureResults),
|
|
26
|
-
fixtures: fixtureResults,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
export function renderIndexBenchmarkReport(report) {
|
|
30
|
-
const date = report.generatedAt.slice(0, 10);
|
|
31
|
-
const lines = [
|
|
32
|
-
"# Output Router Index Benchmark Report - Iteration 1",
|
|
33
|
-
"",
|
|
34
|
-
`Date: ${date}`,
|
|
35
|
-
"",
|
|
36
|
-
"## Scope",
|
|
37
|
-
"",
|
|
38
|
-
"Optional Local Index Experiment for `freeflow_retrieve`. The scanner remains the product default; this benchmark measures an isolated no-dependency local index for cold build, warm query, stale refresh, accuracy, and bounded context bytes.",
|
|
39
|
-
"",
|
|
40
|
-
"The index cache is keyed by repo root and stores outside the repo by default. No external service, vector DB, or native dependency is required.",
|
|
41
|
-
"",
|
|
42
|
-
"## Command",
|
|
43
|
-
"",
|
|
44
|
-
"```sh",
|
|
45
|
-
"npm run bench:router:index",
|
|
46
|
-
"```",
|
|
47
|
-
"",
|
|
48
|
-
"The CLI writes machine-readable JSON under `plugins/freeflow/evals/runs/output-router/` by default. That JSON is generated run data; this Markdown file is the durable runtime report.",
|
|
49
|
-
"",
|
|
50
|
-
"## Summary",
|
|
51
|
-
"",
|
|
52
|
-
`- Fixtures: ${report.summary.fixtures}`,
|
|
53
|
-
`- Scanner remains default: ${report.summary.scannerDefault ? "yes" : "no"}`,
|
|
54
|
-
`- Index adopted by default: ${report.summary.indexAdopted ? "yes" : "no"}`,
|
|
55
|
-
`- Scanner pass: ${report.summary.scanner.passed}/${report.summary.fixtures}`,
|
|
56
|
-
`- Index warm pass: ${report.summary.index.passed}/${report.summary.fixtures}`,
|
|
57
|
-
`- Generated false positives: ${report.summary.generatedFalsePositiveCount}/${report.summary.modeResults}`,
|
|
58
|
-
`- Cold build p50/p95: ${report.summary.coldBuildMs.p50.toFixed(2)}/${report.summary.coldBuildMs.p95.toFixed(2)} ms`,
|
|
59
|
-
`- Warm query p50/p95: ${report.summary.warmQueryMs.p50.toFixed(2)}/${report.summary.warmQueryMs.p95.toFixed(2)} ms`,
|
|
60
|
-
`- Stale refresh p50/p95: ${report.summary.staleRefreshMs.p50.toFixed(2)}/${report.summary.staleRefreshMs.p95.toFixed(2)} ms`,
|
|
61
|
-
`- Index warm context reduction: ${formatPercent(report.summary.index.weightedContextReductionPercent)} (${report.summary.index.totalRawBytes} raw bytes to ${report.summary.index.totalContextBytes} context bytes)`,
|
|
62
|
-
"",
|
|
63
|
-
"## Results",
|
|
64
|
-
"",
|
|
65
|
-
"| fixture | mode | correctness | checks | path | lines | raw/context bytes | context reduction | latency p50/p95 ms | build/query ms | index mode | notes |",
|
|
66
|
-
"| --- | --- | --- | --- | --- | --- | ---: | ---: | ---: | ---: | --- | --- |",
|
|
67
|
-
];
|
|
68
|
-
for (const fixture of report.fixtures) {
|
|
69
|
-
for (const result of fixture.results) {
|
|
70
|
-
const correctness = result.correctness.passed ? "pass" : "fail";
|
|
71
|
-
const checks = formatCorrectnessChecks(result.correctness);
|
|
72
|
-
const buildQuery = `${(result.buildMs ?? 0).toFixed(2)}/${(result.queryMs ?? 0).toFixed(2)}`;
|
|
73
|
-
const notes = result.notes.length ? result.notes.join("; ") : "";
|
|
74
|
-
lines.push(`| ${escapeTable(fixture.id)} | ${escapeTable(result.mode)} | ${correctness} | ${escapeTable(checks)} | ${escapeTable(result.actualPath ?? "-")} | ${escapeTable(result.actualLines ?? "-")} | ${result.rawBytes}/${result.contextBytes} | ${formatPercent(result.contextReductionPercent)} | ${result.latencyMs.p50.toFixed(2)}/${result.latencyMs.p95.toFixed(2)} | ${buildQuery} | ${escapeTable(result.indexMode ?? "-")} | ${escapeTable(notes)} |`);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
lines.push("", "## Adoption Decision", "", "Index adopted by default: no. This slice only adds an experiment and benchmark evidence; scanner behavior remains the default until a later adoption checkpoint explicitly approves otherwise.", "", "## Regression Status", "", report.summary.index.failed === 0
|
|
78
|
-
? "Warm experimental index passed all gated fixtures without generated-artifact false positives."
|
|
79
|
-
: `Warm experimental index failed ${report.summary.index.failed} fixture(s).`, "");
|
|
80
|
-
return lines.join("\n");
|
|
81
|
-
}
|
|
82
|
-
export async function writeIndexBenchmarkReport(report, reportPath) {
|
|
83
|
-
await mkdir(dirname(reportPath), { recursive: true });
|
|
84
|
-
await writeFile(reportPath, renderIndexBenchmarkReport(report), "utf8");
|
|
85
|
-
}
|
|
86
|
-
export async function writeIndexBenchmarkJsonReport(report, reportPath) {
|
|
87
|
-
await mkdir(dirname(reportPath), { recursive: true });
|
|
88
|
-
await writeFile(reportPath, `${JSON.stringify(report, null, 2)}\n`, "utf8");
|
|
89
|
-
}
|
|
90
|
-
export async function writeIndexBenchmarkReports(report, markdownReportPath, options = {}) {
|
|
91
|
-
return writeBenchmarkReportPair({
|
|
92
|
-
report,
|
|
93
|
-
markdownReportPath,
|
|
94
|
-
jsonReportPath: options.jsonReportPath,
|
|
95
|
-
renderMarkdown: renderIndexBenchmarkReport,
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
async function runIndexFixtureMode(fixture, mode, iterations) {
|
|
99
|
-
const latencies = [];
|
|
100
|
-
let observation = null;
|
|
101
|
-
for (let index = 0; index < iterations; index += 1) {
|
|
102
|
-
const startedAt = performance.now();
|
|
103
|
-
observation = await observeIndexFixture(fixture, mode);
|
|
104
|
-
latencies.push(performance.now() - startedAt);
|
|
105
|
-
}
|
|
106
|
-
if (!observation) {
|
|
107
|
-
observation = { toolPathUsed: mode, rawBytes: 0, contextBytes: 0, excerpt: "", notes: ["no observation"] };
|
|
108
|
-
}
|
|
109
|
-
const correctness = scoreCorrectness(fixtureExpectedForMode(fixture, mode), observation);
|
|
110
|
-
const result = {
|
|
111
|
-
mode,
|
|
112
|
-
toolPathUsed: observation.toolPathUsed,
|
|
113
|
-
rawBytes: observation.rawBytes,
|
|
114
|
-
contextBytes: observation.contextBytes,
|
|
115
|
-
contextReductionPercent: reductionPercent(observation.rawBytes, observation.contextBytes),
|
|
116
|
-
latencyMs: latencySummary(latencies),
|
|
117
|
-
excerpt: observation.excerpt,
|
|
118
|
-
correctness,
|
|
119
|
-
notes: observation.notes ?? [],
|
|
120
|
-
};
|
|
121
|
-
if (observation.buildMs !== undefined) {
|
|
122
|
-
result.buildMs = observation.buildMs;
|
|
123
|
-
}
|
|
124
|
-
if (observation.queryMs !== undefined) {
|
|
125
|
-
result.queryMs = observation.queryMs;
|
|
126
|
-
}
|
|
127
|
-
if (observation.indexMode !== undefined) {
|
|
128
|
-
result.indexMode = observation.indexMode;
|
|
129
|
-
}
|
|
130
|
-
if (observation.actualPath !== undefined) {
|
|
131
|
-
result.actualPath = observation.actualPath;
|
|
132
|
-
}
|
|
133
|
-
if (observation.actualLines !== undefined) {
|
|
134
|
-
result.actualLines = observation.actualLines;
|
|
135
|
-
}
|
|
136
|
-
return result;
|
|
137
|
-
}
|
|
138
|
-
async function observeIndexFixture(fixture, mode) {
|
|
139
|
-
const root = await createTempDir("freeflow-router-index-benchmark-repo-");
|
|
140
|
-
const cacheRoot = await createTempDir("freeflow-router-index-benchmark-cache-");
|
|
141
|
-
try {
|
|
142
|
-
if (mode === "index-stale-refresh") {
|
|
143
|
-
await writeFixtureFiles(root.path, fixture.files);
|
|
144
|
-
await buildOrLoadExperimentalRepoIndex({ root: root.path, cacheRoot: cacheRoot.path });
|
|
145
|
-
await writeFixtureFiles(root.path, fixture.staleFiles ?? { "stale-marker.txt": "stale refresh marker" });
|
|
146
|
-
return await indexObservation(root.path, cacheRoot.path, fixture.staleQuery ?? fixture.query, mode);
|
|
147
|
-
}
|
|
148
|
-
const finalFiles = mode === "scanner-default" || mode === "index-cold" || mode === "index-warm"
|
|
149
|
-
? { ...fixture.files, ...(fixture.staleFiles && fixture.staleExpected ? fixture.staleFiles : {}) }
|
|
150
|
-
: fixture.files;
|
|
151
|
-
await writeFixtureFiles(root.path, finalFiles);
|
|
152
|
-
if (mode === "scanner-default") {
|
|
153
|
-
return await scannerObservation(root.path, fixture.staleQuery && fixture.staleExpected ? fixture.staleQuery : fixture.query);
|
|
154
|
-
}
|
|
155
|
-
if (mode === "index-warm") {
|
|
156
|
-
await buildOrLoadExperimentalRepoIndex({ root: root.path, cacheRoot: cacheRoot.path });
|
|
157
|
-
return await indexObservation(root.path, cacheRoot.path, fixture.staleQuery && fixture.staleExpected ? fixture.staleQuery : fixture.query, mode);
|
|
158
|
-
}
|
|
159
|
-
return await indexObservation(root.path, cacheRoot.path, fixture.staleQuery && fixture.staleExpected ? fixture.staleQuery : fixture.query, mode);
|
|
160
|
-
}
|
|
161
|
-
finally {
|
|
162
|
-
await Promise.all([root.cleanup(), cacheRoot.cleanup()]);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
async function scannerObservation(root, query) {
|
|
166
|
-
const rawBytes = await repoRawBytes(root);
|
|
167
|
-
const queryStartedAt = performance.now();
|
|
168
|
-
const result = await freeflowRetrieve({ action: "query", source: { kind: "repo", root }, query, preserve: "important" });
|
|
169
|
-
const queryMs = performance.now() - queryStartedAt;
|
|
170
|
-
const evidence = result.evidence?.[0];
|
|
171
|
-
return {
|
|
172
|
-
toolPathUsed: "scanner-default: freeflowRetrieve repo scanner",
|
|
173
|
-
rawBytes,
|
|
174
|
-
contextBytes: byteLength(JSON.stringify(result)),
|
|
175
|
-
...(evidence?.path !== undefined ? { actualPath: evidence.path } : {}),
|
|
176
|
-
...(evidence?.lines !== undefined ? { actualLines: evidence.lines } : {}),
|
|
177
|
-
excerpt: evidence?.excerpt ?? "",
|
|
178
|
-
queryMs,
|
|
179
|
-
notes: [result.routing.reason],
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
async function indexObservation(root, cacheRoot, query, mode) {
|
|
183
|
-
const rawBytes = await repoRawBytes(root);
|
|
184
|
-
const load = await buildOrLoadExperimentalRepoIndex({ root, cacheRoot });
|
|
185
|
-
const queryStartedAt = performance.now();
|
|
186
|
-
const candidates = queryExperimentalRepoIndex(load.index, query, { topK: 1 });
|
|
187
|
-
const queryMs = performance.now() - queryStartedAt;
|
|
188
|
-
const candidate = candidates[0];
|
|
189
|
-
return {
|
|
190
|
-
toolPathUsed: `${mode}: experimental local index`,
|
|
191
|
-
rawBytes,
|
|
192
|
-
contextBytes: byteLength(JSON.stringify(candidates)),
|
|
193
|
-
...(candidate?.path !== undefined ? { actualPath: candidate.path } : {}),
|
|
194
|
-
...(candidate?.lines !== undefined ? { actualLines: candidate.lines } : {}),
|
|
195
|
-
excerpt: candidate?.excerpt ?? "",
|
|
196
|
-
buildMs: load.buildMs,
|
|
197
|
-
queryMs,
|
|
198
|
-
indexMode: load.mode,
|
|
199
|
-
notes: candidate ? [candidate.reason, `cachePath=${load.cachePath}`, ...(load.refreshReason ? [`refresh=${load.refreshReason}`] : [])] : ["no index candidate"],
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
function summarizeIndexReport(fixtures) {
|
|
203
|
-
const scanner = summarizeMode(fixtures, "scanner-default");
|
|
204
|
-
const index = summarizeMode(fixtures, "index-warm");
|
|
205
|
-
const generatedFalsePositiveCount = fixtures
|
|
206
|
-
.flatMap((fixture) => fixture.results)
|
|
207
|
-
.filter((result) => result.correctness.generatedFalsePositive).length;
|
|
208
|
-
const coldBuildMs = latencyFor(fixtures, "index-cold", "buildMs");
|
|
209
|
-
const warmQueryMs = latencyFor(fixtures, "index-warm", "queryMs");
|
|
210
|
-
const staleRefreshMs = latencyFor(fixtures, "index-stale-refresh", "buildMs");
|
|
211
|
-
return {
|
|
212
|
-
fixtures: fixtures.length,
|
|
213
|
-
modeResults: fixtures.reduce((count, fixture) => count + fixture.results.length, 0),
|
|
214
|
-
scannerDefault: true,
|
|
215
|
-
indexAdopted: false,
|
|
216
|
-
scanner,
|
|
217
|
-
index,
|
|
218
|
-
generatedFalsePositiveCount,
|
|
219
|
-
coldBuildMs,
|
|
220
|
-
warmQueryMs,
|
|
221
|
-
staleRefreshMs,
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
function summarizeMode(fixtures, mode) {
|
|
225
|
-
const results = fixtures
|
|
226
|
-
.map((fixture) => fixture.results.find((result) => result.mode === mode))
|
|
227
|
-
.filter((result) => Boolean(result));
|
|
228
|
-
const totalRawBytes = results.reduce((sum, result) => sum + result.rawBytes, 0);
|
|
229
|
-
const totalContextBytes = results.reduce((sum, result) => sum + result.contextBytes, 0);
|
|
230
|
-
return results.reduce((summary, result) => {
|
|
231
|
-
if (result.correctness.passed) {
|
|
232
|
-
summary.passed += 1;
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
summary.failed += 1;
|
|
236
|
-
}
|
|
237
|
-
if (result.correctness.pathCorrect) {
|
|
238
|
-
summary.pathCorrect += 1;
|
|
239
|
-
}
|
|
240
|
-
if (result.correctness.spanCorrect) {
|
|
241
|
-
summary.spanCorrect += 1;
|
|
242
|
-
}
|
|
243
|
-
if (result.correctness.excerptComplete) {
|
|
244
|
-
summary.excerptComplete += 1;
|
|
245
|
-
}
|
|
246
|
-
return summary;
|
|
247
|
-
}, {
|
|
248
|
-
passed: 0,
|
|
249
|
-
failed: 0,
|
|
250
|
-
pathCorrect: 0,
|
|
251
|
-
spanCorrect: 0,
|
|
252
|
-
excerptComplete: 0,
|
|
253
|
-
totalRawBytes,
|
|
254
|
-
totalContextBytes,
|
|
255
|
-
weightedContextReductionPercent: reductionPercent(totalRawBytes, totalContextBytes),
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
function latencyFor(fixtures, mode, field) {
|
|
259
|
-
const values = fixtures
|
|
260
|
-
.map((fixture) => fixture.results.find((result) => result.mode === mode)?.[field])
|
|
261
|
-
.filter((value) => typeof value === "number");
|
|
262
|
-
return latencySummary(values);
|
|
263
|
-
}
|
|
264
|
-
function indexFixtureDefinitions() {
|
|
265
|
-
return [
|
|
266
|
-
{
|
|
267
|
-
id: "index-exact-copied-text",
|
|
268
|
-
title: "Exact copied text block",
|
|
269
|
-
files: {
|
|
270
|
-
"target.md": ["# Target", "", "ExperimentalIndex exact copied text source truth."].join("\n"),
|
|
271
|
-
"decoy.md": "ExperimentalIndex ExperimentalIndex ExperimentalIndex without copied source truth",
|
|
272
|
-
},
|
|
273
|
-
query: "ExperimentalIndex exact copied text source truth",
|
|
274
|
-
expected: {
|
|
275
|
-
path: "target.md",
|
|
276
|
-
lines: "1-3",
|
|
277
|
-
requiredExcerpt: ["ExperimentalIndex exact copied text source truth"],
|
|
278
|
-
},
|
|
279
|
-
},
|
|
280
|
-
{
|
|
281
|
-
id: "index-generated-artifact-decoy",
|
|
282
|
-
title: "Generated-artifact decoy",
|
|
283
|
-
files: {
|
|
284
|
-
"docs/codex-cli-agent-harness/2026-06-12-pass-3-sandboxing-and-permissions.md": [
|
|
285
|
-
"# Pass 3",
|
|
286
|
-
"",
|
|
287
|
-
"### Sandbox Permissions",
|
|
288
|
-
"",
|
|
289
|
-
"`SandboxPermissions` is a per-command request shape.",
|
|
290
|
-
"",
|
|
291
|
-
"Plain-language meaning:",
|
|
292
|
-
"",
|
|
293
|
-
"UseDefault: run with the turn's normal sandbox.",
|
|
294
|
-
].join("\n"),
|
|
295
|
-
"graphify-out/graph.html": [
|
|
296
|
-
"<html><body>",
|
|
297
|
-
`${"Sandbox Permissions SandboxPermissions Plain-language meaning ".repeat(5000)}GENERATED_GRAPH_DECOY_SENTINEL`,
|
|
298
|
-
"</body></html>",
|
|
299
|
-
].join("\n"),
|
|
300
|
-
},
|
|
301
|
-
query: "Sandbox Permissions SandboxPermissions Plain-language meaning",
|
|
302
|
-
expected: {
|
|
303
|
-
path: "docs/codex-cli-agent-harness/2026-06-12-pass-3-sandboxing-and-permissions.md",
|
|
304
|
-
lines: "3-7",
|
|
305
|
-
requiredExcerpt: ["SandboxPermissions", "Plain-language meaning"],
|
|
306
|
-
},
|
|
307
|
-
},
|
|
308
|
-
{
|
|
309
|
-
id: "index-stale-refresh",
|
|
310
|
-
title: "Changed-file stale refresh",
|
|
311
|
-
files: {
|
|
312
|
-
"target.md": ["# Target", "", "StaleIndexNeedle original source truth."].join("\n"),
|
|
313
|
-
},
|
|
314
|
-
query: "StaleIndexNeedle original source truth",
|
|
315
|
-
expected: {
|
|
316
|
-
path: "target.md",
|
|
317
|
-
lines: "1-3",
|
|
318
|
-
requiredExcerpt: ["StaleIndexNeedle original"],
|
|
319
|
-
},
|
|
320
|
-
staleFiles: {
|
|
321
|
-
"target.md": ["# Target", "", "StaleIndexNeedle refreshed source truth."].join("\n"),
|
|
322
|
-
},
|
|
323
|
-
staleQuery: "StaleIndexNeedle refreshed source truth",
|
|
324
|
-
staleExpected: {
|
|
325
|
-
path: "target.md",
|
|
326
|
-
lines: "1-3",
|
|
327
|
-
requiredExcerpt: ["StaleIndexNeedle refreshed"],
|
|
328
|
-
},
|
|
329
|
-
},
|
|
330
|
-
];
|
|
331
|
-
}
|
|
332
|
-
function fixtureExpectedForMode(fixture, mode) {
|
|
333
|
-
if ((mode === "index-stale-refresh" || fixture.staleQuery) && fixture.staleExpected) {
|
|
334
|
-
return fixture.staleExpected;
|
|
335
|
-
}
|
|
336
|
-
return fixture.expected;
|
|
337
|
-
}
|
|
338
|
-
function scoreCorrectness(expected, observation) {
|
|
339
|
-
const pathCorrect = observation.actualPath === expected.path;
|
|
340
|
-
const spanCorrect = expected.lines ? Boolean(observation.actualLines && rangesOverlap(expected.lines, observation.actualLines)) : true;
|
|
341
|
-
const excerptComplete = expected.requiredExcerpt.every((snippet) => observation.excerpt.toLowerCase().includes(snippet.toLowerCase()));
|
|
342
|
-
const generatedFalsePositive = observation.actualPath ? isGeneratedBenchmarkPath(observation.actualPath) : false;
|
|
343
|
-
return {
|
|
344
|
-
passed: pathCorrect && spanCorrect && excerptComplete && !generatedFalsePositive,
|
|
345
|
-
pathCorrect,
|
|
346
|
-
spanCorrect,
|
|
347
|
-
excerptComplete,
|
|
348
|
-
generatedFalsePositive,
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
async function writeFixtureFiles(root, files) {
|
|
352
|
-
for (const [path, text] of Object.entries(files)) {
|
|
353
|
-
const absolutePath = resolve(root, path);
|
|
354
|
-
await mkdir(dirname(absolutePath), { recursive: true });
|
|
355
|
-
await writeFile(absolutePath, text, "utf8");
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
async function repoRawBytes(root) {
|
|
359
|
-
const entries = [];
|
|
360
|
-
await collectRawText(root, root, entries);
|
|
361
|
-
return byteLength(entries.join("\n"));
|
|
362
|
-
}
|
|
363
|
-
async function collectRawText(root, currentPath, entries) {
|
|
364
|
-
const currentStat = await stat(currentPath);
|
|
365
|
-
if (currentStat.isDirectory()) {
|
|
366
|
-
const dirEntries = await readdir(currentPath, { withFileTypes: true });
|
|
367
|
-
for (const entry of dirEntries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
368
|
-
await collectRawText(root, resolve(currentPath, entry.name), entries);
|
|
369
|
-
}
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
if (!currentStat.isFile()) {
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
try {
|
|
376
|
-
const text = await readFile(currentPath, "utf8");
|
|
377
|
-
if (!text.includes("\0")) {
|
|
378
|
-
entries.push(text);
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
catch {
|
|
382
|
-
// ignore non-text fixture files
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
async function createTempDir(prefix) {
|
|
386
|
-
const path = await mkdtemp(resolve(tmpdir(), prefix));
|
|
387
|
-
return {
|
|
388
|
-
path,
|
|
389
|
-
cleanup: async () => {
|
|
390
|
-
await rm(path, { recursive: true, force: true });
|
|
391
|
-
},
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
function indexBenchmarkModes() {
|
|
395
|
-
return ["scanner-default", "index-cold", "index-warm", "index-stale-refresh"];
|
|
396
|
-
}
|
|
397
|
-
function rangesOverlap(left, right) {
|
|
398
|
-
const leftRange = parseRange(left);
|
|
399
|
-
const rightRange = parseRange(right);
|
|
400
|
-
if (!leftRange || !rightRange) {
|
|
401
|
-
return false;
|
|
402
|
-
}
|
|
403
|
-
return leftRange.start <= rightRange.end && rightRange.start <= leftRange.end;
|
|
404
|
-
}
|
|
405
|
-
function parseRange(range) {
|
|
406
|
-
const match = /^(\d+)-(\d+)$/.exec(range);
|
|
407
|
-
if (!match) {
|
|
408
|
-
return null;
|
|
409
|
-
}
|
|
410
|
-
const start = Number(match[1]);
|
|
411
|
-
const end = Number(match[2]);
|
|
412
|
-
return Number.isInteger(start) && Number.isInteger(end) ? { start, end } : null;
|
|
413
|
-
}
|
|
414
|
-
function isGeneratedBenchmarkPath(path) {
|
|
415
|
-
const segments = path.split(/[\\/]+/);
|
|
416
|
-
if (segments.includes("graphify-out")) {
|
|
417
|
-
return true;
|
|
418
|
-
}
|
|
419
|
-
const name = segments.at(-1)?.toLowerCase() ?? path.toLowerCase();
|
|
420
|
-
return name.endsWith(".log") || name.endsWith(".map") || name.endsWith(".min.js") || name.endsWith(".min.css") || name.includes(".bundle.");
|
|
421
|
-
}
|
|
422
|
-
function byteLength(value) {
|
|
423
|
-
return Buffer.byteLength(value, "utf8");
|
|
424
|
-
}
|
|
425
|
-
function formatCorrectnessChecks(correctness) {
|
|
426
|
-
return [
|
|
427
|
-
`path ${correctness.pathCorrect ? "✓" : "✗"}`,
|
|
428
|
-
`span ${correctness.spanCorrect ? "✓" : "✗"}`,
|
|
429
|
-
`excerpt ${correctness.excerptComplete ? "✓" : "✗"}`,
|
|
430
|
-
`gen-fp ${correctness.generatedFalsePositive ? "✗" : "✓"}`,
|
|
431
|
-
].join(" ");
|
|
432
|
-
}
|
|
433
|
-
function defaultReportPath() {
|
|
434
|
-
return resolve(process.cwd(), "plugins/freeflow/evals/reports/runtime/output-router-index-benchmark-1-report.md");
|
|
435
|
-
}
|
|
436
|
-
async function runCli() {
|
|
437
|
-
const { iterations, reportPath, jsonReportPath } = parseBenchmarkCliArgs(process.argv.slice(2), { reportPath: defaultReportPath() });
|
|
438
|
-
const options = {};
|
|
439
|
-
if (iterations !== undefined) {
|
|
440
|
-
options.iterations = iterations;
|
|
441
|
-
}
|
|
442
|
-
const report = await runIndexBenchmarks(options);
|
|
443
|
-
const reports = await writeIndexBenchmarkReports(report, reportPath, {
|
|
444
|
-
jsonReportPath: jsonReportPath === undefined ? defaultJsonRunReportPath(reportPath) : jsonReportPath,
|
|
445
|
-
});
|
|
446
|
-
const shortId = createHash("sha256").update(JSON.stringify(report.summary)).digest("hex").slice(0, 8);
|
|
447
|
-
console.log(`Freeflow index benchmark ${shortId}: index ${report.summary.index.passed}/${report.summary.fixtures} pass`);
|
|
448
|
-
console.log(`Markdown report: ${reports.markdown}`);
|
|
449
|
-
if (reports.json) {
|
|
450
|
-
console.log(`JSON run data: ${reports.json}`);
|
|
451
|
-
}
|
|
452
|
-
if (report.summary.index.failed > 0) {
|
|
453
|
-
process.exitCode = 1;
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
if (process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
|
|
457
|
-
await runCli();
|
|
458
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export * from "./benchmarks.js";
|
|
2
|
-
export * from "./command-benchmarks.js";
|
|
3
|
-
export * from "./codex-qa-benchmarks.js";
|
|
4
|
-
export * from "./experimental-local-index.js";
|
|
5
|
-
export * from "./index-benchmarks.js";
|
|
6
|
-
export * from "./config.js";
|
|
7
|
-
export * from "./retrieve.js";
|
|
8
|
-
export * from "./run.js";
|
|
9
|
-
export * from "./router-contract.js";
|
|
10
|
-
export * from "./schema.js";
|
|
11
|
-
export * from "./types.js";
|
|
12
|
-
export * from "./vault.js";
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export * from "./benchmarks.js";
|
|
2
|
-
export * from "./command-benchmarks.js";
|
|
3
|
-
export * from "./codex-qa-benchmarks.js";
|
|
4
|
-
export * from "./experimental-local-index.js";
|
|
5
|
-
export * from "./index-benchmarks.js";
|
|
6
|
-
export * from "./config.js";
|
|
7
|
-
export * from "./retrieve.js";
|
|
8
|
-
export * from "./run.js";
|
|
9
|
-
export * from "./router-contract.js";
|
|
10
|
-
export * from "./schema.js";
|
|
11
|
-
export * from "./types.js";
|
|
12
|
-
export * from "./vault.js";
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export interface ExactLineRangeInput {
|
|
2
|
-
start: number;
|
|
3
|
-
end: number;
|
|
4
|
-
}
|
|
5
|
-
export interface ExactLineRange {
|
|
6
|
-
start: number;
|
|
7
|
-
end: number;
|
|
8
|
-
}
|
|
9
|
-
export interface ResolveExactLineRangeOptions {
|
|
10
|
-
requested: ExactLineRangeInput;
|
|
11
|
-
lineCount: number;
|
|
12
|
-
availableLabel: string;
|
|
13
|
-
invalidReason: string;
|
|
14
|
-
}
|
|
15
|
-
export type ResolveExactLineRangeResult = {
|
|
16
|
-
ok: true;
|
|
17
|
-
range: ExactLineRange;
|
|
18
|
-
} | {
|
|
19
|
-
ok: false;
|
|
20
|
-
reason: string;
|
|
21
|
-
};
|
|
22
|
-
export declare function resolveExactLineRange(options: ResolveExactLineRangeOptions): ResolveExactLineRangeResult;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export function resolveExactLineRange(options) {
|
|
2
|
-
const { requested, lineCount, availableLabel, invalidReason } = options;
|
|
3
|
-
if (!isValidExactLineRange(requested)) {
|
|
4
|
-
return { ok: false, reason: invalidReason };
|
|
5
|
-
}
|
|
6
|
-
if (requested.start > lineCount) {
|
|
7
|
-
return {
|
|
8
|
-
ok: false,
|
|
9
|
-
reason: `Requested lineRange start ${requested.start} is outside ${availableLabel} 1-${lineCount}.`,
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
if (requested.end > lineCount) {
|
|
13
|
-
return {
|
|
14
|
-
ok: false,
|
|
15
|
-
reason: `Requested lineRange end ${requested.end} is outside ${availableLabel} 1-${lineCount}.`,
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
return { ok: true, range: { start: requested.start, end: requested.end } };
|
|
19
|
-
}
|
|
20
|
-
function isValidExactLineRange(range) {
|
|
21
|
-
return Number.isInteger(range.start) && Number.isInteger(range.end) && range.start >= 1 && range.end >= range.start;
|
|
22
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { CommandParserMetadata, ExecutionStatus, ImportantLine } from "./types.js";
|
|
2
|
-
export interface CommandParseInput {
|
|
3
|
-
command: string | readonly string[];
|
|
4
|
-
executionStatus: ExecutionStatus;
|
|
5
|
-
exitCode: number | null;
|
|
6
|
-
stdout: string;
|
|
7
|
-
stderr: string;
|
|
8
|
-
combined: string;
|
|
9
|
-
goal?: string;
|
|
10
|
-
}
|
|
11
|
-
export interface ParsedCommandOutput {
|
|
12
|
-
parser: CommandParserMetadata;
|
|
13
|
-
importantLines: ImportantLine[];
|
|
14
|
-
summary?: string;
|
|
15
|
-
}
|
|
16
|
-
export declare function parseCommandOutput(input: CommandParseInput): ParsedCommandOutput;
|