@nklisch/pi-enhanced 0.1.3 → 0.1.4

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 (235) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/node_modules/@nklisch/pi-clearance/README.md +10 -5
  3. package/node_modules/@nklisch/pi-clearance/docs/ARCHITECTURE.md +8 -5
  4. package/node_modules/@nklisch/pi-clearance/docs/CONFIGURATION.md +25 -35
  5. package/node_modules/@nklisch/pi-clearance/docs/DEVELOPER_GUIDE.md +13 -11
  6. package/node_modules/@nklisch/pi-clearance/docs/PACK_AUTHORING.md +5 -4
  7. package/node_modules/@nklisch/pi-clearance/docs/PRINCIPLES.md +14 -10
  8. package/node_modules/@nklisch/pi-clearance/docs/REFERENCE_PATTERNS.md +1 -1
  9. package/node_modules/@nklisch/pi-clearance/docs/REVIEWER_PROMPTS.md +12 -8
  10. package/node_modules/@nklisch/pi-clearance/docs/RULE_PACKS.md +1 -1
  11. package/node_modules/@nklisch/pi-clearance/docs/SPEC.md +7 -6
  12. package/node_modules/@nklisch/pi-clearance/docs/TUNE.md +2 -2
  13. package/node_modules/@nklisch/pi-clearance/docs/USER_GUIDE.md +7 -3
  14. package/node_modules/@nklisch/pi-clearance/docs/VISION.md +3 -3
  15. package/node_modules/@nklisch/pi-clearance/native/clearance-core.darwin-x64.node +0 -0
  16. package/node_modules/@nklisch/pi-clearance/native/clearance-core.linux-arm64-gnu.node +0 -0
  17. package/node_modules/@nklisch/pi-clearance/native/clearance-core.win32-arm64-msvc.node +0 -0
  18. package/node_modules/@nklisch/pi-clearance/native/clearance-core.win32-x64-msvc.node +0 -0
  19. package/node_modules/@nklisch/pi-clearance/package.json +9 -5
  20. package/node_modules/@nklisch/pi-clearance/src/config/config-command-plans.ts +79 -3
  21. package/node_modules/@nklisch/pi-clearance/src/config/config-command-writer.ts +7 -1
  22. package/node_modules/@nklisch/pi-clearance/src/config/defaults.ts +42 -0
  23. package/node_modules/@nklisch/pi-clearance/src/config/gated-tools.ts +7 -0
  24. package/node_modules/@nklisch/pi-clearance/src/config/loader.ts +7 -1
  25. package/node_modules/@nklisch/pi-clearance/src/config/pack-enablement-writer.ts +1 -0
  26. package/node_modules/@nklisch/pi-clearance/src/config/paths.ts +14 -3
  27. package/node_modules/@nklisch/pi-clearance/src/config/persistence.ts +135 -0
  28. package/node_modules/@nklisch/pi-clearance/src/config/schema.ts +74 -26
  29. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCase.ts +1 -1
  30. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseCategory.ts +1 -1
  31. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseExpectation.ts +1 -1
  32. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseResult.ts +1 -1
  33. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseResultOutcome.ts +1 -1
  34. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseSource.ts +1 -1
  35. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialValidationReport.ts +1 -1
  36. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialValidationStatus.ts +1 -1
  37. package/node_modules/@nklisch/pi-clearance/src/contracts/BashBlock.ts +1 -1
  38. package/node_modules/@nklisch/pi-clearance/src/contracts/BashCommandShape.ts +1 -1
  39. package/node_modules/@nklisch/pi-clearance/src/contracts/BashConditionalArm.ts +1 -1
  40. package/node_modules/@nklisch/pi-clearance/src/contracts/BashControlConstruct.ts +1 -1
  41. package/node_modules/@nklisch/pi-clearance/src/contracts/BashFlag.ts +1 -1
  42. package/node_modules/@nklisch/pi-clearance/src/contracts/BashForLoopKeywordSpans.ts +1 -1
  43. package/node_modules/@nklisch/pi-clearance/src/contracts/BashIteratorEntry.ts +1 -1
  44. package/node_modules/@nklisch/pi-clearance/src/contracts/BashIteratorEntryKind.ts +1 -1
  45. package/node_modules/@nklisch/pi-clearance/src/contracts/BashListOperator.ts +1 -1
  46. package/node_modules/@nklisch/pi-clearance/src/contracts/BashLoopVariableReference.ts +1 -1
  47. package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFact.ts +1 -1
  48. package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFactContext.ts +1 -1
  49. package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFactProvenance.ts +1 -1
  50. package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFactProvenanceEntry.ts +1 -1
  51. package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFacts.ts +1 -1
  52. package/node_modules/@nklisch/pi-clearance/src/contracts/BashPipeline.ts +1 -1
  53. package/node_modules/@nklisch/pi-clearance/src/contracts/BashStage.ts +1 -1
  54. package/node_modules/@nklisch/pi-clearance/src/contracts/BashStageProgram.ts +1 -1
  55. package/node_modules/@nklisch/pi-clearance/src/contracts/BlockOperator.ts +1 -1
  56. package/node_modules/@nklisch/pi-clearance/src/contracts/CapturedOutcome.ts +1 -1
  57. package/node_modules/@nklisch/pi-clearance/src/contracts/CommandFamilyKey.ts +1 -1
  58. package/node_modules/@nklisch/pi-clearance/src/contracts/CommandFamilySummary.ts +1 -1
  59. package/node_modules/@nklisch/pi-clearance/src/contracts/CompileError.ts +1 -1
  60. package/node_modules/@nklisch/pi-clearance/src/contracts/CompositionOperator.ts +1 -1
  61. package/node_modules/@nklisch/pi-clearance/src/contracts/CompoundBodyReason.ts +1 -1
  62. package/node_modules/@nklisch/pi-clearance/src/contracts/CompoundFeatureReason.ts +1 -1
  63. package/node_modules/@nklisch/pi-clearance/src/contracts/CompoundForm.ts +1 -1
  64. package/node_modules/@nklisch/pi-clearance/src/contracts/CompoundIteratorReason.ts +1 -1
  65. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusEntry.ts +1 -1
  66. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusExpectedLabel.ts +1 -1
  67. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusFidelity.ts +1 -1
  68. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusQueryModel.ts +1 -1
  69. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusQuerySummary.ts +1 -1
  70. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusQuerySummarySnapshot.ts +1 -1
  71. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusRecord.ts +1 -1
  72. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusSource.ts +1 -1
  73. package/node_modules/@nklisch/pi-clearance/src/contracts/CountByLabel.ts +1 -1
  74. package/node_modules/@nklisch/pi-clearance/src/contracts/Decision.ts +1 -1
  75. package/node_modules/@nklisch/pi-clearance/src/contracts/DecisionEffect.ts +1 -1
  76. package/node_modules/@nklisch/pi-clearance/src/contracts/DecisionProvenance.ts +1 -1
  77. package/node_modules/@nklisch/pi-clearance/src/contracts/DecisionSource.ts +1 -1
  78. package/node_modules/@nklisch/pi-clearance/src/contracts/DiagnosticSeverity.ts +1 -1
  79. package/node_modules/@nklisch/pi-clearance/src/contracts/EffectivePolicy.ts +1 -1
  80. package/node_modules/@nklisch/pi-clearance/src/contracts/EmbeddedShellProjection.ts +1 -1
  81. package/node_modules/@nklisch/pi-clearance/src/contracts/EnvironmentAssignment.ts +1 -1
  82. package/node_modules/@nklisch/pi-clearance/src/contracts/IteratorSourceKind.ts +1 -1
  83. package/node_modules/@nklisch/pi-clearance/src/contracts/LoopQuoteKind.ts +1 -1
  84. package/node_modules/@nklisch/pi-clearance/src/contracts/LoopVariableUnknownReason.ts +1 -1
  85. package/node_modules/@nklisch/pi-clearance/src/contracts/MatcherExpr.ts +1 -1
  86. package/node_modules/@nklisch/pi-clearance/src/contracts/MutationShapeKind.ts +1 -1
  87. package/node_modules/@nklisch/pi-clearance/src/contracts/MutationTrustBoundaryClassification.ts +1 -1
  88. package/node_modules/@nklisch/pi-clearance/src/contracts/MutationTrustBoundaryKind.ts +1 -1
  89. package/node_modules/@nklisch/pi-clearance/src/contracts/PackCompileResult.ts +1 -1
  90. package/node_modules/@nklisch/pi-clearance/src/contracts/PackWarningLevel.ts +1 -1
  91. package/node_modules/@nklisch/pi-clearance/src/contracts/ParsedEvidence.ts +1 -1
  92. package/node_modules/@nklisch/pi-clearance/src/contracts/ParsedShapeSummary.ts +1 -1
  93. package/node_modules/@nklisch/pi-clearance/src/contracts/PathAccess.ts +1 -1
  94. package/node_modules/@nklisch/pi-clearance/src/contracts/PathFactProjectScope.ts +1 -1
  95. package/node_modules/@nklisch/pi-clearance/src/contracts/PathFactsRequirement.ts +1 -1
  96. package/node_modules/@nklisch/pi-clearance/src/contracts/PathFactsResolvedConfig.ts +1 -1
  97. package/node_modules/@nklisch/pi-clearance/src/contracts/PathNormalization.ts +1 -1
  98. package/node_modules/@nklisch/pi-clearance/src/contracts/PathScope.ts +1 -1
  99. package/node_modules/@nklisch/pi-clearance/src/contracts/PathScopeMatcherExpr.ts +1 -1
  100. package/node_modules/@nklisch/pi-clearance/src/contracts/PathScopeMatcherMode.ts +1 -1
  101. package/node_modules/@nklisch/pi-clearance/src/contracts/PathUnknownReason.ts +1 -1
  102. package/node_modules/@nklisch/pi-clearance/src/contracts/PathUsageKind.ts +1 -1
  103. package/node_modules/@nklisch/pi-clearance/src/contracts/PiBuiltinToolOperation.ts +1 -1
  104. package/node_modules/@nklisch/pi-clearance/src/contracts/PiBuiltinToolPathInput.ts +1 -1
  105. package/node_modules/@nklisch/pi-clearance/src/contracts/PiBuiltinToolShape.ts +1 -1
  106. package/node_modules/@nklisch/pi-clearance/src/contracts/PiBuiltinToolSpec.ts +1 -1
  107. package/node_modules/@nklisch/pi-clearance/src/contracts/PiFileMutationToolName.ts +1 -1
  108. package/node_modules/@nklisch/pi-clearance/src/contracts/PiToolMutationFacts.ts +1 -1
  109. package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPack.ts +1 -1
  110. package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPackDocLink.ts +1 -1
  111. package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPackExample.ts +1 -1
  112. package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPackMetadata.ts +1 -1
  113. package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPackWarning.ts +1 -1
  114. package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyRule.ts +1 -1
  115. package/node_modules/@nklisch/pi-clearance/src/contracts/ProposalNotRunReason.ts +1 -1
  116. package/node_modules/@nklisch/pi-clearance/src/contracts/ProposalNotRunSeverity.ts +1 -1
  117. package/node_modules/@nklisch/pi-clearance/src/contracts/QuoteKind.ts +1 -1
  118. package/node_modules/@nklisch/pi-clearance/src/contracts/Redirect.ts +1 -1
  119. package/node_modules/@nklisch/pi-clearance/src/contracts/RedirectStream.ts +1 -1
  120. package/node_modules/@nklisch/pi-clearance/src/contracts/RedirectTargetKind.ts +1 -1
  121. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayCorpus.ts +1 -1
  122. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDelta.ts +1 -1
  123. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaBlockedSummary.ts +1 -1
  124. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaChangedRecord.ts +1 -1
  125. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaFamily.ts +1 -1
  126. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaImprovement.ts +1 -1
  127. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaRegression.ts +1 -1
  128. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaStatus.ts +1 -1
  129. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaTransitionCount.ts +1 -1
  130. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayPathFacts.ts +1 -1
  131. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayReviewerMode.ts +1 -1
  132. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayReviewerOutcome.ts +1 -1
  133. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayStatus.ts +1 -1
  134. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayedDecision.ts +1 -1
  135. package/node_modules/@nklisch/pi-clearance/src/contracts/ShapeDiagnostic.ts +1 -1
  136. package/node_modules/@nklisch/pi-clearance/src/contracts/SourceFidelity.ts +1 -1
  137. package/node_modules/@nklisch/pi-clearance/src/contracts/SourceSpan.ts +1 -1
  138. package/node_modules/@nklisch/pi-clearance/src/contracts/Substitution.ts +1 -1
  139. package/node_modules/@nklisch/pi-clearance/src/contracts/SubstitutionKind.ts +1 -1
  140. package/node_modules/@nklisch/pi-clearance/src/contracts/ToolCallIdentity.ts +1 -1
  141. package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathAccess.ts +1 -1
  142. package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathFact.ts +1 -1
  143. package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathFactContext.ts +1 -1
  144. package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathFacts.ts +1 -1
  145. package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathUsage.ts +1 -1
  146. package/node_modules/@nklisch/pi-clearance/src/contracts/ToolShape.ts +1 -1
  147. package/node_modules/@nklisch/pi-clearance/src/contracts/UnknownPathBehavior.ts +1 -1
  148. package/node_modules/@nklisch/pi-clearance/src/contracts/UnknownToolShape.ts +1 -1
  149. package/node_modules/@nklisch/pi-clearance/src/contracts/index.ts +1 -1
  150. package/node_modules/@nklisch/pi-clearance/src/index.ts +33 -2
  151. package/node_modules/@nklisch/pi-clearance/src/native/loader.ts +12 -6
  152. package/node_modules/@nklisch/pi-clearance/src/replay/reviewer-config-proposals.ts +7 -4
  153. package/node_modules/@nklisch/pi-clearance/src/runtime/allow-request-message.ts +21 -0
  154. package/node_modules/@nklisch/pi-clearance/src/runtime/auto-reviewer-read-models.ts +165 -8
  155. package/node_modules/@nklisch/pi-clearance/src/runtime/command-registry.ts +1 -1
  156. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/allow.ts +26 -2
  157. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/packs.ts +6 -6
  158. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/scope.ts +5 -5
  159. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/actions.ts +11 -0
  160. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/dispatcher.ts +274 -1
  161. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/model-options.ts +52 -0
  162. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/native-ui.ts +54 -67
  163. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/panels/reviewer.ts +19 -3
  164. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/panels/scope.ts +2 -11
  165. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/panels.ts +10 -1
  166. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/read-model.ts +47 -13
  167. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings.ts +32 -37
  168. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/status.ts +3 -0
  169. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/types.ts +14 -5
  170. package/node_modules/@nklisch/pi-clearance/src/runtime/handler.ts +36 -0
  171. package/node_modules/@nklisch/pi-clearance/src/runtime/mode-prompt.ts +0 -1
  172. package/node_modules/@nklisch/pi-clearance/src/runtime/model-adapter.ts +5 -1
  173. package/node_modules/@nklisch/pi-clearance/src/runtime/reviewer-context.ts +73 -10
  174. package/node_modules/@nklisch/pi-clearance/src/runtime/reviewer-prompts.ts +186 -175
  175. package/node_modules/@nklisch/pi-clearance/src/runtime/reviewer.ts +26 -6
  176. package/node_modules/@nklisch/pi-plugins/dist/infrastructure/state/local-lock-filesystem.d.ts +23 -1
  177. package/node_modules/@nklisch/pi-plugins/dist/infrastructure/state/local-lock-filesystem.js +46 -50
  178. package/node_modules/@nklisch/pi-plugins/dist/infrastructure/state/local-lock-filesystem.js.map +1 -1
  179. package/node_modules/@nklisch/pi-plugins/dist/runtime/mcp/pi-mcp-adapter-package.js +2 -2
  180. package/node_modules/@nklisch/pi-plugins/dist/runtime/mcp/pi-mcp-adapter-package.js.map +1 -1
  181. package/node_modules/@nklisch/pi-plugins/dist/runtime/mcp/pi-mcp-adapter-runtime.js +2 -2
  182. package/node_modules/@nklisch/pi-plugins/dist/runtime/mcp/pi-mcp-adapter-runtime.js.map +1 -1
  183. package/node_modules/@nklisch/pi-plugins/dist/runtime/subagents/pi-subagents-lifecycle.js +1 -1
  184. package/node_modules/@nklisch/pi-plugins/dist/runtime/subagents/pi-subagents-package.js +2 -2
  185. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/README.md +41 -31
  186. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/dist/public.d.ts +2 -1
  187. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/FORK-MAINTENANCE.md +17 -11
  188. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/VISION.md +14 -7
  189. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/architecture.md +11 -19
  190. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/comparison-with-upstream.md +58 -53
  191. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/package.json +2 -2
  192. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/agent-type-resolution.ts +43 -0
  193. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/agent-types.ts +11 -6
  194. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/custom-agents.ts +13 -6
  195. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/default-agents.ts +0 -52
  196. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/thinking-levels.ts +12 -0
  197. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/handlers/interrupt.ts +5 -2
  198. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/handlers/lifecycle.ts +3 -3
  199. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/index.ts +7 -6
  200. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/create-subagent-session.ts +7 -2
  201. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/parent-snapshot.ts +11 -3
  202. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent-manager.ts +26 -56
  203. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent-session.ts +48 -9
  204. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent-state.ts +32 -0
  205. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent.ts +105 -17
  206. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/observation/composite-subagent-observer.ts +4 -0
  207. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/observation/notification.ts +50 -46
  208. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/observation/renderer.ts +1 -1
  209. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/observation/subagent-events-observer.ts +15 -0
  210. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/runtime.ts +2 -0
  211. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/service/service-adapter.ts +35 -6
  212. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/service/service.ts +1 -0
  213. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/session/model-label.ts +19 -0
  214. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/session/prompts.ts +24 -1
  215. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/session/session-config.ts +11 -6
  216. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/settings.ts +70 -3
  217. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/agent-tool.ts +27 -10
  218. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/background-spawner.ts +6 -2
  219. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/foreground-runner.ts +12 -3
  220. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/get-result-report.ts +17 -3
  221. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/get-result-tool.ts +13 -20
  222. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/result-renderer.ts +6 -1
  223. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/spawn-config.ts +16 -16
  224. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/steer-tool.ts +12 -4
  225. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/types.ts +2 -2
  226. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/agent-widget.ts +24 -11
  227. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/display.ts +10 -7
  228. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/glyphs.ts +7 -0
  229. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/session-navigation.ts +34 -25
  230. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/session-navigator.ts +30 -10
  231. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/subagents-settings.ts +58 -13
  232. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/widget-renderer.ts +32 -19
  233. package/node_modules/@nklisch/pi-plugins/package.json +3 -3
  234. package/package.json +1 -1
  235. package/test/verify-bundle.mjs +4 -0
