ultimate-pi 0.18.0 → 0.19.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 (314) hide show
  1. package/.agents/skills/harness-debate-plan/SKILL.md +1 -1
  2. package/.agents/skills/harness-decisions/SKILL.md +2 -3
  3. package/.agents/skills/harness-governor/SKILL.md +6 -5
  4. package/.agents/skills/harness-orchestration/SKILL.md +4 -4
  5. package/.agents/skills/harness-review/SKILL.md +7 -7
  6. package/.agents/skills/harness-sentrux-setup/SKILL.md +4 -3
  7. package/.agents/skills/harness-steer/SKILL.md +1 -1
  8. package/.agents/skills/sentrux/SKILL.md +9 -9
  9. package/.pi/PACKAGING.md +4 -4
  10. package/.pi/SYSTEM.md +54 -120
  11. package/.pi/agents/harness/incident-recorder.md +0 -1
  12. package/.pi/agents/harness/planning/decompose.md +1 -3
  13. package/.pi/agents/harness/planning/execution-plan-author.md +0 -2
  14. package/.pi/agents/harness/planning/hypothesis-validator.md +0 -2
  15. package/.pi/agents/harness/planning/hypothesis.md +0 -2
  16. package/.pi/agents/harness/planning/implementation-researcher.md +0 -2
  17. package/.pi/agents/harness/planning/plan-adversary.md +0 -2
  18. package/.pi/agents/harness/planning/plan-evaluator.md +1 -3
  19. package/.pi/agents/harness/planning/planning-context.md +0 -2
  20. package/.pi/agents/harness/planning/review-integrator.md +0 -2
  21. package/.pi/agents/harness/planning/sprint-contract-auditor.md +0 -2
  22. package/.pi/agents/harness/planning/stack-researcher.md +0 -2
  23. package/.pi/agents/harness/{adversary.md → reviewing/adversary.md} +0 -2
  24. package/.pi/agents/harness/{evaluator.md → reviewing/evaluator.md} +0 -2
  25. package/.pi/agents/harness/{tie-breaker.md → reviewing/tie-breaker.md} +0 -2
  26. package/.pi/agents/harness/{executor.md → running/executor.md} +0 -2
  27. package/.pi/agents/harness/sentrux-bootstrap.md +0 -1
  28. package/.pi/agents/harness/sentrux-steward.md +0 -2
  29. package/.pi/agents/harness/trace-librarian.md +0 -1
  30. package/.pi/extensions/00-harness-project-control.ts +133 -0
  31. package/.pi/extensions/00-posthog-network-bootstrap.ts +1 -1
  32. package/.pi/extensions/agt-kill-switch.ts +57 -0
  33. package/.pi/extensions/agt-prompt-guard.ts +32 -0
  34. package/.pi/extensions/budget-guard.ts +2 -0
  35. package/.pi/extensions/custom-footer.ts +46 -145
  36. package/.pi/extensions/custom-header.ts +1 -1
  37. package/.pi/extensions/custom-system-prompt.ts +1 -1
  38. package/.pi/extensions/debate-orchestrator.ts +7 -5
  39. package/.pi/extensions/harness-ask-user.ts +8 -8
  40. package/.pi/extensions/harness-debate-tools.ts +27 -43
  41. package/.pi/extensions/harness-lens.ts +94 -0
  42. package/.pi/extensions/harness-live-widget.ts +33 -2
  43. package/.pi/extensions/harness-plan-approval.ts +12 -12
  44. package/.pi/extensions/harness-run-context.ts +1214 -852
  45. package/.pi/extensions/harness-subagent-governance.ts +8 -0
  46. package/.pi/extensions/harness-subagent-submit.ts +36 -164
  47. package/.pi/extensions/harness-subagents.ts +4 -4
  48. package/.pi/extensions/harness-telemetry.ts +3 -1
  49. package/.pi/extensions/harness-web-tools.ts +3 -3
  50. package/.pi/extensions/observation-bus.ts +2 -0
  51. package/.pi/extensions/policy-gate.ts +27 -5
  52. package/.pi/extensions/review-integrity.ts +91 -10
  53. package/.pi/extensions/sentrux-rules-sync.ts +3 -1
  54. package/.pi/extensions/subagent-governance.ts +92 -0
  55. package/.pi/extensions/test-diff-integrity.ts +1 -0
  56. package/.pi/extensions/trace-recorder.ts +3 -1
  57. package/.pi/extensions/{ultimate-pi-vcc.ts → vcc-compaction.ts} +1 -1
  58. package/.pi/harness/README.md +6 -2
  59. package/.pi/harness/agents.manifest.json +38 -49
  60. package/.pi/harness/agents.policy.yaml +275 -0
  61. package/.pi/harness/corpus/graphify-kb-updater.config.json +55 -0
  62. package/.pi/harness/docs/adrs/0006-sentrux-dual-layer.md +2 -1
  63. package/.pi/harness/docs/adrs/0030-inhouse-vcc-compaction.md +1 -1
  64. package/.pi/harness/docs/adrs/0035-plan-phase-review-gate.md +1 -1
  65. package/.pi/harness/docs/adrs/0044-harness-steer-loop.md +3 -2
  66. package/.pi/harness/docs/adrs/0045-harness-lens-minimal-contract.md +49 -0
  67. package/.pi/harness/docs/adrs/0045-phase-scoped-agent-directories.md +33 -0
  68. package/.pi/harness/docs/adrs/0046-agt-policy-engine.md +51 -0
  69. package/.pi/harness/docs/adrs/0047-agt-layered-security.md +39 -0
  70. package/.pi/harness/docs/adrs/0048-tool-call-hook-order.md +25 -0
  71. package/.pi/harness/docs/adrs/0049-agents-policy-manifest.md +36 -0
  72. package/.pi/harness/docs/adrs/README.md +6 -0
  73. package/.pi/harness/docs/graphify-kb-updater-runbook.md +11 -5
  74. package/.pi/harness/docs/practice-map.md +2 -2
  75. package/.pi/harness/evolution/README.md +1 -2
  76. package/.pi/harness/examples/agents.policy.project.yaml +19 -0
  77. package/.pi/harness/examples/policies/custom-deny-bash.yaml +9 -0
  78. package/.pi/harness/policies/bash-denylists.yaml +5 -0
  79. package/.pi/harness/policies/defaults.yaml +51 -0
  80. package/.pi/harness/policies/orchestrator.yaml +18 -0
  81. package/.pi/harness/policies/phases.yaml +10 -0
  82. package/.pi/harness/policies/roles.yaml +5 -0
  83. package/.pi/harness/policies/web-guard.yaml +5 -0
  84. package/.pi/harness/policies/workflow-sequences.yaml +9 -0
  85. package/.pi/harness/sentrux/architecture.manifest.json +26 -4
  86. package/.pi/harness/specs/harness-spawn-context.schema.json +1 -1
  87. package/.pi/harness/specs/observation.schema.json +2 -1
  88. package/.pi/lib/agents-policy.d.mts +70 -0
  89. package/.pi/lib/agents-policy.mjs +325 -0
  90. package/.pi/lib/agents-policy.ts +19 -0
  91. package/.pi/lib/agt/audit-run-sink.ts +52 -0
  92. package/.pi/lib/agt/build-evaluation-context.ts +285 -0
  93. package/.pi/lib/agt/config.ts +28 -0
  94. package/.pi/lib/agt/delegation.ts +69 -0
  95. package/.pi/lib/agt/evaluate-policy.ts +56 -0
  96. package/.pi/lib/agt/identity-registry.ts +41 -0
  97. package/.pi/lib/agt/index.ts +55 -0
  98. package/.pi/lib/agt/kill-switch-state.ts +11 -0
  99. package/.pi/lib/agt/legacy-evaluate.ts +101 -0
  100. package/.pi/lib/agt/policy-engine.ts +154 -0
  101. package/.pi/lib/agt/rings.ts +21 -0
  102. package/.pi/lib/agt/sre-hooks.ts +45 -0
  103. package/.pi/lib/agt/trust-run-store.ts +26 -0
  104. package/.pi/lib/agt/workflow-history.ts +29 -0
  105. package/.pi/lib/agt-governance-active.ts +14 -0
  106. package/.pi/lib/agt-tool-guard.ts +78 -0
  107. package/.pi/lib/ask-user/dialog.ts +314 -0
  108. package/.pi/{extensions/lib → lib}/debate-bus-core.ts +10 -10
  109. package/.pi/{extensions/lib → lib}/debate-bus-state.ts +1 -1
  110. package/.pi/{extensions/lib → lib}/extension-load-guard.ts +21 -0
  111. package/.pi/lib/harness-agt-tool-guard.ts +5 -0
  112. package/.pi/{extensions/lib → lib}/harness-artifact-gate.ts +6 -16
  113. package/.pi/lib/harness-debate-core-deps.ts +14 -0
  114. package/.pi/lib/harness-debate-workflow-deps.ts +43 -0
  115. package/.pi/lib/harness-lens/.gitattributes +1 -0
  116. package/.pi/lib/harness-lens/clients/edit-autopatch.ts +88 -0
  117. package/.pi/lib/harness-lens/clients/file-kinds.ts +380 -0
  118. package/.pi/lib/harness-lens/clients/file-time.ts +215 -0
  119. package/.pi/lib/harness-lens/clients/file-utils.ts +484 -0
  120. package/.pi/lib/harness-lens/clients/format-service.ts +276 -0
  121. package/.pi/lib/harness-lens/clients/formatters.ts +1000 -0
  122. package/.pi/lib/harness-lens/clients/git-guard.ts +31 -0
  123. package/.pi/lib/harness-lens/clients/indent-retarget.ts +90 -0
  124. package/.pi/lib/harness-lens/clients/installer/index.ts +2368 -0
  125. package/.pi/lib/harness-lens/clients/latency-logger.ts +80 -0
  126. package/.pi/lib/harness-lens/clients/lens-config.ts +43 -0
  127. package/.pi/lib/harness-lens/clients/lens-events.ts +164 -0
  128. package/.pi/lib/harness-lens/clients/lsp/aggregation.ts +91 -0
  129. package/.pi/lib/harness-lens/clients/lsp/client.ts +1466 -0
  130. package/.pi/lib/harness-lens/clients/lsp/config.ts +216 -0
  131. package/.pi/lib/harness-lens/clients/lsp/edits.ts +297 -0
  132. package/.pi/lib/harness-lens/clients/lsp/index.ts +1355 -0
  133. package/.pi/lib/harness-lens/clients/lsp/interactive-install.ts +424 -0
  134. package/.pi/lib/harness-lens/clients/lsp/language.ts +223 -0
  135. package/.pi/lib/harness-lens/clients/lsp/launch.ts +939 -0
  136. package/.pi/lib/harness-lens/clients/lsp/lsp-index.ts +11 -0
  137. package/.pi/lib/harness-lens/clients/lsp/path-utils.ts +12 -0
  138. package/.pi/lib/harness-lens/clients/lsp/server-strategies.ts +81 -0
  139. package/.pi/lib/harness-lens/clients/lsp/server.ts +1971 -0
  140. package/.pi/lib/harness-lens/clients/path-utils.ts +182 -0
  141. package/.pi/lib/harness-lens/clients/pipeline.ts +360 -0
  142. package/.pi/lib/harness-lens/clients/project-profile.ts +117 -0
  143. package/.pi/lib/harness-lens/clients/runtime-agent-end.ts +112 -0
  144. package/.pi/lib/harness-lens/clients/runtime-config.ts +33 -0
  145. package/.pi/lib/harness-lens/clients/runtime-coordinator.ts +186 -0
  146. package/.pi/lib/harness-lens/clients/runtime-tool-result.ts +171 -0
  147. package/.pi/lib/harness-lens/clients/safe-spawn.ts +339 -0
  148. package/.pi/lib/harness-lens/clients/secrets-scanner.ts +214 -0
  149. package/.pi/lib/harness-lens/clients/tool-policy.ts +2072 -0
  150. package/.pi/lib/harness-lens/clients/types.ts +59 -0
  151. package/.pi/lib/harness-lens/clients/widget-state.ts +283 -0
  152. package/.pi/lib/harness-lens/index.ts +532 -0
  153. package/.pi/lib/harness-lens/tools/lsp-diagnostics.ts +706 -0
  154. package/.pi/lib/harness-lens/tools/lsp-navigation.ts +1246 -0
  155. package/.pi/{extensions/lib → lib}/harness-posthog.ts +3 -0
  156. package/.pi/lib/harness-project-config.ts +91 -0
  157. package/.pi/lib/harness-run-context-responses.ts +9 -0
  158. package/.pi/lib/harness-run-context.ts +1 -3
  159. package/.pi/{extensions/lib/spawn-policy.ts → lib/harness-spawn-policy.ts} +4 -3
  160. package/.pi/{extensions/lib → lib}/harness-spawn-topology.ts +5 -28
  161. package/.pi/lib/harness-subagent-auth.ts +51 -0
  162. package/.pi/{extensions/lib → lib}/harness-subagent-precheck.ts +13 -10
  163. package/.pi/{extensions/lib → lib}/harness-subagent-submit-pipeline.ts +3 -3
  164. package/.pi/lib/harness-subagent-submit-register.ts +163 -0
  165. package/.pi/{extensions/lib → lib}/harness-subagent-submit-registry.ts +1 -55
  166. package/.pi/{extensions/lib → lib}/harness-subagents-bridge.ts +53 -14
  167. package/.pi/{extensions/lib → lib}/harness-subprocess-bootstrap.ts +1 -1
  168. package/.pi/lib/harness-ui-state.ts +27 -12
  169. package/.pi/{extensions/lib → lib}/plan-approval/create-plan.ts +2 -2
  170. package/.pi/{extensions/lib → lib}/plan-approval/format-plan.ts +2 -2
  171. package/.pi/{extensions/lib → lib}/plan-approval/plan-review.ts +162 -201
  172. package/.pi/{extensions/lib → lib}/plan-approval/render.ts +1 -1
  173. package/.pi/{extensions/lib → lib}/plan-approval/resolve-disk.ts +2 -2
  174. package/.pi/{extensions/lib → lib}/plan-approval/types.ts +1 -1
  175. package/.pi/{extensions/lib → lib}/plan-approval/validate.ts +3 -3
  176. package/.pi/{extensions/lib → lib}/plan-approval-readiness.ts +3 -52
  177. package/.pi/{extensions/lib → lib}/plan-debate-envelope.ts +1 -1
  178. package/.pi/{extensions/lib → lib}/plan-debate-gate.ts +1 -1
  179. package/.pi/{extensions/lib → lib}/plan-debate-lane.ts +1 -4
  180. package/.pi/{extensions/lib → lib}/plan-messenger.ts +1 -1
  181. package/.pi/prompts/harness-auto.md +2 -2
  182. package/.pi/prompts/harness-plan.md +4 -6
  183. package/.pi/prompts/harness-review.md +9 -9
  184. package/.pi/prompts/harness-run.md +7 -7
  185. package/.pi/prompts/harness-setup.md +42 -68
  186. package/.pi/prompts/harness-steer.md +2 -2
  187. package/.pi/scripts/README.md +3 -5
  188. package/.pi/scripts/generate-agents-policy-yaml.mjs +148 -0
  189. package/.pi/scripts/graphify-kb-updater.mjs +48 -8
  190. package/.pi/scripts/harness-agents-manifest.mjs +61 -4
  191. package/.pi/scripts/harness-agt-doctor.ts +36 -0
  192. package/.pi/scripts/harness-cli-verify.sh +9 -2
  193. package/.pi/scripts/harness-project-toggle.mjs +129 -0
  194. package/.pi/scripts/harness-sentrux-cli.mjs +142 -0
  195. package/.pi/scripts/harness-verify.mjs +113 -39
  196. package/.pi/scripts/harness-web-policy-guard.mjs +2 -2
  197. package/.pi/scripts/validate-plan-dag.mjs +65 -74
  198. package/.pi/scripts/vendor-pi-vcc-settings.stub.ts +2 -2
  199. package/.pi/scripts/vendor-sync-pi-vcc.sh +1 -1
  200. package/.pi/skills/architecture/broker-domain/SKILL.md +65 -0
  201. package/.pi/skills/architecture/cqrs/SKILL.md +63 -0
  202. package/.pi/skills/architecture/event-driven/SKILL.md +60 -0
  203. package/.pi/skills/architecture/hexagonal-ports-adapters/SKILL.md +66 -0
  204. package/.pi/skills/architecture/layered/SKILL.md +68 -0
  205. package/.pi/skills/architecture/microkernel/SKILL.md +62 -0
  206. package/.pi/skills/architecture/microservices/SKILL.md +64 -0
  207. package/.pi/skills/architecture/modular-monolith/SKILL.md +65 -0
  208. package/.pi/skills/architecture/orchestration-driven-soa/SKILL.md +61 -0
  209. package/.pi/skills/architecture/pipeline/SKILL.md +63 -0
  210. package/.pi/skills/architecture/service-based/SKILL.md +64 -0
  211. package/.pi/skills/architecture/service-mesh/SKILL.md +60 -0
  212. package/.pi/skills/architecture/space-based/SKILL.md +60 -0
  213. package/.pi/skills/ast-grep/SKILL.md +40 -321
  214. package/.pi/skills/delivery/debugging-discipline/SKILL.md +36 -0
  215. package/.pi/skills/delivery/documentation-update/SKILL.md +33 -0
  216. package/.pi/skills/delivery/requirements-to-implementation/SKILL.md +34 -0
  217. package/.pi/skills/delivery/risk-based-verification/SKILL.md +43 -0
  218. package/.pi/skills/delivery/tradeoff-analysis/SKILL.md +34 -0
  219. package/.pi/skills/engineering/api-contract-design/SKILL.md +38 -0
  220. package/.pi/skills/engineering/cohesion-coupling/SKILL.md +43 -0
  221. package/.pi/skills/engineering/complexity-control/SKILL.md +31 -0
  222. package/.pi/skills/engineering/defensive-programming/SKILL.md +38 -0
  223. package/.pi/skills/engineering/dependency-management/SKILL.md +29 -0
  224. package/.pi/skills/engineering/domain-modeling/SKILL.md +32 -0
  225. package/.pi/skills/engineering/error-handling/SKILL.md +37 -0
  226. package/.pi/skills/engineering/legacy-code-seams/SKILL.md +35 -0
  227. package/.pi/skills/engineering/naming-and-intent/SKILL.md +29 -0
  228. package/.pi/skills/engineering/refactoring-safe-evolution/SKILL.md +35 -0
  229. package/.pi/skills/engineering/routine-function-design/SKILL.md +34 -0
  230. package/.pi/skills/engineering/small-change-discipline/SKILL.md +35 -0
  231. package/.pi/skills/lsp-navigation/SKILL.md +89 -0
  232. package/.pi/skills/quality/code-review-self-check/SKILL.md +35 -0
  233. package/.pi/skills/quality/privacy-data-handling/SKILL.md +26 -0
  234. package/.pi/skills/quality/security-review/SKILL.md +34 -0
  235. package/.pi/skills/quality/test-strategy/SKILL.md +33 -0
  236. package/.pi/skills/quality/testability-design/SKILL.md +33 -0
  237. package/.pi/skills/systems/concurrency-safety/SKILL.md +32 -0
  238. package/.pi/skills/systems/data-modeling-migrations/SKILL.md +31 -0
  239. package/.pi/skills/systems/observability-instrumentation/SKILL.md +32 -0
  240. package/.pi/skills/systems/performance-measurement/SKILL.md +35 -0
  241. package/.pi/skills/systems/reliability-design/SKILL.md +32 -0
  242. package/.sentrux/rules.toml +20 -4
  243. package/AGENTS.md +5 -0
  244. package/CHANGELOG.md +26 -0
  245. package/README.md +85 -58
  246. package/THIRD_PARTY_NOTICES.md +12 -21
  247. package/package.json +15 -7
  248. package/vendor/pi-subagents/src/agents.ts +45 -1
  249. package/vendor/pi-subagents/src/subagents.ts +866 -811
  250. package/vendor/pi-vcc/src/core/brief.ts +68 -99
  251. package/vendor/pi-vcc/src/core/settings.ts +2 -2
  252. package/.agents/skills/caveman/SKILL.md +0 -67
  253. package/.pi/agents/harness/meta-optimizer.md +0 -36
  254. package/.pi/agents/harness/planning/scout-graphify.md +0 -39
  255. package/.pi/agents/harness/planning/scout-semantic.md +0 -41
  256. package/.pi/agents/harness/planning/scout-structure.md +0 -37
  257. package/.pi/extensions/lib/ask-user/dialog.ts +0 -260
  258. package/.pi/extensions/lib/harness-subagent-auth.ts +0 -209
  259. package/.pi/extensions/lib/harness-subagent-policy.ts +0 -236
  260. package/.pi/extensions/pi-model-router-harness.ts +0 -42
  261. package/.pi/harness/evolution/meta-optimizer.mjs +0 -99
  262. package/.pi/harness/specs/router-tuning-proposal.schema.json +0 -114
  263. package/.pi/model-router.example.json +0 -36
  264. package/.pi/prompts/harness-critic.md +0 -10
  265. package/.pi/prompts/harness-eval.md +0 -10
  266. package/.pi/prompts/harness-router-tune.md +0 -52
  267. package/.pi/scripts/harness-generate-model-router.mjs +0 -327
  268. package/.pi/scripts/harness-model-router-routing.test.mjs +0 -97
  269. package/.pi/scripts/harness-sync-model-router.mjs +0 -97
  270. package/.pi/scripts/vendor-sync-pi-model-router.sh +0 -47
  271. package/vendor/pi-model-router/.prettierignore +0 -4
  272. package/vendor/pi-model-router/.prettierrc +0 -5
  273. package/vendor/pi-model-router/AGENTS.md +0 -39
  274. package/vendor/pi-model-router/LICENSE +0 -21
  275. package/vendor/pi-model-router/README.md +0 -99
  276. package/vendor/pi-model-router/UPSTREAM_PIN.md +0 -10
  277. package/vendor/pi-model-router/docs/ARCHITECTURE.md +0 -54
  278. package/vendor/pi-model-router/extensions/commands.ts +0 -720
  279. package/vendor/pi-model-router/extensions/config.ts +0 -348
  280. package/vendor/pi-model-router/extensions/constants.ts +0 -1
  281. package/vendor/pi-model-router/extensions/index.ts +0 -478
  282. package/vendor/pi-model-router/extensions/provider.ts +0 -580
  283. package/vendor/pi-model-router/extensions/routing.ts +0 -564
  284. package/vendor/pi-model-router/extensions/state.ts +0 -52
  285. package/vendor/pi-model-router/extensions/types.ts +0 -95
  286. package/vendor/pi-model-router/extensions/ui.ts +0 -144
  287. package/vendor/pi-model-router/model-router.example.json +0 -48
  288. package/vendor/pi-model-router/package.json +0 -48
  289. package/vendor/pi-model-router/tsconfig.json +0 -16
  290. /package/.pi/{prompts → harness/docs}/planning-rubrics.md +0 -0
  291. /package/.pi/{extensions/lib → lib}/ask-user/fallback.ts +0 -0
  292. /package/.pi/{extensions/lib → lib}/ask-user/render.ts +0 -0
  293. /package/.pi/{extensions/lib → lib}/ask-user/schema.ts +0 -0
  294. /package/.pi/{extensions/lib → lib}/ask-user/types.ts +0 -0
  295. /package/.pi/{extensions/lib → lib}/ask-user/validate-core.mjs +0 -0
  296. /package/.pi/{extensions/lib → lib}/ask-user/validate.ts +0 -0
  297. /package/.pi/{extensions/lib → lib}/harness-cocoindex-refresh.ts +0 -0
  298. /package/.pi/{extensions/lib → lib}/harness-paths.ts +0 -0
  299. /package/.pi/{extensions/lib → lib}/harness-spawn-budget.ts +0 -0
  300. /package/.pi/{extensions/lib → lib}/harness-vcc-settings.ts +0 -0
  301. /package/.pi/{extensions/lib → lib}/harness-web/run-cli.ts +0 -0
  302. /package/.pi/{extensions/lib → lib}/plan-approval/dialog.ts +0 -0
  303. /package/.pi/{extensions/lib → lib}/plan-approval/schema.ts +0 -0
  304. /package/.pi/{extensions/lib → lib}/plan-debate-eligibility.ts +0 -0
  305. /package/.pi/{extensions/lib → lib}/plan-debate-focus.ts +0 -0
  306. /package/.pi/{extensions/lib → lib}/plan-debate-id.ts +0 -0
  307. /package/.pi/{extensions/lib → lib}/plan-debate-lanes.ts +0 -0
  308. /package/.pi/{extensions/lib → lib}/plan-debate-round-status.ts +0 -0
  309. /package/.pi/{extensions/lib → lib}/plan-debate-write-guard.ts +0 -0
  310. /package/.pi/{extensions/lib → lib}/plan-review-gate.ts +0 -0
  311. /package/.pi/{extensions/lib → lib}/plan-review-integrator-rules.ts +0 -0
  312. /package/.pi/{extensions/lib → lib}/plan-scope-guard.ts +0 -0
  313. /package/.pi/{extensions/lib → lib}/posthog-client.ts +0 -0
  314. /package/.pi/{extensions/lib → lib}/posthog-node.d.ts +0 -0
