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,7 +1,5 @@
1
1
  ---
2
2
  description: Propose architecture.manifest.json changes from graphify evidence (read-only governance steward).
3
- tools: read, grep, find, ls, bash, submit_sentrux_manifest_proposal
4
- disallowed_tools: write, edit, ask_user, approve_plan, create_plan, subagent
5
3
  extensions: false
6
4
  thinking: high
7
5
  max_turns: 16
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  description: Harness trace librarian for run replay, artifact indexing, and forensics summaries.
3
- tools: read, grep, find, ls, submit_human_required
4
3
  extensions: false
5
4
  thinking: medium
6
5
  max_turns: 20
@@ -0,0 +1,133 @@
1
+ /**
2
+ * harness-project-control — always-on enable/disable for harness governance.
3
+ *
4
+ * Writes `.pi/harness/project.json`, blocks workflow slash commands while disabled,
5
+ * and emits `harness-project-enabled:changed` so live TUI surfaces update immediately.
6
+ */
7
+
8
+ import type {
9
+ ExtensionAPI,
10
+ ExtensionCommandContext,
11
+ } from "@earendil-works/pi-coding-agent";
12
+ import {
13
+ isHarnessProjectEnabled,
14
+ isHarnessWorkflowCommand,
15
+ readHarnessProjectConfig,
16
+ writeHarnessProjectEnabled,
17
+ } from "../lib/harness-project-config.js";
18
+ import { parseHarnessSlashInput } from "../lib/harness-run-context.js";
19
+
20
+ function showCommandMessage(
21
+ pi: ExtensionAPI,
22
+ ctx: ExtensionCommandContext,
23
+ text: string,
24
+ ): void {
25
+ if (ctx.hasUI) {
26
+ ctx.ui.notify(text, "info");
27
+ return;
28
+ }
29
+ pi.sendMessage({
30
+ customType: "harness-project-control",
31
+ content: text,
32
+ display: true,
33
+ });
34
+ }
35
+
36
+ function formatStatus(projectRoot: string): string {
37
+ const config = readHarnessProjectConfig(projectRoot);
38
+ const env = process.env.HARNESS_ENABLED?.trim();
39
+ const lines = [
40
+ `Harness governance: ${config.enabled ? "enabled" : "disabled"}`,
41
+ `Config: .pi/harness/project.json`,
42
+ ];
43
+ if (env) {
44
+ lines.push(`Env override: HARNESS_ENABLED=${env}`);
45
+ }
46
+ if (config.updated_at) {
47
+ lines.push(`Updated: ${config.updated_at}`);
48
+ }
49
+ if (!config.enabled) {
50
+ lines.push(
51
+ "Workflow commands (/harness-plan, /harness-run, …) are blocked until you run /harness-enable.",
52
+ );
53
+ } else {
54
+ lines.push("Run /harness-disable to turn governance off.");
55
+ }
56
+ return lines.join("\n");
57
+ }
58
+
59
+ export default function harnessProjectControl(pi: ExtensionAPI) {
60
+ pi.on("input", async (event) => {
61
+ if (event.source === "extension") {
62
+ return { action: "continue" as const };
63
+ }
64
+ const parsed = parseHarnessSlashInput(event.text);
65
+ if (!parsed || !isHarnessWorkflowCommand(parsed.command)) {
66
+ return { action: "continue" as const };
67
+ }
68
+ if (isHarnessProjectEnabled()) {
69
+ return { action: "continue" as const };
70
+ }
71
+ return {
72
+ action: "handled" as const,
73
+ message: [
74
+ `Harness governance is disabled — /${parsed.command} was not started.`,
75
+ "Run /harness-enable to restore the workflow command surface.",
76
+ ].join("\n"),
77
+ };
78
+ });
79
+
80
+ pi.registerCommand("harness-enable", {
81
+ description: "Enable harness governance for this project",
82
+ handler: async (_args, ctx) => {
83
+ const projectRoot = process.cwd();
84
+ const config = writeHarnessProjectEnabled(projectRoot, true);
85
+ const effectiveConfig = readHarnessProjectConfig(projectRoot);
86
+ pi.events.emit("harness-project-enabled:changed", {
87
+ enabled: effectiveConfig.enabled,
88
+ projectRoot,
89
+ updated_at: config.updated_at,
90
+ });
91
+ showCommandMessage(
92
+ pi,
93
+ ctx,
94
+ [
95
+ "Harness governance enabled.",
96
+ `Wrote .pi/harness/project.json (enabled=true, updated ${config.updated_at}).`,
97
+ "Live TUI surfaces were refreshed.",
98
+ ].join("\n"),
99
+ );
100
+ },
101
+ });
102
+
103
+ pi.registerCommand("harness-disable", {
104
+ description: "Disable harness governance for this project",
105
+ handler: async (_args, ctx) => {
106
+ const projectRoot = process.cwd();
107
+ const config = writeHarnessProjectEnabled(projectRoot, false);
108
+ const effectiveConfig = readHarnessProjectConfig(projectRoot);
109
+ pi.events.emit("harness-project-enabled:changed", {
110
+ enabled: effectiveConfig.enabled,
111
+ projectRoot,
112
+ updated_at: config.updated_at,
113
+ });
114
+ showCommandMessage(
115
+ pi,
116
+ ctx,
117
+ [
118
+ "Harness governance disabled.",
119
+ `Wrote .pi/harness/project.json (enabled=false, updated ${config.updated_at}).`,
120
+ "Workflow slash commands are blocked immediately.",
121
+ "Live TUI surfaces were refreshed.",
122
+ ].join("\n"),
123
+ );
124
+ },
125
+ });
126
+
127
+ pi.registerCommand("harness-enabled-status", {
128
+ description: "Show whether harness governance is enabled for this project",
129
+ handler: async (_args, ctx) => {
130
+ showCommandMessage(pi, ctx, formatStatus(process.cwd()));
131
+ },
132
+ });
133
+ }
@@ -2,7 +2,7 @@
2
2
  * Load before other extensions: IPv4-first fetch for *.posthog.com (@posthog/pi uses global fetch).