@@ -1,7 +1,11 @@
1
1
  import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
2
  import { Key, matchesKey, truncateToWidth } from "@earendil-works/pi-tui";
3
3
 
4
- import type { ProjectScopeListField } from "../../../config/config-command-plans.ts";
4
+ import {
5
+ inferScopePreset,
6
+ SCOPE_PRESET_LABELS,
7
+ type ProjectScopeListField,
8
+ } from "../../../config/config-command-plans.ts";
5
9
  import { handleScopeCommand } from "../scope.ts";
6
10
  import type { CommandReport } from "../types.ts";
7
11
  import type { SettingsAction, SettingsActionId } from "./actions.ts";
@@ -645,6 +649,11 @@ export class SettingsNativeUiComponent {
645
649
  `Mode: ${this.model.currentMode.label} - ${this.model.currentMode.description}`,
646
650
  `Reviewer: ${this.model.status.reviewer.path} - ${this.model.status.reviewer.consequence}`,
647
651
  `Review context: ${this.model.status.reviewer.contextMode}`,
652
+ ...((this.model.status.customizations?.length ?? 0) === 0
653
+ ? []
654
+ : [
655
+ `Customizations: ${this.model.status.customizations?.join("; ") ?? ""}`,
656
+ ]),
648
657
  `Packs: ${this.model.status.packs.enabled}/${this.model.status.packs.total} enabled`,
649
658
  ];
