@hassangameryt/freeflow 0.7.3 → 0.9.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 (426) hide show
  1. package/.agents/plugins/marketplace.json +2 -2
  2. package/.claude-plugin/marketplace.json +1 -1
  3. package/.claude-plugin/plugin.json +2 -2
  4. package/.codex-plugin/plugin.json +3 -3
  5. package/.cursor-plugin/plugin.json +1 -1
  6. package/NOTICE +14 -0
  7. package/README.md +101 -159
  8. package/capabilities/cognitive-routing/SKILL.md +47 -210
  9. package/capabilities/cognitive-routing/references/coordinator.md +163 -0
  10. package/capabilities/cognitive-routing/references/worker.md +38 -0
  11. package/capabilities/compaction/SKILL.md +49 -0
  12. package/capabilities/compaction/references/summary-format.md +250 -0
  13. package/capabilities/messaging/SKILL.md +49 -0
  14. package/capabilities/task-memory/SKILL.md +87 -0
  15. package/command-surface.json +8 -52
  16. package/gemini-extension.json +1 -1
  17. package/hooks/claude/hooks.json +13 -3
  18. package/hooks/codex/hooks.json +2 -1
  19. package/hooks/shared/runtime-context.mjs +73 -83
  20. package/licenses/Apache-2.0.txt +55 -0
  21. package/package.json +42 -12
  22. package/pi-extension/README.md +41 -0
  23. package/pi-extension/dist/ask-user/ask.js +108 -0
  24. package/pi-extension/dist/ask-user/form.js +250 -0
  25. package/pi-extension/dist/ask-user/questions.js +66 -0
  26. package/pi-extension/dist/ask-user/tool.js +124 -0
  27. package/pi-extension/dist/cognitive-routing/assembler.js +417 -0
  28. package/pi-extension/dist/cognitive-routing/bootstrap.js +90 -0
  29. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/config.js +8 -6
  30. package/pi-extension/dist/cognitive-routing/economics.js +45 -0
  31. package/pi-extension/dist/cognitive-routing/event-schema.js +388 -0
  32. package/pi-extension/dist/{session-sources/events.js → cognitive-routing/event-store.js} +107 -41
  33. package/pi-extension/dist/cognitive-routing/gate.js +256 -0
  34. package/pi-extension/dist/cognitive-routing/handlers.js +901 -0
  35. package/pi-extension/dist/cognitive-routing/handoffs.js +350 -0
  36. package/pi-extension/dist/cognitive-routing/model-control.js +476 -0
  37. package/pi-extension/dist/cognitive-routing/projection.js +520 -0
  38. package/pi-extension/dist/cognitive-routing/provenance.js +83 -0
  39. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/render.js +15 -15
  40. package/pi-extension/dist/cognitive-routing/runtime.js +398 -0
  41. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/schemas.js +47 -11
  42. package/pi-extension/dist/cognitive-routing/session.js +223 -0
  43. package/pi-extension/dist/{session-sources → cognitive-routing}/sources.js +126 -87
  44. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/state.js +55 -386
  45. package/pi-extension/dist/cognitive-routing/status.js +81 -0
  46. package/pi-extension/dist/cognitive-routing/tools.js +74 -0
  47. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/types.js +14 -11
  48. package/pi-extension/dist/compaction/carry.js +205 -0
  49. package/pi-extension/dist/compaction/config.js +24 -0
  50. package/pi-extension/dist/compaction/controller.js +494 -0
  51. package/pi-extension/dist/compaction/harness.js +93 -0
  52. package/pi-extension/dist/compaction/results.js +159 -0
  53. package/pi-extension/dist/compaction/thresholds.js +35 -0
  54. package/pi-extension/dist/compaction/tool.js +57 -0
  55. package/pi-extension/dist/host/branch.js +13 -0
  56. package/pi-extension/dist/host/canonical.js +12 -0
  57. package/pi-extension/dist/host/catalog.js +62 -0
  58. package/pi-extension/dist/host/config-validation.js +233 -0
  59. package/pi-extension/dist/host/config.js +361 -0
  60. package/pi-extension/dist/host/inbound.js +142 -0
  61. package/pi-extension/dist/host/projection-tags.js +60 -0
  62. package/pi-extension/dist/host/prompts.js +93 -0
  63. package/pi-extension/dist/{session-sources → host}/read-only-session.js +117 -1
  64. package/pi-extension/dist/{runtime → host}/request-history.js +125 -39
  65. package/pi-extension/dist/host/rows.js +25 -0
  66. package/pi-extension/dist/host/runtime-state.js +204 -0
  67. package/pi-extension/dist/host/section-keeper.js +85 -0
  68. package/pi-extension/dist/host/settings/freeflow-command.js +2323 -0
  69. package/pi-extension/dist/{settings/settings-tui.js → host/settings/settings-view.js} +205 -73
  70. package/pi-extension/dist/host/staging.js +28 -0
  71. package/pi-extension/dist/host/status.js +115 -0
  72. package/pi-extension/dist/index.js +1004 -188
  73. package/pi-extension/dist/messaging/config.js +27 -0
  74. package/pi-extension/dist/messaging/messaging.js +398 -0
  75. package/pi-extension/dist/messaging/registry.js +57 -0
  76. package/pi-extension/dist/messaging/render.js +90 -0
  77. package/pi-extension/dist/messaging/tools.js +109 -0
  78. package/pi-extension/dist/messaging/transport.js +101 -0
  79. package/pi-extension/dist/provider-support/cache/anchor.js +21 -0
  80. package/pi-extension/dist/provider-support/cache/anthropic.js +102 -0
  81. package/pi-extension/dist/provider-support/cache/health.js +73 -0
  82. package/pi-extension/dist/provider-support/cache/index.js +58 -0
  83. package/pi-extension/dist/provider-support/cache/keepalive.js +222 -0
  84. package/pi-extension/dist/provider-support/cache/monitor.js +17 -0
  85. package/pi-extension/dist/provider-support/cache/openai-responses.js +48 -0
  86. package/pi-extension/dist/provider-support/effort.js +13 -0
  87. package/pi-extension/dist/provider-support/index.js +44 -3
  88. package/pi-extension/dist/provider-support/{astra → openai}/adapter.js +46 -29
  89. package/pi-extension/dist/provider-support/{astra → openai}/history.js +10 -8
  90. package/pi-extension/dist/provider-support/{astra → openai}/index.js +8 -4
  91. package/pi-extension/dist/provider-support/{astra → openai}/session-state.js +29 -38
  92. package/pi-extension/dist/provider-support/routes.js +17 -0
  93. package/pi-extension/dist/task-memory/config.js +49 -0
  94. package/pi-extension/dist/task-memory/registry.js +119 -0
  95. package/pi-extension/dist/task-memory/render.js +107 -0
  96. package/pi-extension/dist/task-memory/runtime.js +994 -0
  97. package/pi-extension/dist/task-memory/tool.js +233 -0
  98. package/pi-extension/dist/tool-execution/apply-patch/grammar.js +23 -0
  99. package/pi-extension/dist/tool-execution/apply-patch/match.js +38 -0
  100. package/pi-extension/dist/tool-execution/apply-patch/parser.js +177 -0
  101. package/pi-extension/dist/tool-execution/apply-patch/plan.js +201 -0
  102. package/pi-extension/dist/tool-execution/apply-patch/tool.js +84 -0
  103. package/pi-extension/dist/tool-execution/background.js +430 -0
  104. package/pi-extension/dist/tool-execution/bash-guard.js +23 -0
  105. package/pi-extension/dist/tool-execution/config.js +33 -0
  106. package/pi-extension/dist/tool-execution/edit-messages.js +120 -0
  107. package/pi-extension/dist/tool-execution/file-state.js +138 -0
  108. package/pi-extension/dist/tool-execution/file-tracking.js +163 -0
  109. package/pi-extension/dist/tool-execution/guidance-notices.js +124 -0
  110. package/pi-extension/dist/tool-execution/prompt.js +54 -0
  111. package/pi-extension/dist/tool-execution/skill-reads.js +143 -0
  112. package/pi-extension/dist/tool-execution/tools.js +16 -0
  113. package/pi-extension/freeflow/README.md +9 -0
  114. package/runtime/prompts/cognitive-routing.md +4 -4
  115. package/runtime/prompts/core.md +29 -72
  116. package/runtime/prompts/interaction-contract.md +18 -8
  117. package/runtime/prompts/tool-execution.md +25 -0
  118. package/runtime/prompts/working-method.md +25 -0
  119. package/skills/deliver-work/SKILL.md +76 -0
  120. package/skills/deliver-work/references/branch-closeout.md +134 -0
  121. package/skills/deliver-work/references/commit.md +83 -0
  122. package/skills/deliver-work/references/launch.md +94 -0
  123. package/skills/deliver-work/references/release.md +85 -0
  124. package/skills/deliver-work/scripts/commit-state.mjs +139 -0
  125. package/skills/deliver-work/scripts/delivery-state.mjs +107 -0
  126. package/skills/deliver-work/scripts/lib/git-state.mjs +178 -0
  127. package/skills/deliver-work/scripts/push-route.mjs +122 -0
  128. package/skills/deliver-work/scripts/release-preflight.mjs +177 -0
  129. package/skills/discuss-work/SKILL.md +148 -0
  130. package/skills/{discuss → discuss-work}/references/discussion-continuity.md +13 -50
  131. package/skills/discuss-work/references/learning-action.md +36 -0
  132. package/skills/discuss-work/scripts/choices.mjs +101 -0
  133. package/skills/discuss-work/scripts/lib/choices.mjs +159 -0
  134. package/skills/evaluate-behavior/SKILL.md +107 -0
  135. package/skills/evaluate-behavior/references/authoring.md +381 -0
  136. package/skills/evaluate-behavior/references/coding-tasks.md +145 -0
  137. package/skills/evaluate-behavior/references/conversations-pipelines-judges.md +177 -0
  138. package/skills/evaluate-behavior/references/design-and-measurement.md +273 -0
  139. package/skills/evaluate-behavior/references/running-and-evidence.md +245 -0
  140. package/skills/evaluate-behavior/scripts/claude-guard.mjs +76 -0
  141. package/skills/evaluate-behavior/scripts/guard-rules.mjs +309 -0
  142. package/skills/evaluate-behavior/scripts/lib/agreement.mjs +90 -0
  143. package/skills/evaluate-behavior/scripts/lib/arms.mjs +55 -0
  144. package/skills/evaluate-behavior/scripts/lib/budget.mjs +87 -0
  145. package/skills/evaluate-behavior/scripts/lib/build-source.mjs +287 -0
  146. package/skills/evaluate-behavior/scripts/lib/clear.mjs +74 -0
  147. package/skills/evaluate-behavior/scripts/lib/container.mjs +395 -0
  148. package/skills/evaluate-behavior/scripts/lib/decision.mjs +418 -0
  149. package/skills/evaluate-behavior/scripts/lib/definitions.mjs +1072 -0
  150. package/skills/evaluate-behavior/scripts/lib/freeflow.mjs +103 -0
  151. package/skills/evaluate-behavior/scripts/lib/grade-command.mjs +591 -0
  152. package/skills/evaluate-behavior/scripts/lib/grade-comparison.mjs +90 -0
  153. package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/grade-interaction.mjs +19 -18
  154. package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/grade-support.mjs +32 -5
  155. package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/grade-workspace.mjs +28 -12
  156. package/skills/evaluate-behavior/scripts/lib/grade.mjs +101 -0
  157. package/skills/evaluate-behavior/scripts/lib/hooks.mjs +98 -0
  158. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/confinement.mjs +196 -0
  159. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/constraints.mjs +111 -0
  160. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/index.mjs +48 -0
  161. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/isolation.mjs +74 -0
  162. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/launch.mjs +123 -0
  163. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/model-call.mjs +73 -0
  164. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/recorder.mjs +178 -0
  165. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/session.mjs +494 -0
  166. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/skills.mjs +81 -0
  167. package/skills/evaluate-behavior/scripts/lib/hosts/index.mjs +31 -0
  168. package/skills/evaluate-behavior/scripts/lib/hosts/names.mjs +3 -0
  169. package/skills/evaluate-behavior/scripts/lib/hosts/pi/confinement.mjs +173 -0
  170. package/skills/evaluate-behavior/scripts/lib/hosts/pi/host.mjs +148 -0
  171. package/skills/evaluate-behavior/scripts/lib/hosts/pi/index.mjs +70 -0
  172. package/skills/evaluate-behavior/scripts/lib/hosts/pi/isolation.mjs +81 -0
  173. package/skills/evaluate-behavior/scripts/lib/hosts/pi/model-call.mjs +79 -0
  174. package/skills/evaluate-behavior/scripts/lib/hosts/pi/process.mjs +241 -0
  175. package/skills/{evaluate-skill/scripts/lib → evaluate-behavior/scripts/lib/hosts/pi}/rpc.mjs +144 -26
  176. package/skills/evaluate-behavior/scripts/lib/identity.mjs +82 -0
  177. package/skills/evaluate-behavior/scripts/lib/judge.mjs +688 -0
  178. package/skills/evaluate-behavior/scripts/lib/metrics.mjs +332 -0
  179. package/skills/evaluate-behavior/scripts/lib/model-call.mjs +17 -0
  180. package/skills/evaluate-behavior/scripts/lib/participants.mjs +616 -0
  181. package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/process.mjs +22 -0
  182. package/skills/evaluate-behavior/scripts/lib/queue.mjs +54 -0
  183. package/skills/evaluate-behavior/scripts/lib/reference.mjs +343 -0
  184. package/skills/evaluate-behavior/scripts/lib/reuse.mjs +277 -0
  185. package/skills/evaluate-behavior/scripts/lib/review.mjs +933 -0
  186. package/skills/evaluate-behavior/scripts/lib/runner.mjs +732 -0
  187. package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/sandbox.mjs +121 -14
  188. package/skills/evaluate-behavior/scripts/lib/scan-shell.mjs +457 -0
  189. package/skills/evaluate-behavior/scripts/lib/scan.mjs +479 -0
  190. package/skills/evaluate-behavior/scripts/lib/seal.mjs +91 -0
  191. package/skills/evaluate-behavior/scripts/lib/shell.mjs +560 -0
  192. package/skills/evaluate-behavior/scripts/lib/source-override.mjs +64 -0
  193. package/skills/evaluate-behavior/scripts/lib/subject-file.mjs +88 -0
  194. package/skills/{evaluate-skill/scripts/lib/pi.mjs → evaluate-behavior/scripts/lib/subject.mjs} +239 -262
  195. package/skills/evaluate-behavior/scripts/lib/task-copy.mjs +124 -0
  196. package/skills/evaluate-behavior/scripts/lib/trials.mjs +524 -0
  197. package/skills/evaluate-behavior/scripts/lib/validity.mjs +68 -0
  198. package/skills/evaluate-behavior/scripts/lib/view-html.mjs +454 -0
  199. package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/view.mjs +218 -11
  200. package/skills/evaluate-behavior/scripts/pi-command-tool.mjs +159 -0
  201. package/skills/evaluate-behavior/scripts/pi-container-route.mjs +23 -0
  202. package/skills/evaluate-behavior/scripts/pi-guard.mjs +77 -0
  203. package/skills/evaluate-behavior/scripts/pi-login-refresh.mjs +31 -0
  204. package/skills/evaluate-behavior/scripts/skill-eval.mjs +586 -0
  205. package/skills/execute-work/SKILL.md +96 -72
  206. package/skills/execute-work/references/code-practices.md +27 -49
  207. package/skills/execute-work/references/design.md +271 -0
  208. package/skills/execute-work/references/diagnose.md +117 -0
  209. package/skills/execute-work/references/migration.md +108 -0
  210. package/skills/execute-work/references/simplify.md +65 -0
  211. package/skills/execute-work/scripts/self-review.mjs +422 -0
  212. package/skills/execute-work/scripts/touch-map.mjs +290 -0
  213. package/skills/review-work/SKILL.md +94 -64
  214. package/skills/review-work/references/adjudication.md +94 -0
  215. package/skills/review-work/references/artifact.md +198 -0
  216. package/skills/review-work/references/evals-and-judges.md +66 -0
  217. package/skills/review-work/references/work.md +177 -0
  218. package/skills/review-work/scripts/check-brief.mjs +128 -0
  219. package/skills/review-work/scripts/review-packet.mjs +233 -0
  220. package/skills/setup-freeflow/SKILL.md +69 -16
  221. package/skills/track-work/SKILL.md +135 -151
  222. package/skills/track-work/references/handoff.md +190 -0
  223. package/skills/track-work/references/projects.md +51 -0
  224. package/skills/track-work/references/working-record-format.md +201 -344
  225. package/skills/track-work/scripts/lib/document.mjs +79 -19
  226. package/skills/track-work/scripts/lib/format.mjs +18 -1
  227. package/skills/track-work/scripts/lib/recover.mjs +254 -0
  228. package/skills/track-work/scripts/lib/registry.mjs +656 -0
  229. package/skills/track-work/scripts/lib/search.mjs +40 -0
  230. package/skills/track-work/scripts/lib/store.mjs +53 -21
  231. package/skills/track-work/scripts/lib/transitions.mjs +79 -4
  232. package/skills/track-work/scripts/lib/views.mjs +50 -1
  233. package/skills/track-work/scripts/working-record.mjs +263 -22
  234. package/skills/verify-work/SKILL.md +64 -47
  235. package/skills/verify-work/references/feature-map.md +120 -0
  236. package/skills/verify-work/references/runtime-evidence.md +203 -0
  237. package/skills/verify-work/references/test-design.md +27 -6
  238. package/skills/verify-work/scripts/test-changes.mjs +246 -0
  239. package/skills/write-docs/SKILL.md +171 -0
  240. package/skills/write-docs/references/documentation-shapes.md +184 -0
  241. package/skills/write-docs/references/spec-and-plan-shapes.md +308 -0
  242. package/skills/write-docs/scripts/artifact-check.mjs +148 -0
  243. package/skills/write-docs/scripts/docs-check.mjs +229 -0
  244. package/skills/write-docs/scripts/plan-lint.mjs +123 -0
  245. package/skills/write-skill/SKILL.md +165 -165
  246. package/skills/write-skill/references/activation-and-wording.md +143 -0
  247. package/skills/write-skill/references/placement-and-dependencies.md +154 -0
  248. package/skills/write-skill/scripts/lib/compare.mjs +701 -0
  249. package/skills/write-skill/scripts/lib/similarity.mjs +56 -0
  250. package/skills/write-skill/scripts/lib/skill-author.mjs +197 -3
  251. package/skills/write-skill/scripts/skill-author.mjs +67 -8
  252. package/capabilities/context-virtualization/SKILL.md +0 -103
  253. package/capabilities/conversation-history/SKILL.md +0 -53
  254. package/hooks/tests/check-host-adapters.test.mjs +0 -82
  255. package/hooks/tests/check-runtime-context-hook.sh +0 -212
  256. package/pi-extension/dist/cognitive-routing-v2/projection.js +0 -330
  257. package/pi-extension/dist/cognitive-routing-v2/runtime.js +0 -2181
  258. package/pi-extension/dist/cognitive-routing-v2/tools.js +0 -60
  259. package/pi-extension/dist/context-virtualization/commands.js +0 -89
  260. package/pi-extension/dist/context-virtualization/projector.js +0 -42
  261. package/pi-extension/dist/context-virtualization/runtime.js +0 -378
  262. package/pi-extension/dist/context-virtualization/state.js +0 -57
  263. package/pi-extension/dist/context-virtualization/types.js +0 -10
  264. package/pi-extension/dist/conversation-history/passages.js +0 -66
  265. package/pi-extension/dist/conversation-history/ranking.js +0 -105
  266. package/pi-extension/dist/conversation-history/runtime.js +0 -226
  267. package/pi-extension/dist/conversation-history/search.js +0 -56
  268. package/pi-extension/dist/conversation-history/types.js +0 -1
  269. package/pi-extension/dist/freeflow-context/resolver.js +0 -120
  270. package/pi-extension/dist/freeflow-context/runtime.js +0 -80
  271. package/pi-extension/dist/freeflow-context/source-projector.js +0 -95
  272. package/pi-extension/dist/freeflow-context/tool.js +0 -314
  273. package/pi-extension/dist/freeflow-context/types.js +0 -12
  274. package/pi-extension/dist/freeflow-context/visibility.js +0 -28
  275. package/pi-extension/dist/integrations/mcp-config.js +0 -29
  276. package/pi-extension/dist/runtime/runtime-context.js +0 -754
  277. package/pi-extension/dist/runtime/runtime-identity.js +0 -5
  278. package/pi-extension/dist/session-sources/provenance.js +0 -32
  279. package/pi-extension/dist/settings/settings-ui.js +0 -1360
  280. package/pi-extension/dist/ui/text-component.js +0 -57
  281. package/pi-extension/src/cognitive-routing-v2/budget.ts +0 -42
  282. package/pi-extension/src/cognitive-routing-v2/config.ts +0 -173
  283. package/pi-extension/src/cognitive-routing-v2/projection.ts +0 -375
  284. package/pi-extension/src/cognitive-routing-v2/render.ts +0 -277
  285. package/pi-extension/src/cognitive-routing-v2/runtime.ts +0 -2241
  286. package/pi-extension/src/cognitive-routing-v2/schemas.ts +0 -180
  287. package/pi-extension/src/cognitive-routing-v2/state.ts +0 -839
  288. package/pi-extension/src/cognitive-routing-v2/tools.ts +0 -62
  289. package/pi-extension/src/cognitive-routing-v2/types.ts +0 -254
  290. package/pi-extension/src/context-virtualization/commands.ts +0 -111
  291. package/pi-extension/src/context-virtualization/projector.ts +0 -62
  292. package/pi-extension/src/context-virtualization/runtime.ts +0 -428
  293. package/pi-extension/src/context-virtualization/state.ts +0 -79
  294. package/pi-extension/src/context-virtualization/types.ts +0 -92
  295. package/pi-extension/src/conversation-history/passages.ts +0 -81
  296. package/pi-extension/src/conversation-history/ranking.ts +0 -155
  297. package/pi-extension/src/conversation-history/runtime.ts +0 -250
  298. package/pi-extension/src/conversation-history/search.ts +0 -79
  299. package/pi-extension/src/conversation-history/types.ts +0 -31
  300. package/pi-extension/src/freeflow-context/resolver.ts +0 -139
  301. package/pi-extension/src/freeflow-context/runtime.ts +0 -100
  302. package/pi-extension/src/freeflow-context/source-projector.ts +0 -106
  303. package/pi-extension/src/freeflow-context/tool.ts +0 -366
  304. package/pi-extension/src/freeflow-context/types.ts +0 -70
  305. package/pi-extension/src/freeflow-context/visibility.ts +0 -53
  306. package/pi-extension/src/index.ts +0 -390
  307. package/pi-extension/src/integrations/mcp-config.ts +0 -32
  308. package/pi-extension/src/provider-support/astra/adapter.ts +0 -108
  309. package/pi-extension/src/provider-support/astra/history.ts +0 -145
  310. package/pi-extension/src/provider-support/astra/index.ts +0 -12
  311. package/pi-extension/src/provider-support/astra/session-state.ts +0 -113
  312. package/pi-extension/src/provider-support/index.ts +0 -5
  313. package/pi-extension/src/runtime/request-history.ts +0 -243
  314. package/pi-extension/src/runtime/runtime-context.ts +0 -860
  315. package/pi-extension/src/runtime/runtime-identity.ts +0 -8
  316. package/pi-extension/src/session-sources/events.ts +0 -230
  317. package/pi-extension/src/session-sources/provenance.ts +0 -39
  318. package/pi-extension/src/session-sources/read-only-session.ts +0 -170
  319. package/pi-extension/src/session-sources/sources.ts +0 -334
  320. package/pi-extension/src/settings/settings-tui.ts +0 -501
  321. package/pi-extension/src/settings/settings-ui.ts +0 -1652
  322. package/pi-extension/src/ui/text-component.ts +0 -66
  323. package/pi-extension/tests/cache-reuse/history.test.js +0 -117
  324. package/pi-extension/tests/cache-reuse/native.test.js +0 -91
  325. package/pi-extension/tests/cache-reuse/settings.test.js +0 -211
  326. package/pi-extension/tests/cognitive-routing-v2/communication.test.js +0 -577
  327. package/pi-extension/tests/cognitive-routing-v2/compaction-input.test.js +0 -183
  328. package/pi-extension/tests/cognitive-routing-v2/delegation.test.js +0 -557
  329. package/pi-extension/tests/cognitive-routing-v2/native.test.js +0 -474
  330. package/pi-extension/tests/cognitive-routing-v2/performance.test.js +0 -87
  331. package/pi-extension/tests/cognitive-routing-v2/persistence.test.js +0 -300
  332. package/pi-extension/tests/cognitive-routing-v2/projection.test.js +0 -241
  333. package/pi-extension/tests/cognitive-routing-v2/recovery.test.js +0 -1034
  334. package/pi-extension/tests/cognitive-routing-v2/render.test.js +0 -244
  335. package/pi-extension/tests/cognitive-routing-v2/runtime.test.js +0 -423
  336. package/pi-extension/tests/cognitive-routing-v2/stabilization.test.js +0 -521
  337. package/pi-extension/tests/cognitive-routing-v2/state.test.js +0 -586
  338. package/pi-extension/tests/context-virtualization/extension.test.js +0 -775
  339. package/pi-extension/tests/context-virtualization/projector.test.js +0 -110
  340. package/pi-extension/tests/context-virtualization/runtime.test.js +0 -230
  341. package/pi-extension/tests/conversation-history/runtime.test.js +0 -98
  342. package/pi-extension/tests/conversation-history/search.test.js +0 -97
  343. package/pi-extension/tests/fixtures/pi-host.js +0 -4
  344. package/pi-extension/tests/fixtures/routing-native.js +0 -191
  345. package/pi-extension/tests/integration/mode-free-core.test.js +0 -220
  346. package/pi-extension/tests/integration/pi-extension.test.js +0 -1447
  347. package/pi-extension/tests/integration/prompt-architecture.test.js +0 -447
  348. package/pi-extension/tests/integration/unaffected-regressions.test.js +0 -478
  349. package/pi-extension/tests/provider-support/astra-boundaries.test.js +0 -75
  350. package/pi-extension/tests/provider-support/astra.test.js +0 -306
  351. package/pi-extension/tests/provider-support/cli.test.js +0 -92
  352. package/pi-extension/tests/provider-support/native.test.js +0 -183
  353. package/pi-extension/tests/settings/settings-tui.test.js +0 -243
  354. package/pi-extension/tsconfig.json +0 -16
  355. package/plugin.json +0 -33
  356. package/runtime/prompts/context-virtualization.md +0 -3
  357. package/runtime/prompts/conversation-history.md +0 -3
  358. package/skills/action-selection/SKILL.md +0 -100
  359. package/skills/action-selection/references/trajectory-stalls.md +0 -71
  360. package/skills/bypass/SKILL.md +0 -153
  361. package/skills/commit-work/SKILL.md +0 -145
  362. package/skills/commit-work/references/git-state-edges.md +0 -94
  363. package/skills/commit-work/references/simple-push.md +0 -92
  364. package/skills/commit-work/references/staging-decisions.md +0 -106
  365. package/skills/decision-gate/SKILL.md +0 -106
  366. package/skills/design-for-depth/SKILL.md +0 -117
  367. package/skills/design-for-depth/references/design-pressure-signals.md +0 -182
  368. package/skills/design-for-depth/references/implementation-decisions.md +0 -76
  369. package/skills/design-for-depth/references/interface-design-loop.md +0 -136
  370. package/skills/design-for-depth/references/module-and-dependency-design.md +0 -147
  371. package/skills/design-for-depth/references/software-design-philosophy.md +0 -202
  372. package/skills/design-for-depth/references/state-and-failure-boundaries.md +0 -136
  373. package/skills/diagnose-failure/SKILL.md +0 -125
  374. package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +0 -48
  375. package/skills/diagnose-failure/references/flaky-and-performance-diagnosis.md +0 -51
  376. package/skills/discuss/SKILL.md +0 -116
  377. package/skills/evaluate-skill/SKILL.md +0 -219
  378. package/skills/evaluate-skill/references/evaluation-definition-schema.md +0 -385
  379. package/skills/evaluate-skill/references/evaluation-design.md +0 -112
  380. package/skills/evaluate-skill/references/execution-and-evidence.md +0 -90
  381. package/skills/evaluate-skill/references/review-and-revision.md +0 -92
  382. package/skills/evaluate-skill/scripts/lib/definitions.mjs +0 -407
  383. package/skills/evaluate-skill/scripts/lib/grade-comparison.mjs +0 -60
  384. package/skills/evaluate-skill/scripts/lib/grade.mjs +0 -64
  385. package/skills/evaluate-skill/scripts/lib/runner.mjs +0 -368
  386. package/skills/evaluate-skill/scripts/pi-guard.mjs +0 -164
  387. package/skills/evaluate-skill/scripts/skill-eval.mjs +0 -102
  388. package/skills/execute-work/references/execute-work-edges.md +0 -68
  389. package/skills/finish-branch/SKILL.md +0 -117
  390. package/skills/finish-branch/references/integration-options.md +0 -80
  391. package/skills/handoff/SKILL.md +0 -82
  392. package/skills/handoff/references/handoff-templates.md +0 -150
  393. package/skills/launch-work/SKILL.md +0 -116
  394. package/skills/launch-work/references/launch-readiness.md +0 -85
  395. package/skills/migration-work/SKILL.md +0 -115
  396. package/skills/migration-work/references/migration-lifecycle.md +0 -82
  397. package/skills/release-work/SKILL.md +0 -118
  398. package/skills/release-work/references/release-evidence.md +0 -78
  399. package/skills/review-artifact/SKILL.md +0 -142
  400. package/skills/review-artifact/references/adjudicate-artifact-review.md +0 -101
  401. package/skills/review-artifact/references/independent-artifact-reviewer-contract.md +0 -159
  402. package/skills/review-work/references/adjudicate-work-review.md +0 -97
  403. package/skills/review-work/references/independent-work-reviewer-contract.md +0 -139
  404. package/skills/review-work/references/security-risk-lens.md +0 -69
  405. package/skills/setup-freeflow/references/activation-contract.md +0 -109
  406. package/skills/setup-freeflow/references/host-setup.md +0 -67
  407. package/skills/simplify-code/SKILL.md +0 -85
  408. package/skills/simplify-code/references/simplification-patterns.md +0 -70
  409. package/skills/verify-work/references/browser-runtime-evidence.md +0 -55
  410. package/skills/verify-work/references/integration-evidence.md +0 -47
  411. package/skills/verify-work/references/performance-evidence.md +0 -57
  412. package/skills/workflow/SKILL.md +0 -127
  413. package/skills/workflow/references/domain-skill-composition.md +0 -43
  414. package/skills/write-plan/SKILL.md +0 -92
  415. package/skills/write-plan/references/plan-shapes.md +0 -156
  416. package/skills/write-skill/references/activation-boundaries.md +0 -104
  417. package/skills/write-skill/references/agent-first-instructions.md +0 -121
  418. package/skills/write-skill/references/progressive-disclosure.md +0 -127
  419. package/skills/write-skill/references/skill-dependency-graphs.md +0 -190
  420. package/skills/write-spec/SKILL.md +0 -92
  421. package/skills/write-spec/references/artifact-standards.md +0 -86
  422. package/skills/write-spec/references/decision-records.md +0 -78
  423. package/skills/write-spec/references/spec-shapes.md +0 -143
  424. /package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/budget.js +0 -0
  425. /package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/evidence.mjs +0 -0
  426. /package/skills/{evaluate-skill → evaluate-behavior}/scripts/pi-observer.mjs +0 -0