3
3
  */
4
4
 
5
- import { installPostHogFetchPatch } from "./lib/posthog-client.js";
5
+ import { installPostHogFetchPatch } from "../lib/posthog-client.js";
6
6
 
7
7
  installPostHogFetchPatch();
8
8
 
@@ -0,0 +1,57 @@
1
+ /**
2
+ * AGT kill switch — arms on harness-abort and repeated policy denies (ADR 0047).
3
+ */
4
+
5
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
6
+ import { KillSwitch } from "@microsoft/agent-governance-sdk";
7
+ import { isHarnessProjectEnabled } from "../lib/harness-project-config.js";
8
+ import {
9
+ hasHarnessAbortSignal,
10
+ userVisiblePromptSlice,
11
+ } from "../lib/harness-run-context.js";
12
+
13
+ const killSwitch = new KillSwitch({ enabled: true });
14
+
15
+ import { recordHarnessPolicyDeny } from "../lib/agt/kill-switch-state.js";
16
+
17
+ export function getHarnessKillSwitch(): KillSwitch {
18
+ return killSwitch;
19
+ }
20
+
21
+ export function recordHarnessPolicyDenyForKillSwitch(sessionId: string): void {
22
+ const n = recordHarnessPolicyDeny(sessionId);
23
+ if (n >= 5) {
24
+ void killSwitch.kill(sessionId, {
25
+ reason: "Repeated harness policy denials",
26
+ });
27
+ }
28
+ }
29
+
30
+ export default function agtKillSwitch(pi: ExtensionAPI) {
31
+ if (!isHarnessProjectEnabled()) return;
32
+
33
+ pi.on("before_agent_start", async (event, ctx) => {
34
+ const prompt = userVisiblePromptSlice(event.prompt);
35
+ if (hasHarnessAbortSignal(prompt)) {
36
+ const sessionId = ctx.sessionManager.getSessionId();
37
+ await killSwitch.kill(sessionId, {
38
+ reason: "harness-abort command",
39
+ });
40
+ }
41
+ return undefined;
42
+ });
43
+
44
+ pi.on("tool_call", async (_event, ctx) => {
45
+ const sessionId = ctx.sessionManager.getSessionId();
46
+ const history = killSwitch.getHistory();
47
+ const armed = history.some((h) => h.agentId === sessionId);
48
+ if (armed) {
49
+ return {
50
+ block: true,
51
+ reason:
52
+ "agt-kill-switch: harness session halted after abort or repeated policy breaches.",
53
+ };
54
+ }
55
+ return undefined;
56
+ });
57
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * AGT PromptDefense heuristics on harness slash commands (ADR 0047).
3
+ */
4
+
5
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
6
+ import { PromptDefenseEvaluator } from "@microsoft/agent-governance-sdk";
7
+ import { isHarnessProjectEnabled } from "../lib/harness-project-config.js";
8
+ import { userVisiblePromptSlice } from "../lib/harness-run-context.js";
9
+
10
+ const evaluator = new PromptDefenseEvaluator({ minGrade: "D" });
11
+
12
+ export default function agtPromptGuard(pi: ExtensionAPI) {
13
+ if (!isHarnessProjectEnabled()) return;
14
+
15
+ pi.on("before_agent_start", async (event) => {
16
+ const prompt = userVisiblePromptSlice(event.prompt);
17
+ if (!prompt.trim()) return undefined;
18
+ if (!/\/harness-/.test(prompt)) return undefined;
19
+
20
+ const report = evaluator.evaluate(prompt);
21
+ if (report.isBlocking("D")) {
22
+ return {
23
+ message: {
24
+ customType: "harness-policy-violation",
25
+ display: true,
26
+ content: `agt-prompt-guard: prompt defense grade ${report.grade} (${report.score}). Missing defenses: ${report.missing.join(", ") || "see findings"}.`,
27
+ },
28
+ };
29
+ }
30
+ return undefined;
31
+ });
32
+ }
@@ -12,6 +12,7 @@ import {
12
12
  isHarnessBudgetEnforceOn,
13
13
  shouldEmitBlockingBudgetExhausted,
14
14
  } from "../lib/harness-budget-enforce.js";
15
+ import { isHarnessProjectEnabled } from "../lib/harness-project-config.js";
15
16
  import { getRunIdFromSession } from "../lib/harness-run-context.js";
16
17
 
17
18
  type HarnessPhase = "plan" | "execute" | "evaluate" | "adversary" | "merge";
@@ -203,6 +204,7 @@ async function emitBudgetEvent(
203
204
  const debouncedSoftLimit = new Map<string, boolean>();
204
205
 
205
206
  export default function budgetGuard(pi: ExtensionAPI) {
207
+ if (!isHarnessProjectEnabled()) return;
206
208
  pi.on("tool_call", async (_event, ctx) => {
207
209
  const policy = getPolicyContext(ctx);
208
210
  if (policy.phase === null || policy.budgetBypass) return undefined;
@@ -8,7 +8,6 @@
8
8
  import type {
9
9
  ExtensionAPI,
10
10
  ExtensionContext,
11
- ThemeColor,
12
11
  } from "@earendil-works/pi-coding-agent";
13
12
  import type { TUI } from "@earendil-works/pi-tui";
14
13
  import {
@@ -17,56 +16,7 @@ import {
17
16
  truncateToWidth,
18
17
  visibleWidth,
19
18
  } from "@earendil-works/pi-tui";
20
-
21
- // ── router decision reader ──────────────────────────────────────────
22
-
23
- /** Extract last routing decision from model-router session entries. */
24
- function readRouterDecision(ctx: ExtensionContext): {
25
- targetProvider: string;
26
- targetModelId: string;
27
- thinking: string;
28
- profile: string;
29
- enabled: boolean;
30
- } | null {
31
- try {
32
- const entries = ctx.sessionManager.getEntries();
33
- for (let i = entries.length - 1; i >= 0; i--) {
34
- const e = entries[i];
35
- if (
36
- e.type === "custom" &&
37
- (e as any).customType === "router-state" &&
38
- (e as any).data
39
- ) {
40
- const data = (e as any).data;
41
- const d = data.lastDecision;
42
- if (d?.targetProvider && d?.targetModelId) {
43
- return {
44
- targetProvider: d.targetProvider,
45
- targetModelId: d.targetModelId,
46
- thinking: d.thinking,
47
- profile: data.selectedProfile ?? d.profile,
48
- enabled: data.enabled ?? true,
49
- };
50
- }
51
- }
52
- }
53
- } catch {
54
- // session not ready
55
- }
56
- return null;
57
- }
58
-
59
- // ── profile colors ────────────────────────────────────────────────
60
-
61
- const PROFILE_COLORS: Record<string, ThemeColor> = {
62
- auto: "accent",
63
- cheap: "success",
64
- deep: "toolTitle",
65
- };
66
-
67
- function profileColor(profile: string): ThemeColor {
68
- return PROFILE_COLORS[profile] ?? "muted";
69
- }
19
+ import { getLSPService } from "../lib/harness-lens/clients/lsp/index.js";
70
20
 
71
21
  // ── token formatting ──────────────────────────────────────────────
72
22
 
@@ -145,20 +95,6 @@ function modelInfo(ctx: ExtensionContext): ModelInfo {
145
95
  const m = ctx.model;
146
96
  if (!m) return { id: "no-model", provider: "unknown", reasoning: false };
147
97
 
148
- // Router provider — extract actual model from routing decision
149
- if (m.provider === "router") {
150
- const decision = readRouterDecision(ctx);
151
- if (decision) {
152
- return {
153
- id: decision.targetModelId,
154
- provider: decision.targetProvider,
155
- reasoning: true,
156
- };
157
- }
158
- // No decision yet — show profile name so user knows router is active
159
- return { id: m.id, provider: "router", reasoning: m.reasoning };
160
- }
161
-
162
98
  return { id: m.id, provider: m.provider, reasoning: m.reasoning };
163
99
  }
164
100
 
@@ -190,8 +126,17 @@ function pathLabel(
190
126
 
191
127
  // ── extension ─────────────────────────────────────────────────────
192
128
 
129
+ function lspAlive(): boolean {
130
+ try {
131
+ return getLSPService().getAliveClientCount() > 0;
132
+ } catch {
133
+ return false;
134
+ }
135
+ }
136
+
193
137
  export default function customFooter(pi: ExtensionAPI) {
194
138
  let unsubBranch: (() => void) | null = null;
139
+ let lspInvalidateTimer: ReturnType<typeof setInterval> | null = null;
195
140
 
196
141
  const state: {
197
142
  tui: TUI | null;
@@ -204,8 +149,6 @@ export default function customFooter(pi: ExtensionAPI) {
204
149
  modelProvider: string;
205
150
  modelReasoning: boolean;
206
151
  thinkingLevel: string | null;
207
- routerProfile: string | null;
208
- routerActive: boolean;
209
152
  branch: string | null;
210
153
  } = {
211
154
  tui: null,
@@ -218,8 +161,6 @@ export default function customFooter(pi: ExtensionAPI) {
218
161
  modelProvider: "…",
219
162
  modelReasoning: false,
220
163
  thinkingLevel: null,
221
- routerProfile: null,
222
- routerActive: false,
223
164
  branch: null,
224
165
  };
225
166
 
@@ -235,17 +176,7 @@ export default function customFooter(pi: ExtensionAPI) {
235
176
  state.modelProvider = mi.provider;
236
177
  state.modelReasoning = mi.reasoning;
237
178
 
238
- // When router active, use thinking from the routing decision
239
- if (ctx.model?.provider === "router") {
240
- const routerDecision = readRouterDecision(ctx);
241
- state.thinkingLevel = routerDecision?.thinking ?? pi.getThinkingLevel();
242
- state.routerProfile = routerDecision?.profile ?? ctx.model?.id;
243
- state.routerActive = routerDecision?.enabled ?? true;
244
- } else {
245
- state.thinkingLevel = pi.getThinkingLevel();
246
- state.routerProfile = null;
247
- state.routerActive = false;
248
- }
179
+ state.thinkingLevel = pi.getThinkingLevel();
249
180
  }
250
181
 
251
182
  pi.on("session_start", (_event, ctx) => {
@@ -258,6 +189,10 @@ export default function customFooter(pi: ExtensionAPI) {
258
189
  unsubBranch();
259
190
  unsubBranch = null;
260
191
  }
192
+ if (lspInvalidateTimer) {
193
+ clearInterval(lspInvalidateTimer);
194
+ lspInvalidateTimer = null;
195
+ }
261
196
 
262
197
  state.tui = tui;
263
198
  state.branch = footerData.getGitBranch();
@@ -274,12 +209,19 @@ export default function customFooter(pi: ExtensionAPI) {
274
209
  state.box = box;
275
210
  state.textLine = textLine;
276
211
 
212
+ lspInvalidateTimer = setInterval(invalidate, 2000);
213
+ lspInvalidateTimer.unref?.();
214
+
277
215
  return {
278
216
  dispose() {
279
217
  if (unsubBranch) {
280
218
  unsubBranch();
281
219
  unsubBranch = null;
282
220
  }
221
+ if (lspInvalidateTimer) {
222
+ clearInterval(lspInvalidateTimer);
223
+ lspInvalidateTimer = null;
224
+ }
283
225
  state.tui = null;
284
226
  state.box = null;
285
227
  state.textLine = null;
@@ -328,59 +270,39 @@ export default function customFooter(pi: ExtensionAPI) {
328
270
  const tl = thinkingLabel(state.thinkingLevel, state.modelReasoning);
329
271
  const modelDisplay = tl ? `${state.modelId} ${tl}` : state.modelId;
330
272
 
331
- // Colorize: router profile gets mode color, model gets thinking color
332
- const rightStr = state.routerActive
333
- ? (() => {
334
- const pColor = profileColor(state.routerProfile ?? "router");
335
- const profileStr = theme.fg(
336
- pColor,
337
- state.routerProfile ?? "router",
338
- );
339
- const thinkingColorFn = theme.getThinkingBorderColor(
340
- (state.thinkingLevel as any) ?? "medium",
341
- );
342
- const modelStr = thinkingColorFn(modelDisplay);
343
- return `${profileStr} • ${modelStr}`;
344
- })()
345
- : `${state.modelProvider} • ${modelDisplay}`;
273
+ const lspActive = lspAlive();
274
+ const lspIndicator = theme.fg(
275
+ lspActive ? "success" : "error",
276
+ lspActive ? "LSP✓" : "LSP×",
277
+ );
278
+ const rightStr = `${state.modelProvider} • ${modelDisplay}`;
346
279
 
347
280
  // ── compose single line ──
348
281
  const colLeft = leftStr;
349
- const finalRight = state.routerActive ? rightStr : dim(rightStr);
282
+ const contextDisplay = `${lspIndicator} ${barFull}`;
283
+ const finalRight = dim(rightStr);
350
284
  const lw = visibleWidth(colLeft);
351
285
  const rw = visibleWidth(finalRight);
352
- const bw = visibleWidth(barFull);
286
+ const cw = visibleWidth(contextDisplay);
353
287
  const gap = 2;
354
288
 
355
- if (lw + gap + bw + gap + rw <= innerW) {
356
- const pad = innerW - lw - gap - bw - gap - rw;
289
+ if (lw + gap + cw + gap + rw <= innerW) {
290
+ const pad = innerW - lw - gap - cw - gap - rw;
357
291
  const line =
358
292
  colLeft +
359
293
  " ".repeat(gap + pad) +
360
- barFull +
294
+ contextDisplay +
361
295
  " ".repeat(gap) +
362
296
  finalRight;
363
297
  textLine.setText(truncateToWidth(line, innerW));
364
298
  } else {
365
- // Priority: keep bar visible, keep left (cwd) intact, truncate modelId first
299
+ // Priority: keep LSP + context bar visible, keep left (cwd) intact, truncate modelId first
366
300
  const tlNow = thinkingLabel(
367
301
  state.thinkingLevel,
368
302
  state.modelReasoning,
369
303
  );
370
- const thinkingColorFn = theme.getThinkingBorderColor(
371
- (state.thinkingLevel as any) ?? "medium",
372
- );
373
304
  const buildRight = (mid: string) => {
374
305
  const modelPart = tlNow ? `${mid} ${tlNow}` : mid;
375
- if (state.routerActive) {
376
- const pColor = profileColor(state.routerProfile ?? "router");
377
- const profileStr = theme.fg(
378
- pColor,
379
- state.routerProfile ?? "router",
380
- );
381
- const modelStr = thinkingColorFn(modelPart);
382
- return `${profileStr} • ${modelStr}`;
383
- }
384
306
  const parts: string[] = [state.modelProvider];
385
307
  if (modelPart) parts.push(modelPart);
386
308
  return dim(parts.join(" • "));
@@ -392,25 +314,25 @@ export default function customFooter(pi: ExtensionAPI) {
392
314
 
393
315
  while (
394
316
  truncMid.length > 0 &&
395
- lw + gap + bw + gap + rwNow > innerW
317
+ lw + gap + cw + gap + rwNow > innerW
396
318
  ) {
397
319
  truncMid = truncMid.slice(0, -1);
398
320
  dimR = buildRight(truncMid);
399
321
  rwNow = visibleWidth(dimR);
400
322
  }
401
323
 
402
- if (lw + gap + bw + gap + rwNow <= innerW) {
403
- const pad = innerW - lw - gap - bw - gap - rwNow;
324
+ if (lw + gap + cw + gap + rwNow <= innerW) {
325
+ const pad = innerW - lw - gap - cw - gap - rwNow;
404
326
  const line =
405
327
  colLeft +
406
328
  " ".repeat(gap + pad) +
407
- barFull +
329
+ contextDisplay +
408
330
  " ".repeat(gap) +
409
331
  dimR;
410
332
  textLine.setText(truncateToWidth(line, innerW));
411
333
  } else {
412
334
  // ModelId gone, still overflows: truncate leftStr
413
- const avail = innerW - bw - rwNow - gap - gap;
335
+ const avail = innerW - cw - rwNow - gap - gap;
414
336
  if (avail < 1) {
415
337
  textLine.setText(truncateToWidth(dimR, innerW));
416
338
  } else {
@@ -418,7 +340,7 @@ export default function customFooter(pi: ExtensionAPI) {
418
340
  const line =
419
341
  truncLeft +
420
342
  " ".repeat(gap) +
421
- barFull +
343
+ contextDisplay +
422
344
  " ".repeat(gap) +
423
345
  dimR;
424
346
  textLine.setText(truncateToWidth(line, innerW));
@@ -442,32 +364,11 @@ export default function customFooter(pi: ExtensionAPI) {
442
364
  });
443
365
 
444
366
  // Track model changes
445
- pi.on("model_select", (event, ctx) => {
446
- if (event.model?.provider === "router") {
447
- const routerDecision = readRouterDecision(ctx);
448
- if (routerDecision) {
449
- state.modelId = routerDecision.targetModelId;
450
- state.modelProvider = routerDecision.targetProvider;
451
- state.modelReasoning = true;
452
- state.thinkingLevel = routerDecision.thinking;
453
- state.routerProfile = routerDecision.profile;
454
- state.routerActive = routerDecision.enabled;
455
- } else {
456
- state.modelId = event.model.id ?? "…";
457
- state.modelProvider = "router";
458
- state.modelReasoning = event.model?.reasoning ?? false;
459
- state.thinkingLevel = pi.getThinkingLevel();
460
- state.routerProfile = event.model.id;
461
- state.routerActive = true;
462
- }
463
- } else {
464
- state.modelId = event.model?.id ?? "…";
465
- state.modelProvider = event.model?.provider ?? "…";
466
- state.modelReasoning = event.model?.reasoning ?? false;
467
- state.thinkingLevel = pi.getThinkingLevel();
468
- state.routerProfile = null;
469
- state.routerActive = false;
470
- }
367
+ pi.on("model_select", (event) => {
368
+ state.modelId = event.model?.id ?? "";
369
+ state.modelProvider = event.model?.provider ?? "…";
370
+ state.modelReasoning = event.model?.reasoning ?? false;
371
+ state.thinkingLevel = pi.getThinkingLevel();
471
372
  invalidate();
472
373
  });
473
374
 
@@ -9,7 +9,7 @@
9
9
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
10
10
  import { truncateToWidth } from "@earendil-works/pi-tui";
11
11
  import * as JimpModule from "jimp";
12
- import { resolveHarnessAsset } from "./lib/harness-paths.js";
12
+ import { resolveHarnessAsset } from "../lib/harness-paths.js";
13
13
 
14
14
  /** Shipped next to this extension in the npm package — not the host project's .pi dir. */
15
15
  const imagePath = resolveHarnessAsset(
@@ -15,7 +15,7 @@ import type {
15
15
  ExtensionAPI,
16
16
  } from "@earendil-works/pi-coding-agent";
17
17
  import { formatSkillsForPrompt } from "@earendil-works/pi-coding-agent";
18
- import { resolveHarnessAsset } from "./lib/harness-paths.js";
18
+ import { resolveHarnessAsset } from "../lib/harness-paths.js";
19
19
 
20
20
  // @ts-expect-error pi extensions run as ESM
21
21
  const MODULE_URL = import.meta.url;
@@ -6,19 +6,20 @@
6
6
 
7
7
  import { join } from "node:path";
8
8
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
9
- import { getRunIdFromSession } from "../lib/harness-run-context.js";
10
9
  import {
11
10
  acceptDebateRound,
12
11
  finalizeDebateConsensus,
13
12
  openDebateBus,
14
13
  parseRoundEnvelope,
15
- } from "./lib/debate-bus-core.js";
14
+ } from "../lib/debate-bus-core.js";
16
15
  import {
17
16
  getDebateState,
18
17
  restoreDebateStateFromEntry,
19
- } from "./lib/debate-bus-state.js";
20
- import { normalizePlanDebateId } from "./lib/plan-debate-id.js";
21
- import { initPlanMessenger } from "./lib/plan-messenger.js";
18
+ } from "../lib/debate-bus-state.js";
19
+ import { isHarnessProjectEnabled } from "../lib/harness-project-config.js";
20
+ import { getRunIdFromSession } from "../lib/harness-run-context.js";
21
+ import { normalizePlanDebateId } from "../lib/plan-debate-id.js";
22
+ import { initPlanMessenger } from "../lib/plan-messenger.js";
22
23
 
23
24
  function getRunId(ctx: {
24
25
  sessionManager: { getEntries(): unknown[]; getSessionId(): string };
@@ -32,6 +33,7 @@ function getRunId(ctx: {
32
33
  }
33
34
 
34
35
  export default function debateOrchestrator(pi: ExtensionAPI) {
36
+ if (!isHarnessProjectEnabled()) return;
35
37
  const hooks = {
36
38
  appendEntry: (customType: string, data: unknown) =>
37
39
  pi.appendEntry(customType, data),
@@ -4,27 +4,27 @@
4
4
  */
5
5
 
6
6
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
7
- import { runAskDialog } from "./lib/ask-user/dialog.js";
8
- import { runAskFallback } from "./lib/ask-user/fallback.js";
9
- import { renderAskCall, renderAskResult } from "./lib/ask-user/render.js";
7
+ import { runAskDialog } from "../lib/ask-user/dialog.js";
8
+ import { runAskFallback } from "../lib/ask-user/fallback.js";
9
+ import { renderAskCall, renderAskResult } from "../lib/ask-user/render.js";
10
10
  import {
11
11
  AskUserParamsSchema,
12
12
  PROMPT_GUIDELINES,
13
13
  PROMPT_SNIPPET,
14
- } from "./lib/ask-user/schema.js";
15
- import type { AskUserParams, DialogResult } from "./lib/ask-user/types.js";
14
+ } from "../lib/ask-user/schema.js";
15
+ import type { AskUserParams, DialogResult } from "../lib/ask-user/types.js";
16
16
  import {
17
17
  formatResultText,
18
18
  toToolDetails,
19
19
  validateAskParams,
20
- } from "./lib/ask-user/validate.js";
21
- import { claimExtensionLoad } from "./lib/extension-load-guard.js";
20
+ } from "../lib/ask-user/validate.js";
21
+ import { claimHarnessGovernanceLoad } from "../lib/extension-load-guard.js";
22
22
 
23
23
  // @ts-expect-error pi extensions run as ESM
24
24
  const MODULE_URL = import.meta.url;
25
25
 
26
26
  export default function harnessAskUser(pi: ExtensionAPI) {
27
- if (!claimExtensionLoad("harness-ask-user", MODULE_URL)) return;
27
+ if (!claimHarnessGovernanceLoad("harness-ask-user", MODULE_URL)) return;
28
28
  pi.registerTool({
29
29
  name: "ask_user",
30
30
  label: "Ask User",