@hassangameryt/freeflow 0.2.0 → 0.3.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 +2 -2
- package/{plugins/freeflow/.claude-plugin → .claude-plugin}/plugin.json +1 -1
- package/{plugins/freeflow/.codex-plugin → .codex-plugin}/plugin.json +1 -1
- package/README.md +19 -14
- package/assets/freeflow-plugin-icon.png +0 -0
- package/{plugins/freeflow/command-surface.json → command-surface.json} +10 -2
- package/evals/README.md +32 -0
- package/evals/fixtures/copy-conventions.md +31 -0
- package/evals/fixtures/output-router/README.md +12 -0
- package/evals/fixtures/output-router/failed-command-output.txt +9 -0
- package/evals/fixtures/output-router/large-router-manual.md +63 -0
- package/evals/fixtures/output-router/native-large-output.txt +40 -0
- package/evals/fixtures/output-router/noisy-test-output.txt +30 -0
- package/evals/fixtures/output-router/verification-output.txt +8 -0
- package/evals/fixtures/tiny-artifact-review-app/README.md +5 -0
- package/evals/fixtures/tiny-artifact-review-app/docs/billing-policy.md +10 -0
- package/evals/fixtures/tiny-artifact-review-app/docs/specs/billing-webhook-api-draft.md +21 -0
- package/evals/fixtures/tiny-artifact-review-app/docs/specs/failed-payment-grace-period.md +24 -0
- package/evals/fixtures/tiny-artifact-review-app/docs/specs/immediate-downgrade.md +17 -0
- package/evals/fixtures/tiny-artifact-review-app/tests/billing.test.md +8 -0
- package/evals/fixtures/tiny-commit-ambiguous-app/.freeflow-eval-setup.sh +15 -0
- package/evals/fixtures/tiny-commit-ambiguous-app/README.md +3 -0
- package/evals/fixtures/tiny-commit-ambiguous-app/src/billing.ts +5 -0
- package/evals/fixtures/tiny-commit-ambiguous-app/src/settings-page.ts +1 -0
- package/evals/fixtures/tiny-commit-ambiguous-app/tests/settings.test.md +5 -0
- package/evals/fixtures/tiny-commit-app/.freeflow-eval-setup.sh +14 -0
- package/evals/fixtures/tiny-commit-app/README.md +3 -0
- package/evals/fixtures/tiny-commit-app/docs/specs/settings-title.md +5 -0
- package/evals/fixtures/tiny-commit-app/src/billing.ts +5 -0
- package/evals/fixtures/tiny-commit-app/src/settings-page.ts +1 -0
- package/evals/fixtures/tiny-commit-app/tests/settings.test.md +5 -0
- package/evals/fixtures/tiny-commit-everything-app/.freeflow-eval-setup.sh +15 -0
- package/evals/fixtures/tiny-commit-everything-app/README.md +3 -0
- package/evals/fixtures/tiny-commit-everything-app/docs/specs/settings-title.md +5 -0
- package/evals/fixtures/tiny-commit-everything-app/src/billing.ts +5 -0
- package/evals/fixtures/tiny-commit-everything-app/src/settings-page.ts +1 -0
- package/evals/fixtures/tiny-commit-everything-app/tests/settings.test.md +5 -0
- package/evals/fixtures/tiny-commit-staged-app/.freeflow-eval-setup.sh +15 -0
- package/evals/fixtures/tiny-commit-staged-app/README.md +3 -0
- package/evals/fixtures/tiny-commit-staged-app/docs/specs/settings-title.md +5 -0
- package/evals/fixtures/tiny-commit-staged-app/src/billing.ts +5 -0
- package/evals/fixtures/tiny-commit-staged-app/src/settings-page.ts +1 -0
- package/evals/fixtures/tiny-commit-staged-app/tests/settings.test.md +5 -0
- package/evals/fixtures/tiny-commit-staged-mixed-app/.freeflow-eval-setup.sh +15 -0
- package/evals/fixtures/tiny-commit-staged-mixed-app/README.md +3 -0
- package/evals/fixtures/tiny-commit-staged-mixed-app/docs/billing-policy.md +3 -0
- package/evals/fixtures/tiny-commit-staged-mixed-app/docs/release-notes.md +3 -0
- package/evals/fixtures/tiny-commit-staged-mixed-app/src/billing.ts +5 -0
- package/evals/fixtures/tiny-dashboard-stale-app/README.md +11 -0
- package/evals/fixtures/tiny-dashboard-stale-app/src/api-client.ts +13 -0
- package/evals/fixtures/tiny-dashboard-stale-app/src/dashboard-data.ts +19 -0
- package/evals/fixtures/tiny-dashboard-stale-app/tests/dashboard-data.test.md +9 -0
- package/evals/fixtures/tiny-decision-destination-app/README.md +6 -0
- package/evals/fixtures/tiny-decision-destination-app/src/risk.ts +8 -0
- package/evals/fixtures/tiny-decision-destination-app/tests/risk.test.md +4 -0
- package/evals/fixtures/tiny-design-depth-app/README.md +15 -0
- package/evals/fixtures/tiny-design-depth-app/src/routes.ts +25 -0
- package/evals/fixtures/tiny-design-depth-app/src/sendEmail.ts +3 -0
- package/evals/fixtures/tiny-design-depth-app/src/sendSms.ts +3 -0
- package/evals/fixtures/tiny-design-depth-app/src/telemetry.ts +3 -0
- package/evals/fixtures/tiny-design-depth-app/tests/routes.test.md +12 -0
- package/evals/fixtures/tiny-eval-method-app/README.md +8 -0
- package/evals/fixtures/tiny-eval-method-app/evals/reports/review-pr-eval-result.md +5 -0
- package/evals/fixtures/tiny-eval-method-app/evals/reports/triage-question-failure.md +17 -0
- package/evals/fixtures/tiny-eval-method-app/evals/runs/review-pr-with-skill-output.diff +11 -0
- package/evals/fixtures/tiny-eval-method-app/evals/runs/review-pr-with-skill-output.md +3 -0
- package/evals/fixtures/tiny-eval-method-app/skills/review-pr/SKILL.md +10 -0
- package/evals/fixtures/tiny-eval-method-app/skills/triage-question/SKILL.md +10 -0
- package/evals/fixtures/tiny-execute-plan-app/README.md +5 -0
- package/evals/fixtures/tiny-execute-plan-app/checks/settings-and-billing-check.sh +5 -0
- package/evals/fixtures/tiny-execute-plan-app/docs/billing-policy.md +10 -0
- package/evals/fixtures/tiny-execute-plan-app/docs/plans/immediate-downgrade-plan.md +11 -0
- package/evals/fixtures/tiny-execute-plan-app/docs/plans/settings-title-plan.md +12 -0
- package/evals/fixtures/tiny-execute-plan-app/docs/plans/settings-title-with-bad-check.md +15 -0
- package/evals/fixtures/tiny-execute-plan-app/docs/plans/unverified-billing-plan.md +9 -0
- package/evals/fixtures/tiny-execute-plan-app/docs/specs/failed-payment-grace-period.md +9 -0
- package/evals/fixtures/tiny-execute-plan-app/docs/specs/settings-title.md +9 -0
- package/evals/fixtures/tiny-execute-plan-app/src/billing.ts +7 -0
- package/evals/fixtures/tiny-execute-plan-app/src/settings-page.ts +1 -0
- package/evals/fixtures/tiny-execute-plan-app/tests/billing.test.md +7 -0
- package/evals/fixtures/tiny-execute-plan-app/tests/settings.test.md +5 -0
- package/evals/fixtures/tiny-execute-review-loop-app/README.md +5 -0
- package/evals/fixtures/tiny-execute-review-loop-app/docs/billing-policy.md +9 -0
- package/evals/fixtures/tiny-execute-review-loop-app/docs/plans/settings-title-plan.md +12 -0
- package/evals/fixtures/tiny-execute-review-loop-app/docs/review/previous-agent-summary.md +15 -0
- package/evals/fixtures/tiny-execute-review-loop-app/docs/review/review-pass-1-non-pass.md +11 -0
- package/evals/fixtures/tiny-execute-review-loop-app/docs/specs/settings-title.md +9 -0
- package/evals/fixtures/tiny-execute-review-loop-app/src/billing.ts +7 -0
- package/evals/fixtures/tiny-execute-review-loop-app/src/settings-page.ts +1 -0
- package/evals/fixtures/tiny-execute-review-loop-app/tests/billing.test.md +7 -0
- package/evals/fixtures/tiny-execute-review-loop-app/tests/settings.test.md +5 -0
- package/evals/fixtures/tiny-flaky-session-app/README.md +10 -0
- package/evals/fixtures/tiny-flaky-session-app/src/session-timeout.ts +13 -0
- package/evals/fixtures/tiny-flaky-session-app/tests/session-timeout.test.md +8 -0
- package/evals/fixtures/tiny-handoff-app/README.md +5 -0
- package/evals/fixtures/tiny-handoff-app/docs/billing-policy.md +10 -0
- package/evals/fixtures/tiny-handoff-app/docs/handoffs/old-agent-handoff.md +8 -0
- package/evals/fixtures/tiny-handoff-app/docs/plans/billing-retry-plan.md +11 -0
- package/evals/fixtures/tiny-handoff-app/src/billing.ts +7 -0
- package/evals/fixtures/tiny-handoff-report-app/README.md +3 -0
- package/evals/fixtures/tiny-handoff-report-app/evals/runs/handoff-3/hof-003/with-skill-output.diff +1 -0
- package/evals/fixtures/tiny-handoff-report-app/evals/runs/handoff-3/hof-003/with-skill-output.md +1 -0
- package/evals/fixtures/tiny-handoff-report-app/evals/scores/hof-003-score.txt +4 -0
- package/evals/fixtures/tiny-plan-app/README.md +5 -0
- package/evals/fixtures/tiny-plan-app/docs/billing-policy.md +10 -0
- package/evals/fixtures/tiny-plan-app/docs/specs/failed-payment-grace-period.md +25 -0
- package/evals/fixtures/tiny-plan-app/src/billing.ts +17 -0
- package/evals/fixtures/tiny-plan-app/src/settings-page.ts +1 -0
- package/evals/fixtures/tiny-plan-app/tests/billing.test.md +8 -0
- package/evals/fixtures/tiny-plan-app/tests/settings.test.md +5 -0
- package/evals/fixtures/tiny-plan-strict-api-app/README.md +3 -0
- package/evals/fixtures/tiny-plan-strict-api-app/docs/billing-policy.md +5 -0
- package/evals/fixtures/tiny-plan-strict-api-app/docs/specs/billing-webhook-api.md +25 -0
- package/evals/fixtures/tiny-plan-strict-api-app/src/billing.ts +5 -0
- package/evals/fixtures/tiny-plan-strict-api-app/src/webhooks.ts +3 -0
- package/evals/fixtures/tiny-plan-strict-api-app/tests/billing-webhook.test.md +8 -0
- package/evals/fixtures/tiny-post-setup-invalid-config-app/.freeflow/config.json +3 -0
- package/evals/fixtures/tiny-post-setup-invalid-config-app/AGENTS.md +15 -0
- package/evals/fixtures/tiny-post-setup-invalid-config-app/README.md +16 -0
- package/evals/fixtures/tiny-post-setup-invalid-config-app/docs/auth-review.md +15 -0
- package/evals/fixtures/tiny-post-setup-invalid-config-app/docs/billing-policy.md +10 -0
- package/evals/fixtures/tiny-post-setup-invalid-config-app/docs/copy-conventions.md +15 -0
- package/evals/fixtures/tiny-post-setup-invalid-config-app/src/auth-middleware.ts +12 -0
- package/evals/fixtures/tiny-post-setup-invalid-config-app/src/billing.ts +20 -0
- package/evals/fixtures/tiny-post-setup-invalid-config-app/src/login-copy.ts +1 -0
- package/evals/fixtures/tiny-post-setup-invalid-config-app/src/settings-page.ts +1 -0
- package/evals/fixtures/tiny-post-setup-invalid-config-app/tests/auth-middleware.test.md +8 -0
- package/evals/fixtures/tiny-post-setup-invalid-config-app/tests/billing.test.md +8 -0
- package/evals/fixtures/tiny-post-setup-invalid-config-app/tests/copy.test.md +7 -0
- package/evals/fixtures/tiny-post-setup-missing-config-app/AGENTS.md +15 -0
- package/evals/fixtures/tiny-post-setup-missing-config-app/README.md +16 -0
- package/evals/fixtures/tiny-post-setup-missing-config-app/docs/auth-review.md +15 -0
- package/evals/fixtures/tiny-post-setup-missing-config-app/docs/billing-policy.md +10 -0
- package/evals/fixtures/tiny-post-setup-missing-config-app/docs/copy-conventions.md +15 -0
- package/evals/fixtures/tiny-post-setup-missing-config-app/src/auth-middleware.ts +12 -0
- package/evals/fixtures/tiny-post-setup-missing-config-app/src/billing.ts +20 -0
- package/evals/fixtures/tiny-post-setup-missing-config-app/src/login-copy.ts +1 -0
- package/evals/fixtures/tiny-post-setup-missing-config-app/src/settings-page.ts +1 -0
- package/evals/fixtures/tiny-post-setup-missing-config-app/tests/auth-middleware.test.md +8 -0
- package/evals/fixtures/tiny-post-setup-missing-config-app/tests/billing.test.md +8 -0
- package/evals/fixtures/tiny-post-setup-missing-config-app/tests/copy.test.md +7 -0
- package/evals/fixtures/tiny-post-setup-source-conflict-app/.freeflow/config.json +3 -0
- package/evals/fixtures/tiny-post-setup-source-conflict-app/AGENTS.md +15 -0
- package/evals/fixtures/tiny-post-setup-source-conflict-app/README.md +16 -0
- package/evals/fixtures/tiny-post-setup-source-conflict-app/docs/auth-review.md +15 -0
- package/evals/fixtures/tiny-post-setup-source-conflict-app/docs/billing-policy.md +10 -0
- package/evals/fixtures/tiny-post-setup-source-conflict-app/docs/copy-conventions.md +15 -0
- package/evals/fixtures/tiny-post-setup-source-conflict-app/src/auth-middleware.ts +12 -0
- package/evals/fixtures/tiny-post-setup-source-conflict-app/src/billing.ts +20 -0
- package/evals/fixtures/tiny-post-setup-source-conflict-app/src/login-copy.ts +1 -0
- package/evals/fixtures/tiny-post-setup-source-conflict-app/src/settings-page.ts +1 -0
- package/evals/fixtures/tiny-post-setup-source-conflict-app/tests/auth-middleware.test.md +8 -0
- package/evals/fixtures/tiny-post-setup-source-conflict-app/tests/billing.test.md +8 -0
- package/evals/fixtures/tiny-post-setup-source-conflict-app/tests/copy.test.md +7 -0
- package/evals/fixtures/tiny-report-performance-app/README.md +11 -0
- package/evals/fixtures/tiny-report-performance-app/docs/performance.md +10 -0
- package/evals/fixtures/tiny-report-performance-app/src/report-summary.ts +29 -0
- package/evals/fixtures/tiny-report-performance-app/tests/report-performance.test.md +8 -0
- package/evals/fixtures/tiny-review-request-app/README.md +3 -0
- package/evals/fixtures/tiny-review-request-app/docs/billing-policy.md +5 -0
- package/evals/fixtures/tiny-review-request-app/docs/plans/billing-webhook-api.md +19 -0
- package/evals/fixtures/tiny-review-request-app/docs/review/previous-agent-summary.md +20 -0
- package/evals/fixtures/tiny-review-request-app/docs/specs/billing-webhook-api.md +25 -0
- package/evals/fixtures/tiny-review-request-app/src/billing.ts +11 -0
- package/evals/fixtures/tiny-review-request-app/src/webhooks.ts +19 -0
- package/evals/fixtures/tiny-review-request-app/tests/billing-webhook.test.md +8 -0
- package/evals/fixtures/tiny-review-work-app/README.md +5 -0
- package/evals/fixtures/tiny-review-work-app/docs/billing-policy.md +9 -0
- package/evals/fixtures/tiny-review-work-app/docs/plans/settings-title-plan.md +12 -0
- package/evals/fixtures/tiny-review-work-app/docs/review/previous-agent-summary.md +15 -0
- package/evals/fixtures/tiny-review-work-app/docs/specs/settings-title.md +9 -0
- package/evals/fixtures/tiny-review-work-app/src/billing.ts +7 -0
- package/evals/fixtures/tiny-review-work-app/src/settings-page.ts +1 -0
- package/evals/fixtures/tiny-review-work-app/tests/billing.test.md +7 -0
- package/evals/fixtures/tiny-review-work-app/tests/settings.test.md +5 -0
- package/evals/fixtures/tiny-saas-app/README.md +16 -0
- package/evals/fixtures/tiny-saas-app/docs/auth-review.md +15 -0
- package/evals/fixtures/tiny-saas-app/docs/billing-policy.md +10 -0
- package/evals/fixtures/tiny-saas-app/docs/copy-conventions.md +15 -0
- package/evals/fixtures/tiny-saas-app/docs/specs/settings-title.md +13 -0
- package/evals/fixtures/tiny-saas-app/src/auth-middleware.ts +12 -0
- package/evals/fixtures/tiny-saas-app/src/billing.ts +20 -0
- package/evals/fixtures/tiny-saas-app/src/login-copy.ts +1 -0
- package/evals/fixtures/tiny-saas-app/src/settings-page.ts +1 -0
- package/evals/fixtures/tiny-saas-app/tests/auth-middleware.test.md +8 -0
- package/evals/fixtures/tiny-saas-app/tests/billing.test.md +8 -0
- package/evals/fixtures/tiny-saas-app/tests/copy.test.md +7 -0
- package/evals/fixtures/tiny-setup-agents-app/AGENTS.md +6 -0
- package/evals/fixtures/tiny-setup-both-app/AGENTS.md +5 -0
- package/evals/fixtures/tiny-setup-both-app/CLAUDE.md +5 -0
- package/evals/fixtures/tiny-setup-claude-app/CLAUDE.md +6 -0
- package/evals/fixtures/tiny-setup-codex-rules-app/.codex/rules/shell.rules +5 -0
- package/evals/fixtures/tiny-setup-codex-rules-app/AGENTS.md +6 -0
- package/evals/fixtures/tiny-setup-conflict-app/AGENTS.md +6 -0
- package/evals/fixtures/tiny-setup-existing-block-app/AGENTS.md +14 -0
- package/evals/fixtures/tiny-setup-four-rules-app/CLAUDE.md +6 -0
- package/evals/fixtures/tiny-skill-dev-app/README.md +10 -0
- package/evals/fixtures/tiny-skill-dev-app/evals/prompts/review-pr-001.txt +8 -0
- package/evals/fixtures/tiny-skill-dev-app/evals/reports/review-pr-failure.md +17 -0
- package/evals/fixtures/tiny-skill-dev-app/skills/review-pr/SKILL.md +13 -0
- package/evals/fixtures/tiny-team-app/README.md +5 -0
- package/evals/fixtures/tiny-team-app/docs/product.md +6 -0
- package/evals/fixtures/tiny-team-app/src/teams.ts +9 -0
- package/evals/fixtures/tiny-team-app/src/users.ts +5 -0
- package/evals/fixtures/tiny-team-app/tests/teams.test.md +7 -0
- package/evals/fixtures/tiny-verify-app/README.md +5 -0
- package/evals/fixtures/tiny-verify-app/src/settings-nav.ts +1 -0
- package/evals/fixtures/tiny-verify-app/src/settings-page.ts +1 -0
- package/evals/fixtures/tiny-verify-app/tests/settings.test.md +7 -0
- package/evals/prompts/aon-001.txt +2 -0
- package/evals/prompts/byp-001.txt +2 -0
- package/evals/prompts/byp-002.txt +2 -0
- package/evals/prompts/cap-001.txt +3 -0
- package/evals/prompts/cap-002.txt +3 -0
- package/evals/prompts/cmd-001.txt +3 -0
- package/evals/prompts/cmd-002.txt +3 -0
- package/evals/prompts/cmd-003.txt +6 -0
- package/evals/prompts/cmd-004.txt +5 -0
- package/evals/prompts/cmd-005.txt +5 -0
- package/evals/prompts/cmd-006.txt +5 -0
- package/evals/prompts/cmd-007.txt +5 -0
- package/evals/prompts/cmd-008.txt +5 -0
- package/evals/prompts/cmd-009.txt +8 -0
- package/evals/prompts/cmd-010.txt +5 -0
- package/evals/prompts/cmd-011.txt +5 -0
- package/evals/prompts/cmd-012.txt +5 -0
- package/evals/prompts/cmd-013.txt +5 -0
- package/evals/prompts/cmd-014.txt +7 -0
- package/evals/prompts/cmd-015.txt +7 -0
- package/evals/prompts/cmd-016.txt +5 -0
- package/evals/prompts/cmt-001.txt +1 -0
- package/evals/prompts/cmt-002.txt +1 -0
- package/evals/prompts/cmt-003.txt +1 -0
- package/evals/prompts/cmt-004.txt +1 -0
- package/evals/prompts/cmt-005.txt +1 -0
- package/evals/prompts/dfd-001.txt +3 -0
- package/evals/prompts/dia-001.txt +3 -0
- package/evals/prompts/dia-002.txt +3 -0
- package/evals/prompts/dia-003.txt +3 -0
- package/evals/prompts/dis-001.txt +5 -0
- package/evals/prompts/dis-002.txt +5 -0
- package/evals/prompts/esk-001.txt +5 -0
- package/evals/prompts/esk-002.txt +5 -0
- package/evals/prompts/esk-003.txt +5 -0
- package/evals/prompts/grc-001.txt +3 -0
- package/evals/prompts/hof-001.txt +3 -0
- package/evals/prompts/hof-002.txt +1 -0
- package/evals/prompts/hof-003.txt +1 -0
- package/evals/prompts/hof-004.txt +1 -0
- package/evals/prompts/hof-005.txt +1 -0
- package/evals/prompts/ivg-001.txt +1 -0
- package/evals/prompts/ivg-002.txt +11 -0
- package/evals/prompts/ivg-003.txt +1 -0
- package/evals/prompts/ivg-004.txt +1 -0
- package/evals/prompts/mode-001.txt +3 -0
- package/evals/prompts/mode-002.txt +1 -0
- package/evals/prompts/mode-003.txt +3 -0
- package/evals/prompts/mode-004.txt +3 -0
- package/evals/prompts/mode-005.txt +3 -0
- package/evals/prompts/mode-006.txt +3 -0
- package/evals/prompts/mode-007.txt +3 -0
- package/evals/prompts/otr-001.txt +3 -0
- package/evals/prompts/otr-002.txt +3 -0
- package/evals/prompts/rar-001.txt +5 -0
- package/evals/prompts/rar-002.txt +3 -0
- package/evals/prompts/rar-003.txt +6 -0
- package/evals/prompts/rar-004.txt +15 -0
- package/evals/prompts/rar-005.txt +10 -0
- package/evals/prompts/rbr-001.txt +3 -0
- package/evals/prompts/rbr-002.txt +3 -0
- package/evals/prompts/rbr-003.txt +7 -0
- package/evals/prompts/rev-001.txt +3 -0
- package/evals/prompts/rev-002.txt +5 -0
- package/evals/prompts/rev-003.txt +6 -0
- package/evals/prompts/rev-004.txt +1 -0
- package/evals/prompts/rev-005.txt +15 -0
- package/evals/prompts/rev-006.txt +5 -0
- package/evals/prompts/stp-001.txt +1 -0
- package/evals/prompts/stp-002.txt +1 -0
- package/evals/prompts/stp-003.txt +1 -0
- package/evals/prompts/stp-004.txt +1 -0
- package/evals/prompts/stp-005.txt +1 -0
- package/evals/prompts/stp-006.txt +1 -0
- package/evals/prompts/stp-007.txt +1 -0
- package/evals/prompts/stp-008.txt +1 -0
- package/evals/prompts/stp-009.txt +1 -0
- package/evals/prompts/stp-010.txt +1 -0
- package/evals/prompts/stp-011.txt +1 -0
- package/evals/prompts/vfy-003.txt +1 -0
- package/evals/prompts/wpl-001.txt +3 -0
- package/evals/prompts/wpl-002.txt +5 -0
- package/evals/prompts/wpl-003.txt +3 -0
- package/evals/prompts/wpl-004.txt +5 -0
- package/evals/prompts/wpl-005.txt +1 -0
- package/evals/prompts/wrc-001.txt +10 -0
- package/evals/prompts/wrc-002.txt +3 -0
- package/evals/prompts/wsk-001.txt +6 -0
- package/evals/prompts/wsp-001.txt +5 -0
- package/evals/prompts/wsp-002.txt +15 -0
- package/evals/prompts/wsp-003.txt +3 -0
- package/evals/prompts/wsp-004.txt +15 -0
- package/evals/prompts/wsp-005.txt +5 -0
- package/evals/prompts/wsp-006.txt +12 -0
- package/evals/prompts/wsp-007.txt +9 -0
- package/evals/prompts/wsp-008.txt +13 -0
- package/evals/prompts/xpl-001.txt +1 -0
- package/evals/prompts/xpl-002.txt +3 -0
- package/evals/prompts/xpl-003.txt +3 -0
- package/evals/prompts/xpl-004.txt +3 -0
- package/evals/prompts/xpl-005.txt +5 -0
- package/evals/prompts/xpl-006.txt +3 -0
- package/evals/registries/adversarial-evals.json +39 -0
- package/evals/registries/fixture-evals.json +2513 -0
- package/evals/registries/handoff-evals.json +74 -0
- package/evals/registries/legacy-evals.json +147 -0
- package/evals/registries/skill-evidence.json +193 -0
- package/evals/registries/verify-work-evals.json +46 -0
- package/evals/reports/acceptance/v0.1-acceptance-report.md +130 -0
- package/evals/reports/by-command-surface/command-surface-1-report.md +45 -0
- package/evals/reports/by-command-surface/command-surface-10-report.md +76 -0
- package/evals/reports/by-command-surface/command-surface-11-report.md +77 -0
- package/evals/reports/by-command-surface/command-surface-12-report.md +91 -0
- package/evals/reports/by-command-surface/command-surface-13-report.md +64 -0
- package/evals/reports/by-command-surface/command-surface-14-report.md +66 -0
- package/evals/reports/by-command-surface/command-surface-15-report.md +124 -0
- package/evals/reports/by-command-surface/command-surface-16-report.md +39 -0
- package/evals/reports/by-command-surface/command-surface-2-report.md +80 -0
- package/evals/reports/by-command-surface/command-surface-3-report.md +86 -0
- package/evals/reports/by-command-surface/command-surface-4-report.md +76 -0
- package/evals/reports/by-command-surface/command-surface-5-report.md +80 -0
- package/evals/reports/by-command-surface/command-surface-6-report.md +74 -0
- package/evals/reports/by-command-surface/command-surface-7-report.md +84 -0
- package/evals/reports/by-command-surface/command-surface-8-report.md +79 -0
- package/evals/reports/by-command-surface/command-surface-9-report.md +79 -0
- package/evals/reports/by-command-surface/command-surface-matrix.md +91 -0
- package/evals/reports/by-skill/bypass-1-report.md +124 -0
- package/evals/reports/by-skill/capture-decisions-1-report.md +99 -0
- package/evals/reports/by-skill/capture-decisions-2-report.md +102 -0
- package/evals/reports/by-skill/commit-work-1-report.md +165 -0
- package/evals/reports/by-skill/commit-work-2-report.md +109 -0
- package/evals/reports/by-skill/design-for-depth-1-report.md +95 -0
- package/evals/reports/by-skill/diagnose-failure-1-report.md +91 -0
- package/evals/reports/by-skill/diagnose-failure-2-report.md +94 -0
- package/evals/reports/by-skill/discover-1-report.md +118 -0
- package/evals/reports/by-skill/evaluate-skill-2-report.md +71 -0
- package/evals/reports/by-skill/execute-plan-1-report.md +103 -0
- package/evals/reports/by-skill/execute-plan-2-report.md +112 -0
- package/evals/reports/by-skill/execute-plan-3-report.md +87 -0
- package/evals/reports/by-skill/grill-context-1-report.md +103 -0
- package/evals/reports/by-skill/handoff-1-report.md +123 -0
- package/evals/reports/by-skill/handoff-2-report.md +105 -0
- package/evals/reports/by-skill/handoff-3-report.md +100 -0
- package/evals/reports/by-skill/handoff-7-report.md +77 -0
- package/evals/reports/by-skill/interview-gate-1-report.md +63 -0
- package/evals/reports/by-skill/interview-gate-2-report.md +105 -0
- package/evals/reports/by-skill/mode-contract-1-report.md +74 -0
- package/evals/reports/by-skill/mode-contract-2-report.md +87 -0
- package/evals/reports/by-skill/mode-contract-3-report.md +65 -0
- package/evals/reports/by-skill/mode-contract-4-report.md +71 -0
- package/evals/reports/by-skill/mode-contract-5-report.md +70 -0
- package/evals/reports/by-skill/output-router-1-report.md +76 -0
- package/evals/reports/by-skill/output-router-2-report.md +65 -0
- package/evals/reports/by-skill/research-1-report.md +144 -0
- package/evals/reports/by-skill/research-brief-1-report.md +94 -0
- package/evals/reports/by-skill/research-brief-2-report.md +75 -0
- package/evals/reports/by-skill/review-artifact-1-report.md +91 -0
- package/evals/reports/by-skill/review-artifact-2-report.md +79 -0
- package/evals/reports/by-skill/review-artifact-3-report.md +120 -0
- package/evals/reports/by-skill/review-artifact-4-report.md +89 -0
- package/evals/reports/by-skill/review-artifact-5-report.md +66 -0
- package/evals/reports/by-skill/review-work-1-report.md +85 -0
- package/evals/reports/by-skill/review-work-2-report.md +87 -0
- package/evals/reports/by-skill/review-work-3-report.md +104 -0
- package/evals/reports/by-skill/review-work-4-report.md +108 -0
- package/evals/reports/by-skill/review-work-5-report.md +73 -0
- package/evals/reports/by-skill/review-work-6-report.md +66 -0
- package/evals/reports/by-skill/setup-freeflow-1-report.md +199 -0
- package/evals/reports/by-skill/setup-freeflow-2-report.md +105 -0
- package/evals/reports/by-skill/setup-freeflow-3-report.md +105 -0
- package/evals/reports/by-skill/setup-freeflow-4-report.md +88 -0
- package/evals/reports/by-skill/setup-freeflow-5-report.md +115 -0
- package/evals/reports/by-skill/skill-authoring-1-report.md +81 -0
- package/evals/reports/by-skill/verify-work-1-report.md +111 -0
- package/evals/reports/by-skill/verify-work-2-report.md +120 -0
- package/evals/reports/by-skill/workflow-1-report.md +65 -0
- package/evals/reports/by-skill/write-plan-1-report.md +123 -0
- package/evals/reports/by-skill/write-plan-2-report.md +98 -0
- package/evals/reports/by-skill/write-plan-3-report.md +110 -0
- package/evals/reports/by-skill/write-spec-1-report.md +88 -0
- package/evals/reports/by-skill/write-spec-2-report.md +89 -0
- package/evals/reports/by-skill/write-spec-3-report.md +90 -0
- package/evals/reports/by-skill/write-spec-4-report.md +167 -0
- package/evals/reports/harness/claude-harness-1-report.md +103 -0
- package/evals/reports/harness/eval-harness-1-report.md +91 -0
- package/evals/reports/iterations/iteration-1-report.md +71 -0
- package/evals/reports/iterations/iteration-2-report.md +78 -0
- package/evals/reports/iterations/iteration-3-report.md +118 -0
- package/evals/reports/iterations/iteration-4-report.md +131 -0
- package/evals/reports/iterations/iteration-5-report.md +149 -0
- package/evals/reports/iterations/iteration-6-report.md +136 -0
- package/evals/reports/runtime/always-on-runtime-1-report.md +107 -0
- package/evals/reports/runtime/context-mode-normalized-benchmark-1-report.md +52 -0
- package/evals/reports/runtime/context-mode-real-deep-baseline-1-report.md +410 -0
- package/evals/reports/runtime/context-mode-real-deep-final-slice-11-report.md +203 -0
- package/evals/reports/runtime/context-mode-real-deep-final-slice-11-review.md +51 -0
- package/evals/reports/runtime/context-saving-native-tools-baseline-1-report.md +99 -0
- package/evals/reports/runtime/eryx-python-compatibility-reprobe-1-report.md +166 -0
- package/evals/reports/runtime/eryx-python-proof-spike-1-report.md +96 -0
- package/evals/reports/runtime/eryx-python-proof-spike-2-report.md +151 -0
- package/evals/reports/runtime/eryx-python-script-derive-execution-1-report.md +233 -0
- package/evals/reports/runtime/jq-script-derive-execution-1-report.md +215 -0
- package/evals/reports/runtime/jq-wasm-proof-spike-1-report.md +67 -0
- package/evals/reports/runtime/output-router-benchmark-1-report.md +81 -0
- package/evals/reports/runtime/output-router-capture-derive-provider-eval-1-report.md +35 -0
- package/evals/reports/runtime/output-router-codex-large-index-sqlite-adhoc-report.md +150 -0
- package/evals/reports/runtime/output-router-codex-qa-benchmark-1-report.md +46 -0
- package/evals/reports/runtime/output-router-command-benchmark-1-report.md +62 -0
- package/evals/reports/runtime/output-router-index-benchmark-1-report.md +64 -0
- package/evals/reports/runtime/output-router-regression-1-report.md +81 -0
- package/evals/reports/runtime/output-router-transform-eval-1-report.md +28 -0
- package/evals/reports/runtime/pi-observed-routing-eval-1-report.md +44 -0
- package/evals/reports/runtime/quickjs-script-derive-execution-1-report.md +159 -0
- package/evals/reports/runtime/quickjs-wasi-proof-spike-1-report.md +55 -0
- package/evals/reports/runtime/render-format-row-protocol-1-report.md +58 -0
- package/evals/reports/runtime/script-sandbox-adapter-selection-review-1-report.md +84 -0
- package/evals/reports/runtime/script-sandbox-probe-resource-hardening-1-report.md +51 -0
- package/evals/reports/runtime/storage-policy-benchmark-1-report.md +176 -0
- package/evals/reports/runtime/vault-index-storage-spike-1-report.md +39 -0
- package/evals/reports/runtime/workflow-context-hook-1-report.md +82 -0
- package/evals/runbooks/adversarial-eval-runbook.md +28 -0
- package/evals/runbooks/fixture-eval-runbook.md +137 -0
- package/evals/runbooks/handoff-eval-runbook.md +22 -0
- package/evals/runbooks/verify-work-eval-runbook.md +27 -0
- package/evals/scripts/audit-command-surface.sh +160 -0
- package/evals/scripts/check-activation-contract.sh +121 -0
- package/evals/scripts/check-runtime-context-hook.sh +183 -0
- package/evals/scripts/grade-fixture-eval.sh +446 -0
- package/evals/scripts/run-claude-fixture-eval.sh +26 -0
- package/evals/scripts/run-codex-fixture-eval.sh +26 -0
- package/evals/scripts/run-eryx-python-proof-spike.js +559 -0
- package/evals/scripts/run-fixture-eval-by-id.sh +23 -0
- package/evals/scripts/run-fixture-eval.sh +464 -0
- package/evals/scripts/run-jq-wasm-proof-spike.js +299 -0
- package/evals/scripts/run-output-router-transform-eval.js +115 -0
- package/evals/scripts/run-pi-observed-routing-eval.js +478 -0
- package/evals/scripts/run-quickjs-wasi-proof-spike.js +339 -0
- package/evals/scripts/skill-evidence.sh +316 -0
- package/evals/scripts/validate-release-metadata.sh +486 -0
- package/evals/suites/v0.1-acceptance-suite.md +131 -0
- package/{plugins/freeflow/hooks → hooks}/freeflow-runtime-context.mjs +46 -12
- package/package.json +39 -19
- package/pi-extension/dist/host-producer-identification.js +186 -0
- package/pi-extension/dist/index.js +85 -0
- package/pi-extension/dist/mcp-config.js +30 -0
- package/pi-extension/dist/native-safety-net.js +209 -0
- package/pi-extension/dist/observed-tool-routing.js +114 -0
- package/pi-extension/dist/renderers.js +835 -0
- package/pi-extension/dist/router-tools.js +438 -0
- package/pi-extension/dist/runtime-context.js +288 -0
- package/pi-extension/dist/schemas.js +254 -0
- package/pi-extension/dist/status.js +449 -0
- package/pi-extension/dist/utils.js +467 -0
- package/pi-extension/src/host-producer-identification.ts +226 -0
- package/pi-extension/src/index.ts +121 -0
- package/pi-extension/src/mcp-config.ts +32 -0
- package/pi-extension/src/native-safety-net.ts +252 -0
- package/pi-extension/src/observed-tool-routing.ts +126 -0
- package/pi-extension/src/renderers.ts +917 -0
- package/pi-extension/src/router-tools.ts +478 -0
- package/pi-extension/src/runtime-context.ts +347 -0
- package/pi-extension/src/schemas.ts +259 -0
- package/pi-extension/src/status.ts +505 -0
- package/pi-extension/src/utils.ts +492 -0
- package/pi-extension/tsconfig.json +16 -0
- package/{plugins/freeflow/docs → plugin-docs}/README.md +3 -3
- package/plugin-docs/adr/0002-evals-before-hooks.md +17 -0
- package/{plugins/freeflow/docs → plugin-docs}/adr/0003-release-boundary.md +2 -2
- package/plugin-docs/adr/0004-discover-replaces-shallow-discovery-skills.md +26 -0
- package/plugin-docs/adr/README.md +10 -0
- package/plugin-docs/architecture.md +89 -0
- package/plugin-docs/output-router.md +396 -0
- package/plugin-docs/release-evidence.md +77 -0
- package/{plugins/freeflow/docs → plugin-docs}/skills.md +3 -2
- package/{plugins/freeflow/docs → plugin-docs}/workflow.md +4 -4
- package/{plugins/freeflow/router/dist → router/dist/benchmarks}/benchmark-harness.js +1 -1
- package/{plugins/freeflow/router/dist → router/dist/benchmarks}/benchmarks.js +14 -14
- package/{plugins/freeflow/router/dist → router/dist/benchmarks}/codex-qa-benchmarks.js +6 -6
- package/{plugins/freeflow/router/dist → router/dist/benchmarks}/command-benchmarks.d.ts +1 -1
- package/{plugins/freeflow/router/dist → router/dist/benchmarks}/command-benchmarks.js +11 -10
- package/router/dist/benchmarks/context-mode-normalized-benchmarks.d.ts +74 -0
- package/router/dist/benchmarks/context-mode-normalized-benchmarks.js +707 -0
- package/router/dist/benchmarks/context-mode-real-deep-benchmark.d.ts +124 -0
- package/router/dist/benchmarks/context-mode-real-deep-benchmark.js +1295 -0
- package/router/dist/benchmarks/context-saving-baseline.d.ts +54 -0
- package/router/dist/benchmarks/context-saving-baseline.js +439 -0
- package/{plugins/freeflow/router/dist → router/dist/benchmarks}/index-benchmarks.d.ts +16 -2
- package/{plugins/freeflow/router/dist → router/dist/benchmarks}/index-benchmarks.js +330 -26
- package/router/dist/benchmarks/storage-policy-benchmarks.d.ts +90 -0
- package/router/dist/benchmarks/storage-policy-benchmarks.js +538 -0
- package/router/dist/benchmarks/vault-index-benchmarks.d.ts +47 -0
- package/router/dist/benchmarks/vault-index-benchmarks.js +257 -0
- package/router/dist/config/config.d.ts +96 -0
- package/router/dist/config/config.js +453 -0
- package/{plugins/freeflow/router/dist → router/dist/config}/schema.js +248 -2
- package/router/dist/config/types.d.ts +521 -0
- package/router/dist/config/types.js +30 -0
- package/{plugins/freeflow/router/dist → router/dist/evidence}/bounded-evidence.d.ts +1 -1
- package/{plugins/freeflow/router/dist → router/dist/evidence}/evidence-range-selector.js +65 -14
- package/{plugins/freeflow/router/dist → router/dist/evidence}/evidence-search.js +18 -2
- package/{plugins/freeflow/router/dist → router/dist/evidence}/evidence.d.ts +1 -1
- package/router/dist/evidence/failure-contracts.d.ts +27 -0
- package/router/dist/evidence/failure-contracts.js +160 -0
- package/router/dist/index.d.ts +30 -0
- package/router/dist/index.js +32 -0
- package/router/dist/processing/engine.d.ts +108 -0
- package/router/dist/processing/engine.js +435 -0
- package/router/dist/processing/reducers.d.ts +266 -0
- package/router/dist/processing/reducers.js +1495 -0
- package/router/dist/processing/renderers.d.ts +25 -0
- package/router/dist/processing/renderers.js +186 -0
- package/router/dist/processing/scripts.d.ts +78 -0
- package/router/dist/processing/scripts.js +333 -0
- package/router/dist/routing/observed-reducers.d.ts +35 -0
- package/router/dist/routing/observed-reducers.js +647 -0
- package/router/dist/routing/observed-routing.d.ts +17 -0
- package/router/dist/routing/observed-routing.js +377 -0
- package/{plugins/freeflow/router/dist → router/dist/routing}/parsers.d.ts +1 -1
- package/{plugins/freeflow/router/dist → router/dist/routing}/parsers.js +1 -1
- package/router/dist/routing/run-filters.d.ts +56 -0
- package/router/dist/routing/run-filters.js +230 -0
- package/router/dist/routing/run-reducers.d.ts +30 -0
- package/router/dist/routing/run-reducers.js +110 -0
- package/router/dist/sandbox/adapter-roots.d.ts +38 -0
- package/router/dist/sandbox/adapter-roots.js +64 -0
- package/router/dist/sandbox/eryx-python-adapter.d.ts +9 -0
- package/router/dist/sandbox/eryx-python-adapter.js +797 -0
- package/router/dist/sandbox/jq-wasm-adapter.d.ts +9 -0
- package/router/dist/sandbox/jq-wasm-adapter.js +421 -0
- package/router/dist/sandbox/quickjs-wasi-adapter.d.ts +9 -0
- package/router/dist/sandbox/quickjs-wasi-adapter.js +381 -0
- package/router/dist/sandbox/script-sandbox.d.ts +113 -0
- package/router/dist/sandbox/script-sandbox.js +303 -0
- package/router/dist/setup/script-transform-adapters.d.ts +28 -0
- package/router/dist/setup/script-transform-adapters.js +259 -0
- package/router/dist/tools/batch.d.ts +22 -0
- package/router/dist/tools/batch.js +509 -0
- package/router/dist/tools/run.d.ts +50 -0
- package/router/dist/tools/run.js +1219 -0
- package/router/dist/tools/search.d.ts +44 -0
- package/{plugins/freeflow/router/dist/retrieve.js → router/dist/tools/search.js} +395 -45
- package/router/dist/transform/engine.d.ts +143 -0
- package/router/dist/transform/engine.js +1955 -0
- package/router/dist/vault/vault-index.d.ts +106 -0
- package/router/dist/vault/vault-index.js +411 -0
- package/{plugins/freeflow/router/dist → router/dist/vault}/vault.d.ts +24 -1
- package/{plugins/freeflow/router/dist → router/dist/vault}/vault.js +152 -1
- package/skills/design-for-depth/SKILL.md +90 -0
- package/skills/design-for-depth/references/design-pressure-signals.md +265 -0
- package/skills/design-for-depth/references/software-design-philosophy.md +219 -0
- package/{plugins/freeflow/skills → skills}/diagnose-failure/SKILL.md +6 -1
- package/{plugins/freeflow/skills/research → skills/discover}/ARTIFACT-DESTINATIONS.md +4 -4
- package/{plugins/freeflow/skills/research → skills/discover}/CHECKPOINTS.md +4 -4
- package/skills/discover/SKILL.md +173 -0
- package/{plugins/freeflow/skills → skills}/execute-plan/SKILL.md +5 -4
- package/{plugins/freeflow/skills → skills}/execute-plan/references/execution-map.md +2 -2
- package/{plugins/freeflow/skills → skills}/mode-contract/SKILL.md +9 -4
- package/skills/output-router/SKILL.md +202 -0
- package/skills/output-router/references/safety-policy.md +40 -0
- package/{plugins/freeflow/skills → skills}/review-artifact/SKILL.md +5 -2
- package/{plugins/freeflow/skills → skills}/review-artifact/references/reviewer-prompt.md +2 -1
- package/{plugins/freeflow/skills → skills}/review-work/SKILL.md +6 -1
- package/{plugins/freeflow/skills → skills}/setup-freeflow/SKILL.md +21 -9
- package/{plugins/freeflow/skills → skills}/setup-freeflow/references/activation-contract.md +11 -10
- package/{plugins/freeflow/skills → skills}/setup-freeflow/references/host-setup.md +3 -3
- package/skills/setup-freeflow/references/output-router-setup.md +102 -0
- package/{plugins/freeflow/skills → skills}/verify-work/SKILL.md +3 -1
- package/{plugins/freeflow/skills → skills}/workflow/SKILL.md +16 -14
- package/{plugins/freeflow/skills → skills}/workflow/references/workflow-map.md +16 -14
- package/{plugins/freeflow/skills → skills}/write-plan/SKILL.md +9 -1
- package/{plugins/freeflow/skills → skills}/write-spec/SKILL.md +9 -6
- package/plugins/freeflow/docs/adr/0002-evals-before-hooks.md +0 -17
- 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/pi-extension/index.js +0 -1176
- package/plugins/freeflow/router/dist/config.d.ts +0 -22
- package/plugins/freeflow/router/dist/config.js +0 -114
- 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/index.d.ts +0 -12
- package/plugins/freeflow/router/dist/index.js +0 -12
- package/plugins/freeflow/router/dist/retrieve.d.ts +0 -33
- package/plugins/freeflow/router/dist/run.d.ts +0 -26
- package/plugins/freeflow/router/dist/run.js +0 -356
- package/plugins/freeflow/router/dist/types.d.ts +0 -234
- package/plugins/freeflow/router/dist/types.js +0 -9
- 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/LANGUAGE.md +0 -61
- package/plugins/freeflow/skills/research/SKILL.md +0 -128
- package/plugins/freeflow/skills/setup-freeflow/references/output-router-setup.md +0 -52
- /package/{plugins/freeflow/assets → assets}/freeflow-plugin-icon-transparent.png +0 -0
- /package/{plugins/freeflow/hooks → hooks}/hooks.json +0 -0
- /package/{plugins/freeflow/docs → plugin-docs}/adr/0001-three-modes.md +0 -0
- /package/{plugins/freeflow/router/dist → router/dist/benchmarks}/benchmark-harness.d.ts +0 -0
- /package/{plugins/freeflow/router/dist → router/dist/benchmarks}/benchmarks.d.ts +0 -0
- /package/{plugins/freeflow/router/dist → router/dist/benchmarks}/codex-qa-benchmarks.d.ts +0 -0
- /package/{plugins/freeflow/router/dist → router/dist/config}/router-contract.d.ts +0 -0
- /package/{plugins/freeflow/router/dist → router/dist/config}/router-contract.js +0 -0
- /package/{plugins/freeflow/router/dist → router/dist/config}/schema.d.ts +0 -0
- /package/{plugins/freeflow/router/dist → router/dist/evidence}/bounded-evidence.js +0 -0
- /package/{plugins/freeflow/router/dist → router/dist/evidence}/evidence-range-selector.d.ts +0 -0
- /package/{plugins/freeflow/router/dist → router/dist/evidence}/evidence-search.d.ts +0 -0
- /package/{plugins/freeflow/router/dist → router/dist/evidence}/evidence.js +0 -0
- /package/{plugins/freeflow/router/dist → router/dist/evidence}/line-ranges.d.ts +0 -0
- /package/{plugins/freeflow/router/dist → router/dist/evidence}/line-ranges.js +0 -0
- /package/{plugins/freeflow/router → router}/dist/experiments/local-index.d.ts +0 -0
- /package/{plugins/freeflow/router → router}/dist/experiments/local-index.js +0 -0
- /package/{plugins/freeflow/router/dist → router/dist/repo}/repo-traversal.d.ts +0 -0
- /package/{plugins/freeflow/router/dist → router/dist/repo}/repo-traversal.js +0 -0
- /package/{plugins/freeflow/skills → skills}/bypass/SKILL.md +0 -0
- /package/{plugins/freeflow/skills → skills}/commit-work/SKILL.md +0 -0
- /package/{plugins/freeflow/skills → skills}/commit-work/references/staging-decisions.md +0 -0
- /package/{plugins/freeflow/skills → skills}/diagnose-failure/references/feedback-loop-catalog.md +0 -0
- /package/{plugins/freeflow/skills → skills}/diagnose-failure/references/flaky-and-performance.md +0 -0
- /package/{plugins/freeflow/skills → skills}/evaluate-skill/SKILL.md +0 -0
- /package/{plugins/freeflow/skills → skills}/evaluate-skill/references/eval-patterns.md +0 -0
- /package/{plugins/freeflow/skills → skills}/evaluate-skill/references/grading-priority.md +0 -0
- /package/{plugins/freeflow/skills → skills}/handoff/SKILL.md +0 -0
- /package/{plugins/freeflow/skills → skills}/handoff/references/templates.md +0 -0
- /package/{plugins/freeflow/skills → skills}/interview-gate/SKILL.md +0 -0
- /package/{plugins/freeflow/skills → skills}/review-work/references/reviewer-prompt.md +0 -0
- /package/{plugins/freeflow/skills → skills}/write-plan/references/plan-shapes.md +0 -0
- /package/{plugins/freeflow/skills → skills}/write-skill/SKILL.md +0 -0
- /package/{plugins/freeflow/skills → skills}/write-spec/references/artifact-standards.md +0 -0
- /package/{plugins/freeflow/skills → skills}/write-spec/references/spec-shapes.md +0 -0
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { mkdir, mkdtemp, readdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
3
4
|
import { tmpdir } from "node:os";
|
|
4
|
-
import { dirname, resolve } from "node:path";
|
|
5
|
+
import { dirname, relative, resolve } from "node:path";
|
|
5
6
|
import { fileURLToPath } from "node:url";
|
|
6
7
|
import { performance } from "node:perf_hooks";
|
|
7
8
|
import { defaultJsonRunReportPath, escapeMarkdownTableCell as escapeTable, formatPercent, latencySummary, normalizeIterations, parseBenchmarkCliArgs, reductionPercent, writeBenchmarkReportPair, } from "./benchmark-harness.js";
|
|
8
|
-
import {
|
|
9
|
-
import { buildOrLoadExperimentalRepoIndex, queryExperimentalRepoIndex, } from "
|
|
9
|
+
import { freeflowSearch } from "../tools/search.js";
|
|
10
|
+
import { buildOrLoadExperimentalRepoIndex, queryExperimentalRepoIndex, } from "../experiments/local-index.js";
|
|
10
11
|
const DEFAULT_ITERATIONS = 3;
|
|
12
|
+
const BENCHMARK_TOP_K = 3;
|
|
13
|
+
const FTS_CONTEXT_LINES = 2;
|
|
14
|
+
const require = createRequire(import.meta.url);
|
|
15
|
+
let cachedFtsCandidateStatus;
|
|
11
16
|
export async function runIndexBenchmarks(options = {}) {
|
|
12
17
|
const iterations = normalizeIterations(options.iterations, DEFAULT_ITERATIONS);
|
|
13
18
|
const fixtures = indexFixtureDefinitions();
|
|
@@ -35,9 +40,9 @@ export function renderIndexBenchmarkReport(report) {
|
|
|
35
40
|
"",
|
|
36
41
|
"## Scope",
|
|
37
42
|
"",
|
|
38
|
-
"
|
|
43
|
+
"Repo Search Backend Benchmark for `freeflow_search`. The scanner remains the product default; this benchmark compares scanner-only retrieval, the no-dependency local lexical index, a conservative hybrid scanner+index path, and records whether an FTS5/BM25/trigram candidate is available.",
|
|
39
44
|
"",
|
|
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.",
|
|
45
|
+
"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 for the local lexical index.",
|
|
41
46
|
"",
|
|
42
47
|
"## Command",
|
|
43
48
|
"",
|
|
@@ -45,15 +50,18 @@ export function renderIndexBenchmarkReport(report) {
|
|
|
45
50
|
"npm run bench:router:index",
|
|
46
51
|
"```",
|
|
47
52
|
"",
|
|
48
|
-
"The CLI writes machine-readable JSON under `
|
|
53
|
+
"The CLI writes machine-readable JSON under `evals/runs/output-router/` by default. That JSON is generated run data; this Markdown file is the durable runtime report.",
|
|
49
54
|
"",
|
|
50
55
|
"## Summary",
|
|
51
56
|
"",
|
|
52
57
|
`- Fixtures: ${report.summary.fixtures}`,
|
|
53
58
|
`- Scanner remains default: ${report.summary.scannerDefault ? "yes" : "no"}`,
|
|
54
59
|
`- 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}`,
|
|
60
|
+
`- Scanner pass: ${report.summary.scanner.passed}/${report.summary.fixtures} (recall@${BENCHMARK_TOP_K}: ${report.summary.scanner.recallAtK}/${report.summary.fixtures})`,
|
|
61
|
+
`- Index warm pass: ${report.summary.index.passed}/${report.summary.fixtures} (recall@${BENCHMARK_TOP_K}: ${report.summary.index.recallAtK}/${report.summary.fixtures})`,
|
|
62
|
+
`- FTS5/BM25/trigram pass: ${report.summary.fts.passed}/${report.summary.fixtures} (skipped: ${report.summary.fts.skipped}; recall@${BENCHMARK_TOP_K}: ${report.summary.fts.recallAtK}/${report.summary.fixtures})`,
|
|
63
|
+
`- Hybrid warm pass: ${report.summary.hybrid.passed}/${report.summary.fixtures} (recall@${BENCHMARK_TOP_K}: ${report.summary.hybrid.recallAtK}/${report.summary.fixtures})`,
|
|
64
|
+
`- FTS5/BM25/trigram candidate: ${report.summary.ftsCandidate.available ? "available" : "unavailable"} — ${report.summary.ftsCandidate.reason}`,
|
|
57
65
|
`- Generated false positives: ${report.summary.generatedFalsePositiveCount}/${report.summary.modeResults}`,
|
|
58
66
|
`- Cold build p50/p95: ${report.summary.coldBuildMs.p50.toFixed(2)}/${report.summary.coldBuildMs.p95.toFixed(2)} ms`,
|
|
59
67
|
`- Warm query p50/p95: ${report.summary.warmQueryMs.p50.toFixed(2)}/${report.summary.warmQueryMs.p95.toFixed(2)} ms`,
|
|
@@ -62,21 +70,21 @@ export function renderIndexBenchmarkReport(report) {
|
|
|
62
70
|
"",
|
|
63
71
|
"## Results",
|
|
64
72
|
"",
|
|
65
|
-
"| fixture | mode | correctness | checks | path | lines | raw/context bytes | context reduction | latency p50/p95 ms | build/query ms | index mode | notes |",
|
|
66
|
-
"| --- | --- | --- | --- | --- | --- | ---: | ---: | ---: | ---: | --- | --- |",
|
|
73
|
+
"| fixture | mode | correctness | checks | path | lines | candidates | raw/context bytes | context reduction | latency p50/p95 ms | build/query ms | index mode | notes |",
|
|
74
|
+
"| --- | --- | --- | --- | --- | --- | --- | ---: | ---: | ---: | ---: | --- | --- |",
|
|
67
75
|
];
|
|
68
76
|
for (const fixture of report.fixtures) {
|
|
69
77
|
for (const result of fixture.results) {
|
|
70
|
-
const correctness = result.correctness.passed ? "pass" : "fail";
|
|
78
|
+
const correctness = result.skipped ? "skipped" : result.correctness.passed ? "pass" : "fail";
|
|
71
79
|
const checks = formatCorrectnessChecks(result.correctness);
|
|
72
80
|
const buildQuery = `${(result.buildMs ?? 0).toFixed(2)}/${(result.queryMs ?? 0).toFixed(2)}`;
|
|
73
81
|
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)} |`);
|
|
82
|
+
lines.push(`| ${escapeTable(fixture.id)} | ${escapeTable(result.mode)} | ${correctness} | ${escapeTable(checks)} | ${escapeTable(result.actualPath ?? "-")} | ${escapeTable(result.actualLines ?? "-")} | ${escapeTable(result.candidatePaths.join(", ") || "-")} | ${result.rawBytes}/${result.contextBytes} | ${formatPercent(result.contextReductionPercent)} | ${result.latencyMs.p50.toFixed(2)}/${result.latencyMs.p95.toFixed(2)} | ${buildQuery} | ${escapeTable(result.indexMode ?? "-")} | ${escapeTable(notes)} |`);
|
|
75
83
|
}
|
|
76
84
|
}
|
|
77
|
-
lines.push("", "## Adoption Decision", "", "Index adopted by default: no. This slice only
|
|
78
|
-
? "Warm experimental index passed all gated fixtures without generated-artifact false positives."
|
|
79
|
-
: `
|
|
85
|
+
lines.push("", "## Adoption Decision", "", "Index adopted by default: no. This slice only records benchmark evidence; scanner behavior remains the default until a later adoption checkpoint explicitly approves otherwise.", "", "## Regression Status", "", report.summary.index.failed === 0 && report.summary.fts.failed === 0 && report.summary.hybrid.failed === 0
|
|
86
|
+
? "Warm experimental index, FTS5/BM25/trigram, and hybrid modes passed all gated fixtures without generated-artifact false positives."
|
|
87
|
+
: `Failures: warm index ${report.summary.index.failed}, FTS5/BM25/trigram ${report.summary.fts.failed}, hybrid ${report.summary.hybrid.failed}.`, "");
|
|
80
88
|
return lines.join("\n");
|
|
81
89
|
}
|
|
82
90
|
export async function writeIndexBenchmarkReport(report, reportPath) {
|
|
@@ -104,20 +112,25 @@ async function runIndexFixtureMode(fixture, mode, iterations) {
|
|
|
104
112
|
latencies.push(performance.now() - startedAt);
|
|
105
113
|
}
|
|
106
114
|
if (!observation) {
|
|
107
|
-
observation = { toolPathUsed: mode, rawBytes: 0, contextBytes: 0, excerpt: "", notes: ["no observation"] };
|
|
115
|
+
observation = { toolPathUsed: mode, skipped: true, skipReason: "No observation was produced.", rawBytes: 0, contextBytes: 0, excerpt: "", notes: ["no observation"] };
|
|
108
116
|
}
|
|
109
117
|
const correctness = scoreCorrectness(fixtureExpectedForMode(fixture, mode), observation);
|
|
110
118
|
const result = {
|
|
111
119
|
mode,
|
|
112
120
|
toolPathUsed: observation.toolPathUsed,
|
|
121
|
+
skipped: observation.skipped ?? false,
|
|
113
122
|
rawBytes: observation.rawBytes,
|
|
114
123
|
contextBytes: observation.contextBytes,
|
|
115
124
|
contextReductionPercent: reductionPercent(observation.rawBytes, observation.contextBytes),
|
|
116
125
|
latencyMs: latencySummary(latencies),
|
|
126
|
+
candidatePaths: observation.candidatePaths ?? [],
|
|
117
127
|
excerpt: observation.excerpt,
|
|
118
128
|
correctness,
|
|
119
129
|
notes: observation.notes ?? [],
|
|
120
130
|
};
|
|
131
|
+
if (observation.skipReason) {
|
|
132
|
+
result.skipReason = observation.skipReason;
|
|
133
|
+
}
|
|
121
134
|
if (observation.buildMs !== undefined) {
|
|
122
135
|
result.buildMs = observation.buildMs;
|
|
123
136
|
}
|
|
@@ -145,13 +158,20 @@ async function observeIndexFixture(fixture, mode) {
|
|
|
145
158
|
await writeFixtureFiles(root.path, fixture.staleFiles ?? { "stale-marker.txt": "stale refresh marker" });
|
|
146
159
|
return await indexObservation(root.path, cacheRoot.path, fixture.staleQuery ?? fixture.query, mode);
|
|
147
160
|
}
|
|
148
|
-
const finalFiles = mode === "scanner-default" || mode === "index-cold" || mode === "index-warm"
|
|
161
|
+
const finalFiles = mode === "scanner-default" || mode === "index-cold" || mode === "index-warm" || mode === "fts5-bm25-trigram" || mode === "hybrid-warm"
|
|
149
162
|
? { ...fixture.files, ...(fixture.staleFiles && fixture.staleExpected ? fixture.staleFiles : {}) }
|
|
150
163
|
: fixture.files;
|
|
151
164
|
await writeFixtureFiles(root.path, finalFiles);
|
|
152
165
|
if (mode === "scanner-default") {
|
|
153
166
|
return await scannerObservation(root.path, fixture.staleQuery && fixture.staleExpected ? fixture.staleQuery : fixture.query);
|
|
154
167
|
}
|
|
168
|
+
if (mode === "fts5-bm25-trigram") {
|
|
169
|
+
return await ftsObservation(root.path, fixture.staleQuery && fixture.staleExpected ? fixture.staleQuery : fixture.query);
|
|
170
|
+
}
|
|
171
|
+
if (mode === "hybrid-warm") {
|
|
172
|
+
await buildOrLoadExperimentalRepoIndex({ root: root.path, cacheRoot: cacheRoot.path });
|
|
173
|
+
return await hybridObservation(root.path, cacheRoot.path, fixture.staleQuery && fixture.staleExpected ? fixture.staleQuery : fixture.query);
|
|
174
|
+
}
|
|
155
175
|
if (mode === "index-warm") {
|
|
156
176
|
await buildOrLoadExperimentalRepoIndex({ root: root.path, cacheRoot: cacheRoot.path });
|
|
157
177
|
return await indexObservation(root.path, cacheRoot.path, fixture.staleQuery && fixture.staleExpected ? fixture.staleQuery : fixture.query, mode);
|
|
@@ -165,15 +185,17 @@ async function observeIndexFixture(fixture, mode) {
|
|
|
165
185
|
async function scannerObservation(root, query) {
|
|
166
186
|
const rawBytes = await repoRawBytes(root);
|
|
167
187
|
const queryStartedAt = performance.now();
|
|
168
|
-
const result = await
|
|
188
|
+
const result = await freeflowSearch({ action: "query", source: { kind: "repo", root }, query, preserve: "important", topK: BENCHMARK_TOP_K });
|
|
169
189
|
const queryMs = performance.now() - queryStartedAt;
|
|
170
190
|
const evidence = result.evidence?.[0];
|
|
191
|
+
const candidatePaths = uniqueCandidatePaths(result.evidence?.map((packet) => packet.path));
|
|
171
192
|
return {
|
|
172
|
-
toolPathUsed: "scanner-default:
|
|
193
|
+
toolPathUsed: "scanner-default: freeflowSearch repo scanner",
|
|
173
194
|
rawBytes,
|
|
174
195
|
contextBytes: byteLength(JSON.stringify(result)),
|
|
175
196
|
...(evidence?.path !== undefined ? { actualPath: evidence.path } : {}),
|
|
176
197
|
...(evidence?.lines !== undefined ? { actualLines: evidence.lines } : {}),
|
|
198
|
+
candidatePaths,
|
|
177
199
|
excerpt: evidence?.excerpt ?? "",
|
|
178
200
|
queryMs,
|
|
179
201
|
notes: [result.routing.reason],
|
|
@@ -183,7 +205,7 @@ async function indexObservation(root, cacheRoot, query, mode) {
|
|
|
183
205
|
const rawBytes = await repoRawBytes(root);
|
|
184
206
|
const load = await buildOrLoadExperimentalRepoIndex({ root, cacheRoot });
|
|
185
207
|
const queryStartedAt = performance.now();
|
|
186
|
-
const candidates = queryExperimentalRepoIndex(load.index, query, { topK:
|
|
208
|
+
const candidates = queryExperimentalRepoIndex(load.index, query, { topK: BENCHMARK_TOP_K });
|
|
187
209
|
const queryMs = performance.now() - queryStartedAt;
|
|
188
210
|
const candidate = candidates[0];
|
|
189
211
|
return {
|
|
@@ -192,6 +214,7 @@ async function indexObservation(root, cacheRoot, query, mode) {
|
|
|
192
214
|
contextBytes: byteLength(JSON.stringify(candidates)),
|
|
193
215
|
...(candidate?.path !== undefined ? { actualPath: candidate.path } : {}),
|
|
194
216
|
...(candidate?.lines !== undefined ? { actualLines: candidate.lines } : {}),
|
|
217
|
+
candidatePaths: uniqueCandidatePaths(candidates.map((entry) => entry.path)),
|
|
195
218
|
excerpt: candidate?.excerpt ?? "",
|
|
196
219
|
buildMs: load.buildMs,
|
|
197
220
|
queryMs,
|
|
@@ -199,9 +222,250 @@ async function indexObservation(root, cacheRoot, query, mode) {
|
|
|
199
222
|
notes: candidate ? [candidate.reason, `cachePath=${load.cachePath}`, ...(load.refreshReason ? [`refresh=${load.refreshReason}`] : [])] : ["no index candidate"],
|
|
200
223
|
};
|
|
201
224
|
}
|
|
225
|
+
async function ftsObservation(root, query) {
|
|
226
|
+
const rawBytes = await repoRawBytes(root);
|
|
227
|
+
const ftsStatus = detectFtsCandidateStatus();
|
|
228
|
+
if (!ftsStatus.available) {
|
|
229
|
+
return {
|
|
230
|
+
toolPathUsed: "fts5-bm25-trigram: unavailable optional candidate",
|
|
231
|
+
skipped: true,
|
|
232
|
+
skipReason: ftsStatus.reason,
|
|
233
|
+
rawBytes,
|
|
234
|
+
contextBytes: 0,
|
|
235
|
+
candidatePaths: [],
|
|
236
|
+
excerpt: "",
|
|
237
|
+
notes: [ftsStatus.reason],
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
const files = await readFtsTextFiles(root);
|
|
241
|
+
const sqlite = loadSqliteModule();
|
|
242
|
+
const startedAt = performance.now();
|
|
243
|
+
const db = new sqlite.DatabaseSync(":memory:");
|
|
244
|
+
try {
|
|
245
|
+
db.exec("CREATE VIRTUAL TABLE docs USING fts5(path UNINDEXED, body, tokenize='trigram')");
|
|
246
|
+
const insert = db.prepare("INSERT INTO docs(path, body) VALUES (?, ?)");
|
|
247
|
+
for (const file of files) {
|
|
248
|
+
insert.run(file.path, file.text);
|
|
249
|
+
}
|
|
250
|
+
const matchQuery = ftsMatchQuery(query);
|
|
251
|
+
const rows = matchQuery
|
|
252
|
+
? db.prepare("SELECT path, bm25(docs) AS rank FROM docs WHERE docs MATCH ? ORDER BY rank LIMIT ?").all(matchQuery, BENCHMARK_TOP_K)
|
|
253
|
+
: [];
|
|
254
|
+
const queryMs = performance.now() - startedAt;
|
|
255
|
+
const byPath = new Map(files.map((file) => [file.path, file]));
|
|
256
|
+
const candidates = rows.flatMap((row) => {
|
|
257
|
+
const file = byPath.get(row.path);
|
|
258
|
+
if (!file) {
|
|
259
|
+
return [];
|
|
260
|
+
}
|
|
261
|
+
const range = bestFtsLineRange(file, query);
|
|
262
|
+
return [{
|
|
263
|
+
path: file.path,
|
|
264
|
+
lines: `${range.start}-${range.end}`,
|
|
265
|
+
excerpt: file.lines.slice(range.start - 1, range.end).join("\n"),
|
|
266
|
+
rank: row.rank,
|
|
267
|
+
reason: `SQLite FTS5 trigram MATCH with bm25 rank ${row.rank.toFixed(6)}`,
|
|
268
|
+
}];
|
|
269
|
+
});
|
|
270
|
+
const first = candidates[0];
|
|
271
|
+
return {
|
|
272
|
+
toolPathUsed: "fts5-bm25-trigram: node:sqlite FTS5 trigram virtual table",
|
|
273
|
+
rawBytes,
|
|
274
|
+
contextBytes: byteLength(JSON.stringify(candidates)),
|
|
275
|
+
...(first?.path !== undefined ? { actualPath: first.path } : {}),
|
|
276
|
+
...(first?.lines !== undefined ? { actualLines: first.lines } : {}),
|
|
277
|
+
candidatePaths: uniqueCandidatePaths(candidates.map((candidate) => candidate.path)),
|
|
278
|
+
excerpt: first?.excerpt ?? "",
|
|
279
|
+
buildMs: queryMs,
|
|
280
|
+
queryMs,
|
|
281
|
+
notes: first ? [first.reason] : ["no FTS5 candidate"],
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
finally {
|
|
285
|
+
db.close();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async function hybridObservation(root, cacheRoot, query) {
|
|
289
|
+
const rawBytes = await repoRawBytes(root);
|
|
290
|
+
const load = await buildOrLoadExperimentalRepoIndex({ root, cacheRoot });
|
|
291
|
+
const indexStartedAt = performance.now();
|
|
292
|
+
const indexCandidates = queryExperimentalRepoIndex(load.index, query, { topK: BENCHMARK_TOP_K });
|
|
293
|
+
const indexQueryMs = performance.now() - indexStartedAt;
|
|
294
|
+
const scannerStartedAt = performance.now();
|
|
295
|
+
const scanner = await freeflowSearch({ action: "query", source: { kind: "repo", root }, query, preserve: "important", topK: BENCHMARK_TOP_K });
|
|
296
|
+
const scannerQueryMs = performance.now() - scannerStartedAt;
|
|
297
|
+
const scannerEvidence = scanner.evidence?.[0];
|
|
298
|
+
const scannerPaths = uniqueCandidatePaths(scanner.evidence?.map((packet) => packet.path));
|
|
299
|
+
const indexPaths = uniqueCandidatePaths(indexCandidates.map((candidate) => candidate.path));
|
|
300
|
+
const hybridInput = { scannerPaths, indexCandidates, indexPaths };
|
|
301
|
+
if (scannerEvidence !== undefined) {
|
|
302
|
+
hybridInput.scannerEvidence = scannerEvidence;
|
|
303
|
+
}
|
|
304
|
+
const selected = chooseHybridCandidate(hybridInput);
|
|
305
|
+
const contextPayload = {
|
|
306
|
+
selected: selected.payload,
|
|
307
|
+
scannerCandidateCount: scannerPaths.length,
|
|
308
|
+
indexCandidateCount: indexPaths.length,
|
|
309
|
+
selection: selected.selection,
|
|
310
|
+
};
|
|
311
|
+
return {
|
|
312
|
+
toolPathUsed: "hybrid-warm: scanner fallback with warm lexical-index candidates",
|
|
313
|
+
rawBytes,
|
|
314
|
+
contextBytes: byteLength(JSON.stringify(contextPayload)),
|
|
315
|
+
...(selected.path !== undefined ? { actualPath: selected.path } : {}),
|
|
316
|
+
...(selected.lines !== undefined ? { actualLines: selected.lines } : {}),
|
|
317
|
+
candidatePaths: uniqueCandidatePaths([...scannerPaths, ...indexPaths]),
|
|
318
|
+
excerpt: selected.excerpt,
|
|
319
|
+
buildMs: load.buildMs,
|
|
320
|
+
queryMs: indexQueryMs + scannerQueryMs,
|
|
321
|
+
indexMode: load.mode,
|
|
322
|
+
notes: [
|
|
323
|
+
`selection=${selected.selection}`,
|
|
324
|
+
`scannerQueryMs=${scannerQueryMs.toFixed(2)}`,
|
|
325
|
+
`indexQueryMs=${indexQueryMs.toFixed(2)}`,
|
|
326
|
+
...(load.refreshReason ? [`refresh=${load.refreshReason}`] : []),
|
|
327
|
+
],
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
function chooseHybridCandidate(options) {
|
|
331
|
+
const scannerEvidence = options.scannerEvidence;
|
|
332
|
+
if (scannerEvidence?.path) {
|
|
333
|
+
const indexAgrees = options.indexPaths.includes(scannerEvidence.path);
|
|
334
|
+
return {
|
|
335
|
+
selection: indexAgrees ? "scanner-index-agree" : "scanner-fallback",
|
|
336
|
+
path: scannerEvidence.path,
|
|
337
|
+
...(scannerEvidence.lines !== undefined ? { lines: scannerEvidence.lines } : {}),
|
|
338
|
+
excerpt: scannerEvidence.excerpt ?? "",
|
|
339
|
+
payload: {
|
|
340
|
+
source: "scanner",
|
|
341
|
+
path: scannerEvidence.path,
|
|
342
|
+
...(scannerEvidence.lines !== undefined ? { lines: scannerEvidence.lines } : {}),
|
|
343
|
+
indexAgrees,
|
|
344
|
+
},
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
const indexCandidate = options.indexCandidates[0];
|
|
348
|
+
if (indexCandidate) {
|
|
349
|
+
return {
|
|
350
|
+
selection: "index-only",
|
|
351
|
+
path: indexCandidate.path,
|
|
352
|
+
lines: indexCandidate.lines,
|
|
353
|
+
excerpt: indexCandidate.excerpt,
|
|
354
|
+
payload: {
|
|
355
|
+
source: "index",
|
|
356
|
+
path: indexCandidate.path,
|
|
357
|
+
lines: indexCandidate.lines,
|
|
358
|
+
score: indexCandidate.score,
|
|
359
|
+
},
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
return { selection: "none", excerpt: "", payload: { source: "none" } };
|
|
363
|
+
}
|
|
364
|
+
function detectFtsCandidateStatus() {
|
|
365
|
+
if (cachedFtsCandidateStatus !== undefined) {
|
|
366
|
+
return cachedFtsCandidateStatus;
|
|
367
|
+
}
|
|
368
|
+
let db;
|
|
369
|
+
try {
|
|
370
|
+
const sqlite = loadSqliteModule();
|
|
371
|
+
db = new sqlite.DatabaseSync(":memory:");
|
|
372
|
+
db.exec("CREATE VIRTUAL TABLE docs USING fts5(path UNINDEXED, body, tokenize='trigram')");
|
|
373
|
+
db.exec("INSERT INTO docs(path, body) VALUES ('probe', 'freeflow fts probe')");
|
|
374
|
+
const rows = db.prepare("SELECT path, bm25(docs) AS rank FROM docs WHERE docs MATCH ?").all("freeflow AND probe");
|
|
375
|
+
cachedFtsCandidateStatus = rows.length > 0
|
|
376
|
+
? {
|
|
377
|
+
available: true,
|
|
378
|
+
engine: "fts5-bm25-trigram",
|
|
379
|
+
reason: "Node node:sqlite is available and supports SQLite FTS5 trigram tokenization with bm25 ranking.",
|
|
380
|
+
}
|
|
381
|
+
: {
|
|
382
|
+
available: false,
|
|
383
|
+
engine: "none",
|
|
384
|
+
reason: "SQLite FTS5 probe returned no rows for a known trigram query.",
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
catch (error) {
|
|
388
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
389
|
+
cachedFtsCandidateStatus = {
|
|
390
|
+
available: false,
|
|
391
|
+
engine: "none",
|
|
392
|
+
reason: `SQLite FTS5/BM25/trigram candidate unavailable: ${message}`,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
finally {
|
|
396
|
+
db?.close();
|
|
397
|
+
}
|
|
398
|
+
return cachedFtsCandidateStatus;
|
|
399
|
+
}
|
|
400
|
+
function loadSqliteModule() {
|
|
401
|
+
return require("node:sqlite");
|
|
402
|
+
}
|
|
403
|
+
async function readFtsTextFiles(root) {
|
|
404
|
+
const files = [];
|
|
405
|
+
await collectFtsTextFiles(root, root, files);
|
|
406
|
+
return files.sort((a, b) => a.path.localeCompare(b.path));
|
|
407
|
+
}
|
|
408
|
+
async function collectFtsTextFiles(root, currentPath, files) {
|
|
409
|
+
const currentStat = await stat(currentPath);
|
|
410
|
+
if (currentStat.isDirectory()) {
|
|
411
|
+
const dirEntries = await readdir(currentPath, { withFileTypes: true });
|
|
412
|
+
for (const entry of dirEntries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
413
|
+
await collectFtsTextFiles(root, resolve(currentPath, entry.name), files);
|
|
414
|
+
}
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
if (!currentStat.isFile()) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
const path = relative(root, currentPath).split(/[\\/]+/).join("/");
|
|
421
|
+
if (isGeneratedBenchmarkPath(path)) {
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
try {
|
|
425
|
+
const text = await readFile(currentPath, "utf8");
|
|
426
|
+
if (!text.includes("\0")) {
|
|
427
|
+
files.push({ path, text, lines: splitLines(text) });
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
catch {
|
|
431
|
+
// ignore non-text fixture files
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
function ftsMatchQuery(query) {
|
|
435
|
+
return searchTokens(query).filter((token) => token.length >= 3).join(" AND ");
|
|
436
|
+
}
|
|
437
|
+
function bestFtsLineRange(file, query) {
|
|
438
|
+
const tokens = searchTokens(query);
|
|
439
|
+
let bestIndex = 0;
|
|
440
|
+
let bestScore = -1;
|
|
441
|
+
for (let index = 0; index < file.lines.length; index += 1) {
|
|
442
|
+
const normalizedLine = (file.lines[index] ?? "").toLowerCase();
|
|
443
|
+
const score = tokens.reduce((sum, token) => sum + (normalizedLine.includes(token) ? 1 : 0), 0);
|
|
444
|
+
if (score > bestScore) {
|
|
445
|
+
bestScore = score;
|
|
446
|
+
bestIndex = index;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
const start = Math.max(1, bestIndex + 1 - FTS_CONTEXT_LINES);
|
|
450
|
+
const end = Math.min(file.lines.length, bestIndex + 1 + FTS_CONTEXT_LINES);
|
|
451
|
+
return { start, end };
|
|
452
|
+
}
|
|
453
|
+
function searchTokens(value) {
|
|
454
|
+
const seen = new Set();
|
|
455
|
+
const tokens = [];
|
|
456
|
+
for (const token of value.toLowerCase().match(/[a-z0-9_]+/g) ?? []) {
|
|
457
|
+
if (!seen.has(token)) {
|
|
458
|
+
seen.add(token);
|
|
459
|
+
tokens.push(token);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
return tokens;
|
|
463
|
+
}
|
|
202
464
|
function summarizeIndexReport(fixtures) {
|
|
203
465
|
const scanner = summarizeMode(fixtures, "scanner-default");
|
|
204
466
|
const index = summarizeMode(fixtures, "index-warm");
|
|
467
|
+
const fts = summarizeMode(fixtures, "fts5-bm25-trigram");
|
|
468
|
+
const hybrid = summarizeMode(fixtures, "hybrid-warm");
|
|
205
469
|
const generatedFalsePositiveCount = fixtures
|
|
206
470
|
.flatMap((fixture) => fixture.results)
|
|
207
471
|
.filter((result) => result.correctness.generatedFalsePositive).length;
|
|
@@ -213,8 +477,11 @@ function summarizeIndexReport(fixtures) {
|
|
|
213
477
|
modeResults: fixtures.reduce((count, fixture) => count + fixture.results.length, 0),
|
|
214
478
|
scannerDefault: true,
|
|
215
479
|
indexAdopted: false,
|
|
480
|
+
ftsCandidate: detectFtsCandidateStatus(),
|
|
216
481
|
scanner,
|
|
217
482
|
index,
|
|
483
|
+
fts,
|
|
484
|
+
hybrid,
|
|
218
485
|
generatedFalsePositiveCount,
|
|
219
486
|
coldBuildMs,
|
|
220
487
|
warmQueryMs,
|
|
@@ -228,7 +495,10 @@ function summarizeMode(fixtures, mode) {
|
|
|
228
495
|
const totalRawBytes = results.reduce((sum, result) => sum + result.rawBytes, 0);
|
|
229
496
|
const totalContextBytes = results.reduce((sum, result) => sum + result.contextBytes, 0);
|
|
230
497
|
return results.reduce((summary, result) => {
|
|
231
|
-
if (result.
|
|
498
|
+
if (result.skipped) {
|
|
499
|
+
summary.skipped += 1;
|
|
500
|
+
}
|
|
501
|
+
else if (result.correctness.passed) {
|
|
232
502
|
summary.passed += 1;
|
|
233
503
|
}
|
|
234
504
|
else {
|
|
@@ -243,13 +513,18 @@ function summarizeMode(fixtures, mode) {
|
|
|
243
513
|
if (result.correctness.excerptComplete) {
|
|
244
514
|
summary.excerptComplete += 1;
|
|
245
515
|
}
|
|
516
|
+
if (result.correctness.recallAtK) {
|
|
517
|
+
summary.recallAtK += 1;
|
|
518
|
+
}
|
|
246
519
|
return summary;
|
|
247
520
|
}, {
|
|
248
521
|
passed: 0,
|
|
249
522
|
failed: 0,
|
|
523
|
+
skipped: 0,
|
|
250
524
|
pathCorrect: 0,
|
|
251
525
|
spanCorrect: 0,
|
|
252
526
|
excerptComplete: 0,
|
|
527
|
+
recallAtK: 0,
|
|
253
528
|
totalRawBytes,
|
|
254
529
|
totalContextBytes,
|
|
255
530
|
weightedContextReductionPercent: reductionPercent(totalRawBytes, totalContextBytes),
|
|
@@ -336,15 +611,28 @@ function fixtureExpectedForMode(fixture, mode) {
|
|
|
336
611
|
return fixture.expected;
|
|
337
612
|
}
|
|
338
613
|
function scoreCorrectness(expected, observation) {
|
|
614
|
+
if (observation.skipped) {
|
|
615
|
+
return {
|
|
616
|
+
passed: false,
|
|
617
|
+
pathCorrect: false,
|
|
618
|
+
spanCorrect: false,
|
|
619
|
+
excerptComplete: false,
|
|
620
|
+
recallAtK: false,
|
|
621
|
+
generatedFalsePositive: false,
|
|
622
|
+
};
|
|
623
|
+
}
|
|
339
624
|
const pathCorrect = observation.actualPath === expected.path;
|
|
340
625
|
const spanCorrect = expected.lines ? Boolean(observation.actualLines && rangesOverlap(expected.lines, observation.actualLines)) : true;
|
|
341
626
|
const excerptComplete = expected.requiredExcerpt.every((snippet) => observation.excerpt.toLowerCase().includes(snippet.toLowerCase()));
|
|
627
|
+
const candidatePaths = observation.candidatePaths ?? [];
|
|
628
|
+
const recallAtK = candidatePaths.length === 0 ? pathCorrect : candidatePaths.includes(expected.path);
|
|
342
629
|
const generatedFalsePositive = observation.actualPath ? isGeneratedBenchmarkPath(observation.actualPath) : false;
|
|
343
630
|
return {
|
|
344
|
-
passed: pathCorrect && spanCorrect && excerptComplete && !generatedFalsePositive,
|
|
631
|
+
passed: pathCorrect && spanCorrect && excerptComplete && recallAtK && !generatedFalsePositive,
|
|
345
632
|
pathCorrect,
|
|
346
633
|
spanCorrect,
|
|
347
634
|
excerptComplete,
|
|
635
|
+
recallAtK,
|
|
348
636
|
generatedFalsePositive,
|
|
349
637
|
};
|
|
350
638
|
}
|
|
@@ -392,7 +680,7 @@ async function createTempDir(prefix) {
|
|
|
392
680
|
};
|
|
393
681
|
}
|
|
394
682
|
function indexBenchmarkModes() {
|
|
395
|
-
return ["scanner-default", "index-cold", "index-warm", "index-stale-refresh"];
|
|
683
|
+
return ["scanner-default", "index-cold", "index-warm", "index-stale-refresh", "fts5-bm25-trigram", "hybrid-warm"];
|
|
396
684
|
}
|
|
397
685
|
function rangesOverlap(left, right) {
|
|
398
686
|
const leftRange = parseRange(left);
|
|
@@ -411,6 +699,18 @@ function parseRange(range) {
|
|
|
411
699
|
const end = Number(match[2]);
|
|
412
700
|
return Number.isInteger(start) && Number.isInteger(end) ? { start, end } : null;
|
|
413
701
|
}
|
|
702
|
+
function uniqueCandidatePaths(paths) {
|
|
703
|
+
const seen = new Set();
|
|
704
|
+
const unique = [];
|
|
705
|
+
for (const path of paths ?? []) {
|
|
706
|
+
if (!path || seen.has(path)) {
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
seen.add(path);
|
|
710
|
+
unique.push(path);
|
|
711
|
+
}
|
|
712
|
+
return unique;
|
|
713
|
+
}
|
|
414
714
|
function isGeneratedBenchmarkPath(path) {
|
|
415
715
|
const segments = path.split(/[\\/]+/);
|
|
416
716
|
if (segments.includes("graphify-out")) {
|
|
@@ -419,6 +719,9 @@ function isGeneratedBenchmarkPath(path) {
|
|
|
419
719
|
const name = segments.at(-1)?.toLowerCase() ?? path.toLowerCase();
|
|
420
720
|
return name.endsWith(".log") || name.endsWith(".map") || name.endsWith(".min.js") || name.endsWith(".min.css") || name.includes(".bundle.");
|
|
421
721
|
}
|
|
722
|
+
function splitLines(text) {
|
|
723
|
+
return text.split(/\r?\n/);
|
|
724
|
+
}
|
|
422
725
|
function byteLength(value) {
|
|
423
726
|
return Buffer.byteLength(value, "utf8");
|
|
424
727
|
}
|
|
@@ -427,11 +730,12 @@ function formatCorrectnessChecks(correctness) {
|
|
|
427
730
|
`path ${correctness.pathCorrect ? "✓" : "✗"}`,
|
|
428
731
|
`span ${correctness.spanCorrect ? "✓" : "✗"}`,
|
|
429
732
|
`excerpt ${correctness.excerptComplete ? "✓" : "✗"}`,
|
|
733
|
+
`recall@${BENCHMARK_TOP_K} ${correctness.recallAtK ? "✓" : "✗"}`,
|
|
430
734
|
`gen-fp ${correctness.generatedFalsePositive ? "✗" : "✓"}`,
|
|
431
735
|
].join(" ");
|
|
432
736
|
}
|
|
433
737
|
function defaultReportPath() {
|
|
434
|
-
return resolve(process.cwd(), "
|
|
738
|
+
return resolve(process.cwd(), "evals/reports/runtime/output-router-index-benchmark-1-report.md");
|
|
435
739
|
}
|
|
436
740
|
async function runCli() {
|
|
437
741
|
const { iterations, reportPath, jsonReportPath } = parseBenchmarkCliArgs(process.argv.slice(2), { reportPath: defaultReportPath() });
|
|
@@ -444,12 +748,12 @@ async function runCli() {
|
|
|
444
748
|
jsonReportPath: jsonReportPath === undefined ? defaultJsonRunReportPath(reportPath) : jsonReportPath,
|
|
445
749
|
});
|
|
446
750
|
const shortId = createHash("sha256").update(JSON.stringify(report.summary)).digest("hex").slice(0, 8);
|
|
447
|
-
console.log(`Freeflow
|
|
751
|
+
console.log(`Freeflow repo search backend benchmark ${shortId}: scanner ${report.summary.scanner.passed}/${report.summary.fixtures}, index ${report.summary.index.passed}/${report.summary.fixtures}, fts ${report.summary.fts.passed}/${report.summary.fixtures}, hybrid ${report.summary.hybrid.passed}/${report.summary.fixtures} pass`);
|
|
448
752
|
console.log(`Markdown report: ${reports.markdown}`);
|
|
449
753
|
if (reports.json) {
|
|
450
754
|
console.log(`JSON run data: ${reports.json}`);
|
|
451
755
|
}
|
|
452
|
-
if (report.summary.index.failed > 0) {
|
|
756
|
+
if (report.summary.scanner.failed > 0 || report.summary.index.failed > 0 || report.summary.fts.failed > 0 || report.summary.hybrid.failed > 0) {
|
|
453
757
|
process.exitCode = 1;
|
|
454
758
|
}
|
|
455
759
|
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { ExecutionStatus } from "../config/types.js";
|
|
2
|
+
export interface StoragePolicyBenchmarkOptions {
|
|
3
|
+
iterations?: number;
|
|
4
|
+
generatedAt?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface StoragePolicyBenchmarkReport {
|
|
7
|
+
generatedAt: string;
|
|
8
|
+
iterations: number;
|
|
9
|
+
summary: StoragePolicyBenchmarkSummary;
|
|
10
|
+
fixtures: StoragePolicyFixtureDefinition[];
|
|
11
|
+
policies: StoragePolicyResult[];
|
|
12
|
+
}
|
|
13
|
+
export interface StoragePolicyBenchmarkSummary {
|
|
14
|
+
fixtures: number;
|
|
15
|
+
policies: number;
|
|
16
|
+
safeCandidateIds: string[];
|
|
17
|
+
disqualifiedCandidateIds: string[];
|
|
18
|
+
defaultUnchanged: true;
|
|
19
|
+
}
|
|
20
|
+
export interface StoragePolicyResult {
|
|
21
|
+
policyId: StoragePolicyId;
|
|
22
|
+
label: string;
|
|
23
|
+
description: string;
|
|
24
|
+
totals: StoragePolicyTotals;
|
|
25
|
+
safety: StoragePolicySafety;
|
|
26
|
+
fixtures: StoragePolicyFixtureResult[];
|
|
27
|
+
notes: string[];
|
|
28
|
+
}
|
|
29
|
+
export interface StoragePolicyTotals {
|
|
30
|
+
rawCombinedBytes: number;
|
|
31
|
+
rawCombinedTokensApprox: number;
|
|
32
|
+
exactStoredCombinedBytes: number;
|
|
33
|
+
exactStoredTokensApprox: number;
|
|
34
|
+
storageBytes: number;
|
|
35
|
+
indexBytes: number;
|
|
36
|
+
metadataOnlyRecords: number;
|
|
37
|
+
exactRecords: number;
|
|
38
|
+
duplicateMetadataRecords: number;
|
|
39
|
+
storageReductionPercent: number;
|
|
40
|
+
tokenSurfaceReductionPercent: number;
|
|
41
|
+
privacySurfacePercent: number;
|
|
42
|
+
latencyMs: {
|
|
43
|
+
p50: number;
|
|
44
|
+
p95: number;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export interface StoragePolicySafety {
|
|
48
|
+
exactnessSensitiveFixtures: number;
|
|
49
|
+
exactnessSensitiveRecoverable: number;
|
|
50
|
+
exactnessSensitiveRecoveryPassed: boolean;
|
|
51
|
+
metadataOnlyRecoveryLabeled: boolean;
|
|
52
|
+
repeatedOutputsDeduped: boolean;
|
|
53
|
+
}
|
|
54
|
+
export interface StoragePolicyFixtureResult {
|
|
55
|
+
fixtureId: string;
|
|
56
|
+
iteration: number;
|
|
57
|
+
outputId: string;
|
|
58
|
+
recordKind: "command" | "metadata";
|
|
59
|
+
persistence: string;
|
|
60
|
+
recoverability: string;
|
|
61
|
+
rawCombinedBytes: number;
|
|
62
|
+
exactStoredCombinedBytes: number;
|
|
63
|
+
latencyMs: number;
|
|
64
|
+
exactRecovery: "passed" | "failed" | "not-exact";
|
|
65
|
+
usefulRecovery: "exact" | "metadata-only" | "duplicate-ref" | "none";
|
|
66
|
+
duplicateOf?: string;
|
|
67
|
+
exactnessSensitive: boolean;
|
|
68
|
+
notes: string[];
|
|
69
|
+
}
|
|
70
|
+
interface StoragePolicyFixtureDefinition {
|
|
71
|
+
id: string;
|
|
72
|
+
title: string;
|
|
73
|
+
command: string;
|
|
74
|
+
stdout: string;
|
|
75
|
+
stderr: string;
|
|
76
|
+
executionStatus: ExecutionStatus;
|
|
77
|
+
exitCode: number | null;
|
|
78
|
+
exactnessSensitive: boolean;
|
|
79
|
+
repeatedGroup?: string;
|
|
80
|
+
}
|
|
81
|
+
type StoragePolicyId = "store-everything" | "threshold-exact" | "metadata-small-exact-large-hybrid" | "duplicate-output-dedupe" | "hybrid-dedupe";
|
|
82
|
+
export declare function runStoragePolicyBenchmarks(options?: StoragePolicyBenchmarkOptions): Promise<StoragePolicyBenchmarkReport>;
|
|
83
|
+
export declare function renderStoragePolicyBenchmarkReport(report: StoragePolicyBenchmarkReport): string;
|
|
84
|
+
export declare function writeStoragePolicyBenchmarkReports(report: StoragePolicyBenchmarkReport, markdownReportPath?: string, options?: {
|
|
85
|
+
jsonReportPath?: string | false;
|
|
86
|
+
}): Promise<{
|
|
87
|
+
markdown: string;
|
|
88
|
+
json?: string;
|
|
89
|
+
}>;
|
|
90
|
+
export {};
|