@@ -1,42 +0,0 @@
1
- /**
2
- * Vendored [pi-model-router](https://github.com/yeliu84/pi-model-router), gated behind
3
- * a project-local `.pi/model-router.json` from `/harness-setup` so the extension
4
- * (and built-in fallback tiers) never load before harness bootstrap.
5
- */
6
-
7
- import { existsSync, readFileSync } from "node:fs";
8
- import { join } from "node:path";
9
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
10
- import vendorModelRouter from "../../vendor/pi-model-router/extensions/index.js";
11
-
12
- function isHarnessRouterReady(cwd: string): boolean {
13
- const path = join(cwd, ".pi", "model-router.json");
14
- if (!existsSync(path)) {
15
- return false;
16
- }
17
- try {
18
- const data: unknown = JSON.parse(readFileSync(path, "utf8"));
19
- if (typeof data !== "object" || data === null) {
20
- return false;
21
- }
22
- const profiles = (data as { profiles?: unknown }).profiles;
23
- return (
24
- typeof profiles === "object" &&
25
- profiles !== null &&
26
- Object.keys(profiles).length > 0
27
- );
28
- } catch {
29
- return false;
30
- }
31
- }
32
-
33
- export default function piModelRouterHarness(pi: ExtensionAPI) {
34
- const cwd = process.cwd();
35
- if (!isHarnessRouterReady(cwd)) {
36
- console.warn(
37
- "[ultimate-pi] Model router disabled until `.pi/model-router.json` exists (generate via /harness-setup Step 3.5).",
38
- );
39
- return;
40
- }
41
- vendorModelRouter(pi);
42
- }
@@ -1,99 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * meta-optimizer — read harness JSONL index and emit tuning proposals (no LLM).
4
- */
5
-
6
- import { readFile, readdir } from "node:fs/promises";
7
- import { join, dirname } from "node:path";
8
- import { fileURLToPath } from "node:url";
9
-
10
- const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
11
- const RUNS = join(ROOT, ".pi", "harness", "runs");
12
- const OUT = join(ROOT, ".pi", "harness", "router", "proposals", "meta-optimizer-proposal.json");
13
-
14
- async function loadIndexLines() {
15
- const indexPath = join(RUNS, "index.jsonl");
16
- try {
17
- const raw = await readFile(indexPath, "utf-8");
18
- return raw
19
- .trim()
20
- .split("\n")
21
- .filter(Boolean)
22
- .map((line) => JSON.parse(line));
23
- } catch {
24
- return [];
25
- }
26
- }
27
-
28
- async function countEventTypes(runId) {
29
- const eventsPath = join(RUNS, runId, "events.jsonl");
30
- try {
31
- const raw = await readFile(eventsPath, "utf-8");
32
- const counts = {};
33
- for (const line of raw.trim().split("\n").filter(Boolean)) {
34
- const row = JSON.parse(line);
35
- const t = row.type ?? "unknown";
36
- counts[t] = (counts[t] ?? 0) + 1;
37
- }
38
- return counts;
39
- } catch {
40
- return {};
41
- }
42
- }
43
-
44
- async function main() {
45
- const index = await loadIndexLines();
46
- const recent = index.slice(-20);
47
- let totalToolSpans = 0;
48
- let runs = 0;
49
- const policyHints = [];
50
-
51
- for (const row of recent) {
52
- const runId = row.run_id;
53
- if (!runId) continue;
54
- runs += 1;
55
- try {
56
- const trace = JSON.parse(
57
- await readFile(join(RUNS, runId, "trace.json"), "utf-8"),
58
- );
59
- totalToolSpans += trace.tool_span_count ?? trace.tool_spans?.length ?? 0;
60
- } catch {
61
- /* skip */
62
- }
63
- const events = await countEventTypes(runId);
64
- if ((events.tool_result ?? 0) > 50) {
65
- policyHints.push({
66
- run_id: runId,
67
- hint: "High tool volume; consider stricter phase caps or router to smaller model for plan phase.",
68
- });
69
- }
70
- }
71
-
72
- const avgTools = runs > 0 ? totalToolSpans / runs : 0;
73
- const proposal = {
74
- schema_version: "1.0.0",
75
- generated_at: new Date().toISOString(),
76
- source: "meta-optimizer",
77
- sample_runs: runs,
78
- avg_tool_spans_per_run: avgTools,
79
- router_hints: policyHints,
80
- recommendation:
81
- avgTools > 30
82
- ? "Consider lowering execute-phase tool budget or enabling HARNESS_BUDGET_HARD_STOP."
83
- : "No automatic router change; metrics within nominal band.",
84
- };
85
-
86
- await import("node:fs/promises").then(({ mkdir, writeFile }) =>
87
- mkdir(dirname(OUT), { recursive: true }).then(() =>
88
- writeFile(OUT, `${JSON.stringify(proposal, null, 2)}\n`),
89
- ),
90
- );
91
-
92
- console.log(JSON.stringify(proposal, null, 2));
93
- console.log(`\nWrote ${OUT}`);
94
- }
95
-
96
- main().catch((err) => {
97
- console.error(err);
98
- process.exit(1);
99
- });
@@ -1,114 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://ultimate-pi.local/.pi/harness/specs/router-tuning-proposal.schema.json",
4
- "title": "RouterTuningProposal",
5
- "description": "Evidence-gated, approval-required proposal for model-router updates.",
6
- "type": "object",
7
- "additionalProperties": false,
8
- "required": [
9
- "schema_version",
10
- "proposal_id",
11
- "created_at",
12
- "router_path",
13
- "base_router_sha256",
14
- "candidate_router_sha256",
15
- "evidence",
16
- "status",
17
- "approval",
18
- "candidate_router"
19
- ],
20
- "properties": {
21
- "schema_version": {
22
- "type": "string",
23
- "const": "1.0.0"
24
- },
25
- "proposal_id": {
26
- "type": "string",
27
- "minLength": 1
28
- },
29
- "created_at": {
30
- "type": "string",
31
- "minLength": 1
32
- },
33
- "router_path": {
34
- "type": "string",
35
- "const": ".pi/model-router.json"
36
- },
37
- "base_router_sha256": {
38
- "type": "string",
39
- "pattern": "^[a-f0-9]{64}$"
40
- },
41
- "candidate_router_sha256": {
42
- "type": "string",
43
- "pattern": "^[a-f0-9]{64}$"
44
- },
45
- "status": {
46
- "type": "string",
47
- "enum": ["proposed", "approved_applied", "rejected"]
48
- },
49
- "evidence": {
50
- "type": "object",
51
- "additionalProperties": false,
52
- "required": [
53
- "sample_count",
54
- "min_sample_count",
55
- "success_rate_delta",
56
- "cost_per_task_delta",
57
- "regression_guard_passed",
58
- "trace_refs"
59
- ],
60
- "properties": {
61
- "sample_count": {
62
- "type": "integer",
63
- "minimum": 1
64
- },
65
- "min_sample_count": {
66
- "type": "integer",
67
- "minimum": 1
68
- },
69
- "success_rate_delta": {
70
- "type": "number"
71
- },
72
- "cost_per_task_delta": {
73
- "type": "number"
74
- },
75
- "regression_guard_passed": {
76
- "type": "boolean"
77
- },
78
- "trace_refs": {
79
- "type": "array",
80
- "items": {
81
- "type": "string",
82
- "minLength": 1
83
- }
84
- },
85
- "notes": {
86
- "type": "string"
87
- }
88
- }
89
- },
90
- "approval": {
91
- "type": "object",
92
- "additionalProperties": false,
93
- "required": ["required", "approved_by", "approved_at", "justification"],
94
- "properties": {
95
- "required": {
96
- "type": "boolean",
97
- "const": true
98
- },
99
- "approved_by": {
100
- "type": ["string", "null"]
101
- },
102
- "approved_at": {
103
- "type": ["string", "null"]
104
- },
105
- "justification": {
106
- "type": ["string", "null"]
107
- }
108
- }
109
- },
110
- "candidate_router": {
111
- "type": "object"
112
- }
113
- }
114
- }
@@ -1,36 +0,0 @@
1
- {
2
- "defaultProfile": "auto",
3
- "debug": false,
4
- "classifierModel": "openai/gpt-5.4-nano",
5
- "phaseBias": 0.5,
6
- "maxSessionBudget": 1.0,
7
- "largeContextThreshold": 100000,
8
- "rules": [
9
- {
10
- "matches": ["deploy", "production", "release"],
11
- "tier": "high",
12
- "reason": "Safety check for production tasks"
13
- },
14
- { "matches": "changelog", "tier": "low" }
15
- ],
16
- "profiles": {
17
- "auto": {
18
- "high": {
19
- "model": "openai/gpt-5.5",
20
- "thinking": "high",
21
- "fallbacks": ["openai/gpt-5.4-nano"]
22
- },
23
- "medium": { "model": "openai/gpt-5.5", "thinking": "medium" },
24
- "low": { "model": "openai/gpt-5.5", "thinking": "low" }
25
- },
26
- "opencode-go": {
27
- "high": {
28
- "model": "opencode-go/qwen3.6-plus",
29
- "thinking": "high",
30
- "fallbacks": ["opencode-go/deepseek-v4-flash"]
31
- },
32
- "medium": { "model": "opencode-go/qwen3.6-plus", "thinking": "medium" },
33
- "low": { "model": "opencode-go/qwen3.6-plus", "thinking": "low" }
34
- }
35
- }
36
- }
@@ -1,10 +0,0 @@
1
- ---
2
- description: "Deprecated alias — use /harness-review (includes adversary phase)."
3
- argument-hint: "[--run <run-id>] [--trace <trace-ref>] [--risk low|med|high]"
4
- ---
5
-
6
- # harness-critic
7
-
8
- **This command is deprecated.** Run **`/harness-review`** instead — Phase 4 runs `harness/adversary` after benchmark and policy verdict pass (skip with `--quick`).
9
-
10
- If you must continue this turn only: forward to `/harness-review` with the same `$ARGUMENTS` (omit `--quick` if you need adversary). Do not spawn adversary in isolation unless the user explicitly requested adversary-only review.
@@ -1,10 +0,0 @@
1
- ---
2
- description: "Deprecated alias — use /harness-review (post-run master orchestrator)."
3
- argument-hint: "[--run <run-id>] [--quick] [--trace <trace-ref>]"
4
- ---
5
-
6
- # harness-eval
7
-
8
- **This command is deprecated.** Run **`/harness-review`** instead — it orchestrates deterministic gates, benchmark eval, policy verdict, and adversary review in one flow (ADR 0039).
9
-
10
- If you must continue this turn only: forward all work to `/harness-review` with the same arguments (`$ARGUMENTS`). Do not spawn a separate benchmark-only pass unless the user explicitly asked for benchmark-only diagnostics.
@@ -1,52 +0,0 @@
1
- ---
2
- description: Propose model-router updates from eval evidence; apply only with explicit approval.
3
- argument-hint: "--evidence <evidence.json> --candidate <candidate-router.json> [--proposal <out.json>]"
4
- ---
5
-
6
- # harness-router-tune
7
-
8
- Orchestrator — scripts + `harness/meta-optimizer` spawn. **Never** write `.pi/model-router.json` directly.
9
-
10
- ## Step 0 — Parse arguments
11
-
12
- - required: `--evidence <evidence.json>`, `--candidate <candidate-router.json>`
13
- - optional: `--proposal <out.json>`
14
-
15
- If missing required args:
16
-
17
- `Usage: /harness-router-tune --evidence <path> --candidate <path> [--proposal <out.json>]`
18
-
19
- ## Orchestration (required)
20
-
21
- 1. Parent validates evidence paths exist.
22
- 2. Optionally spawn:
23
-
24
- ```
25
- subagent({ agentScope: "both", agent: "harness/meta-optimizer", task: "mode: tune, evidence paths…" })
26
- ```
27
-
28
- 3. Parent runs proposal script:
29
-
30
- ```bash
31
- node .pi/harness/router/propose-router-tuning.mjs \
32
- --evidence <evidence.json> \
33
- --candidate <candidate-router.json> \
34
- --proposal-out .pi/harness/router/proposals/<id>.json
35
- ```
36
-
37
- 4. `ask_user` approve / reject / edit (harness-decisions).
38
- 5. Apply only after approval:
39
-
40
- ```bash
41
- node .pi/harness/router/apply-router-proposal.mjs \
42
- --proposal .pi/harness/router/proposals/<id>.json \
43
- --approve-by "<human>" \
44
- --justification "<reason>" \
45
- --write
46
- ```
47
-
48
- ## Completion
49
-
50
- - `tuning_status`: `proposed`, `human_required`, or `rejected`
51
- - Evidence gate summary
52
- - Confirm `.pi/model-router.json` was not mutated without apply script
@@ -1,327 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Generate `.pi/model-router.json` from Pi's authenticated providers (auth.json + env),
4
- * not from raw env-var heuristics alone.
5
- *
6
- * Uses @earendil-works/pi-coding-agent ModelRegistry.getAvailable() — same source as /login.
7
- *
8
- * Usage: node harness-generate-model-router.mjs [--force] [--dry-run]
9
- * --force overwrite existing .pi/model-router.json
10
- * --dry-run print JSON to stdout, do not write
11
- *
12
- * Requires @earendil-works/pi-coding-agent (peer of ultimate-pi; bundled with pi).
13
- */
14
-
15
- import { existsSync, mkdirSync, writeFileSync } from "node:fs";
16
- import { createRequire } from "node:module";
17
- import { dirname, join } from "node:path";
18
- import { fileURLToPath, pathToFileURL } from "node:url";
19
-
20
- const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url));
21
- const UP_PKG = join(SCRIPT_DIR, "..", "..");
22
- const OUT_PATH = join(process.cwd(), ".pi", "model-router.json");
23
-
24
- const PROVIDER_PRIORITY = [
25
- "openai",
26
- "opencode-go",
27
- "anthropic",
28
- "google",
29
- "openrouter",
30
- "groq",
31
- "mistral",
32
- "amazon",
33
- ];
34
-
35
- /** Substring hints per tier (first match in available ids wins). */
36
- const TIER_HINTS = {
37
- high: [
38
- "gpt-5.5-pro",
39
- "deepseek-v4-pro",
40
- "gpt-5.4-pro",
41
- "claude-opus",
42
- "sonnet-4",
43
- "gemini-2.5-pro",
44
- "pro",
45
- ],
46
- medium: [
47
- "gpt-5.5",
48
- "qwen3.6-plus",
49
- "kimi-k2.6",
50
- "gpt-5.4",
51
- "claude-sonnet",
52
- "gemini-flash",
53
- "plus",
54
- ],
55
- low: [
56
- "deepseek-v4-flash",
57
- "gpt-5.4-nano",
58
- "haiku",
59
- "flash-lite",
60
- "flash",
61
- "mini",
62
- ],
63
- };
64
-
65
- function fail(msg) {
66
- console.error(`harness-generate-model-router: ${msg}`);
67
- process.exit(1);
68
- }
69
-
70
- async function loadPiCodingAgent() {
71
- const scopes = ["@earendil-works", "@mariozechner"];
72
- const agentRoots = scopes.flatMap((scope) => [
73
- join(UP_PKG, "node_modules", scope, "pi-coding-agent"),
74
- join(UP_PKG, ".pi", "npm", "node_modules", scope, "pi-coding-agent"),
75
- ]);
76
- for (const root of agentRoots) {
77
- const entry = join(root, "dist", "index.js");
78
- if (existsSync(entry)) {
79
- return import(pathToFileURL(entry).href);
80
- }
81
- }
82
- for (const spec of ["@earendil-works/pi-coding-agent", "@mariozechner/pi-coding-agent"]) {
83
- for (const base of [UP_PKG, process.cwd()]) {
84
- try {
85
- const req = createRequire(join(base, "package.json"));
86
- return req(spec);
87
- } catch {
88
- /* try next */
89
- }
90
- }
91
- }
92
- fail(
93
- "@earendil-works/pi-coding-agent not found (install pi or npm i in ultimate-pi). Peer: @earendil-works/pi-coding-agent",
94
- );
95
- }
96
-
97
- function canonicalRef(provider, modelId) {
98
- return `${provider}/${modelId}`;
99
- }
100
-
101
- function pickTierModel(models, tier) {
102
- const hints = TIER_HINTS[tier];
103
- for (const hint of hints) {
104
- const exact = models.find((m) => m.id === hint);
105
- if (exact) return canonicalRef(exact.provider, exact.id);
106
- }
107
- for (const hint of hints) {
108
- const match = models.find((m) => m.id.includes(hint));
109
- if (match) return canonicalRef(match.provider, match.id);
110
- }
111
- if (models.length === 0) return null;
112
- if (tier === "high") {
113
- const reasoning = models.find((m) => m.reasoning);
114
- if (reasoning) return canonicalRef(reasoning.provider, reasoning.id);
115
- }
116
- if (tier === "low") {
117
- return canonicalRef(models[models.length - 1].provider, models[models.length - 1].id);
118
- }
119
- return canonicalRef(models[0].provider, models[0].id);
120
- }
121
-
122
- function modelsForProvider(available, provider) {
123
- return available.filter((m) => m.provider === provider);
124
- }
125
-
126
- function choosePrimaryProvider(available) {
127
- const byProvider = new Map();
128
- for (const m of available) {
129
- if (!byProvider.has(m.provider)) byProvider.set(m.provider, []);
130
- byProvider.get(m.provider).push(m);
131
- }
132
- for (const p of PROVIDER_PRIORITY) {
133
- if (byProvider.has(p)) return { provider: p, models: byProvider.get(p) };
134
- }
135
- const first = [...byProvider.keys()].sort()[0];
136
- return { provider: first, models: byProvider.get(first) ?? [] };
137
- }
138
-
139
- function buildFallbacks(available, primaryProvider, highModel) {
140
- const fallbacks = [];
141
- for (const p of ["anthropic", "google", "openai", "opencode-go"]) {
142
- if (p === primaryProvider) continue;
143
- const alt = available.filter((m) => m.provider === p);
144
- if (alt.length === 0) continue;
145
- const ref = pickTierModel(alt, "medium");
146
- if (ref && ref !== highModel) fallbacks.push(ref);
147
- }
148
- return fallbacks.slice(0, 3);
149
- }
150
-
151
- /** Session-locked router: one model SKU per profile; tiers vary thinking only. */
152
- function buildRoutedProfile(available, provider) {
153
- const models = modelsForProvider(available, provider);
154
- if (models.length === 0) return null;
155
- const sku =
156
- pickTierModel(models, "medium") ??
157
- pickTierModel(models, "high") ??
158
- pickTierModel(models, "low");
159
- if (!sku) return null;
160
- const fallbacks = buildFallbacks(available, provider, sku);
161
- const high = { model: sku, thinking: "high" };
162
- if (fallbacks.length) high.fallbacks = fallbacks;
163
- return {
164
- high,
165
- medium: { model: sku, thinking: "medium" },
166
- low: { model: sku, thinking: "low" },
167
- };
168
- }
169
-
170
- function addCheapDeepProfiles(profiles, available, provider) {
171
- const models = modelsForProvider(available, provider);
172
- if (models.length === 0) return;
173
- const sku =
174
- pickTierModel(models, "medium") ??
175
- pickTierModel(models, "high") ??
176
- pickTierModel(models, "low");
177
- if (!sku) return;
178
- const fallbacks = buildFallbacks(available, provider, sku);
179
- const deepHigh = { model: sku, thinking: "xhigh" };
180
- if (fallbacks.length) deepHigh.fallbacks = fallbacks;
181
- profiles.cheap = {
182
- high: { model: sku, thinking: "low" },
183
- medium: { model: sku, thinking: "off" },
184
- low: { model: sku, thinking: "off" },
185
- };
186
- profiles.deep = {
187
- high: deepHigh,
188
- medium: { model: sku, thinking: "medium" },
189
- low: { model: sku, thinking: "low" },
190
- };
191
- }
192
-
193
- function resolveClassifierModel(available) {
194
- const openaiModels = modelsForProvider(available, "openai");
195
- if (openaiModels.length > 0) {
196
- return (
197
- pickTierModel(openaiModels, "low") ??
198
- canonicalRef(openaiModels[openaiModels.length - 1].provider, openaiModels[openaiModels.length - 1].id)
199
- );
200
- }
201
- const { models } = choosePrimaryProvider(available);
202
- return pickTierModel(models, "medium");
203
- }
204
-
205
- /** OpenAI-backed default profile name exposed as `router/auto`. */
206
- const OPENAI_PROFILE_NAME = "auto";
207
-
208
- function routerProfileName(provider) {
209
- return provider === "openai" ? OPENAI_PROFILE_NAME : provider;
210
- }
211
-
212
- function resolveDefaultProfile(profiles) {
213
- if (profiles[OPENAI_PROFILE_NAME]) return OPENAI_PROFILE_NAME;
214
- if (profiles["opencode-go"]) return "opencode-go";
215
- return (
216
- Object.keys(profiles).find((name) => name !== "cheap" && name !== "deep") ??
217
- OPENAI_PROFILE_NAME
218
- );
219
- }
220
-
221
- async function main() {
222
- const force = process.argv.includes("--force");
223
- const dryRun = process.argv.includes("--dry-run");
224
-
225
- if (existsSync(OUT_PATH) && !force) {
226
- console.log(
227
- "✓ .pi/model-router.json already exists — preserving (use --force to regenerate)",
228
- );
229
- process.exit(0);
230
- }
231
-
232
- const { AuthStorage, ModelRegistry } = await loadPiCodingAgent();
233
- const authStorage = AuthStorage.create();
234
- const modelRegistry = ModelRegistry.create(authStorage);
235
- const available = await modelRegistry.getAvailable();
236
-
237
- if (available.length === 0) {
238
- console.log(
239
- "✗ No authenticated Pi providers — skip model-router.json",
240
- );
241
- console.log(
242
- " Log in inside pi: /login (or set API keys in ~/.pi/agent/auth.json)",
243
- );
244
- const providers = authStorage.list();
245
- if (providers.length > 0) {
246
- console.log(
247
- ` Stored providers in auth.json (may need refresh): ${providers.join(", ")}`,
248
- );
249
- }
250
- process.exit(0);
251
- }
252
-
253
- const profiles = {};
254
- for (const provider of ["openai", "opencode-go"]) {
255
- const profile = buildRoutedProfile(available, provider);
256
- if (profile) profiles[routerProfileName(provider)] = profile;
257
- }
258
-
259
- if (Object.keys(profiles).length === 0) {
260
- const { provider: primaryProvider, models: primaryModels } =
261
- choosePrimaryProvider(available);
262
- const profile = buildRoutedProfile(available, primaryProvider);
263
- if (!profile) {
264
- fail("could not assign tier models from available registry");
265
- }
266
- profiles[primaryProvider] = profile;
267
- }
268
-
269
- const cheapDeepSource = profiles["opencode-go"]
270
- ? "opencode-go"
271
- : resolveDefaultProfile(profiles);
272
- addCheapDeepProfiles(profiles, available, cheapDeepSource);
273
-
274
- const defaultProfile = resolveDefaultProfile(profiles);
275
- const classifierModel = resolveClassifierModel(available);
276
- if (!classifierModel) {
277
- fail("could not assign classifier model from available registry");
278
- }
279
-
280
- const config = {
281
- defaultProfile,
282
- debug: false,
283
- classifierModel,
284
- phaseBias: 0.5,
285
- maxSessionBudget: 1.0,
286
- largeContextThreshold: 100000,
287
- rules: [
288
- {
289
- matches: ["deploy", "production", "release"],
290
- tier: "high",
291
- reason: "Safety check for production tasks",
292
- },
293
- { matches: "changelog", tier: "low" },
294
- ],
295
- profiles,
296
- };
297
-
298
- const json = `${JSON.stringify(config, null, 2)}\n`;
299
- const providerSet = [...new Set(available.map((m) => m.provider))].sort();
300
- const autoProfile = profiles[OPENAI_PROFILE_NAME];
301
- const opencodeProfile = profiles["opencode-go"];
302
-
303
- if (dryRun) {
304
- process.stdout.write(json);
305
- process.exit(0);
306
- }
307
-
308
- mkdirSync(dirname(OUT_PATH), { recursive: true });
309
- writeFileSync(OUT_PATH, json, "utf8");
310
-
311
- console.log("✓ Generated .pi/model-router.json from Pi authenticated providers:");
312
- console.log(` Default profile: ${defaultProfile}`);
313
- console.log(` Classifier: ${classifierModel}`);
314
- console.log(` Authenticated providers: ${providerSet.join(", ")}`);
315
- console.log(` Available models: ${available.length}`);
316
- if (autoProfile) {
317
- console.log(` auto (openai) high: ${autoProfile.high.model}`);
318
- }
319
- if (opencodeProfile) {
320
- console.log(` opencode-go high: ${opencodeProfile.high.model}`);
321
- }
322
- }
323
-
324
- main().catch((err) => {
325
- console.error(err);
326
- process.exit(1);
327
- });