@hassangameryt/freeflow 0.5.0 → 0.7.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 (301) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +2 -2
  3. package/.codex-plugin/plugin.json +4 -5
  4. package/README.md +141 -163
  5. package/capabilities/cognitive-routing/SKILL.md +387 -0
  6. package/capabilities/context-virtualization/SKILL.md +103 -0
  7. package/capabilities/conversation-history/SKILL.md +53 -0
  8. package/command-surface.json +6 -37
  9. package/hooks/freeflow-runtime-context.mjs +50 -541
  10. package/hooks/hooks.json +1 -26
  11. package/hooks/tests/check-runtime-context-hook.sh +114 -308
  12. package/package.json +27 -17
  13. package/pi-extension/dist/cognitive-routing/commands.js +96 -0
  14. package/pi-extension/dist/cognitive-routing/config.js +232 -0
  15. package/pi-extension/dist/cognitive-routing/controller.js +1292 -0
  16. package/pi-extension/dist/cognitive-routing/history.js +451 -0
  17. package/pi-extension/dist/cognitive-routing/host.js +188 -0
  18. package/pi-extension/dist/cognitive-routing/pi-routing-session.js +414 -0
  19. package/pi-extension/dist/cognitive-routing/pi-session-control.js +320 -0
  20. package/pi-extension/dist/cognitive-routing/runtime.js +43 -0
  21. package/pi-extension/dist/cognitive-routing/tool.js +212 -0
  22. package/pi-extension/dist/cognitive-routing/types.js +6 -0
  23. package/pi-extension/dist/context-virtualization/commands.js +89 -0
  24. package/pi-extension/dist/context-virtualization/projector.js +42 -0
  25. package/pi-extension/dist/context-virtualization/runtime.js +356 -0
  26. package/pi-extension/dist/context-virtualization/state.js +57 -0
  27. package/pi-extension/dist/context-virtualization/types.js +10 -0
  28. package/pi-extension/dist/conversation-history/passages.js +66 -0
  29. package/pi-extension/dist/conversation-history/ranking.js +105 -0
  30. package/pi-extension/dist/conversation-history/runtime.js +226 -0
  31. package/pi-extension/dist/conversation-history/search.js +56 -0
  32. package/pi-extension/dist/conversation-history/types.js +1 -0
  33. package/pi-extension/dist/freeflow-context/resolver.js +120 -0
  34. package/pi-extension/dist/freeflow-context/runtime.js +80 -0
  35. package/pi-extension/dist/freeflow-context/source-projector.js +95 -0
  36. package/pi-extension/dist/freeflow-context/tool.js +308 -0
  37. package/pi-extension/dist/freeflow-context/types.js +12 -0
  38. package/pi-extension/dist/freeflow-context/visibility.js +28 -0
  39. package/pi-extension/dist/index.js +564 -129
  40. package/pi-extension/dist/runtime/runtime-context.js +357 -470
  41. package/pi-extension/dist/runtime/runtime-identity.js +5 -0
  42. package/pi-extension/dist/settings/settings-tui.js +78 -0
  43. package/pi-extension/dist/settings/settings-ui.js +572 -826
  44. package/pi-extension/dist/ui/text-component.js +57 -0
  45. package/pi-extension/src/cognitive-routing/commands.ts +129 -0
  46. package/pi-extension/src/cognitive-routing/config.ts +303 -0
  47. package/pi-extension/src/cognitive-routing/controller.ts +1628 -0
  48. package/pi-extension/src/cognitive-routing/history.ts +650 -0
  49. package/pi-extension/src/cognitive-routing/host.ts +266 -0
  50. package/pi-extension/src/cognitive-routing/pi-routing-session.ts +538 -0
  51. package/pi-extension/src/cognitive-routing/pi-session-control.ts +444 -0
  52. package/pi-extension/src/cognitive-routing/runtime.ts +57 -0
  53. package/pi-extension/src/cognitive-routing/tool.ts +273 -0
  54. package/pi-extension/src/cognitive-routing/types.ts +89 -0
  55. package/pi-extension/src/context-virtualization/commands.ts +111 -0
  56. package/pi-extension/src/context-virtualization/projector.ts +62 -0
  57. package/pi-extension/src/context-virtualization/runtime.ts +406 -0
  58. package/pi-extension/src/context-virtualization/state.ts +79 -0
  59. package/pi-extension/src/context-virtualization/types.ts +92 -0
  60. package/pi-extension/src/conversation-history/passages.ts +81 -0
  61. package/pi-extension/src/conversation-history/ranking.ts +155 -0
  62. package/pi-extension/src/conversation-history/runtime.ts +250 -0
  63. package/pi-extension/src/conversation-history/search.ts +79 -0
  64. package/pi-extension/src/conversation-history/types.ts +31 -0
  65. package/pi-extension/src/freeflow-context/resolver.ts +139 -0
  66. package/pi-extension/src/freeflow-context/runtime.ts +100 -0
  67. package/pi-extension/src/freeflow-context/source-projector.ts +106 -0
  68. package/pi-extension/src/freeflow-context/tool.ts +360 -0
  69. package/pi-extension/src/freeflow-context/types.ts +70 -0
  70. package/pi-extension/src/freeflow-context/visibility.ts +53 -0
  71. package/pi-extension/src/index.ts +597 -135
  72. package/pi-extension/src/runtime/runtime-context.ts +373 -491
  73. package/pi-extension/src/runtime/runtime-identity.ts +8 -0
  74. package/pi-extension/src/settings/settings-tui.ts +93 -0
  75. package/pi-extension/src/settings/settings-ui.ts +679 -910
  76. package/pi-extension/src/ui/text-component.ts +66 -0
  77. package/pi-extension/tests/cognitive-routing/commands.test.js +134 -0
  78. package/pi-extension/tests/cognitive-routing/controller.test.js +1128 -0
  79. package/pi-extension/tests/cognitive-routing/extension-lifecycle.test.js +1142 -0
  80. package/pi-extension/tests/cognitive-routing/history.test.js +274 -0
  81. package/pi-extension/tests/cognitive-routing/host-fixture.js +4 -0
  82. package/pi-extension/tests/cognitive-routing/host-identity.test.js +63 -0
  83. package/pi-extension/tests/cognitive-routing/pi-normal-lifecycle.test.js +434 -0
  84. package/pi-extension/tests/cognitive-routing/pi-session-control.test.js +174 -0
  85. package/pi-extension/tests/cognitive-routing/pi-session-history.test.js +91 -0
  86. package/pi-extension/tests/cognitive-routing/profile-resolution.test.js +279 -0
  87. package/pi-extension/tests/cognitive-routing/tool.test.js +230 -0
  88. package/pi-extension/tests/context-virtualization/extension.test.js +749 -0
  89. package/pi-extension/tests/context-virtualization/projector.test.js +110 -0
  90. package/pi-extension/tests/context-virtualization/runtime.test.js +216 -0
  91. package/pi-extension/tests/conversation-history/runtime.test.js +98 -0
  92. package/pi-extension/tests/conversation-history/search.test.js +97 -0
  93. package/pi-extension/tests/integration/mode-free-core.test.js +218 -0
  94. package/pi-extension/tests/integration/pi-extension.test.js +532 -3701
  95. package/pi-extension/tests/integration/prompt-architecture.test.js +350 -0
  96. package/pi-extension/tests/integration/unaffected-regressions.test.js +411 -0
  97. package/runtime/prompts/cognitive-routing.md +10 -0
  98. package/runtime/prompts/context-virtualization.md +3 -0
  99. package/runtime/prompts/conversation-history.md +3 -0
  100. package/runtime/prompts/core.md +84 -0
  101. package/runtime/prompts/interaction-contract.md +11 -0
  102. package/skills/action-selection/SKILL.md +140 -0
  103. package/skills/action-selection/references/trajectory-stalls.md +71 -0
  104. package/skills/bypass/SKILL.md +109 -38
  105. package/skills/commit-work/SKILL.md +94 -55
  106. package/skills/commit-work/references/git-state-edges.md +94 -0
  107. package/skills/commit-work/references/simple-push.md +92 -0
  108. package/skills/commit-work/references/staging-decisions.md +79 -46
  109. package/skills/decision-gate/SKILL.md +80 -22
  110. package/skills/design-for-depth/SKILL.md +206 -60
  111. package/skills/design-for-depth/references/design-pressure-signals.md +108 -240
  112. package/skills/design-for-depth/references/interface-design-loop.md +77 -97
  113. package/skills/design-for-depth/references/module-and-dependency-design.md +147 -0
  114. package/skills/design-for-depth/references/software-design-philosophy.md +128 -174
  115. package/skills/design-for-depth/references/state-and-failure-boundaries.md +136 -0
  116. package/skills/diagnose-failure/SKILL.md +200 -48
  117. package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +18 -6
  118. package/skills/diagnose-failure/references/{flaky-and-performance.md → flaky-and-performance-diagnosis.md} +13 -5
  119. package/skills/discuss/SKILL.md +119 -65
  120. package/skills/discuss/references/discussion-continuity.md +123 -0
  121. package/skills/evaluate-skill/SKILL.md +166 -52
  122. package/skills/evaluate-skill/references/{definition-schema.md → evaluation-definition-schema.md} +43 -3
  123. package/skills/evaluate-skill/references/evaluation-design.md +56 -30
  124. package/skills/evaluate-skill/references/execution-and-evidence.md +8 -3
  125. package/skills/evaluate-skill/references/review-and-revision.md +62 -21
  126. package/skills/evaluate-skill/scripts/lib/definitions.mjs +114 -3
  127. package/skills/evaluate-skill/scripts/lib/grade-interaction.mjs +156 -1
  128. package/skills/evaluate-skill/scripts/lib/grade.mjs +9 -1
  129. package/skills/evaluate-skill/scripts/lib/pi.mjs +147 -32
  130. package/skills/evaluate-skill/scripts/lib/rpc.mjs +4 -4
  131. package/skills/evaluate-skill/scripts/lib/runner.mjs +36 -14
  132. package/skills/evaluate-skill/scripts/lib/sandbox.mjs +92 -0
  133. package/skills/evaluate-skill/scripts/pi-guard.mjs +1 -1
  134. package/skills/evaluate-skill/scripts/pi-observer.mjs +66 -0
  135. package/skills/evaluate-skill/scripts/skill-eval.mjs +6 -5
  136. package/skills/execute-work/SKILL.md +99 -57
  137. package/skills/execute-work/references/code-practices.md +4 -4
  138. package/skills/execute-work/references/execute-work-edges.md +62 -0
  139. package/skills/finish-branch/SKILL.md +2 -2
  140. package/skills/finish-branch/references/integration-options.md +1 -1
  141. package/skills/handoff/SKILL.md +3 -3
  142. package/skills/launch-work/SKILL.md +1 -1
  143. package/skills/launch-work/references/launch-readiness.md +2 -2
  144. package/skills/migration-work/SKILL.md +2 -2
  145. package/skills/migration-work/references/migration-lifecycle.md +1 -1
  146. package/skills/release-work/SKILL.md +1 -1
  147. package/skills/release-work/references/release-evidence.md +1 -1
  148. package/skills/review-artifact/SKILL.md +129 -66
  149. package/skills/review-artifact/references/adjudicate-artifact-review.md +101 -0
  150. package/skills/review-artifact/references/independent-artifact-reviewer-contract.md +159 -0
  151. package/skills/review-work/SKILL.md +113 -68
  152. package/skills/review-work/references/adjudicate-work-review.md +97 -0
  153. package/skills/review-work/references/independent-work-reviewer-contract.md +139 -0
  154. package/skills/review-work/references/security-risk-lens.md +18 -16
  155. package/skills/setup-freeflow/SKILL.md +16 -17
  156. package/skills/setup-freeflow/references/activation-contract.md +24 -30
  157. package/skills/setup-freeflow/references/host-setup.md +6 -7
  158. package/skills/simplify-code/SKILL.md +97 -39
  159. package/skills/simplify-code/references/simplification-patterns.md +1 -1
  160. package/skills/tdd/SKILL.md +100 -53
  161. package/skills/tdd/references/test-design.md +3 -3
  162. package/skills/track-work/SKILL.md +195 -58
  163. package/skills/track-work/references/working-record-format.md +515 -0
  164. package/skills/track-work/scripts/lib/document.mjs +713 -0
  165. package/skills/track-work/scripts/lib/format.mjs +166 -0
  166. package/skills/track-work/scripts/lib/store.mjs +233 -0
  167. package/skills/track-work/scripts/lib/transitions.mjs +790 -0
  168. package/skills/track-work/scripts/lib/views.mjs +40 -0
  169. package/skills/track-work/scripts/working-record.mjs +316 -0
  170. package/skills/verify-work/SKILL.md +57 -19
  171. package/skills/verify-work/references/browser-runtime-evidence.md +2 -2
  172. package/skills/verify-work/references/integration-evidence.md +1 -7
  173. package/skills/verify-work/references/performance-evidence.md +2 -2
  174. package/skills/workflow/SKILL.md +137 -55
  175. package/skills/workflow/references/domain-skill-composition.md +26 -40
  176. package/skills/write-plan/SKILL.md +1 -1
  177. package/skills/write-skill/SKILL.md +218 -61
  178. package/skills/write-skill/references/activation-boundaries.md +63 -21
  179. package/skills/write-skill/references/agent-first-instructions.md +61 -27
  180. package/skills/write-skill/references/progressive-disclosure.md +97 -33
  181. package/skills/write-skill/references/skill-dependency-graphs.md +190 -0
  182. package/capabilities/output-router/SKILL.md +0 -206
  183. package/capabilities/output-router/references/safety-policy.md +0 -40
  184. package/capabilities/output-router/references/setup.md +0 -110
  185. package/pi-extension/dist/output-router/host-producer-identification.js +0 -232
  186. package/pi-extension/dist/output-router/native-safety-net.js +0 -216
  187. package/pi-extension/dist/output-router/observed-tool-routing.js +0 -122
  188. package/pi-extension/dist/output-router/renderers.js +0 -1023
  189. package/pi-extension/dist/output-router/router-tools.js +0 -554
  190. package/pi-extension/dist/output-router/schemas.js +0 -383
  191. package/pi-extension/dist/output-router/status.js +0 -744
  192. package/pi-extension/dist/output-router/utils.js +0 -502
  193. package/pi-extension/src/output-router/host-producer-identification.ts +0 -256
  194. package/pi-extension/src/output-router/native-safety-net.ts +0 -248
  195. package/pi-extension/src/output-router/observed-tool-routing.ts +0 -134
  196. package/pi-extension/src/output-router/renderers.ts +0 -1108
  197. package/pi-extension/src/output-router/router-tools.ts +0 -579
  198. package/pi-extension/src/output-router/schemas.ts +0 -387
  199. package/pi-extension/src/output-router/status.ts +0 -791
  200. package/pi-extension/src/output-router/utils.ts +0 -554
  201. package/pi-extension/tests/output-router/observed-producers.test.js +0 -132
  202. package/pi-extension/tests/output-router/search.test.js +0 -722
  203. package/router/dist/benchmarks/benchmark-harness.d.ts +0 -35
  204. package/router/dist/benchmarks/benchmark-harness.js +0 -92
  205. package/router/dist/benchmarks/benchmarks.d.ts +0 -109
  206. package/router/dist/benchmarks/benchmarks.js +0 -979
  207. package/router/dist/benchmarks/codex-qa-benchmarks.d.ts +0 -95
  208. package/router/dist/benchmarks/codex-qa-benchmarks.js +0 -500
  209. package/router/dist/benchmarks/command-benchmarks.d.ts +0 -143
  210. package/router/dist/benchmarks/command-benchmarks.js +0 -698
  211. package/router/dist/benchmarks/context-mode-normalized-benchmarks.d.ts +0 -82
  212. package/router/dist/benchmarks/context-mode-normalized-benchmarks.js +0 -773
  213. package/router/dist/benchmarks/context-mode-real-deep-benchmark.d.ts +0 -132
  214. package/router/dist/benchmarks/context-mode-real-deep-benchmark.js +0 -1380
  215. package/router/dist/benchmarks/context-saving-baseline.d.ts +0 -60
  216. package/router/dist/benchmarks/context-saving-baseline.js +0 -470
  217. package/router/dist/benchmarks/index-benchmarks.d.ts +0 -103
  218. package/router/dist/benchmarks/index-benchmarks.js +0 -862
  219. package/router/dist/benchmarks/storage-policy-benchmarks.d.ts +0 -101
  220. package/router/dist/benchmarks/storage-policy-benchmarks.js +0 -618
  221. package/router/dist/benchmarks/vault-index-benchmarks.d.ts +0 -56
  222. package/router/dist/benchmarks/vault-index-benchmarks.js +0 -322
  223. package/router/dist/config/config.d.ts +0 -103
  224. package/router/dist/config/config.js +0 -632
  225. package/router/dist/config/router-contract.d.ts +0 -10
  226. package/router/dist/config/router-contract.js +0 -54
  227. package/router/dist/config/schema.d.ts +0 -27
  228. package/router/dist/config/schema.js +0 -648
  229. package/router/dist/config/types.d.ts +0 -573
  230. package/router/dist/config/types.js +0 -41
  231. package/router/dist/evidence/bounded-evidence.d.ts +0 -40
  232. package/router/dist/evidence/bounded-evidence.js +0 -323
  233. package/router/dist/evidence/evidence-range-selector.d.ts +0 -24
  234. package/router/dist/evidence/evidence-range-selector.js +0 -232
  235. package/router/dist/evidence/evidence-search.d.ts +0 -27
  236. package/router/dist/evidence/evidence-search.js +0 -490
  237. package/router/dist/evidence/evidence.d.ts +0 -38
  238. package/router/dist/evidence/evidence.js +0 -200
  239. package/router/dist/evidence/failure-contracts.d.ts +0 -37
  240. package/router/dist/evidence/failure-contracts.js +0 -166
  241. package/router/dist/evidence/line-ranges.d.ts +0 -24
  242. package/router/dist/evidence/line-ranges.js +0 -22
  243. package/router/dist/experiments/local-index.d.ts +0 -64
  244. package/router/dist/experiments/local-index.js +0 -581
  245. package/router/dist/index.d.ts +0 -30
  246. package/router/dist/index.js +0 -32
  247. package/router/dist/local/local-traversal.d.ts +0 -18
  248. package/router/dist/local/local-traversal.js +0 -334
  249. package/router/dist/processing/engine.d.ts +0 -132
  250. package/router/dist/processing/engine.js +0 -533
  251. package/router/dist/processing/reducers.d.ts +0 -280
  252. package/router/dist/processing/reducers.js +0 -1673
  253. package/router/dist/processing/renderers.d.ts +0 -31
  254. package/router/dist/processing/renderers.js +0 -195
  255. package/router/dist/processing/scripts.d.ts +0 -91
  256. package/router/dist/processing/scripts.js +0 -386
  257. package/router/dist/repo/repo-traversal.d.ts +0 -18
  258. package/router/dist/repo/repo-traversal.js +0 -245
  259. package/router/dist/routing/observed-reducers.d.ts +0 -41
  260. package/router/dist/routing/observed-reducers.js +0 -661
  261. package/router/dist/routing/observed-routing.d.ts +0 -26
  262. package/router/dist/routing/observed-routing.js +0 -378
  263. package/router/dist/routing/parsers.d.ts +0 -16
  264. package/router/dist/routing/parsers.js +0 -521
  265. package/router/dist/routing/run-filters.d.ts +0 -60
  266. package/router/dist/routing/run-filters.js +0 -238
  267. package/router/dist/routing/run-reducers.d.ts +0 -49
  268. package/router/dist/routing/run-reducers.js +0 -122
  269. package/router/dist/sandbox/adapter-roots.d.ts +0 -46
  270. package/router/dist/sandbox/adapter-roots.js +0 -66
  271. package/router/dist/sandbox/eryx-python-adapter.d.ts +0 -13
  272. package/router/dist/sandbox/eryx-python-adapter.js +0 -868
  273. package/router/dist/sandbox/jq-wasm-adapter.d.ts +0 -9
  274. package/router/dist/sandbox/jq-wasm-adapter.js +0 -429
  275. package/router/dist/sandbox/quickjs-wasi-adapter.d.ts +0 -13
  276. package/router/dist/sandbox/quickjs-wasi-adapter.js +0 -384
  277. package/router/dist/sandbox/script-sandbox.d.ts +0 -134
  278. package/router/dist/sandbox/script-sandbox.js +0 -337
  279. package/router/dist/setup/script-transform-adapters.d.ts +0 -32
  280. package/router/dist/setup/script-transform-adapters.js +0 -278
  281. package/router/dist/tools/batch.d.ts +0 -33
  282. package/router/dist/tools/batch.js +0 -586
  283. package/router/dist/tools/run.d.ts +0 -62
  284. package/router/dist/tools/run.js +0 -1304
  285. package/router/dist/tools/search.d.ts +0 -66
  286. package/router/dist/tools/search.js +0 -1364
  287. package/router/dist/transform/engine.d.ts +0 -168
  288. package/router/dist/transform/engine.js +0 -2072
  289. package/router/dist/vault/vault-index.d.ts +0 -125
  290. package/router/dist/vault/vault-index.js +0 -416
  291. package/router/dist/vault/vault.d.ts +0 -138
  292. package/router/dist/vault/vault.js +0 -630
  293. package/runtime/interaction-contract.md +0 -16
  294. package/skills/discuss/references/checkpoints.md +0 -66
  295. package/skills/execute-work/references/execution-loop.md +0 -77
  296. package/skills/mode-contract/SKILL.md +0 -104
  297. package/skills/review-artifact/references/reviewer-prompt.md +0 -148
  298. package/skills/review-work/references/reviewer-prompt.md +0 -134
  299. package/skills/track-work/references/working-record-schema.md +0 -378
  300. package/skills/workflow/references/workflow-loop.md +0 -92
  301. /package/skills/handoff/references/{templates.md → handoff-templates.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 {};