@hassangameryt/freeflow 0.4.0 → 0.6.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.
Files changed (285) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +2 -1
  3. package/.codex-plugin/plugin.json +2 -1
  4. package/README.md +150 -155
  5. package/capabilities/cognitive-routing/SKILL.md +229 -0
  6. package/capabilities/context-virtualization/SKILL.md +103 -0
  7. package/capabilities/conversation-history/SKILL.md +53 -0
  8. package/command-surface.json +17 -13
  9. package/hooks/freeflow-runtime-context.mjs +393 -159
  10. package/hooks/hooks.json +26 -1
  11. package/hooks/tests/check-runtime-context-hook.sh +223 -54
  12. package/package.json +25 -16
  13. package/pi-extension/dist/cognitive-routing/commands.js +96 -0
  14. package/pi-extension/dist/cognitive-routing/config.js +236 -0
  15. package/pi-extension/dist/cognitive-routing/controller.js +862 -0
  16. package/pi-extension/dist/cognitive-routing/history.js +439 -0
  17. package/pi-extension/dist/cognitive-routing/host.js +126 -0
  18. package/pi-extension/dist/cognitive-routing/runtime.js +43 -0
  19. package/pi-extension/dist/cognitive-routing/tool.js +211 -0
  20. package/pi-extension/dist/cognitive-routing/types.js +6 -0
  21. package/pi-extension/dist/context-virtualization/commands.js +89 -0
  22. package/pi-extension/dist/context-virtualization/projector.js +42 -0
  23. package/pi-extension/dist/context-virtualization/runtime.js +356 -0
  24. package/pi-extension/dist/context-virtualization/state.js +57 -0
  25. package/pi-extension/dist/context-virtualization/types.js +10 -0
  26. package/pi-extension/dist/conversation-history/passages.js +66 -0
  27. package/pi-extension/dist/conversation-history/ranking.js +105 -0
  28. package/pi-extension/dist/conversation-history/runtime.js +226 -0
  29. package/pi-extension/dist/conversation-history/search.js +56 -0
  30. package/pi-extension/dist/conversation-history/types.js +1 -0
  31. package/pi-extension/dist/freeflow-context/resolver.js +120 -0
  32. package/pi-extension/dist/freeflow-context/runtime.js +80 -0
  33. package/pi-extension/dist/freeflow-context/source-projector.js +95 -0
  34. package/pi-extension/dist/freeflow-context/tool.js +308 -0
  35. package/pi-extension/dist/freeflow-context/types.js +12 -0
  36. package/pi-extension/dist/freeflow-context/visibility.js +28 -0
  37. package/pi-extension/dist/index.js +516 -98
  38. package/pi-extension/dist/runtime/runtime-context.js +318 -271
  39. package/pi-extension/dist/runtime/runtime-identity.js +5 -0
  40. package/pi-extension/dist/settings/settings-tui.js +78 -0
  41. package/pi-extension/dist/settings/settings-ui.js +593 -563
  42. package/pi-extension/dist/ui/text-component.js +57 -0
  43. package/pi-extension/src/cognitive-routing/commands.ts +119 -0
  44. package/pi-extension/src/cognitive-routing/config.ts +307 -0
  45. package/pi-extension/src/cognitive-routing/controller.ts +1118 -0
  46. package/pi-extension/src/cognitive-routing/history.ts +638 -0
  47. package/pi-extension/src/cognitive-routing/host.ts +172 -0
  48. package/pi-extension/src/cognitive-routing/runtime.ts +57 -0
  49. package/pi-extension/src/cognitive-routing/tool.ts +272 -0
  50. package/pi-extension/src/cognitive-routing/types.ts +89 -0
  51. package/pi-extension/src/context-virtualization/commands.ts +111 -0
  52. package/pi-extension/src/context-virtualization/projector.ts +62 -0
  53. package/pi-extension/src/context-virtualization/runtime.ts +406 -0
  54. package/pi-extension/src/context-virtualization/state.ts +79 -0
  55. package/pi-extension/src/context-virtualization/types.ts +92 -0
  56. package/pi-extension/src/conversation-history/passages.ts +81 -0
  57. package/pi-extension/src/conversation-history/ranking.ts +155 -0
  58. package/pi-extension/src/conversation-history/runtime.ts +250 -0
  59. package/pi-extension/src/conversation-history/search.ts +79 -0
  60. package/pi-extension/src/conversation-history/types.ts +31 -0
  61. package/pi-extension/src/freeflow-context/resolver.ts +139 -0
  62. package/pi-extension/src/freeflow-context/runtime.ts +100 -0
  63. package/pi-extension/src/freeflow-context/source-projector.ts +106 -0
  64. package/pi-extension/src/freeflow-context/tool.ts +360 -0
  65. package/pi-extension/src/freeflow-context/types.ts +70 -0
  66. package/pi-extension/src/freeflow-context/visibility.ts +53 -0
  67. package/pi-extension/src/index.ts +553 -101
  68. package/pi-extension/src/runtime/runtime-context.ts +339 -281
  69. package/pi-extension/src/runtime/runtime-identity.ts +8 -0
  70. package/pi-extension/src/settings/settings-tui.ts +93 -0
  71. package/pi-extension/src/settings/settings-ui.ts +700 -613
  72. package/pi-extension/src/ui/text-component.ts +66 -0
  73. package/pi-extension/tests/cognitive-routing/commands.test.js +134 -0
  74. package/pi-extension/tests/cognitive-routing/controller.test.js +1099 -0
  75. package/pi-extension/tests/cognitive-routing/extension-lifecycle.test.js +1071 -0
  76. package/pi-extension/tests/cognitive-routing/history.test.js +274 -0
  77. package/pi-extension/tests/cognitive-routing/host-fixture.js +4 -0
  78. package/pi-extension/tests/cognitive-routing/host-identity.test.js +63 -0
  79. package/pi-extension/tests/cognitive-routing/profile-resolution.test.js +236 -0
  80. package/pi-extension/tests/cognitive-routing/tool.test.js +230 -0
  81. package/pi-extension/tests/context-virtualization/extension.test.js +749 -0
  82. package/pi-extension/tests/context-virtualization/projector.test.js +110 -0
  83. package/pi-extension/tests/context-virtualization/runtime.test.js +216 -0
  84. package/pi-extension/tests/conversation-history/runtime.test.js +98 -0
  85. package/pi-extension/tests/conversation-history/search.test.js +97 -0
  86. package/pi-extension/tests/integration/pi-extension.test.js +928 -2047
  87. package/pi-extension/tests/integration/prompt-architecture.test.js +305 -0
  88. package/runtime/prompts/cognitive-routing.md +9 -0
  89. package/runtime/prompts/context-virtualization.md +3 -0
  90. package/runtime/prompts/conversation-history.md +3 -0
  91. package/runtime/prompts/core.md +13 -0
  92. package/runtime/prompts/interaction-contract.md +7 -0
  93. package/runtime/prompts/skills.md +65 -0
  94. package/skills/action-selection/SKILL.md +91 -0
  95. package/skills/bypass/SKILL.md +3 -2
  96. package/skills/commit-work/SKILL.md +1 -1
  97. package/skills/commit-work/references/staging-decisions.md +1 -1
  98. package/skills/decision-gate/SKILL.md +1 -1
  99. package/skills/design-for-depth/SKILL.md +14 -33
  100. package/skills/design-for-depth/references/design-pressure-signals.md +1 -1
  101. package/skills/design-for-depth/references/interface-design-loop.md +1 -1
  102. package/skills/design-for-depth/references/software-design-philosophy.md +1 -1
  103. package/skills/diagnose-failure/SKILL.md +20 -14
  104. package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +1 -3
  105. package/skills/diagnose-failure/references/{flaky-and-performance.md → flaky-and-performance-diagnosis.md} +1 -1
  106. package/skills/discuss/SKILL.md +34 -22
  107. package/skills/discuss/references/discussion-continuity.md +71 -0
  108. package/skills/evaluate-skill/SKILL.md +5 -5
  109. package/skills/evaluate-skill/references/{definition-schema.md → evaluation-definition-schema.md} +42 -2
  110. package/skills/evaluate-skill/references/execution-and-evidence.md +8 -3
  111. package/skills/evaluate-skill/scripts/lib/definitions.mjs +114 -3
  112. package/skills/evaluate-skill/scripts/lib/grade-interaction.mjs +156 -1
  113. package/skills/evaluate-skill/scripts/lib/grade.mjs +9 -1
  114. package/skills/evaluate-skill/scripts/lib/pi.mjs +147 -32
  115. package/skills/evaluate-skill/scripts/lib/rpc.mjs +4 -4
  116. package/skills/evaluate-skill/scripts/lib/runner.mjs +36 -14
  117. package/skills/evaluate-skill/scripts/lib/sandbox.mjs +92 -0
  118. package/skills/evaluate-skill/scripts/pi-guard.mjs +1 -1
  119. package/skills/evaluate-skill/scripts/pi-observer.mjs +66 -0
  120. package/skills/evaluate-skill/scripts/skill-eval.mjs +6 -5
  121. package/skills/execute-work/SKILL.md +18 -15
  122. package/skills/execute-work/references/code-practices.md +1 -1
  123. package/skills/execute-work/references/execute-work-edges.md +42 -0
  124. package/skills/finish-branch/SKILL.md +2 -2
  125. package/skills/finish-branch/references/integration-options.md +1 -1
  126. package/skills/handoff/SKILL.md +3 -3
  127. package/skills/launch-work/SKILL.md +1 -1
  128. package/skills/launch-work/references/launch-readiness.md +2 -2
  129. package/skills/migration-work/SKILL.md +2 -2
  130. package/skills/migration-work/references/migration-lifecycle.md +1 -1
  131. package/skills/mode-contract/SKILL.md +32 -10
  132. package/skills/release-work/SKILL.md +1 -1
  133. package/skills/release-work/references/release-evidence.md +1 -1
  134. package/skills/review-artifact/SKILL.md +28 -26
  135. package/skills/review-work/SKILL.md +28 -26
  136. package/skills/review-work/references/{reviewer-prompt.md → independent-work-reviewer-contract.md} +1 -1
  137. package/skills/review-work/references/security-risk-lens.md +1 -1
  138. package/skills/setup-freeflow/SKILL.md +6 -10
  139. package/skills/setup-freeflow/references/activation-contract.md +5 -10
  140. package/skills/setup-freeflow/references/host-setup.md +3 -7
  141. package/skills/simplify-code/SKILL.md +1 -1
  142. package/skills/simplify-code/references/simplification-patterns.md +1 -1
  143. package/skills/tdd/SKILL.md +18 -38
  144. package/skills/tdd/references/test-design.md +2 -2
  145. package/skills/track-work/SKILL.md +362 -58
  146. package/skills/track-work/scripts/lib/codec.mjs +570 -0
  147. package/skills/track-work/scripts/lib/commands.mjs +568 -0
  148. package/skills/track-work/scripts/lib/contract.mjs +303 -0
  149. package/skills/track-work/scripts/lib/model.mjs +506 -0
  150. package/skills/track-work/scripts/lib/operations.mjs +965 -0
  151. package/skills/track-work/scripts/lib/record-store.mjs +264 -0
  152. package/skills/track-work/scripts/lib/result.mjs +37 -0
  153. package/skills/track-work/scripts/lib/rewrites.mjs +740 -0
  154. package/skills/track-work/scripts/lib/schema.mjs +277 -0
  155. package/skills/track-work/scripts/lib/source-inventory.mjs +162 -0
  156. package/skills/track-work/scripts/lib/views.mjs +443 -0
  157. package/skills/track-work/scripts/lib/workspace.mjs +134 -0
  158. package/skills/track-work/scripts/working-record.mjs +122 -0
  159. package/skills/verify-work/SKILL.md +14 -2
  160. package/skills/verify-work/references/browser-runtime-evidence.md +1 -1
  161. package/skills/verify-work/references/integration-evidence.md +1 -1
  162. package/skills/verify-work/references/performance-evidence.md +1 -1
  163. package/skills/workflow/SKILL.md +105 -53
  164. package/skills/workflow/references/domain-skill-composition.md +22 -42
  165. package/skills/write-plan/SKILL.md +1 -1
  166. package/skills/write-skill/SKILL.md +3 -2
  167. package/skills/write-skill/references/progressive-disclosure.md +17 -3
  168. package/pi-extension/dist/output-router/host-producer-identification.js +0 -232
  169. package/pi-extension/dist/output-router/native-safety-net.js +0 -216
  170. package/pi-extension/dist/output-router/observed-tool-routing.js +0 -122
  171. package/pi-extension/dist/output-router/renderers.js +0 -1023
  172. package/pi-extension/dist/output-router/router-tools.js +0 -554
  173. package/pi-extension/dist/output-router/schemas.js +0 -383
  174. package/pi-extension/dist/output-router/status.js +0 -744
  175. package/pi-extension/dist/output-router/utils.js +0 -502
  176. package/pi-extension/src/output-router/host-producer-identification.ts +0 -256
  177. package/pi-extension/src/output-router/native-safety-net.ts +0 -248
  178. package/pi-extension/src/output-router/observed-tool-routing.ts +0 -134
  179. package/pi-extension/src/output-router/renderers.ts +0 -1108
  180. package/pi-extension/src/output-router/router-tools.ts +0 -579
  181. package/pi-extension/src/output-router/schemas.ts +0 -387
  182. package/pi-extension/src/output-router/status.ts +0 -791
  183. package/pi-extension/src/output-router/utils.ts +0 -554
  184. package/pi-extension/tests/output-router/observed-producers.test.js +0 -132
  185. package/pi-extension/tests/output-router/search.test.js +0 -722
  186. package/router/dist/benchmarks/benchmark-harness.d.ts +0 -35
  187. package/router/dist/benchmarks/benchmark-harness.js +0 -92
  188. package/router/dist/benchmarks/benchmarks.d.ts +0 -109
  189. package/router/dist/benchmarks/benchmarks.js +0 -979
  190. package/router/dist/benchmarks/codex-qa-benchmarks.d.ts +0 -95
  191. package/router/dist/benchmarks/codex-qa-benchmarks.js +0 -500
  192. package/router/dist/benchmarks/command-benchmarks.d.ts +0 -143
  193. package/router/dist/benchmarks/command-benchmarks.js +0 -698
  194. package/router/dist/benchmarks/context-mode-normalized-benchmarks.d.ts +0 -82
  195. package/router/dist/benchmarks/context-mode-normalized-benchmarks.js +0 -773
  196. package/router/dist/benchmarks/context-mode-real-deep-benchmark.d.ts +0 -132
  197. package/router/dist/benchmarks/context-mode-real-deep-benchmark.js +0 -1380
  198. package/router/dist/benchmarks/context-saving-baseline.d.ts +0 -60
  199. package/router/dist/benchmarks/context-saving-baseline.js +0 -470
  200. package/router/dist/benchmarks/index-benchmarks.d.ts +0 -103
  201. package/router/dist/benchmarks/index-benchmarks.js +0 -862
  202. package/router/dist/benchmarks/storage-policy-benchmarks.d.ts +0 -101
  203. package/router/dist/benchmarks/storage-policy-benchmarks.js +0 -618
  204. package/router/dist/benchmarks/vault-index-benchmarks.d.ts +0 -56
  205. package/router/dist/benchmarks/vault-index-benchmarks.js +0 -322
  206. package/router/dist/config/config.d.ts +0 -103
  207. package/router/dist/config/config.js +0 -632
  208. package/router/dist/config/router-contract.d.ts +0 -10
  209. package/router/dist/config/router-contract.js +0 -54
  210. package/router/dist/config/schema.d.ts +0 -27
  211. package/router/dist/config/schema.js +0 -648
  212. package/router/dist/config/types.d.ts +0 -573
  213. package/router/dist/config/types.js +0 -41
  214. package/router/dist/evidence/bounded-evidence.d.ts +0 -40
  215. package/router/dist/evidence/bounded-evidence.js +0 -323
  216. package/router/dist/evidence/evidence-range-selector.d.ts +0 -24
  217. package/router/dist/evidence/evidence-range-selector.js +0 -232
  218. package/router/dist/evidence/evidence-search.d.ts +0 -27
  219. package/router/dist/evidence/evidence-search.js +0 -490
  220. package/router/dist/evidence/evidence.d.ts +0 -38
  221. package/router/dist/evidence/evidence.js +0 -200
  222. package/router/dist/evidence/failure-contracts.d.ts +0 -37
  223. package/router/dist/evidence/failure-contracts.js +0 -166
  224. package/router/dist/evidence/line-ranges.d.ts +0 -24
  225. package/router/dist/evidence/line-ranges.js +0 -22
  226. package/router/dist/experiments/local-index.d.ts +0 -64
  227. package/router/dist/experiments/local-index.js +0 -581
  228. package/router/dist/index.d.ts +0 -30
  229. package/router/dist/index.js +0 -32
  230. package/router/dist/local/local-traversal.d.ts +0 -18
  231. package/router/dist/local/local-traversal.js +0 -334
  232. package/router/dist/processing/engine.d.ts +0 -132
  233. package/router/dist/processing/engine.js +0 -533
  234. package/router/dist/processing/reducers.d.ts +0 -280
  235. package/router/dist/processing/reducers.js +0 -1673
  236. package/router/dist/processing/renderers.d.ts +0 -31
  237. package/router/dist/processing/renderers.js +0 -195
  238. package/router/dist/processing/scripts.d.ts +0 -91
  239. package/router/dist/processing/scripts.js +0 -386
  240. package/router/dist/repo/repo-traversal.d.ts +0 -18
  241. package/router/dist/repo/repo-traversal.js +0 -245
  242. package/router/dist/routing/observed-reducers.d.ts +0 -41
  243. package/router/dist/routing/observed-reducers.js +0 -661
  244. package/router/dist/routing/observed-routing.d.ts +0 -26
  245. package/router/dist/routing/observed-routing.js +0 -378
  246. package/router/dist/routing/parsers.d.ts +0 -16
  247. package/router/dist/routing/parsers.js +0 -521
  248. package/router/dist/routing/run-filters.d.ts +0 -60
  249. package/router/dist/routing/run-filters.js +0 -238
  250. package/router/dist/routing/run-reducers.d.ts +0 -49
  251. package/router/dist/routing/run-reducers.js +0 -122
  252. package/router/dist/sandbox/adapter-roots.d.ts +0 -46
  253. package/router/dist/sandbox/adapter-roots.js +0 -66
  254. package/router/dist/sandbox/eryx-python-adapter.d.ts +0 -13
  255. package/router/dist/sandbox/eryx-python-adapter.js +0 -868
  256. package/router/dist/sandbox/jq-wasm-adapter.d.ts +0 -9
  257. package/router/dist/sandbox/jq-wasm-adapter.js +0 -429
  258. package/router/dist/sandbox/quickjs-wasi-adapter.d.ts +0 -13
  259. package/router/dist/sandbox/quickjs-wasi-adapter.js +0 -384
  260. package/router/dist/sandbox/script-sandbox.d.ts +0 -134
  261. package/router/dist/sandbox/script-sandbox.js +0 -337
  262. package/router/dist/setup/script-transform-adapters.d.ts +0 -32
  263. package/router/dist/setup/script-transform-adapters.js +0 -278
  264. package/router/dist/tools/batch.d.ts +0 -33
  265. package/router/dist/tools/batch.js +0 -586
  266. package/router/dist/tools/run.d.ts +0 -62
  267. package/router/dist/tools/run.js +0 -1304
  268. package/router/dist/tools/search.d.ts +0 -66
  269. package/router/dist/tools/search.js +0 -1364
  270. package/router/dist/transform/engine.d.ts +0 -168
  271. package/router/dist/transform/engine.js +0 -2072
  272. package/router/dist/vault/vault-index.d.ts +0 -125
  273. package/router/dist/vault/vault-index.js +0 -416
  274. package/router/dist/vault/vault.d.ts +0 -138
  275. package/router/dist/vault/vault.js +0 -630
  276. package/runtime/interaction-contract.md +0 -16
  277. package/skills/discuss/references/checkpoints.md +0 -66
  278. package/skills/execute-work/references/execution-loop.md +0 -77
  279. package/skills/output-router/SKILL.md +0 -206
  280. package/skills/output-router/references/safety-policy.md +0 -40
  281. package/skills/setup-freeflow/references/output-router-setup.md +0 -110
  282. package/skills/track-work/references/working-record-schema.md +0 -378
  283. package/skills/workflow/references/workflow-loop.md +0 -92
  284. /package/skills/handoff/references/{templates.md → handoff-templates.md} +0 -0
  285. /package/skills/review-artifact/references/{reviewer-prompt.md → independent-artifact-reviewer-contract.md} +0 -0