650
659
  }
@@ -720,16 +729,11 @@ export class SettingsNativeUiComponent {
720
729
 
721
730
  function homeItems(model: SettingsReadModel): readonly NativeSettingsItem[] {
722
731
  return [
723
- ...model.modes.map((mode) => ({
724
- kind: "selection" as const,
725
- label: `Set mode: ${mode.label}`,
726
- description: mode.description,
727
- selection: {
728
- kind: "action" as const,
729
- label: `Set mode: ${mode.label}`,
730
- action: { id: "mode.set" as const, args: { mode: mode.mode } },
731
- },
732
- })),
732
+ actionItem(
733
+ `Mode: ${model.currentMode.label}`,
734
+ model.currentMode.description,
735
+ { id: "mode.select", args: {} },
736
+ ),
733
737
  ...model.panels.map((descriptor) => ({
734
738
  kind: "panel" as const,
735
739
  label: descriptor.title,
@@ -763,22 +767,36 @@ function panelItems(
763
767
  function reviewerItems(
764
768
  model: SettingsReadModel,
765
769
  ): readonly NativeSettingsItem[] {
770
+ const configuredModel = model.status.reviewer.configuredModel;
771
+ const gatedToolItems = model.gatedTools.names.map((toolName) =>
772
+ actionItem(
773
+ `Gated tool: ${toolName}`,
774
+ "Toggle this exact non-Bash tool off; Bash cannot be listed.",
775
+ { id: "gated-tools.remove", args: { toolName } },
776
+ ),
777
+ );
766
778
  return [
767
- ...model.reviewerModels.map((option) =>
768
779
  actionItem(
769
- `Use reviewer model ${option.label}`,
770
- "Pin the reviewer model; writes user-owned config after confirmation.",
771
- { id: "reviewer.model", args: { model: option.spec } },
780
+ `Reviewer model: ${configuredModel ?? "session model"}`,
781
+ "Choose a configured model or return to the active session model; writes require confirmation.",
782
+ { id: "reviewer.model", args: {} },
772
783
  ),
784
+ actionItem(
785
+ `Prompt posture: ${model.status.reviewer.promptPosture}`,
786
+ "Choose the evidence threshold used by the model reviewer; writes require confirmation.",
787
+ { id: "reviewer.posture.select", args: {} },
773
788
  ),
774
789
  actionItem(
775
- "Clear explicit reviewer model",
776
- "Fall back to the active session model for review.",
777
- { id: "reviewer.model", args: { model: null } },
790
+ `Gated non-Bash tools: ${model.gatedTools.names.length}`,
791
+ model.gatedTools.addableToolNames.length === 0
792
+ ? "No active non-Bash tools are available to add."
793
+ : "Choose an active non-Bash tool to opt into exact-name Clearance gating.",
794
+ { id: "gated-tools.add", args: {} },
778
795
  ),
796
+ ...gatedToolItems,
779
797
  actionItem(
780
798
  "Show reviewer details",
781
- "Reviewer settings are read-only except model selection.",
799
+ "Reviewer settings and current evidence thresholds.",
782
800
  { id: "reviewer.open", args: {} },
783
801
  ),
784
802
  backItem(),
@@ -786,24 +804,13 @@ function reviewerItems(
786
804
  }
787
805
 
788
806
  function scopeItems(model: SettingsReadModel): readonly NativeSettingsItem[] {
789
- const safeHomeEnabled = model.projectScope.safeHomeUseDefaults !== false;
790
- const agentSupportEnabled =
791
- model.projectScope.agentSupportUseDefaults !== false;
807
+ const safeHomeEnabled = model.projectScope.safeHomeUseDefaults;
808
+ const agentSupportEnabled = model.projectScope.agentSupportUseDefaults;
792
809
  return [
793
810
  actionItem(
794
- "Preset: Project only",
795
- "Review anything touching paths outside the project; safe-home and agent-support defaults off.",
796
- { id: "scope.preset", args: { preset: "project" } },
797
- ),
798
- actionItem(
799
- "Preset: Home + project",
800
- "Baseline read auto-approvals extend into non-secret home directories.",
801
- { id: "scope.preset", args: { preset: "home" } },
802
- ),
803
- actionItem(
804
- "Preset: Full minus danger list",
805
- "Broad home reads; credential and key paths are hard-denied.",
806
- { id: "scope.preset", args: { preset: "unrestricted" } },
811
+ `Scope preset: ${scopePresetLabel(model)}`,
812
+ "Choose one behavior bundle; path lists remain unchanged and writes require confirmation.",
813
+ { id: "scope.preset.select", args: {} },
807
814
  ),
808
815
  actionItem(
809
816
  "Show full scope details",
@@ -813,20 +820,9 @@ function scopeItems(model: SettingsReadModel): readonly NativeSettingsItem[] {
813
820
  ...scopePathItems("scope.add-path", "Add"),
814
821
  ...scopePathItems("scope.remove-path", "Remove"),
815
822
  actionItem(
816
- "Unknown paths: review",
817
- "Review ambiguous paths instead of denying immediately.",
818
- {
819
- id: "scope.unknown-path",
820
- args: { behavior: "review" },
821
- },
822
- ),
823
- actionItem(
824
- "Unknown paths: deny",
825
- "Deny ambiguous paths unless policy can prove safety.",
826
- {
827
- id: "scope.unknown-path",
828
- args: { behavior: "deny" },
829
- },
823
+ `Unknown paths: ${model.projectScope.unknownPathBehavior}`,
824
+ "Choose whether ambiguous paths review or deny; writes require confirmation.",
825
+ { id: "scope.unknown-path.select", args: {} },
830
826
  ),
831
827
  actionItem(
832
828
  safeHomeEnabled ? "Safe-home defaults: off" : "Safe-home defaults: on",
@@ -888,30 +884,21 @@ export function packItems(
888
884
  ];
889
885
  }
890
886
 
887
+ function scopePresetLabel(model: SettingsReadModel): string {
888
+ const scope = model.projectScope;
889
+ const preset = inferScopePreset(scope);
890
+ return preset === "custom" ? "Custom" : SCOPE_PRESET_LABELS[preset];
891
+ }
892
+
891
893
  function briefingItems(
892
894
  model: SettingsReadModel,
893
895
  ): readonly NativeSettingsItem[] {
894
896
  const briefing = model.briefing;
895
897
  return [
896
898
  actionItem(
897
- `Note text: reason + accent${briefing.mode === "reason+accent" ? " (current)" : ""}`,
898
- "Show the decision reason inline after each reviewed call.",
899
- { id: "briefing.mode", args: { mode: "reason+accent" } },
900
- ),
901
- actionItem(
902
- `Note text: accent only${briefing.mode === "accent-only" ? " (current)" : ""}`,
903
- "Quiet allows: no reason text, accent marker only.",
904
- { id: "briefing.mode", args: { mode: "accent-only" } },
905
- ),
906
- actionItem(
907
- `Note text: reason + model${briefing.mode === "reason+model" ? " (current)" : ""}`,
908
- "Show the decision reason and the reviewer model label.",
909
- { id: "briefing.mode", args: { mode: "reason+model" } },
910
- ),
911
- actionItem(
912
- `Note text: off${briefing.mode === "off" ? " (current)" : ""}`,
913
- "Hide review-note text entirely.",
914
- { id: "briefing.mode", args: { mode: "off" } },
899
+ `Note mode: ${briefing.mode}`,
900
+ "Choose the inline review-note mode; writes require confirmation.",
901
+ { id: "briefing.mode.select", args: {} },
915
902
  ),
916
903
  actionItem(
917
904
  briefing.showModelLabel ? "Model label: hide" : "Model label: show",
@@ -5,7 +5,14 @@ export const REVIEWER_PANEL: SettingsPanel = {
5
5
  id: "reviewer",
6
6
  title: "Reviewer",
7
7
  rows: reviewerRows,
8
- actions: ["reviewer.model", "reviewer.open"],
8
+ actions: [
9
+ "reviewer.model",
10
+ "reviewer.posture.select",
11
+ "reviewer.posture.set",
12
+ "gated-tools.add",
13
+ "gated-tools.remove",
14
+ "reviewer.open",
15
+ ],
9
16
  };
10
17
 
11
18
  export function reviewerRows(model: SettingsReadModel): readonly SettingsRow[] {
@@ -33,7 +40,7 @@ export function reviewerRows(model: SettingsReadModel): readonly SettingsRow[] {
33
40
  {
34
41
  label: "Prompt posture",
35
42
  value: reviewer.promptPosture,
36
- meaning: "Edit advanced reviewer settings in global.json.",
43
+ meaning: "Select a posture; writes global.json after confirmation.",
37
44
  },
38
45
  {
39
46
  label: "Context mode",
@@ -42,6 +49,15 @@ export function reviewerRows(model: SettingsReadModel): readonly SettingsRow[] {
42
49
  },
43
50
  { label: "Token budget", value: formatTokenBudget(reviewer.tokenBudget) },
44
51
  { label: "Escalation", value: formatEscalation(reviewer.escalation) },
52
+ {
53
+ label: "Gated non-Bash tools",
54
+ value:
55
+ model.gatedTools.names.length === 0
56
+ ? "none"
57
+ : `${model.gatedTools.names.length} configured`,
58
+ meaning:
59
+ "Only exact names shown in this control are analyzed by Clearance; Bash remains gated and cannot be listed.",
60
+ },
45
61
  ];
46
62
  }
47
63
 
@@ -51,7 +67,7 @@ export function renderReviewerPanel(model: SettingsReadModel): string {
51
67
  "",
52
68
  markdownTable(reviewerRows(model)),
53
69
  "",
54
- "Model selection is interactive. Other reviewer settings are read-only here; edit global.json.",
70
+ "Model and prompt-posture selection are interactive and confirm-backed. Other reviewer settings are read-only here; edit global.json.",
55
71
  ].join("\n");
56
72
  }
57
73
 
@@ -5,7 +5,6 @@ import {
5
5
  type ProjectScopeListField,
6
6
  SCOPE_PRESET_LABELS,
7
7
  } from "../../../../config/config-command-plans.ts";
8
- import type { ProjectScopeConfig } from "../../../../config/schema.ts";
9
8
  import type { CommandReport } from "../../types.ts";
10
9
  import type { SettingsAction } from "../actions.ts";
11
10
  import {
@@ -84,15 +83,7 @@ export const SCOPE_PANEL: SettingsPanel = {
84
83
 
85
84
  export function scopeRows(model: SettingsReadModel): readonly SettingsRow[] {
86
85
  const scope = model.projectScope;
87
- const preset = inferScopePreset({
88
- safeHomeUseDefaults: scope.safeHomeUseDefaults ?? true,
89
- ...(scope.agentSupportUseDefaults === undefined
90
- ? {}
91
- : { agentSupportUseDefaults: scope.agentSupportUseDefaults }),
92
- homePathBehavior: scope.homePathBehavior,
93
- sensitivePathBehavior: scope.sensitivePathBehavior,
94
- unknownPathBehavior: scope.unknownPathBehavior,
95
- } as ProjectScopeConfig);
86
+ const preset = inferScopePreset(scope);
96
87
 
97
88
  return [
98
89
  {
@@ -308,5 +299,5 @@ function markdownTable(rows: readonly SettingsRow[]): string {
308
299
  }
309
300
 
310
301
  function escapeCell(value: string): string {
311
- return value.replaceAll("|", "\\|").replaceAll("\n", "<br>");
302
+ return value.replaceAll("|", "\\|").replaceAll("\n", "; ");
312
303
  }
@@ -30,12 +30,21 @@ export const SETTINGS_PANELS = [
30
30
  ] as const satisfies readonly SettingsPanel[];
31
31
 
32
32
  export function renderControlCenter(model: SettingsReadModel): string {
33
- const rows: readonly SettingsRow[] = [
33
+ const rows: SettingsRow[] = [
34
34
  {
35
35
  label: "Clearance mode",
36
36
  value: model.currentMode.label,
37
37
  meaning: model.currentMode.description,
38
38
  },
39
+ ...(model.status.customizations === undefined ||
40
+ model.status.customizations.length === 0
41
+ ? []
42
+ : [
43
+ {
44
+ label: "Customizations",
45
+ value: model.status.customizations.join("; "),
46
+ },
47
+ ]),
39
48
  {
40
49
  label: "Tune mode",
41
50
  value: formatTuneCueStatus(model.status.ratchet.active),
@@ -2,10 +2,15 @@ import type {
2
2
  ResolvedProjectScope,
3
3
  ResolvedReviewNotePreference,
4
4
  } from "../../../config/loader.ts";
5
+ import {
6
+ DEFAULT_PROJECT_SCOPE_BEHAVIOR,
7
+ DEFAULT_REVIEW_NOTE_DISPLAY,
8
+ } from "../../../config/defaults.ts";
5
9
  import type { ClearanceMode } from "../../../config/schema.ts";
6
10
  import type { AutoReviewerStatusView } from "../../auto-reviewer-read-models.ts";
7
11
  import type { ReviewDecisionDisplayCapability } from "../../review-decision-display.ts";
8
12
  import type { SettingsActionId } from "./actions.ts";
13
+ import type { ReviewerModelOption } from "./model-options.ts";
9
14
 
10
15
  export interface SettingsModeCopy {
11
16
  readonly mode: ClearanceMode;
@@ -26,11 +31,16 @@ export interface SettingsBriefingRow {
26
31
  readonly note: string;
27
32
  }
28
33
 
29
- export interface SettingsProjectScope extends ResolvedProjectScope {
34
+ export interface SettingsProjectScopeInput extends ResolvedProjectScope {
30
35
  readonly safeHomeUseDefaults?: boolean;
31
36
  readonly agentSupportUseDefaults?: boolean;
32
37
  }
33
38
 
39
+ export interface SettingsProjectScope extends ResolvedProjectScope {
40
+ readonly safeHomeUseDefaults: boolean;
41
+ readonly agentSupportUseDefaults: boolean;
42
+ }
43
+
34
44
  /** A pack row for the settings pack explorer. */
35
45
  export interface SettingsPackRow {
36
46
  readonly id: string;
@@ -45,10 +55,16 @@ export interface SettingsPackRow {
45
55
  }
46
56
 
47
57
  /** A reviewer model option for the settings reviewer panel. */
48
- export interface SettingsReviewerModelOption {
49
- /** Canonical provider/modelId spec written to config. */
50
- readonly spec: string;
51
- readonly label: string;
58
+ export type SettingsReviewerModelOption = ReviewerModelOption;
59
+
60
+ export interface SettingsGatedTools {
61
+ /** Exact non-Bash names currently opted into Clearance gating. */
62
+ readonly names: readonly string[];
63
+ /** Active host tools are the only names offered by the add chooser. */
64
+ readonly activeToolNames: readonly string[];
65
+ /** All host metadata, when available, for disclosure and diagnostics. */
66
+ readonly allToolNames: readonly string[];
67
+ readonly addableToolNames: readonly string[];
52
68
  }
53
69
 
54
70
  export interface SettingsPanelDescriptor {
@@ -66,6 +82,7 @@ export interface SettingsReadModel {
66
82
  readonly briefing: SettingsBriefingRow;
67
83
  readonly packs: readonly SettingsPackRow[];
68
84
  readonly reviewerModels: readonly SettingsReviewerModelOption[];
85
+ readonly gatedTools: SettingsGatedTools;
69
86
  readonly panels: readonly SettingsPanelDescriptor[];
70
87
  }
71
88
 
@@ -90,11 +107,8 @@ export const SETTINGS_MODE_COPIES = [
90
107
  },
91
108
  ] as const satisfies readonly SettingsModeCopy[];
92
109
 
93
- export const DEFAULT_REVIEW_NOTE_PREFERENCE = {
94
- mode: "reason+accent",
95
- showModelLabel: false,
96
- accent: true,
97
- } as const satisfies ResolvedReviewNotePreference;
110
+ export const DEFAULT_REVIEW_NOTE_PREFERENCE =
111
+ DEFAULT_REVIEW_NOTE_DISPLAY satisfies ResolvedReviewNotePreference;
98
112
 
99
113
  export const DEFAULT_SETTINGS_BRIEFING_ROW = buildSettingsBriefingRow(
100
114
  DEFAULT_REVIEW_NOTE_PREFERENCE,
@@ -105,7 +119,7 @@ const SETTINGS_PANEL_DESCRIPTORS = [
105
119
  id: "reviewer",
106
120
  title: "Reviewer",
107
121
  summary:
108
- "Configured model and prompt details (read-only except model selection).",
122
+ "Confirm-backed model and prompt-posture selectors; other advanced details are read-only.",
109
123
  drillActionId: "reviewer.open" as const,
110
124
  },
111
125
  {
@@ -131,10 +145,11 @@ const SETTINGS_PANEL_DESCRIPTORS = [
131
145
 
132
146
  export function buildSettingsReadModel(input: {
133
147
  readonly status: AutoReviewerStatusView;
134
- readonly projectScope: SettingsProjectScope;
148
+ readonly projectScope: SettingsProjectScopeInput;
135
149
  readonly reviewNoteDisplay?: ResolvedReviewNotePreference;
136
150
  readonly packs?: readonly SettingsPackRow[];
137
151
  readonly reviewerModels?: readonly SettingsReviewerModelOption[];
152
+ readonly gatedTools?: SettingsGatedTools;
138
153
  }): SettingsReadModel {
139
154
  const currentMode = SETTINGS_MODE_COPIES.find(
140
155
  (mode) => mode.mode === input.status.mode,
@@ -145,16 +160,35 @@ export function buildSettingsReadModel(input: {
145
160
  modes: SETTINGS_MODE_COPIES.map((mode) => ({ ...mode })),
146
161
  currentMode: { ...currentMode },
147
162
  status: input.status,
148
- projectScope: input.projectScope,
163
+ projectScope: normalizeSettingsProjectScope(input.projectScope),
149
164
  briefing: buildSettingsBriefingRow(
150
165
  input.reviewNoteDisplay ?? DEFAULT_REVIEW_NOTE_PREFERENCE,
151
166
  ),
152
167
  packs: input.packs ?? [],
153
168
  reviewerModels: input.reviewerModels ?? [],
169
+ gatedTools: input.gatedTools ?? {
170
+ names: [],
171
+ activeToolNames: [],
172
+ allToolNames: [],
173
+ addableToolNames: [],
174
+ },
154
175
  panels: SETTINGS_PANEL_DESCRIPTORS.map((panel) => ({ ...panel })),
155
176
  };
156
177
  }
157
178
 
179
+ function normalizeSettingsProjectScope(
180
+ scope: SettingsProjectScopeInput,
181
+ ): SettingsProjectScope {
182
+ return {
183
+ ...scope,
184
+ safeHomeUseDefaults:
185
+ scope.safeHomeUseDefaults ?? DEFAULT_PROJECT_SCOPE_BEHAVIOR.safeHomeUseDefaults,
186
+ agentSupportUseDefaults:
187
+ scope.agentSupportUseDefaults ??
188
+ DEFAULT_PROJECT_SCOPE_BEHAVIOR.agentSupportUseDefaults,
189
+ };
190
+ }
191
+
158
192
  function buildSettingsBriefingRow(
159
193
  preference: ResolvedReviewNotePreference,
160
194
  ): SettingsBriefingRow {
@@ -1,7 +1,6 @@
1
1
  import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
2
 
3
3
  import { buildAutoReviewerStatusView } from "../auto-reviewer-read-models.ts";
4
- import type { ReviewerModelRegistry } from "../reviewer-model.ts";
5
4
  import {
6
5
  canOpenSettingsNativeUi,
7
6
  openSettingsNativeUi,
@@ -16,6 +15,9 @@ import {
16
15
  resolvePolicyReport,
17
16
  usageReport,
18
17
  } from "./types.ts";
18
+ import { availableReviewerModels } from "./settings/model-options.ts";
19
+
20
+ export { availableReviewerModels } from "./settings/model-options.ts";
19
21
 
20
22
  type SettingsNativePanel = SettingsReadModel["panels"][number]["id"];
21
23
 
@@ -156,9 +158,7 @@ async function buildSettingsCommandView(
156
158
  : {
157
159
  ...policy.policy.config.projectScope,
158
160
  safeHomeUseDefaults: rawScope.safeHomeUseDefaults,
159
- ...(rawScope.agentSupportUseDefaults === undefined
160
- ? {}
161
- : { agentSupportUseDefaults: rawScope.agentSupportUseDefaults }),
161
+ agentSupportUseDefaults: rawScope.agentSupportUseDefaults ?? true,
162
162
  homePathBehavior: rawScope.homePathBehavior,
163
163
  sensitivePathBehavior: rawScope.sensitivePathBehavior,
164
164
  };
@@ -183,43 +183,38 @@ async function buildSettingsCommandView(
183
183
  };
184
184
  }),
185
185
  reviewerModels: availableReviewerModels(ctx),
186
+ gatedTools: buildGatedToolsReadModel(
187
+ policy.policy.config.gatedTools ?? [],
188
+ deps.toolMetadata?.() ?? { activeToolNames: [], allToolNames: [] },
189
+ ),
186
190
  });
187
191
 
188
192
  return { ok: true, model };
189
193
  }
190
194
 
191
- const REVIEWER_MODEL_OPTION_LIMIT = 12;
192
-
193
- /** Available reviewer model specs (provider/modelId) with configured auth. */
194
- export function availableReviewerModels(
195
- ctx: ExtensionCommandContext,
196
- ): readonly { readonly spec: string; readonly label: string }[] {
197
- // Pi's ModelRegistry.hasConfiguredAuth takes the MODEL, not a provider
198
- // string passing a string silently filters out every model.
199
- const registry = (ctx as { readonly modelRegistry?: unknown })
200
- .modelRegistry as ReviewerModelRegistry | undefined;
201
- if (
202
- registry === undefined ||
203
- typeof registry.getAll !== "function" ||
204
- typeof registry.hasConfiguredAuth !== "function"
205
- ) {
206
- return [];
207
- }
195
+ function buildGatedToolsReadModel(
196
+ gatedTools: readonly string[],
197
+ metadata: {
198
+ readonly activeToolNames: readonly string[];
199
+ readonly allToolNames: readonly string[];
200
+ },
201
+ ): SettingsReadModel["gatedTools"] {
202
+ const names = uniqueToolNames(gatedTools).filter((name) => name !== "bash");
203
+ const activeToolNames = uniqueToolNames(metadata.activeToolNames).filter(
204
+ (name) => name !== "bash",
205
+ );
206
+ const allToolNames = uniqueToolNames(metadata.allToolNames).filter(
207
+ (name) => name !== "bash",
208
+ );
209
+ const addSource = activeToolNames.length > 0 ? activeToolNames : allToolNames;
210
+ return {
211
+ names,
212
+ activeToolNames,
213
+ allToolNames,
214
+ addableToolNames: addSource.filter((name) => !names.includes(name)),
215
+ };
216
+ }
208
217
 
209
- try {
210
- return registry
211
- .getAll()
212
- .filter((model) => registry.hasConfiguredAuth(model))
213
- .map((model) => ({
214
- spec: `${model.provider}/${model.id}`,
215
- label:
216
- typeof model.name === "string" && model.name.length > 0
217
- ? `${model.name} (${model.provider}/${model.id})`
218
- : `${model.provider}/${model.id}`,
219
- }))
220
- .sort((a, b) => a.spec.localeCompare(b.spec))
221
- .slice(0, REVIEWER_MODEL_OPTION_LIMIT);
222
- } catch {
223
- return [];
224
- }
218
+ function uniqueToolNames(names: readonly string[]): string[] {
219
+ return [...new Set(names.filter((name) => name.trim().length > 0))].sort();
225
220
  }
@@ -51,6 +51,9 @@ function formatStatusMarkdown(
51
51
  `- Reviewer prompt: ${details.reviewer.promptPosture}; context ${formatReviewerContextModeLabel(details.reviewer.contextMode)}`,
52
52
  `- Reviewer model configured: ${details.reviewer.configuredModel === null ? "none" : `\`${details.reviewer.configuredModel}\``}`,
53
53
  `- Reviewer model resolved: ${details.reviewer.resolvedModel === null ? "none" : `\`${details.reviewer.resolvedModel}\``} (${details.reviewer.resolvedModelSource})`,
54
+ ...((details.customizations?.length ?? 0) === 0
55
+ ? []
56
+ : [`- Customizations: ${details.customizations?.join("; ") ?? ""}`]),
54
57
  `- Packs: ${details.packs.enabled} enabled / ${details.packs.total} total`,
55
58
  `- Warnings: ${details.warnings.length}`,
56
59
  ];
@@ -15,11 +15,20 @@ export type {
15
15
  RecentDecisionSource,
16
16
  } from "../reviewer-context.ts";
17
17
 
18
+ export interface CommandToolMetadata {
19
+ /** Currently active tool names, when the host exposes them. */
20
+ readonly activeToolNames: readonly string[];
21
+ /** All configured tool names, when the host exposes them. */
22
+ readonly allToolNames: readonly string[];
23
+ }
24
+
18
25
  export interface AutoReviewerCommandDependencies {
19
26
  readonly manager: RatchetModeManager;
20
27
  readonly policyResolver: PolicyResolver;
21
28
  readonly packageRegistration: () => PackageRegistrationSnapshot;
22
29
  readonly audit: AuditLogger;
30
+ /** Optional host tool catalog used by the exact gated-tools settings control. */
31
+ readonly toolMetadata?: () => CommandToolMetadata;
23
32
  /** Bounded recent audit decisions used by `/clearance allow` with no text. */
24
33
  readonly recentDecisionSource: RecentDecisionSource;
25
34
  /** Structural analyzer used only to summarize the recent command for the agent. */
@@ -46,7 +55,7 @@ export type CommandPi = Pick<
46
55
  | "getAllTools"
47
56
  | "setActiveTools"
48
57
  | "registerTool"
49
- | "sendUserMessage"
58
+ | "sendMessage"
50
59
  >;
51
60
 
52
61
  export const USAGE_MARKDOWN = [
@@ -66,7 +75,7 @@ export const USAGE_MARKDOWN = [
66
75
  "",
67
76
  "Tune analysis tools are available only while `/clearance tune` is active; proposal tools remain available in every mode.",
68
77
  "",
69
- "Advanced settings such as reviewer prompt posture, context mode, token budget, and escalation are edited in user-owned global config; reviewer model selection remains available in settings.",
78
+ "Reviewer prompt posture and model pinning are available as confirm-backed settings selectors; context mode, token budget, escalation, and other advanced fields are edited in user-owned global config.",
70
79
  ].join("\n");
71
80
 
72
81
  export async function resolvePolicyForCommand(
@@ -75,7 +84,7 @@ export async function resolvePolicyForCommand(
75
84
  ): Promise<ResolvedPolicy> {
76
85
  const result = await deps.policyResolver.resolve(ctx);
77
86
  if (!result.ok) {
78
- throw new Error(`auto-reviewer policy resolution failed: ${result.reason}`);
87
+ throw new Error(`Pi Clearance policy resolution failed: ${result.reason}`);
79
88
  }
80
89
 
81
90
  return result.policy;
@@ -98,10 +107,10 @@ export async function resolvePolicyReport(
98
107
  return {
99
108
  ok: false,
100
109
  report: {
101
- title: "Auto-reviewer command failed",
110
+ title: "Pi Clearance command failed",
102
111
  summary: message,
103
112
  markdown: [
104
- "# Auto-reviewer command failed",
113
+ "# Pi Clearance command failed",
105
114
  "",
106
115
  `- Error: ${message}`,
107
116
  "- No config changes were written.",
@@ -99,6 +99,21 @@ export function createHandleToolCall(
99
99
 
100
100
  deps.operatorStatus?.refresh(ctx, resolved.policy);
101
101
 
102
+ // Harness availability is the host-level approval boundary for non-Bash
103
+ // tools. Only exact names in global.gatedTools enter Clearance; Bash is
104
+ // intentionally never eligible for this bypass.
105
+ if (shouldBypassNonBashTool(event.toolName, resolved.policy)) {
106
+ const decision = nonBashBypassDecision(event.toolName);
107
+ await logPolicyDecision(
108
+ deps.audit,
109
+ inputSnapshot,
110
+ event,
111
+ ctx,
112
+ decision,
113
+ );
114
+ return {};
115
+ }
116
+
102
117
  const rawShape = await deps.analyzerRegistry.analyze(
103
118
  event.toolName,
104
119
  event.input,
@@ -208,6 +223,10 @@ async function mapDecisionToResult(
208
223
  // command. event.input may be mutated by transforms after the allow below.
209
224
  toolInput: input.inputSnapshot,
210
225
  shape: input.shape,
226
+ deterministicEvidence: {
227
+ reason: input.decision.reason,
228
+ provenance: input.decision.provenance,
229
+ },
211
230
  reviewerConfig: input.resolvedPolicy.config.reviewer,
212
231
  resolvedConfig: input.resolvedPolicy.config,
213
232
  humanAdapter: adapters.humanAdapter,
@@ -279,6 +298,23 @@ function reviewVisibilityAdapter(
279
298
  };
280
299
  }
281
300
 
301
+ function shouldBypassNonBashTool(
302
+ toolName: string,
303
+ resolvedPolicy: ResolvedPolicy,
304
+ ): boolean {
305
+ if (toolName === "bash") return false;
306
+ const gatedTools = resolvedPolicy.config.gatedTools ?? [];
307
+ return !gatedTools.includes(toolName);
308
+ }
309
+
310
+ function nonBashBypassDecision(toolName: string): Decision {
311
+ return {
312
+ effect: "allow",
313
+ reason: `non-bash tool ${toolName} bypassed Clearance: not listed in gatedTools`,
314
+ provenance: { source: "default", ruleId: "clearance.non-bash-bypass" },
315
+ };
316
+ }
317
+
282
318
  function deterministicDecision(
283
319
  shape: ToolShape,
284
320
  resolvedPolicy: ResolvedPolicy,
@@ -9,7 +9,6 @@ import type { RatchetModeManager } from "./ratchet-mode.ts";
9
9
  const PROPOSAL_FLOW_GUIDANCE = [
10
10
  "## Clearance proposal flow guidance",
11
11
  "- Agent-authored policy batches are always available: call clearance_propose, then call clearance_present to show the deterministic summary card.",
12
- "- Only an explicit user approval from the presented card may write user-owned config; never apply proposals or write policy directly.",
13
12
  ].join("\n");
14
13
 
15
14
  function formatRatchetToolGuidance(toolNames: readonly string[]): string {