@@ -1,244 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import { visibleWidth } from "@earendil-works/pi-tui";
4
- import { renderRoutingCall, renderRoutingResult } from "../../dist/cognitive-routing-v2/render.js";
5
-
6
- test("evidence inspection renders metadata and gaps without source previews", () => {
7
- const receipt = {
8
- count: 1,
9
- returned: 1,
10
- selected: ["ctx:old"],
11
- candidates: [
12
- {
13
- ref: "ctx:old",
14
- kind: "toolResult",
15
- producer: "executor",
16
- toolName: "read",
17
- locator: {
18
- callRef: "ctx:call-source",
19
- toolCallId: "call-1",
20
- label: "read: evidence.txt (offset 1, limit 20)",
21
- truncated: false,
22
- },
23
- assignment: "a1",
24
- selected: true,
25
- active: false,
26
- eligible: true,
27
- targetReady: false,
28
- preview: "SOURCE_BODY_MUST_NOT_APPEAR",
29
- limitations: [{ code: "target_representation", detail: "Required image unsupported" }],
30
- },
31
- ],
32
- };
33
- const rendered = renderRoutingResult({ details: receipt }, { expanded: true }, "freeflow_project", {
34
- args: { operation: "inspect" },
35
- })
36
- .render(100)
37
- .join("\n");
38
- assert.doesNotMatch(rendered, /SOURCE_BODY_MUST_NOT_APPEAR|undefined/);
39
- for (const value of [
40
- "ctx:old",
41
- "executor",
42
- "read",
43
- "read: evidence.txt (offset 1, limit 20)",
44
- "call-1 (ctx:call-source)",
45
- "assignment a1",
46
- "Required image unsupported",
47
- ])
48
- assert.ok(rendered.includes(value));
49
- });
50
-
51
- test("expanded receipts retain complete captured reports at narrow and wide widths", () => {
52
- const report = "Captured report " + "long evidence with Unicode 界 and words ".repeat(20) + " END_OF_REPORT";
53
- const receipt = {
54
- status: "accepted",
55
- reportSaved: true,
56
- transition: "blocked",
57
- ready: false,
58
- report,
59
- evidence: { withdrawals: [{ ref: "ctx:a", reason: "Reason stays visible" }] },
60
- };
61
- for (const width of [24, 40, 100]) {
62
- const lines = renderRoutingResult({ details: receipt }, { expanded: true }).render(width);
63
- assert.ok(lines.every((line) => visibleWidth(line) <= width));
64
- assert.match(lines.join("\n"), /END_OF_REPORT/);
65
- assert.match(lines.join("\n").replace(/\s+/g, " "), /Reason stays visible/);
66
- const compact = renderRoutingResult({ details: receipt }, {}).render(width).join("\n");
67
- assert.match(compact, /Report saved/);
68
- assert.match(compact, /needs correction/);
69
- assert.doesNotMatch(compact, /END_OF_REPORT/);
70
- }
71
- });
72
-
73
- test("streaming arguments follow the latest six wrapped lines; expansion retains the whole draft", () => {
74
- const report = Array.from({ length: 12 }, (_, i) => `Report line ${i + 1}`).join("\n");
75
- const live = { argsComplete: false, isPartial: true, expanded: false };
76
- const lines = renderRoutingCall("freeflow_return", { operation: "submit", report }, live).render(40);
77
- assert.match(lines.join("\n"), /Writing report/);
78
- assert.match(lines.join("\n"), /Report line 12/);
79
- assert.doesNotMatch(lines.join("\n"), /Report line 1\s/);
80
- assert.equal(lines.filter((line) => line.includes("Report line")).length, 6);
81
- const full = renderRoutingCall("freeflow_return", { operation: "submit", report }, { ...live, expanded: true })
82
- .render(40)
83
- .join("\n");
84
- assert.match(full, /Report line 1\s/);
85
- assert.match(full, /Report line 12/);
86
- const done = renderRoutingCall(
87
- "freeflow_return",
88
- { operation: "submit", report },
89
- { ...live, argsComplete: true, isPartial: false },
90
- )
91
- .render(40)
92
- .join("\n");
93
- assert.equal(done.trim(), "Return to Coordinator");
94
- });
95
-
96
- test("report streaming is not obscured by limitations sent before or after the report", () => {
97
- const limitations = ["First limitation", "Second limitation", "Third limitation"];
98
- const live = { isPartial: true, argsComplete: false };
99
- for (const reportFirst of [true, false]) {
100
- for (const length of [2, 12, 20]) {
101
- const report = Array.from({ length }, (_, i) => `Report progress ${i + 1}`).join("\n");
102
- const args = reportFirst
103
- ? { operation: "submit", report, limitations }
104
- : { operation: "submit", limitations, report };
105
- const collapsed = renderRoutingCall("freeflow_return", args, live).render(60).join("\n");
106
- assert.match(collapsed, new RegExp(`Report progress ${length}`));
107
- assert.doesNotMatch(collapsed, /Limitation:/);
108
- const expanded = renderRoutingCall("freeflow_return", args, { ...live, expanded: true })
109
- .render(60)
110
- .join("\n");
111
- for (const limit of limitations) assert.ok(expanded.includes(limit));
112
- assert.match(expanded, /Report progress 1/);
113
- }
114
- }
115
- assert.doesNotMatch(
116
- renderRoutingCall("freeflow_return", { operation: "submit", limitations }, live).render(60).join("\n"),
117
- /Limitation:/,
118
- );
119
- });
120
-
121
- test("replacement streaming follows the contract without a sticky reason", () => {
122
- const reason = "Replacement reason " + "keeps its full explanation. ".repeat(30);
123
- const live = { isPartial: true, argsComplete: false };
124
- for (const length of [2, 12]) {
125
- const contract = Array.from({ length }, (_, i) => `Replacement progress ${i + 1}`).join("\n");
126
- for (const args of [
127
- { operation: "replace", reason, contract },
128
- { operation: "replace", contract, reason },
129
- ]) {
130
- const compact = renderRoutingCall("freeflow_delegate", args, live).render(60).join("\n");
131
- assert.match(compact, new RegExp(`Replacement progress ${length}`));
132
- assert.doesNotMatch(compact, /Reason:|Replacement reason/);
133
- const expanded = renderRoutingCall("freeflow_delegate", args, { ...live, expanded: true })
134
- .render(60)
135
- .join("\n");
136
- assert.match(expanded, /Reason: Replacement reason/);
137
- assert.match(expanded, /Replacement progress 1/);
138
- }
139
- }
140
- });
141
-
142
- test("completed receipts describe outcomes without protocol state disclaimers", () => {
143
- for (const [name, operation, receipt, expected] of [
144
- ["freeflow_delegate", "assign", { status: "accepted", transition: "pending" }, "Assignment saved"],
145
- ["freeflow_delegate", "replace", { status: "accepted", transition: "pending" }, "Replacement saved"],
146
- [
147
- "freeflow_return",
148
- "submit",
149
- { status: "accepted", reportSaved: true, ready: true, transition: "pending" },
150
- "Report saved",
151
- ],
152
- [
153
- "freeflow_return",
154
- "retry",
155
- { status: "accepted", reportSaved: true, reportUnchanged: true, ready: true },
156
- "Saved report retained",
157
- ],
158
- ["freeflow_project", "add", { status: "saved", selected: ["ctx:a", "ctx:b"], ready: true }, "2 sources selected"],
159
- ["freeflow_project", "list", { status: "listed", count: 12, selectableCount: 8 }, "12 sources · 8 selectable"],
160
- ["freeflow_unit", "close", { status: "closed", outcome: "deferred" }, "Deferred"],
161
- ["freeflow_unit", "history", { history: [{}, {}] }, "2 events"],
162
- ["freeflow_project", "remove", { selected: ["ctx:b"], items: [{ status: "removed" }] }, "1 removed · 1 remaining"],
163
- // Older receipts used withdrawn for selected and unresolved references alike.
164
- [
165
- "freeflow_project",
166
- "remove",
167
- { selected: [], items: [{ status: "withdrawn" }] },
168
- "1 reference withdrawn · 0 remaining",
169
- ],
170
- [
171
- "freeflow_project",
172
- "inspect",
173
- { selected: ["ctx:a"], ready: true },
174
- "1 source selected · No unresolved references",
175
- ],
176
- [
177
- "freeflow_project",
178
- "add",
179
- { selected: ["ctx:a"], items: [{ status: "already_selected" }], ready: true },
180
- "No changes · 1 source selected",
181
- ],
182
- ["freeflow_unit", "assess", { status: "resumed", ready: true }, "Evidence prepared"],
183
- ["freeflow_unit", "assess", { status: "suspended", ready: false }, "Assessment remains paused"],
184
- [
185
- "freeflow_unit",
186
- "status",
187
- { effective: true, activeProfile: "executor", controlMode: "automatic", assignment: { state: "outstanding" } },
188
- "Executor · Assignment in progress",
189
- ],
190
- ]) {
191
- const text = renderRoutingResult({ details: receipt }, {}, name, { args: { operation } }).render(100).join("\n");
192
- assert.ok(text.includes(expected), text);
193
- assert.doesNotMatch(text, /transfer pending|not acceptance|status:/);
194
- }
195
- });
196
-
197
- test("preview limits apply after wrapping long text, and interrupted drafts remain inspectable", () => {
198
- const args = {
199
- operation: "assign",
200
- contract: "Unicode 界 and \u001b[32mcoloured\u001b[0m text ".repeat(40) + " FINAL_WORD",
201
- };
202
- const component = renderRoutingCall("freeflow_delegate", args, { isPartial: true, argsComplete: false });
203
- for (const width of [24, 50, 100]) {
204
- const lines = component.render(width);
205
- assert.ok(lines.every((line) => visibleWidth(line) <= width));
206
- assert.ok(lines.length <= 12, "header, hint and six preview rows stay bounded");
207
- assert.match(lines.join("\n"), /FINAL_WORD/);
208
- }
209
- const failed = renderRoutingResult(
210
- { content: [{ type: "text", text: "Operation aborted" }] },
211
- { expanded: true },
212
- "freeflow_delegate",
213
- { args },
214
- )
215
- .render(50)
216
- .join("\n");
217
- assert.match(failed, /Submitted contract/);
218
- assert.match(failed, /FINAL_WORD/);
219
- });
220
- test("partial and absent arguments/results render without requiring live runtime state", () => {
221
- assert.ok(renderRoutingCall("freeflow_delegate", undefined).render(30).length);
222
- assert.match(renderRoutingResult({}, { isPartial: true }).render(30).join(""), /Working/);
223
- const inspection = renderRoutingCall(
224
- "freeflow_unit",
225
- { operation: "inspect", view: "detail", ref: "assignment:existing" },
226
- { isPartial: true, argsComplete: false },
227
- )
228
- .render(60)
229
- .join("\n");
230
- assert.match(inspection, /View: detail/);
231
- assert.match(inspection, /Ref: assignment:existing/);
232
- });
233
-
234
- test("native error results with empty details never look like successful saved assignments", () => {
235
- const result = { content: [{ type: "text", text: "Operation aborted" }], details: {} };
236
- const rendered = renderRoutingResult(result, {}, "freeflow_delegate", {
237
- args: { operation: "assign" },
238
- isError: true,
239
- })
240
- .render(60)
241
- .join("\n");
242
- assert.match(rendered, /Operation aborted/);
243
- assert.doesNotMatch(rendered, /Assignment saved/);
244
- });
@@ -1,423 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import { mkdtemp, rm } from "node:fs/promises";
4
- import { tmpdir } from "node:os";
5
- import { join } from "node:path";
6
- import { SessionManager } from "@earendil-works/pi-coding-agent";
7
- import { RoutingRuntime } from "../../dist/cognitive-routing-v2/runtime.js";
8
- import { EventStore } from "../../dist/session-sources/events.js";
9
- import { replay } from "../../dist/cognitive-routing-v2/state.js";
10
-
11
- const modelIds = ["coordinator", "helper", "executor", "coordinator-fast", "helper-fast", "executor-cheap"];
12
- const models = Object.fromEntries(
13
- modelIds.map((id) => [
14
- id,
15
- {
16
- id,
17
- provider: "fixture",
18
- api: "fixture",
19
- input: ["text"],
20
- reasoning: true,
21
- contextWindow: 100000,
22
- maxTokens: 1000,
23
- },
24
- ]),
25
- );
26
- const cap = {
27
- effective: true,
28
- enabled: true,
29
- projection: false,
30
- profiles: Object.fromEntries(
31
- ["coordinator", "executor"].map((id) => [id, { provider: "fixture", model: id, thinking: "off" }]),
32
- ),
33
- blockingReason: { code: "", message: "" },
34
- };
35
- const helperCap = {
36
- ...cap,
37
- delegation: "helper",
38
- profiles: Object.fromEntries(
39
- ["coordinator", "helper"].map((id) => [id, { provider: "fixture", model: id, thinking: "off" }]),
40
- ),
41
- };
42
- async function environment(run) {
43
- const root = await mkdtemp(join(tmpdir(), "routing-runtime-"));
44
- let active;
45
- const make = (label) => {
46
- const manager = SessionManager.create(root, join(root, label));
47
- manager.appendMessage({
48
- role: "assistant",
49
- content: [{ type: "text", text: "seed" }],
50
- model: "coordinator",
51
- provider: "fixture",
52
- api: "fixture",
53
- stopReason: "stop",
54
- timestamp: 1,
55
- });
56
- return {
57
- sessionManager: manager,
58
- model: models.coordinator,
59
- thinkingLevel: "off",
60
- failNextModelId: undefined,
61
- failNextThinkingLevel: undefined,
62
- modelRegistry: { find: (_p, id) => models[id], getApiKeyAndHeaders: async () => ({ ok: true }) },
63
- getSystemPrompt: () => "",
64
- isIdle: () => true,
65
- abort() {},
66
- };
67
- };
68
- const pi = {
69
- appendEntry: (type, data) => active.sessionManager.appendCustomEntry(type, data),
70
- setModel: async (model) => {
71
- if (active.failNextModelId === model.id) {
72
- active.failNextModelId = undefined;
73
- return false;
74
- }
75
- active.model = model;
76
- return true;
77
- },
78
- setThinkingLevel: (level) => {
79
- if (active.failNextThinkingLevel === level) {
80
- active.failNextThinkingLevel = undefined;
81
- throw new Error("fixture thinking application failed");
82
- }
83
- active.thinkingLevel = level;
84
- },
85
- getAllTools: () => [],
86
- sendMessage() {},
87
- };
88
- const runtime = new RoutingRuntime(pi);
89
- try {
90
- await run({
91
- runtime,
92
- make,
93
- activate: (ctx) => {
94
- active = ctx;
95
- },
96
- pi,
97
- });
98
- } finally {
99
- runtime.unbind();
100
- await rm(root, { recursive: true, force: true });
101
- }
102
- }
103
-
104
- test("delayed old control cannot change or poison a newly bound session", async () =>
105
- environment(async ({ runtime, make, activate }) => {
106
- const a = make("a"),
107
- b = make("b");
108
- activate(a);
109
- await runtime.bind(a, cap);
110
- const original = EventStore.prototype.reconcile;
111
- let release, entered;
112
- const gate = new Promise((r) => {
113
- release = r;
114
- });
115
- const entrance = new Promise((r) => {
116
- entered = r;
117
- });
118
- EventStore.prototype.reconcile = async function () {
119
- await original.call(this);
120
- if (this.reader === a.sessionManager) {
121
- entered();
122
- await gate;
123
- }
124
- };
125
- try {
126
- const old = runtime.setManualProfile("executor");
127
- await entrance;
128
- activate(b);
129
- await runtime.bind(b, cap);
130
- const before = b.sessionManager.getEntries().length;
131
- release();
132
- assert.equal((await old).status, "blocked");
133
- assert.equal(b.sessionManager.getEntries().length, before);
134
- assert.equal(b.model.id, "coordinator");
135
- assert.equal(runtime.state().runtimeStatus, "active");
136
- assert.equal(replay(b.sessionManager.getBranch()).control, "automatic");
137
- } finally {
138
- release();
139
- EventStore.prototype.reconcile = original;
140
- }
141
- }));
142
-
143
- for (const [name, firstCapability, heldWorker, secondCapability] of [
144
- ["Helper to Executor", helperCap, "helper", cap],
145
- ["Executor to Helper", cap, "executor", helperCap],
146
- ]) {
147
- test(`binding a fresh ${name} session does not inherit the prior manual hold`, async () =>
148
- environment(async ({ runtime, make, activate }) => {
149
- const first = make(`${name}-first`);
150
- activate(first);
151
- await runtime.bind(first, firstCapability);
152
- assert.equal((await runtime.setManualProfile(heldWorker)).status, "active");
153
- const firstEntryCount = first.sessionManager.getEntries().length;
154
-
155
- const second = make(`${name}-second`);
156
- activate(second);
157
- await runtime.bind(second, secondCapability);
158
-
159
- assert.equal(runtime.state().runtimeStatus, "active");
160
- assert.equal(runtime.state().controlMode, "automatic");
161
- assert.equal(runtime.state().activeProfile, "coordinator");
162
- assert.equal(second.model.id, "coordinator");
163
- assert.equal(first.sessionManager.getEntries().length, firstEntryCount);
164
- assert.equal(replay(first.sessionManager.getBranch()).control, "manual");
165
- assert.equal(replay(first.sessionManager.getBranch()).profile, heldWorker);
166
- }));
167
- }
168
-
169
- test("settled unbound attempt is retired truthfully and next request has a new identity", async () =>
170
- environment(async ({ runtime, make, activate }) => {
171
- const ctx = make("interrupt");
172
- activate(ctx);
173
- await runtime.bind(ctx, cap);
174
- const first = { role: "user", content: "one", timestamp: 2 };
175
- ctx.sessionManager.appendMessage(first);
176
- await runtime.context(ctx, [first]);
177
- const assistant = {
178
- role: "assistant",
179
- content: [{ type: "toolCall", id: "call", name: "read", arguments: {} }],
180
- timestamp: 3,
181
- };
182
- runtime.messageEnd(assistant);
183
- ctx.sessionManager.appendMessage(assistant);
184
- runtime.preflight({ toolName: "read", toolCallId: "call" }, ctx);
185
- const old = [...replay(ctx.sessionManager.getBranch()).executions.values()][0];
186
- await runtime.settled(ctx);
187
- const retired = replay(ctx.sessionManager.getBranch()).executions.get(old.id);
188
- assert.match(retired.interrupted, /unresolved/);
189
- assert.equal(retired.assistantEntryId, undefined);
190
- const second = { role: "user", content: "two", timestamp: 4 };
191
- ctx.sessionManager.appendMessage(second);
192
- await runtime.context(ctx, [first, assistant, second]);
193
- const next = {
194
- role: "assistant",
195
- content: [{ type: "toolCall", id: "next", name: "read", arguments: {} }],
196
- timestamp: 5,
197
- };
198
- runtime.messageEnd(next);
199
- ctx.sessionManager.appendMessage(next);
200
- runtime.preflight({ toolName: "read", toolCallId: "next" }, ctx);
201
- const executions = [...replay(ctx.sessionManager.getBranch()).executions.values()];
202
- assert.equal(executions.length, 2);
203
- assert.notEqual(executions[1].id, old.id);
204
- assert.notEqual(executions[1].basisUserEntryId, old.basisUserEntryId);
205
- }));
206
-
207
- test("session profile overrides apply only to the selected pair and restore configured pairs", async () =>
208
- environment(async ({ runtime, make, activate }) => {
209
- const ctx = make("session-profile");
210
- activate(ctx);
211
- await runtime.bind(ctx, cap);
212
- assert.equal(ctx.model.id, "coordinator");
213
-
214
- const coordinatorOverride = await runtime.setSessionProfileOverride("coordinator", {
215
- provider: "fixture",
216
- modelId: "coordinator-fast",
217
- thinking: "high",
218
- });
219
- assert.equal(coordinatorOverride.status, "active");
220
- assert.equal(ctx.model.id, "coordinator-fast");
221
- assert.equal(ctx.thinkingLevel, "high");
222
- assert.deepEqual(replay(ctx.sessionManager.getBranch()).profileOverrides.get("coordinator"), {
223
- provider: "fixture",
224
- modelId: "coordinator-fast",
225
- thinking: "high",
226
- });
227
-
228
- const executorOverride = await runtime.setSessionProfileOverride("executor", {
229
- provider: "fixture",
230
- modelId: "executor-cheap",
231
- thinking: "low",
232
- });
233
- assert.equal(executorOverride.status, "stored");
234
- assert.equal(ctx.model.id, "coordinator-fast");
235
- assert.equal(ctx.thinkingLevel, "high");
236
-
237
- runtime.unbind();
238
- ctx.model = models.coordinator;
239
- ctx.thinkingLevel = "off";
240
- activate(ctx);
241
- await runtime.bind(ctx, cap);
242
- assert.equal(ctx.model.id, "coordinator-fast");
243
- assert.equal(ctx.thinkingLevel, "high");
244
-
245
- const held = await runtime.setManualProfile("executor");
246
- assert.equal(held.status, "active");
247
- assert.equal(ctx.model.id, "executor-cheap");
248
- assert.equal(ctx.thinkingLevel, "low");
249
-
250
- ctx.model = models.executor;
251
- ctx.thinkingLevel = "off";
252
- await runtime.ancestryChanged(ctx, false);
253
- assert.equal(ctx.model.id, "executor-cheap");
254
- assert.equal(ctx.thinkingLevel, "low");
255
- assert.equal(runtime.state().controlMode, "manual-executor");
256
-
257
- const inheritedExecutor = await runtime.setSessionProfileOverride("executor", null);
258
- assert.equal(inheritedExecutor.status, "active");
259
- assert.equal(ctx.model.id, "executor");
260
- assert.equal(ctx.thinkingLevel, "off");
261
- assert.equal(replay(ctx.sessionManager.getBranch()).profileOverrides.has("coordinator"), true);
262
- assert.equal(replay(ctx.sessionManager.getBranch()).profileOverrides.has("executor"), false);
263
-
264
- const reset = await runtime.resetSessionProfileOverrides();
265
- assert.equal(reset.status, "stored");
266
- assert.equal(ctx.model.id, "executor");
267
- assert.equal(ctx.thinkingLevel, "off");
268
- assert.equal(replay(ctx.sessionManager.getBranch()).profileOverrides.size, 0);
269
- assert.equal(runtime.state().controlMode, "manual-executor");
270
-
271
- runtime.unbind();
272
- activate(ctx);
273
- await runtime.bind(ctx, cap);
274
- assert.equal(ctx.model.id, "executor");
275
- }));
276
-
277
- test("Helper session presets apply through the same guarded profile path", async () =>
278
- environment(async ({ runtime, make, activate }) => {
279
- const ctx = make("session-helper-profile");
280
- activate(ctx);
281
- await runtime.bind(ctx, helperCap);
282
- const helperOverride = { provider: "fixture", modelId: "helper-fast", thinking: "high" };
283
- assert.equal((await runtime.setSessionProfileOverride("helper", helperOverride)).status, "stored");
284
- assert.equal(ctx.model.id, "coordinator");
285
- assert.equal((await runtime.setManualProfile("helper")).status, "active");
286
- assert.equal(ctx.model.id, "helper-fast");
287
- assert.equal(ctx.thinkingLevel, "high");
288
- assert.deepEqual(replay(ctx.sessionManager.getBranch()).profileOverrides.get("helper"), helperOverride);
289
- assert.equal((await runtime.resetSessionProfileOverrides()).status, "active");
290
- assert.equal(ctx.model.id, "helper");
291
- assert.equal(ctx.thinkingLevel, "off");
292
- assert.equal(replay(ctx.sessionManager.getBranch()).profileOverrides.size, 0);
293
- assert.equal(runtime.state().controlMode, "manual-helper");
294
- }));
295
-
296
- test("manual control rejects a disabled worker without poisoning routing", async () =>
297
- environment(async ({ runtime, make, activate }) => {
298
- const ctx = make("disabled-manual-worker");
299
- activate(ctx);
300
- await runtime.bind(ctx, helperCap);
301
- const result = await runtime.setManualProfile("executor");
302
- assert.equal(result.status, "blocked");
303
- assert.match(result.reason, /not enabled/);
304
- assert.equal(runtime.state().runtimeStatus, "active");
305
- assert.equal(runtime.state().activeProfile, "coordinator");
306
- assert.equal(ctx.model.id, "coordinator");
307
- }));
308
-
309
- test("invalid session profile overrides preserve the native pair and routing state", async () =>
310
- environment(async ({ runtime, make, activate }) => {
311
- const ctx = make("session-invalid");
312
- activate(ctx);
313
- await runtime.bind(ctx, cap);
314
- const beforeEntries = ctx.sessionManager.getEntries().length;
315
- const result = await runtime.setSessionProfileOverride("coordinator", {
316
- provider: "fixture",
317
- modelId: "missing-model",
318
- thinking: "high",
319
- });
320
- assert.equal(result.status, "blocked");
321
- assert.equal(ctx.model.id, "coordinator");
322
- assert.equal(ctx.thinkingLevel, "off");
323
- assert.equal(ctx.sessionManager.getEntries().length, beforeEntries);
324
- assert.equal(replay(ctx.sessionManager.getBranch()).profileOverrides.size, 0);
325
- }));
326
-
327
- test("rebind rejects a persisted session override when its model is unavailable", async () =>
328
- await environment(async ({ runtime, make, activate }) => {
329
- const ctx = make("session-stale");
330
- activate(ctx);
331
- await runtime.bind(ctx, cap);
332
- assert.equal(
333
- (
334
- await runtime.setSessionProfileOverride("coordinator", {
335
- provider: "fixture",
336
- modelId: "coordinator-fast",
337
- thinking: "high",
338
- })
339
- ).status,
340
- "active",
341
- );
342
- runtime.unbind();
343
- const saved = models["coordinator-fast"];
344
- delete models["coordinator-fast"];
345
- try {
346
- ctx.model = models.coordinator;
347
- ctx.thinkingLevel = "off";
348
- activate(ctx);
349
- await runtime.bind(ctx, cap);
350
- assert.equal(runtime.state().runtimeStatus, "blocked");
351
- assert.match(runtime.state().runtimeReason, /profile_unavailable|Model unavailable/);
352
- } finally {
353
- models["coordinator-fast"] = saved;
354
- }
355
- const corrected = await runtime.setSessionProfileOverride("coordinator", null);
356
- assert.equal(corrected.status, "active");
357
- assert.equal(runtime.state().runtimeStatus, "active");
358
- assert.equal(ctx.model.id, "coordinator");
359
- assert.equal(replay(ctx.sessionManager.getBranch()).profileOverrides.size, 0);
360
- }));
361
-
362
- test("failed active session override restores the prior pair and event state", async () =>
363
- await environment(async ({ runtime, make, activate }) => {
364
- const ctx = make("session-rollback");
365
- activate(ctx);
366
- await runtime.bind(ctx, cap);
367
- assert.equal(
368
- (
369
- await runtime.setSessionProfileOverride("coordinator", {
370
- provider: "fixture",
371
- modelId: "coordinator-fast",
372
- thinking: "high",
373
- })
374
- ).status,
375
- "active",
376
- );
377
- ctx.failNextModelId = "coordinator";
378
- const result = await runtime.setSessionProfileOverride("coordinator", null);
379
- assert.equal(result.status, "blocked");
380
- assert.equal(ctx.model.id, "coordinator-fast");
381
- assert.equal(ctx.thinkingLevel, "high");
382
- assert.deepEqual(replay(ctx.sessionManager.getBranch()).profileOverrides.get("coordinator"), {
383
- provider: "fixture",
384
- modelId: "coordinator-fast",
385
- thinking: "high",
386
- });
387
- }));
388
-
389
- test("active session reset restores the configured pair and control mode", async () =>
390
- await environment(async ({ runtime, make, activate }) => {
391
- const ctx = make("session-active-reset");
392
- activate(ctx);
393
- await runtime.bind(ctx, cap);
394
- const override = { provider: "fixture", modelId: "coordinator-fast", thinking: "high" };
395
- assert.equal((await runtime.setSessionProfileOverride("coordinator", override)).status, "active");
396
- const result = await runtime.resetSessionProfileOverrides();
397
- assert.equal(result.status, "active");
398
- assert.equal(ctx.model.id, "coordinator");
399
- assert.equal(ctx.thinkingLevel, "off");
400
- assert.equal(replay(ctx.sessionManager.getBranch()).profileOverrides.size, 0);
401
- assert.equal(runtime.state().controlMode, "automatic");
402
- }));
403
-
404
- for (const operation of ["clear", "reset"]) {
405
- test(`partial active ${operation} failure restores the prior native pair and override`, async () =>
406
- await environment(async ({ runtime, make, activate }) => {
407
- const ctx = make(`session-partial-${operation}`);
408
- activate(ctx);
409
- await runtime.bind(ctx, cap);
410
- const override = { provider: "fixture", modelId: "coordinator-fast", thinking: "high" };
411
- assert.equal((await runtime.setSessionProfileOverride("coordinator", override)).status, "active");
412
- ctx.failNextThinkingLevel = "off";
413
- const result =
414
- operation === "clear"
415
- ? await runtime.setSessionProfileOverride("coordinator", null)
416
- : await runtime.resetSessionProfileOverrides();
417
- assert.equal(result.status, "blocked");
418
- assert.equal(ctx.model.id, "coordinator-fast");
419
- assert.equal(ctx.thinkingLevel, "high");
420
- assert.deepEqual(replay(ctx.sessionManager.getBranch()).profileOverrides.get("coordinator"), override);
421
- assert.equal(runtime.state().runtimeStatus, "blocked");
422
- }));
423
- }