@@ -1,60 +0,0 @@
1
- export interface RunContextSavingBaselineOptions {
2
- generatedAt?: string;
3
- }
4
- export interface ContextSavingBaselineReport {
5
- generatedAt: string;
6
- summary: ContextSavingBaselineSummary;
7
- observations: ContextSavingBaselineObservation[];
8
- guardrails: ContextSavingGuardrail[];
9
- notes: string[];
10
- }
11
- export interface ContextSavingBaselineSummary {
12
- fixtures: number;
13
- factsPreserved: number;
14
- recoveryAvailable: number;
15
- totalRawBytes: number;
16
- totalModelVisibleBytes: number;
17
- totalDetailsPayloadBytes: number;
18
- totalRawTokensApprox: number;
19
- totalModelVisibleTokensApprox: number;
20
- totalDetailsPayloadTokensApprox: number;
21
- weightedModelVisibleReductionPercent: number;
22
- }
23
- export interface ContextSavingBaselineObservation {
24
- id: string;
25
- title: string;
26
- tool: "freeflow_run" | "freeflow_search" | "freeflow_search action=transform";
27
- action: string;
28
- rawBytes: number;
29
- modelVisibleBytes: number;
30
- detailsPayloadBytes: number;
31
- rawTokensApprox: number;
32
- modelVisibleTokensApprox: number;
33
- detailsPayloadTokensApprox: number;
34
- modelVisibleReductionPercent: number;
35
- factsPreserved: boolean;
36
- recoveryAvailable: boolean;
37
- recoveryHint: string;
38
- status: string;
39
- outputId?: string;
40
- evidenceLocations: string[];
41
- notes: string[];
42
- }
43
- export interface ContextSavingGuardrail {
44
- path: string;
45
- behaviors: string[];
46
- }
47
- export declare function runContextSavingBaseline(
48
- options?: RunContextSavingBaselineOptions,
49
- ): Promise<ContextSavingBaselineReport>;
50
- export declare function renderContextSavingBaselineReport(report: ContextSavingBaselineReport): string;
51
- export declare function writeContextSavingBaselineReport(
52
- report: ContextSavingBaselineReport,
53
- markdownReportPath: string,
54
- options?: {
55
- jsonReportPath?: string | false;
56
- },
57
- ): Promise<{
58
- markdown: string;
59
- json?: string;
60
- }>;
@@ -1,470 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
3
- import { tmpdir } from "node:os";
4
- import { join, resolve } from "node:path";
5
- import { fileURLToPath } from "node:url";
6
- import {
7
- approximateTokens,
8
- defaultJsonRunReportPath,
9
- escapeMarkdownTableCell as escapeTable,
10
- formatPercent,
11
- parseBenchmarkCliArgs,
12
- reductionPercent,
13
- writeBenchmarkReportPair,
14
- } from "./benchmark-harness.js";
15
- import { freeflowTransform } from "../transform/engine.js";
16
- import { freeflowSearch } from "../tools/search.js";
17
- import { freeflowRun } from "../tools/run.js";
18
- const REPO_DOC_TEXT = `# Output Router Architecture
19
-
20
- Freeflow captures raw command stdout and stderr outside model context.
21
-
22
- Exact recovery uses outputId handles and line ranges so future agents can retrieve source evidence.
23
-
24
- Parser decisions stay structured in details.result while model-visible text can become compact.
25
-
26
- Batch intermediates should be stored without flooding the model context.
27
- `;
28
- const COMMAND_STDOUT = [
29
- "FAIL packages/auth/auth.test.ts",
30
- " ● refresh token keeps AUTH_TOKEN scoped",
31
- " Expected AUTH_TOKEN to be redacted before logging",
32
- "PASS packages/router/run.test.ts",
33
- "PASS packages/router/search.test.ts",
34
- "Tests: 1 failed, 24 passed, 25 total",
35
- "Snapshots: 0 total",
36
- "Time: 4.21 s",
37
- "Ran all test suites.",
38
- ].join("\n");
39
- const COMMAND_STDERR = [
40
- "Error: ROUTER_BENCH_FAILED",
41
- " at refreshToken (packages/auth/auth.ts:42:11)",
42
- " at main (packages/auth/auth.test.ts:8:3)",
43
- ].join("\n");
44
- const GUARDED_FIXTURES = [
45
- {
46
- path: "router/tests/run.test.js",
47
- behaviors: [
48
- "freeflowRun parser/recovery behavior",
49
- "duplicate output compaction",
50
- "exact failure and verification evidence preservation",
51
- ],
52
- },
53
- {
54
- path: "router/tests/tools/search.test.js",
55
- behaviors: [
56
- "exact repo path/range retrieval",
57
- "exact vault line retrieval",
58
- "vault-wide query/locate",
59
- "repo/vault expand and explain behavior",
60
- ],
61
- },
62
- {
63
- path: "router/tests/transform/engine.test.js",
64
- behaviors: [
65
- "deterministic transform operations",
66
- "transformed-output lineage and exact recovery",
67
- "structured failures for invalid operations and missing sources",
68
- ],
69
- },
70
- {
71
- path: "router/tests/tools/batch.test.js",
72
- behaviors: [
73
- "batch accepts public run/search step kinds",
74
- "batch rejects legacy retrieve/transform step kinds",
75
- "query aggregation from child evidence handles",
76
- ],
77
- },
78
- {
79
- path: "router/tests/pi-extension.test.js",
80
- behaviors: ["public Pi tool schemas", "content/details result contract", "compact and expanded TUI renderers"],
81
- },
82
- {
83
- path: "router/tests/pi/pi-extension-search.test.js",
84
- behaviors: [
85
- "search action=transform disabled-by-default behavior",
86
- "adapter-unavailable behavior",
87
- "proof-backed adapter execution path",
88
- ],
89
- },
90
- {
91
- path: "router/tests/regression-fixtures.test.js",
92
- behaviors: [
93
- "generated decoy avoidance",
94
- "huge-line bounded evidence",
95
- "exact phrase and source-prior retrieval regressions",
96
- ],
97
- },
98
- {
99
- path: "router/tests/vault-index.test.js",
100
- behaviors: [
101
- "command/native/observed/transformed vault record indexing",
102
- "metadata-only indexing without raw recovery claims",
103
- "retention and degraded-index behavior",
104
- ],
105
- },
106
- ];
107
- export async function runContextSavingBaseline(options = {}) {
108
- const root = await createTempDir("freeflow-context-saving-baseline-");
109
- const repoRoot = join(root.path, "repo");
110
- const vaultRoot = join(root.path, "vault");
111
- const sessionId = "context-saving-baseline";
112
- try {
113
- await mkdir(join(repoRoot, "plugin-docs"), { recursive: true });
114
- await writeFile(join(repoRoot, "plugin-docs/output-router.md"), REPO_DOC_TEXT, "utf8");
115
- const commandRawBytes = byteLength(`${COMMAND_STDOUT}\n${COMMAND_STDERR}\n`);
116
- const runResult = await freeflowRun(
117
- {
118
- command: "npm test -- --runInBand",
119
- sessionId,
120
- vaultRoot,
121
- preserve: "important",
122
- goal: "baseline model-visible output size",
123
- },
124
- {
125
- async run() {
126
- return {
127
- stdout: `${COMMAND_STDOUT}\n`,
128
- stderr: `${COMMAND_STDERR}\n`,
129
- combined: `STDOUT:\n${COMMAND_STDOUT}\n\nSTDERR:\n${COMMAND_STDERR}\n`,
130
- executionStatus: "failed",
131
- exitCode: 1,
132
- durationMs: 4210,
133
- };
134
- },
135
- },
136
- );
137
- const outputId = typeof runResult.outputId === "string" ? runResult.outputId : "";
138
- const observations = [];
139
- observations.push(
140
- makeObservation({
141
- id: "run-failed-test-output",
142
- title: "freeflow_run failed test output",
143
- tool: "freeflow_run",
144
- action: "run",
145
- rawBytes: commandRawBytes,
146
- result: runResult,
147
- requiredFacts: ["ROUTER_BENCH_FAILED", "failed", "ffout_"],
148
- notes: ["Current Pi model-visible text is the full pretty-printed routed result JSON."],
149
- }),
150
- );
151
- const repoQueryResult = await freeflowSearch({
152
- action: "query",
153
- source: { kind: "repo", root: repoRoot },
154
- query: "Exact recovery outputId line ranges parser decisions",
155
- topK: 1,
156
- preserve: "important",
157
- });
158
- observations.push(
159
- makeObservation({
160
- id: "search-repo-query",
161
- title: "freeflow_search repo query",
162
- tool: "freeflow_search",
163
- action: "query repo",
164
- rawBytes: byteLength(REPO_DOC_TEXT),
165
- result: repoQueryResult,
166
- requiredFacts: ["outputId", "line ranges", "details.result"],
167
- }),
168
- );
169
- const repoExactResult = await freeflowSearch({
170
- action: "retrieve",
171
- source: { kind: "repo", root: repoRoot, path: "plugin-docs/output-router.md" },
172
- lineRange: { start: 3, end: 5 },
173
- preserve: "full",
174
- });
175
- observations.push(
176
- makeObservation({
177
- id: "search-repo-exact-range",
178
- title: "freeflow_search exact repo range",
179
- tool: "freeflow_search",
180
- action: "retrieve repo range",
181
- rawBytes: byteLength(REPO_DOC_TEXT),
182
- result: repoExactResult,
183
- requiredFacts: ["stdout", "stderr", "line ranges"],
184
- notes: ["This guards the existing public advanced path/range recovery behavior."],
185
- }),
186
- );
187
- if (outputId) {
188
- const vaultQueryResult = await freeflowSearch({
189
- action: "query",
190
- source: { kind: "vault", root: vaultRoot, sessionId, outputId, stream: "combined" },
191
- query: "ROUTER_BENCH_FAILED",
192
- topK: 1,
193
- preserve: "important",
194
- });
195
- observations.push(
196
- makeObservation({
197
- id: "search-vault-query",
198
- title: "freeflow_search vault query",
199
- tool: "freeflow_search",
200
- action: "query vault",
201
- rawBytes: commandRawBytes,
202
- result: vaultQueryResult,
203
- requiredFacts: ["ROUTER_BENCH_FAILED", outputId],
204
- }),
205
- );
206
- const transformResult = await freeflowTransform({
207
- source: { kind: "vault", outputId, stream: "combined" },
208
- operation: { kind: "regexFilter", pattern: "AUTH_TOKEN|ROUTER_BENCH_FAILED|Tests:", maxMatches: 10 },
209
- sessionId,
210
- vaultRoot,
211
- preserve: "important",
212
- });
213
- observations.push(
214
- makeObservation({
215
- id: "transform-regex-filter",
216
- title: "freeflow_search action=transform regexFilter",
217
- tool: "freeflow_search action=transform",
218
- action: "regexFilter vault",
219
- rawBytes: commandRawBytes,
220
- result: transformResult,
221
- requiredFacts: ["AUTH_TOKEN", "ROUTER_BENCH_FAILED", "regexFilter"],
222
- }),
223
- );
224
- }
225
- return {
226
- generatedAt: options.generatedAt ?? new Date().toISOString(),
227
- summary: summarizeObservations(observations),
228
- observations,
229
- guardrails: GUARDED_FIXTURES,
230
- notes: [
231
- "This is a Slice 0 baseline for current Freeflow-owned tools before compact-output redesign.",
232
- "Model-visible bytes use the current Pi routedToolText shape: JSON.stringify(result, null, 2).",
233
- "Details payload bytes use the current Pi details shape: { result } with the same structured result.",
234
- "Negative reduction means the current routed JSON is larger than the raw fixture bytes; this is expected baseline evidence for compact-output work.",
235
- ],
236
- };
237
- } finally {
238
- await root.cleanup();
239
- }
240
- }
241
- export function renderContextSavingBaselineReport(report) {
242
- const date = report.generatedAt.slice(0, 10);
243
- const lines = [
244
- "# Freeflow Context-Saving Native Tools Baseline Report - Slice 0",
245
- "",
246
- `Date: ${date}`,
247
- "",
248
- "## Scope",
249
- "",
250
- "Baseline current model-visible output sizes for representative `freeflow_run`, `freeflow_search`, and `freeflow_search action=transform` results before the compact-output redesign.",
251
- "",
252
- "The baseline intentionally measures current Pi tool text as pretty-printed routed result JSON. Later slices should reduce model-visible bytes while keeping details and exact recovery available.",
253
- "",
254
- "## Summary",
255
- "",
256
- `- Fixtures measured: ${report.summary.fixtures}`,
257
- `- Facts preserved: ${report.summary.factsPreserved}/${report.summary.fixtures}`,
258
- `- Recovery available: ${report.summary.recoveryAvailable}/${report.summary.fixtures}`,
259
- `- Raw bytes: ${report.summary.totalRawBytes}`,
260
- `- Model-visible bytes: ${report.summary.totalModelVisibleBytes}`,
261
- `- Details payload bytes: ${report.summary.totalDetailsPayloadBytes}`,
262
- `- Approx raw tokens: ${report.summary.totalRawTokensApprox}`,
263
- `- Approx model-visible tokens: ${report.summary.totalModelVisibleTokensApprox}`,
264
- `- Weighted model-visible reduction vs raw: ${formatPercent(report.summary.weightedModelVisibleReductionPercent)}`,
265
- "",
266
- "## Measurements",
267
- "",
268
- "| Fixture | Tool | Action | Raw bytes | Model-visible bytes | Details bytes | Reduction vs raw | Facts | Recovery | Status |",
269
- "| --- | --- | --- | ---: | ---: | ---: | ---: | --- | --- | --- |",
270
- ];
271
- for (const observation of report.observations) {
272
- lines.push(
273
- `| ${escapeTable(observation.id)} | ${observation.tool} | ${escapeTable(observation.action)} | ${observation.rawBytes} | ${observation.modelVisibleBytes} | ${observation.detailsPayloadBytes} | ${formatPercent(observation.modelVisibleReductionPercent)} | ${observation.factsPreserved ? "yes" : "no"} | ${observation.recoveryAvailable ? "yes" : "no"} | ${escapeTable(observation.status)} |`,
274
- );
275
- }
276
- lines.push("", "## Recovery And Evidence Handles", "");
277
- for (const observation of report.observations) {
278
- lines.push(`### ${observation.id}`);
279
- if (observation.outputId) {
280
- lines.push(`- outputId: \`${observation.outputId}\``);
281
- }
282
- lines.push(`- recovery: ${observation.recoveryHint || "none"}`);
283
- if (observation.evidenceLocations.length > 0) {
284
- lines.push(`- evidence: ${observation.evidenceLocations.map((item) => `\`${item}\``).join(", ")}`);
285
- }
286
- for (const note of observation.notes) {
287
- lines.push(`- note: ${note}`);
288
- }
289
- lines.push("");
290
- }
291
- lines.push("## Guardrail Inventory", "");
292
- lines.push("Existing tests/fixtures that must remain stable during the redesign:", "");
293
- for (const guardrail of report.guardrails) {
294
- lines.push(`- \`${guardrail.path}\``);
295
- for (const behavior of guardrail.behaviors) {
296
- lines.push(` - ${behavior}`);
297
- }
298
- }
299
- lines.push("", "## Notes", "");
300
- for (const note of report.notes) {
301
- lines.push(`- ${note}`);
302
- }
303
- return `${lines.join("\n")}\n`;
304
- }
305
- export async function writeContextSavingBaselineReport(report, markdownReportPath, options = {}) {
306
- return writeBenchmarkReportPair({
307
- report,
308
- markdownReportPath,
309
- jsonReportPath: options.jsonReportPath,
310
- renderMarkdown: renderContextSavingBaselineReport,
311
- });
312
- }
313
- function makeObservation(input) {
314
- const modelVisibleText = currentPiModelVisibleText(input.result);
315
- const detailsPayloadText = JSON.stringify({ result: input.result }, null, 2);
316
- const modelVisibleBytes = byteLength(modelVisibleText);
317
- const detailsPayloadBytes = byteLength(detailsPayloadText);
318
- const evidenceLocations = resultEvidenceLocations(input.result);
319
- const recoveryHint = resultRecoveryHint(input.result);
320
- const outputId = resultOutputId(input.result);
321
- const observation = {
322
- id: input.id,
323
- title: input.title,
324
- tool: input.tool,
325
- action: input.action,
326
- rawBytes: input.rawBytes,
327
- modelVisibleBytes,
328
- detailsPayloadBytes,
329
- rawTokensApprox: approximateTokens(input.rawBytes),
330
- modelVisibleTokensApprox: approximateTokens(modelVisibleBytes),
331
- detailsPayloadTokensApprox: approximateTokens(detailsPayloadBytes),
332
- modelVisibleReductionPercent: reductionPercent(input.rawBytes, modelVisibleBytes),
333
- factsPreserved: input.requiredFacts.every(
334
- (fact) => modelVisibleText.includes(fact) || detailsPayloadText.includes(fact),
335
- ),
336
- recoveryAvailable: Boolean(recoveryHint || outputId || evidenceLocations.length > 0),
337
- recoveryHint,
338
- status: resultStatus(input.result),
339
- evidenceLocations,
340
- notes: input.notes ?? [],
341
- };
342
- if (outputId) {
343
- observation.outputId = outputId;
344
- }
345
- return observation;
346
- }
347
- function summarizeObservations(observations) {
348
- const totalRawBytes = observations.reduce((sum, observation) => sum + observation.rawBytes, 0);
349
- const totalModelVisibleBytes = observations.reduce((sum, observation) => sum + observation.modelVisibleBytes, 0);
350
- const totalDetailsPayloadBytes = observations.reduce((sum, observation) => sum + observation.detailsPayloadBytes, 0);
351
- return {
352
- fixtures: observations.length,
353
- factsPreserved: observations.filter((observation) => observation.factsPreserved).length,
354
- recoveryAvailable: observations.filter((observation) => observation.recoveryAvailable).length,
355
- totalRawBytes,
356
- totalModelVisibleBytes,
357
- totalDetailsPayloadBytes,
358
- totalRawTokensApprox: approximateTokens(totalRawBytes),
359
- totalModelVisibleTokensApprox: approximateTokens(totalModelVisibleBytes),
360
- totalDetailsPayloadTokensApprox: approximateTokens(totalDetailsPayloadBytes),
361
- weightedModelVisibleReductionPercent: reductionPercent(totalRawBytes, totalModelVisibleBytes),
362
- };
363
- }
364
- function currentPiModelVisibleText(result) {
365
- return JSON.stringify(result, null, 2);
366
- }
367
- function resultStatus(result) {
368
- const value = asRecord(result);
369
- if (!value) {
370
- return "unknown";
371
- }
372
- const statuses = [
373
- stringAt(value, "toolStatus"),
374
- stringAt(asRecord(value.execution), "status"),
375
- stringAt(asRecord(value.routing), "status"),
376
- ].filter((status) => Boolean(status));
377
- return statuses.join("/") || "unknown";
378
- }
379
- function resultOutputId(result) {
380
- const value = asRecord(result);
381
- const outputId = stringAt(value, "outputId");
382
- if (outputId) {
383
- return outputId;
384
- }
385
- return stringAt(asRecord(value?.recovery), "outputId") ?? "";
386
- }
387
- function resultRecoveryHint(result) {
388
- const value = asRecord(result);
389
- return stringAt(asRecord(value?.recovery), "how") ?? "";
390
- }
391
- function resultEvidenceLocations(result) {
392
- const value = asRecord(result);
393
- const locations = [];
394
- const evidence = Array.isArray(value?.evidence) ? value.evidence : [];
395
- for (const packet of evidence) {
396
- const record = asRecord(packet);
397
- if (!record) {
398
- continue;
399
- }
400
- const path =
401
- stringAt(record, "path") ??
402
- stringAt(asRecord(record.source), "path") ??
403
- stringAt(asRecord(record.source), "outputId") ??
404
- "evidence";
405
- const lines = stringAt(record, "lines");
406
- locations.push(lines ? `${path}:${lines}` : path);
407
- }
408
- const importantLines = Array.isArray(value?.importantLines) ? value.importantLines : [];
409
- for (const line of importantLines) {
410
- const record = asRecord(line);
411
- if (!record) {
412
- continue;
413
- }
414
- const stream = stringAt(record, "stream") ?? "stream";
415
- const linesValue = stringAt(record, "lines") ?? "?";
416
- locations.push(`${stream}:${linesValue}`);
417
- }
418
- return locations;
419
- }
420
- function stringAt(record, key) {
421
- const value = record?.[key];
422
- return typeof value === "string" ? value : undefined;
423
- }
424
- function asRecord(value) {
425
- if (value && typeof value === "object" && !Array.isArray(value)) {
426
- return value;
427
- }
428
- return undefined;
429
- }
430
- async function createTempDir(prefix) {
431
- const path = await mkdtemp(resolve(tmpdir(), prefix));
432
- return {
433
- path,
434
- cleanup: async () => {
435
- await rm(path, { recursive: true, force: true });
436
- },
437
- };
438
- }
439
- function byteLength(value) {
440
- return Buffer.byteLength(value, "utf8");
441
- }
442
- function defaultReportPath() {
443
- return resolve(process.cwd(), "router/evals/reports/context-saving-native-tools-baseline-1-report.md");
444
- }
445
- async function runCli() {
446
- const { reportPath, jsonReportPath } = parseBenchmarkCliArgs(process.argv.slice(2), {
447
- reportPath: defaultReportPath(),
448
- });
449
- const report = await runContextSavingBaseline();
450
- const reports = await writeContextSavingBaselineReport(report, reportPath, {
451
- jsonReportPath: jsonReportPath === undefined ? defaultJsonRunReportPath(reportPath) : jsonReportPath,
452
- });
453
- const shortId = createHash("sha256").update(JSON.stringify(report.summary)).digest("hex").slice(0, 8);
454
- console.log(
455
- `Freeflow context-saving baseline ${shortId}: ${report.summary.factsPreserved}/${report.summary.fixtures} facts preserved, ${report.summary.recoveryAvailable}/${report.summary.fixtures} recoverable`,
456
- );
457
- console.log(`Markdown report: ${reports.markdown}`);
458
- if (reports.json) {
459
- console.log(`JSON run data: ${reports.json}`);
460
- }
461
- if (
462
- report.summary.factsPreserved !== report.summary.fixtures ||
463
- report.summary.recoveryAvailable !== report.summary.fixtures
464
- ) {
465
- process.exitCode = 1;
466
- }
467
- }
468
- if (process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
469
- await runCli();
470
- }
@@ -1,103 +0,0 @@
1
- import { type ExperimentalIndexLoadMode } from "../experiments/local-index.js";
2
- export interface RunIndexBenchmarksOptions {
3
- iterations?: number;
4
- generatedAt?: string;
5
- }
6
- export interface IndexBenchmarkReport {
7
- generatedAt: string;
8
- iterations: number;
9
- summary: IndexBenchmarkSummary;
10
- fixtures: IndexBenchmarkFixtureResult[];
11
- }
12
- export interface IndexBenchmarkSummary {
13
- fixtures: number;
14
- modeResults: number;
15
- scannerDefault: boolean;
16
- indexAdopted: boolean;
17
- ftsCandidate: FtsCandidateStatus;
18
- scanner: IndexModeSummary;
19
- index: IndexModeSummary;
20
- fts: IndexModeSummary;
21
- hybrid: IndexModeSummary;
22
- generatedFalsePositiveCount: number;
23
- coldBuildMs: LatencySummary;
24
- warmQueryMs: LatencySummary;
25
- staleRefreshMs: LatencySummary;
26
- }
27
- export interface FtsCandidateStatus {
28
- available: boolean;
29
- engine: "none" | "fts5-bm25-trigram";
30
- reason: string;
31
- }
32
- export interface IndexModeSummary {
33
- passed: number;
34
- failed: number;
35
- skipped: number;
36
- pathCorrect: number;
37
- spanCorrect: number;
38
- excerptComplete: number;
39
- recallAtK: number;
40
- totalRawBytes: number;
41
- totalContextBytes: number;
42
- weightedContextReductionPercent: number;
43
- }
44
- export interface LatencySummary {
45
- p50: number;
46
- p95: number;
47
- }
48
- export interface IndexBenchmarkFixtureResult {
49
- id: string;
50
- title: string;
51
- expected: IndexBenchmarkExpected;
52
- results: IndexBenchmarkModeResult[];
53
- }
54
- export interface IndexBenchmarkExpected {
55
- path: string;
56
- lines?: string;
57
- requiredExcerpt: string[];
58
- }
59
- export interface IndexBenchmarkModeResult {
60
- mode: IndexBenchmarkMode;
61
- toolPathUsed: string;
62
- skipped: boolean;
63
- skipReason?: string;
64
- rawBytes: number;
65
- contextBytes: number;
66
- contextReductionPercent: number;
67
- latencyMs: LatencySummary;
68
- buildMs?: number;
69
- queryMs?: number;
70
- indexMode?: ExperimentalIndexLoadMode;
71
- actualPath?: string;
72
- actualLines?: string;
73
- candidatePaths: string[];
74
- excerpt: string;
75
- correctness: IndexCorrectnessResult;
76
- notes: string[];
77
- }
78
- export interface IndexCorrectnessResult {
79
- passed: boolean;
80
- pathCorrect: boolean;
81
- spanCorrect: boolean;
82
- excerptComplete: boolean;
83
- recallAtK: boolean;
84
- generatedFalsePositive: boolean;
85
- }
86
- type IndexBenchmarkMode =
87
- "scanner-default" | "index-cold" | "index-warm" | "index-stale-refresh" | "fts5-bm25-trigram" | "hybrid-warm";
88
- export declare function runIndexBenchmarks(options?: RunIndexBenchmarksOptions): Promise<IndexBenchmarkReport>;
89
- export declare function renderIndexBenchmarkReport(report: IndexBenchmarkReport): string;
90
- export declare function writeIndexBenchmarkReport(report: IndexBenchmarkReport, reportPath: string): Promise<void>;
91
- export declare function writeIndexBenchmarkJsonReport(report: IndexBenchmarkReport, reportPath: string): Promise<void>;
92
- export interface WriteIndexBenchmarkReportsOptions {
93
- jsonReportPath?: string | false;
94
- }
95
- export declare function writeIndexBenchmarkReports(
96
- report: IndexBenchmarkReport,
97
- markdownReportPath: string,
98
- options?: WriteIndexBenchmarkReportsOptions,
99
- ): Promise<{
100
- markdown: string;
101
- json?: string;
102
- }>;
103
- export {};