@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
@@ -0,0 +1,476 @@
1
+ import { ROUTING_RECOVERY_HINT } from "./session.js";
2
+ export { ROUTING_RECOVERY_HINT };
3
+ import { sessionStage, stagedFor } from "../host/staging.js";
4
+ import { resolveCognitiveRoutingState } from "./config.js";
5
+ import { presetWarnings } from "./economics.js";
6
+ import { keepsCacheAcrossEffort } from "../provider-support/effort.js";
7
+ import { workersForDelegation, RoutingError, isWorkerProfile, requireCondition as check, samePair } from "./types.js";
8
+ /**
9
+ * The only part of routing that changes the host model and effort: manual holds and releases, session presets,
10
+ * delegation mode, switches staged until the next prompt, and preset advice. Idle switches are recorded and applied
11
+ * as the next prompt starts; switches during a run apply at once, and a recorded profile never names a model the
12
+ * host is not running.
13
+ */
14
+ export class ModelControl {
15
+ session;
16
+ pi;
17
+ constructor(session, pi) {
18
+ this.session = session;
19
+ this.pi = pi;
20
+ }
21
+ applying;
22
+ externalChange = false;
23
+ heldNotice;
24
+ /** A manual hold whose profile model is not what the host runs, e.g. after a change in Pi's model picker. */
25
+ heldMismatch(state = this.session.stateData()) {
26
+ if (!this.session.supported() || state.control !== "manual" || !state.profile || this.applying) return;
27
+ const observed = this.intended();
28
+ let expected;
29
+ try {
30
+ expected = this.session.profilePair(state.profile);
31
+ } catch {
32
+ return;
33
+ }
34
+ return observed && !samePair(observed, expected) ? { profile: state.profile, expected, observed } : undefined;
35
+ }
36
+ /** Set when a run is prepared before it starts (in beforeRun, or by routing itself); consumed by the run it starts. */
37
+ promptRun = false;
38
+ /** A run that nothing prepared has started and its first message has not been seen yet. */
39
+ unpreparedRun = false;
40
+ /** The next run is already prepared by routing itself (explicit resume sends the message that starts it). */
41
+ preparedRun() {
42
+ this.promptRun = true;
43
+ }
44
+ /** Pi starts a run: from a user prompt or an extension's message (prepared in beforeRun), or a retry. */
45
+ runStarted() {
46
+ this.unpreparedRun = !this.promptRun;
47
+ this.promptRun = false;
48
+ }
49
+ /**
50
+ * Whether this message starts a run an extension's message triggered that beforeRun did not prepare. Pi before 1.2.0
51
+ * skips before_agent_start for those runs, so routing prepares them here, before their first request; from 1.2.0 Pi
52
+ * fires it for them and this returns false. A retry's run starts with no message and is left as is.
53
+ */
54
+ startedByMessage(message) {
55
+ if (!this.unpreparedRun) return false;
56
+ this.unpreparedRun = false;
57
+ return message?.role === "custom";
58
+ }
59
+ /**
60
+ * Prepare a run before its first request. `prompt` and `message` come from before_agent_start, which Pi 1.2.0 and
61
+ * later also fire for a run an extension's message starts; a run routing prepared itself (explicit resume) is not
62
+ * prepared again, so the resumed worker keeps its model. `late` comes from the first message of a run Pi started
63
+ * without before_agent_start.
64
+ */
65
+ async beforeRun(ctx, trigger = "prompt") {
66
+ if (trigger === "message" && this.promptRun) return;
67
+ if (trigger !== "late") this.promptRun = true;
68
+ this.session.ctx = ctx;
69
+ if (this.session.store && this.session.supported() && !this.session.store.blocked && !this.session.error) {
70
+ if (this.session.stateData().control === "automatic" && isWorkerProfile(this.session.stateData().profile)) {
71
+ const result = await this.control("coordinator", false);
72
+ check(result.status !== "blocked", "reconciliation_required", result.reason);
73
+ }
74
+ // A switch made while idle reaches Pi's model now, as the prompt starts and before it is recorded.
75
+ const target = this.pending();
76
+ try {
77
+ await this.applyPending();
78
+ } catch (error) {
79
+ const current = this.session.observed();
80
+ ctx.ui?.notify?.(
81
+ `Could not switch to ${target?.modelId}/${target?.thinking} (${error instanceof Error ? error.message : String(error)}); this prompt runs on ${current?.modelId}/${current?.thinking}.`,
82
+ "warning",
83
+ );
84
+ }
85
+ }
86
+ const held = this.session.store ? this.heldMismatch() : undefined;
87
+ const notice = held && JSON.stringify(held);
88
+ // The hold is the user's; report the divergence once instead of overriding a deliberate model choice.
89
+ if (notice && notice !== this.heldNotice)
90
+ ctx.ui?.notify?.(
91
+ `Manual hold is ${held.profile} (${held.expected.modelId}/${held.expected.thinking}) but Pi is using ${held.observed.modelId}/${held.observed.thinking}. Run /freeflow profile ${held.profile} to reapply it, or /freeflow profile auto to release the hold.`,
92
+ "warning",
93
+ );
94
+ this.heldNotice = notice;
95
+ }
96
+ async validateProfilePairs(pairs) {
97
+ check(pairs.coordinator, "profile_missing", "Configure the coordinator profile.");
98
+ const helper = pairs.helper !== undefined;
99
+ const executor = pairs.executor !== undefined;
100
+ check(helper || executor, "profile_missing", "Configure an enabled worker profile.");
101
+ const delegation = helper && executor ? "both" : helper ? "helper" : "executor";
102
+ const profiles = Object.fromEntries(
103
+ Object.entries(pairs).map(([profile, pair]) => [
104
+ profile,
105
+ { provider: pair.provider, model: pair.modelId, thinking: pair.thinking },
106
+ ]),
107
+ );
108
+ const result = await resolveCognitiveRoutingState(
109
+ { cognitiveRouting: { enabled: true, delegation, profiles } },
110
+ {},
111
+ this.session.ctx,
112
+ );
113
+ check(result.effective, result.blockingReason.code, result.blockingReason.message);
114
+ }
115
+ model(profile) {
116
+ const pair = this.session.profilePair(profile);
117
+ const model = this.session.ctx?.modelRegistry?.find(pair.provider, pair.modelId);
118
+ check(model, "profile_unavailable");
119
+ return model;
120
+ }
121
+ /** Advisory preset checks for the effective Coordinator and enabled workers. */
122
+ presetWarnings(state = this.session.stateData()) {
123
+ if (!this.session.supported()) return [];
124
+ const pairs = {};
125
+ for (const profile of ["coordinator", ...this.session.enabledWorkers(state)])
126
+ try {
127
+ pairs[profile] = this.session.profilePair(profile);
128
+ } catch {}
129
+ return presetWarnings(
130
+ pairs,
131
+ this.session.enabledWorkers(state),
132
+ (provider, modelId) => this.session.ctx?.modelRegistry?.find?.(provider, modelId),
133
+ (model) => keepsCacheAcrossEffort(model, this.session.ctx),
134
+ // The host's default retention, which Freeflow reads and never sets; unset means the short tier. (Pi also takes a
135
+ // per-request cacheRetention option, which Freeflow does not pass.)
136
+ process.env.PI_CACHE_RETENTION === "long" ? "long" : "short",
137
+ );
138
+ }
139
+ presetNotice;
140
+ announcePresets(ctx = this.session.ctx) {
141
+ const warnings = this.presetWarnings();
142
+ const notice = warnings.length ? JSON.stringify(warnings) : undefined;
143
+ if (notice && notice !== this.presetNotice)
144
+ ctx?.ui?.notify?.(`Cognitive Routing preset: ${warnings.join(" ")}`, "warning");
145
+ this.presetNotice = notice;
146
+ }
147
+ /**
148
+ * The user picked a model or effort in Pi itself. Under automatic control that ends routing's ownership of the
149
+ * model: returns true when it did, so the caller turns routing off for the session where the user can see it.
150
+ */
151
+ async nativeChange(ctx) {
152
+ this.session.ctx = ctx;
153
+ if (!this.session.supported() || !this.session.store) return false;
154
+ if (this.applying) {
155
+ if (ctx.model?.provider !== this.applying.provider || ctx.model?.id !== this.applying.modelId) {
156
+ this.externalChange = true;
157
+ this.session.revision++;
158
+ }
159
+ return false; // Never await a queue already held by our setter.
160
+ }
161
+ // The user's own pick in Pi wins over a switch still waiting for the next prompt.
162
+ this.setPending(undefined);
163
+ const state = this.session.stateData();
164
+ if (
165
+ state.control !== "automatic" ||
166
+ !state.profile ||
167
+ samePair(this.session.observed(), this.session.profilePair(state.profile))
168
+ )
169
+ return false;
170
+ try {
171
+ this.session.revision++;
172
+ this.session.manualHold = undefined;
173
+ this.session.automaticControl = false;
174
+ this.session.append({ type: "control", control: "inactive", reason: "External native model/effort change" });
175
+ const now = this.session.observed();
176
+ ctx.ui?.notify?.(
177
+ `Cognitive Routing is off for this session: the model or effort was changed outside routing${now ? ` (now ${now.modelId}/${now.thinking})` : ""}. Turn it back on with /freeflow profile auto, Ctrl+Shift+A, or /freeflow settings.`,
178
+ "warning",
179
+ );
180
+ return true;
181
+ } catch (error) {
182
+ this.session.mark(error);
183
+ return false;
184
+ }
185
+ }
186
+ async applyPair(target) {
187
+ const subject = this.session.subject(),
188
+ token = this.session.token,
189
+ prior = this.session.observed();
190
+ if (samePair(prior, target)) return;
191
+ const model = this.session.ctx.modelRegistry.find(target.provider, target.modelId);
192
+ check(model, "profile_unavailable");
193
+ const auth = await this.session.ctx.modelRegistry.getApiKeyAndHeaders(model);
194
+ this.session.guard(subject);
195
+ check(auth?.ok, "profile_unauthenticated");
196
+ this.applying = target;
197
+ let ownedPair = target;
198
+ this.externalChange = false;
199
+ try {
200
+ check(await this.pi.setModel(model), "model_rejected");
201
+ this.session.guard(subject);
202
+ this.pi.setThinkingLevel(target.thinking);
203
+ check(!this.externalChange && samePair(this.session.observed(), target), "configuration_mismatch");
204
+ } catch (error) {
205
+ if (this.session.current(subject) && prior && !this.externalChange) {
206
+ const old = this.session.ctx.modelRegistry.find(prior.provider, prior.modelId);
207
+ try {
208
+ this.applying = prior;
209
+ ownedPair = prior;
210
+ check(old && (await this.pi.setModel(old)), "rollback_failed");
211
+ this.session.guard(subject);
212
+ this.pi.setThinkingLevel(prior.thinking);
213
+ check(samePair(this.session.observed(), prior), "rollback_failed");
214
+ } catch {
215
+ if (this.session.current(subject))
216
+ this.session.error = "configuration_unknown: rollback could not be observed";
217
+ }
218
+ }
219
+ throw error;
220
+ } finally {
221
+ if (token === this.session.token && this.applying === ownedPair) this.applying = undefined;
222
+ }
223
+ }
224
+ /** A profile switch made while idle, kept with the session's stage so a reload keeps it. */
225
+ pending() {
226
+ return stagedFor(this.session.ctx?.sessionManager)?.pair;
227
+ }
228
+ setPending(pair) {
229
+ const stage = pair ? sessionStage(this.session.ctx?.sessionManager) : stagedFor(this.session.ctx?.sessionManager);
230
+ if (!stage) return;
231
+ if (pair) stage.pair = pair;
232
+ else delete stage.pair;
233
+ }
234
+ /** The pair routing intends the host to run: a pending switch, or what the host runs now. */
235
+ intended() {
236
+ return this.pending() ?? this.session.observed();
237
+ }
238
+ async checkPair(target) {
239
+ const model = this.session.ctx.modelRegistry.find(target.provider, target.modelId);
240
+ check(model, "profile_unavailable");
241
+ check((await this.session.ctx.modelRegistry.getApiKeyAndHeaders(model))?.ok, "profile_unauthenticated");
242
+ }
243
+ /**
244
+ * Apply a switch made while idle, so the prompt runs on the profile the user chose. If the host cannot run it,
245
+ * the switch and the control changes staged with it are dropped, so recorded control still names what runs.
246
+ */
247
+ async applyPending() {
248
+ const target = this.pending();
249
+ if (!target) return;
250
+ try {
251
+ await this.applyPair(target);
252
+ } catch (error) {
253
+ const stage = stagedFor(this.session.ctx?.sessionManager);
254
+ if (stage) stage.events = [];
255
+ throw error;
256
+ } finally {
257
+ this.setPending(undefined);
258
+ }
259
+ }
260
+ /**
261
+ * Switch the host model, then record what the switch means. A switch that fails records nothing, and a
262
+ * record that cannot be written restores the prior model, so recorded control never names a profile
263
+ * whose model the host is not running.
264
+ */
265
+ async transition(target, record, subject) {
266
+ if (this.session.ctx?.isIdle?.() !== false) {
267
+ // An idle switch reaches Pi's model at the next prompt; checking the target now keeps errors immediate.
268
+ if (!samePair(this.intended(), target)) await this.checkPair(target);
269
+ this.session.guard(subject);
270
+ record();
271
+ this.setPending(samePair(this.session.observed(), target) ? undefined : target);
272
+ return;
273
+ }
274
+ this.setPending(undefined);
275
+ const prior = this.session.observed();
276
+ await this.applyPair(target);
277
+ try {
278
+ this.session.guard(subject);
279
+ record();
280
+ } catch (error) {
281
+ if (subject.token === this.session.token && prior && !samePair(this.session.observed(), prior))
282
+ await this.applyPair(prior).catch(() => {});
283
+ throw error;
284
+ }
285
+ }
286
+ /**
287
+ * Control requests run one at a time, each against the state left by the previous one. The host model
288
+ * is switched before the new control is recorded, so a superseded or failed request never leaves a
289
+ * recorded profile running on another profile's model.
290
+ */
291
+ async control(request, manual) {
292
+ return this.session.enqueue(async () => {
293
+ this.session.revision++;
294
+ const subject = this.session.subject();
295
+ try {
296
+ check(this.session.capability?.effective && this.session.store, "routing_unavailable");
297
+ await this.session.store.reconcile();
298
+ this.session.guard(subject);
299
+ const previous = this.session.stateData();
300
+ const profile = typeof request === "function" ? request(previous) : request;
301
+ if (manual && isWorkerProfile(profile))
302
+ check(
303
+ this.session.enabledWorkers().includes(profile),
304
+ "worker_disabled",
305
+ `${profile} is not enabled by delegation mode.`,
306
+ );
307
+ this.session.error = undefined;
308
+ this.session.suppressed = false;
309
+ if (
310
+ previous.control === (manual ? "manual" : "automatic") &&
311
+ previous.profile === profile &&
312
+ samePair(this.intended(), this.session.profilePair(profile))
313
+ ) {
314
+ this.session.manualHold = manual ? profile : undefined;
315
+ this.session.automaticControl = !manual;
316
+ return { status: manual ? "active" : "automatic" };
317
+ }
318
+ await this.transition(
319
+ this.session.profilePair(profile),
320
+ () =>
321
+ this.session.append({
322
+ type: "control",
323
+ control: manual ? "manual" : "automatic",
324
+ profile,
325
+ reason: manual ? "Explicit user manual hold" : "Explicit user automatic release/reconciliation",
326
+ }),
327
+ subject,
328
+ );
329
+ this.session.manualHold = manual ? profile : undefined;
330
+ this.session.automaticControl = !manual;
331
+ return { status: manual ? "active" : "automatic" };
332
+ } catch (error) {
333
+ if (this.session.current(subject) && !(error instanceof RoutingError && error.code === "worker_disabled"))
334
+ this.session.mark(error);
335
+ return { status: "blocked", reason: error instanceof Error ? error.message : String(error) };
336
+ }
337
+ });
338
+ }
339
+ /** Advance one manual-hold step from the state left by any earlier queued request. */
340
+ cycleManualProfile() {
341
+ return this.control((state) => {
342
+ const profiles = ["coordinator", ...workersForDelegation(this.session.delegation(state))];
343
+ return profiles[(profiles.indexOf(state.profile ?? "coordinator") + 1) % profiles.length];
344
+ }, true);
345
+ }
346
+ setManualProfile(profile, _mechanism) {
347
+ return this.control(profile, true);
348
+ }
349
+ sessionProfileOverrides() {
350
+ return Object.fromEntries(this.session.stateData().profileOverrides);
351
+ }
352
+ sessionDelegationOverride() {
353
+ return this.session.stateData().delegationOverride;
354
+ }
355
+ async setSessionDelegationOverride(override, mechanism = "Session delegation override") {
356
+ return this.session.enqueue(async () => {
357
+ this.session.revision++;
358
+ const subject = this.session.subject();
359
+ try {
360
+ check(this.session.capability?.effective && this.session.store, "routing_unavailable");
361
+ check(
362
+ this.session.ctx?.isIdle?.() !== false,
363
+ "host_busy",
364
+ "Wait for Pi to become idle before changing delegation mode.",
365
+ );
366
+ await this.session.store.reconcile();
367
+ this.session.guard(subject);
368
+ const state = this.session.stateData();
369
+ if ((state.delegationOverride ?? null) === override) return { status: "unchanged" };
370
+ const delegation = override ?? this.session.capability.delegation;
371
+ await this.validateProfilePairs(this.session.profilePairs(this.session.requiredProfiles(state, delegation)));
372
+ this.session.guard(subject);
373
+ this.session.append({ type: "delegation-override", delegation: override, reason: mechanism });
374
+ this.announcePresets();
375
+ return { status: "stored" };
376
+ } catch (error) {
377
+ return { status: "blocked", reason: error instanceof Error ? error.message : String(error) };
378
+ }
379
+ });
380
+ }
381
+ async setSessionProfileOverride(profile, override, mechanism = "Session profile override") {
382
+ return this.session.enqueue(async () => {
383
+ this.session.revision++;
384
+ const subject = this.session.subject();
385
+ try {
386
+ check(this.session.capability?.effective && this.session.store, "routing_unavailable");
387
+ check(
388
+ this.session.ctx?.isIdle?.() !== false,
389
+ "host_busy",
390
+ "Wait for Pi to become idle before changing session presets.",
391
+ );
392
+ await this.session.store.reconcile();
393
+ this.session.guard(subject);
394
+ const state = this.session.stateData();
395
+ const previous = state.profileOverrides.get(profile);
396
+ if ((override === null && !previous) || (override !== null && samePair(previous, override)))
397
+ return { status: "unchanged" };
398
+ const target = override ?? this.session.configuredProfilePair(profile);
399
+ const profiles = new Set(this.session.requiredProfiles(state));
400
+ profiles.add(profile);
401
+ const pairs = Object.fromEntries(
402
+ [...profiles].map((name) => [name, name === profile ? target : this.session.profilePair(name)]),
403
+ );
404
+ await this.validateProfilePairs(pairs);
405
+ const record = () =>
406
+ this.session.append({
407
+ type: "profile-overrides",
408
+ overrides: { [profile]: override },
409
+ reason: mechanism,
410
+ });
411
+ if (state.control !== "inactive" && state.profile === profile) {
412
+ await this.transition(target, record, subject);
413
+ this.session.error = undefined;
414
+ this.announcePresets();
415
+ return { status: "active" };
416
+ }
417
+ this.session.guard(subject);
418
+ record();
419
+ this.session.error = undefined;
420
+ this.announcePresets();
421
+ return { status: "stored" };
422
+ } catch (error) {
423
+ if (this.session.current(subject)) this.session.mark(error);
424
+ return { status: "blocked", reason: error instanceof Error ? error.message : String(error) };
425
+ }
426
+ });
427
+ }
428
+ async resetSessionProfileOverrides(mechanism = "Reset session profile overrides") {
429
+ return this.session.enqueue(async () => {
430
+ this.session.revision++;
431
+ const subject = this.session.subject();
432
+ try {
433
+ check(this.session.capability?.effective && this.session.store, "routing_unavailable");
434
+ check(
435
+ this.session.ctx?.isIdle?.() !== false,
436
+ "host_busy",
437
+ "Wait for Pi to become idle before resetting session presets.",
438
+ );
439
+ await this.session.store.reconcile();
440
+ this.session.guard(subject);
441
+ const state = this.session.stateData();
442
+ if (state.profileOverrides.size === 0) return { status: "unchanged" };
443
+ const previous = Object.fromEntries(state.profileOverrides);
444
+ const required = this.session.requiredProfiles(state);
445
+ const targetPairs = Object.fromEntries(
446
+ required.map((profile) => [profile, this.session.configuredProfilePair(profile)]),
447
+ );
448
+ await this.validateProfilePairs(targetPairs);
449
+ const record = () =>
450
+ this.session.append({
451
+ type: "profile-overrides",
452
+ overrides: { coordinator: null, helper: null, executor: null },
453
+ reason: mechanism,
454
+ });
455
+ const active = state.control !== "inactive" ? state.profile : undefined;
456
+ if (active && previous[active]) {
457
+ await this.transition(targetPairs[active], record, subject);
458
+ this.session.error = undefined;
459
+ this.announcePresets();
460
+ return { status: "active" };
461
+ }
462
+ this.session.guard(subject);
463
+ record();
464
+ this.session.error = undefined;
465
+ this.announcePresets();
466
+ return { status: "stored" };
467
+ } catch (error) {
468
+ if (this.session.current(subject)) this.session.mark(error);
469
+ return { status: "blocked", reason: error instanceof Error ? error.message : String(error) };
470
+ }
471
+ });
472
+ }
473
+ setAutomaticControl(_mechanism) {
474
+ return this.control("coordinator", false);
475
+ }
476
+ }