@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,6 +1,10 @@
1
1
  import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
2
 
3
3
  import type { ToolAnalyzerRegistry } from "../../parse/registry.ts";
4
+ import {
5
+ CLEARANCE_ALLOW_REQUEST_CUSTOM_TYPE,
6
+ type ClearanceAllowRequestDetails,
7
+ } from "../allow-request-message.ts";
4
8
  import type { ToolShape } from "../../parse/shape.ts";
5
9
  import {
6
10
  flattenStages,
@@ -385,10 +389,30 @@ async function handoff(
385
389
  if (!prepared.ok) return prepared.report;
386
390
 
387
391
  try {
392
+ const details: ClearanceAllowRequestDetails = {
393
+ brief: prepared.brief,
394
+ form: prepared.form,
395
+ };
388
396
  if (ctx.isIdle()) {
389
- await pi.sendUserMessage(prepared.brief);
397
+ await pi.sendMessage(
398
+ {
399
+ customType: CLEARANCE_ALLOW_REQUEST_CUSTOM_TYPE,
400
+ content: prepared.brief,
401
+ display: true,
402
+ details,
403
+ },
404
+ { triggerTurn: true },
405
+ );
390
406
  } else {
391
- await pi.sendUserMessage(prepared.brief, { deliverAs: "followUp" });
407
+ await pi.sendMessage(
408
+ {
409
+ customType: CLEARANCE_ALLOW_REQUEST_CUSTOM_TYPE,
410
+ content: prepared.brief,
411
+ display: true,
412
+ details,
413
+ },
414
+ { deliverAs: "followUp" },
415
+ );
392
416
  }
393
417
  } catch (error: unknown) {
394
418
  const message = errorMessage(error);
@@ -165,7 +165,7 @@ export interface DefaultPackListingDetails
165
165
  }
166
166
 
167
167
  /**
168
- * Human-facing default pack listing used by `/auto-reviewer packs` and
168
+ * Human-facing default pack listing used by `/clearance packs` and
169
169
  * settings drill-downs. Titles are the primary labels; stable pack ids stay as
170
170
  * secondary metadata so humans do not have to scan dot/colon-path identifiers.
171
171
  */
@@ -221,7 +221,7 @@ export async function handlePackMutationCommand(input: {
221
221
  reason:
222
222
  "Pack enable/disable requires interactive Pi UI confirmation; no config changes were written.",
223
223
  markdownLines: [
224
- "- Mutating `/auto-reviewer packs enable|disable` commands require Pi UI confirmation.",
224
+ "- Mutating `/clearance packs enable|disable` commands require Pi UI confirmation.",
225
225
  "- No config changes were written.",
226
226
  ],
227
227
  });
@@ -338,7 +338,7 @@ export async function handlePackMutationCommand(input: {
338
338
  };
339
339
 
340
340
  return {
341
- title: "Auto-reviewer pack enablement updated",
341
+ title: "Pi Clearance pack enablement updated",
342
342
  summary: `${packId} ${request.action} planned for ${target.target.scope}; effective state ${formatEffectiveState(effectivePack)}.`,
343
343
  markdown: formatPackMutationSuccessMarkdown(details),
344
344
  details,
@@ -1038,7 +1038,7 @@ function formatPackExplorerNameCell(
1038
1038
  const secondary = idsPrimary
1039
1039
  ? escapeCell(pack.title)
1040
1040
  : `\`${escapeCell(pack.id)}\``;
1041
- return `${primary}<br><small>${secondary}</small>`;
1041
+ return `${primary} — ${secondary}`;
1042
1042
  }
1043
1043
 
1044
1044
  function formatPackExplorerScope(pack: AutoReviewerPackExplorerView): string {
@@ -1362,7 +1362,7 @@ function formatPackMutationSuccessMarkdown(
1362
1362
  details: PackMutationSuccessDetails,
1363
1363
  ): string {
1364
1364
  const lines = [
1365
- "# Auto-reviewer pack enablement updated",
1365
+ "# Pi Clearance pack enablement updated",
1366
1366
  "",
1367
1367
  `- Pack: \`${details.request.packId}\``,
1368
1368
  `- Action: ${details.request.action}`,
@@ -1513,7 +1513,7 @@ function escapeCell(value: string): string {
1513
1513
  }
1514
1514
 
1515
1515
  function packConfirmationTitle(plan: PackEnablementPlan): string {
1516
- return `${capitalize(plan.request.action)} auto-reviewer pack?`;
1516
+ return `${capitalize(plan.request.action)} Pi Clearance pack?`;
1517
1517
  }
1518
1518
 
1519
1519
  function yesNo(value: boolean): string {
@@ -146,7 +146,7 @@ export async function handleScopeCommand(
146
146
  reason:
147
147
  "Project scope changes require interactive Pi UI confirmation; no config changes were written.",
148
148
  markdownLines: [
149
- "- Mutating `/auto-reviewer scope` commands require Pi UI confirmation.",
149
+ "- Mutating `/clearance scope` commands require Pi UI confirmation.",
150
150
  "- No config changes were written.",
151
151
  ],
152
152
  change: parsed.change,
@@ -232,7 +232,7 @@ export async function handleScopeCommand(
232
232
  };
233
233
 
234
234
  return {
235
- title: "Auto-reviewer project scope updated",
235
+ title: "Pi Clearance project scope updated",
236
236
  summary: `${planned.plan.title}; changed ${apply.changed ? "yes" : "no"}.`,
237
237
  markdown: formatScopeMutationSuccessMarkdown(details),
238
238
  details,
@@ -292,7 +292,7 @@ async function handleScopeStatus(
292
292
 
293
293
  const details = scopeStatusFromConfig(policy.policy.config);
294
294
  return {
295
- title: "Auto-reviewer project scope",
295
+ title: "Pi Clearance project scope",
296
296
  summary: `Project scope has ${details.raw.roots.length} configured root(s), ${details.raw.writableDirectories.length} configured writable path(s), and unknown paths ${details.raw.unknownPathBehavior}.`,
297
297
  markdown: formatScopeStatusMarkdown(details),
298
298
  details,
@@ -476,7 +476,7 @@ function scopeStatusFromConfig(config: ResolvedConfig): ScopeStatusDetails {
476
476
 
477
477
  function formatScopeStatusMarkdown(details: ScopeStatusDetails): string {
478
478
  const lines = [
479
- "# Auto-reviewer project scope",
479
+ "# Pi Clearance project scope",
480
480
  "",
481
481
  "Project scope is lexical-only: it normalizes strings but does not follow symlinks, check filesystem existence, or provide sandbox containment.",
482
482
  "",
@@ -618,7 +618,7 @@ function formatScopeMutationSuccessMarkdown(
618
618
  details: ScopeMutationSuccessDetails,
619
619
  ): string {
620
620
  const lines = [
621
- "# Auto-reviewer project scope updated",
621
+ "# Pi Clearance project scope updated",
622
622
  "",
623
623
  `- Change: ${details.plan.title}`,
624
624
  `- Target file: \`${details.plan.target.path}\``,
@@ -1,7 +1,10 @@
1
1
  export type SettingsActionId =
2
+ | "mode.select"
2
3
  | "mode.set"
3
4
  | "reviewer.open"
4
5
  | "reviewer.model"
6
+ | "reviewer.posture.select"
7
+ | "reviewer.posture.set"
5
8
  | "reviewer.prompt-append"
6
9
  | "reviewer.prompt-override.set"
7
10
  | "reviewer.prompt-override.clear"
@@ -9,15 +12,20 @@ export type SettingsActionId =
9
12
  | "scope.add-path"
10
13
  | "scope.remove-path"
11
14
  | "scope.unknown-path"
15
+ | "scope.unknown-path.select"
12
16
  | "scope.safe-home-defaults"
13
17
  | "scope.agent-support-defaults"
14
18
  | "scope.preset"
19
+ | "scope.preset.select"
15
20
  | "packs.open"
16
21
  | "packs.show"
17
22
  | "packs.enable"
18
23
  | "packs.disable"
19
24
  | "briefing.open"
20
25
  | "briefing.mode"
26
+ | "briefing.mode.select"
27
+ | "gated-tools.add"
28
+ | "gated-tools.remove"
21
29
  | "briefing.model-label"
22
30
  | "briefing.accent";
23
31
 
@@ -28,6 +36,9 @@ export interface SettingsAction {
28
36
 
29
37
  export const WRITE_ACTION_IDS = [
30
38
  "mode.set",
39
+ "reviewer.posture.set",
40
+ "gated-tools.add",
41
+ "gated-tools.remove",
31
42
  "reviewer.model",
32
43
  "reviewer.prompt-append",
33
44
  "reviewer.prompt-override.set",
@@ -2,10 +2,12 @@ import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
2
 
3
3
  import {
4
4
  type ProjectScopeListField,
5
+ planGatedToolCommandChange,
5
6
  planModeCommandChange,
6
7
  planProjectScopeCommandChange,
7
8
  planReviewerCommandChange,
8
9
  planReviewNoteDisplayCommandChange,
10
+ type GatedToolCommandChange,
9
11
  type ReviewerCommandChange,
10
12
  type ReviewNoteDisplayCommandChange,
11
13
  type ScopeCommandChange,
@@ -15,9 +17,17 @@ import {
15
17
  type ConfigCommandApplyResult,
16
18
  type ConfigCommandPlan,
17
19
  } from "../../../config/config-command-writer.ts";
18
- import type { ClearanceMode } from "../../../config/schema.ts";
20
+ import {
21
+ CLEARANCE_MODES,
22
+ type ClearanceMode,
23
+ REVIEW_NOTE_MODES,
24
+ } from "../../../config/schema.ts";
19
25
  import type { JsonPatchOperation } from "../../../replay/proposal-schema.ts";
20
26
  import { detectReviewDecisionDisplayCapability } from "../../review-decision-display.ts";
27
+ import {
28
+ isShippedReviewerPostureId,
29
+ SHIPPED_REVIEWER_POSTURE_OPTIONS,
30
+ } from "../../reviewer-prompts.ts";
21
31
  import {
22
32
  handlePackMutationCommand,
23
33
  type PackMutationRequest,
@@ -36,6 +46,11 @@ import {
36
46
  type SettingsActionId,
37
47
  } from "./actions.ts";
38
48
  import { renderPacksOpenDrill, renderPacksShowDrill } from "./panels/packs.ts";
49
+ import {
50
+ ACTIVE_SESSION_MODEL_LABEL,
51
+ availableReviewerModels,
52
+ type ReviewerModelOption,
53
+ } from "./model-options.ts";
39
54
 
40
55
  export interface SettingsDispatchDependencies
41
56
  extends AutoReviewerCommandDependencies {}
@@ -83,6 +98,10 @@ export async function dispatchSettingsAction(
83
98
  ctx: ExtensionCommandContext,
84
99
  deps: SettingsDispatchDependencies,
85
100
  ): Promise<CommandReport<SettingsDispatchDetails | unknown>> {
101
+ const selected = await resolveSelectorAction(action, ctx, deps);
102
+ if (!selected.ok) return selected.report;
103
+ action = selected.action;
104
+
86
105
  if (isDrillAction(action.id)) {
87
106
  if (action.id === "packs.open") {
88
107
  return await renderPacksOpenDrill({ action, ctx, deps });
@@ -133,6 +152,11 @@ export async function dispatchSettingsAction(
133
152
  mode: change.mode,
134
153
  resolvedConfig: policy.policy.config,
135
154
  });
155
+ case "gated-tools":
156
+ return planGatedToolCommandChange({
157
+ change: change.change,
158
+ resolvedConfig: policy.policy.config,
159
+ });
136
160
  case "reviewer":
137
161
  return planReviewerCommandChange({
138
162
  change: change.change,
@@ -236,8 +260,217 @@ export function settingsUiRequiredReport(
236
260
  };
237
261
  }
238
262
 
263
+ async function resolveSelectorAction(
264
+ action: SettingsAction,
265
+ ctx: ExtensionCommandContext,
266
+ deps: SettingsDispatchDependencies,
267
+ ): Promise<
268
+ | { readonly ok: true; readonly action: SettingsAction }
269
+ | { readonly ok: false; readonly report: CommandReport }
270
+ > {
271
+ const isSelector =
272
+ action.id === "mode.select" ||
273
+ (action.id === "reviewer.model" && !Object.hasOwn(action.args, "model")) ||
274
+ action.id === "reviewer.posture.select" ||
275
+ action.id === "scope.preset.select" ||
276
+ action.id === "scope.unknown-path.select" ||
277
+ action.id === "briefing.mode.select" ||
278
+ (action.id === "gated-tools.add" &&
279
+ !Object.hasOwn(action.args, "toolName"));
280
+ if (!isSelector) return { ok: true, action };
281
+ if (ctx.hasUI !== true)
282
+ return { ok: false, report: settingsUiRequiredReport(action) };
283
+
284
+ const policy = await resolvePolicyReport(ctx, deps);
285
+ if (!policy.ok) return { ok: false, report: policy.report };
286
+ const reviewerModelOptions =
287
+ action.id === "reviewer.model" ? availableReviewerModels(ctx) : [];
288
+ const options = selectorOptions(
289
+ action,
290
+ deps,
291
+ reviewerModelOptions,
292
+ policy.policy.config.gatedTools ?? [],
293
+ );
294
+ if (options.length === 0) {
295
+ return {
296
+ ok: false,
297
+ report: invalidActionReport(
298
+ action,
299
+ "No choices are available in the current Pi session.",
300
+ ),
301
+ };
302
+ }
303
+
304
+ let selected: string | undefined;
305
+ try {
306
+ selected = await ctx.ui.select(selectorTitle(action), [...options]);
307
+ } catch {
308
+ selected = undefined;
309
+ }
310
+ if (selected === undefined) {
311
+ return {
312
+ ok: false,
313
+ report: {
314
+ title: "Settings selection cancelled",
315
+ summary: "No setting was selected; no config changes were written.",
316
+ markdown:
317
+ "# Settings selection cancelled\n\nNo config changes were written.",
318
+ details: { reason: "cancelled", action },
319
+ level: "warning",
320
+ },
321
+ };
322
+ }
323
+
324
+ const selectedAction = selectorSelection(
325
+ action,
326
+ selected,
327
+ reviewerModelOptions,
328
+ );
329
+ return selectedAction === undefined
330
+ ? {
331
+ ok: false,
332
+ report: invalidActionReport(action, "Unknown settings selection."),
333
+ }
334
+ : { ok: true, action: selectedAction };
335
+ }
336
+
337
+ function selectorOptions(
338
+ action: SettingsAction,
339
+ deps: SettingsDispatchDependencies,
340
+ reviewerModelOptions: readonly ReviewerModelOption[],
341
+ gatedTools: readonly string[],
342
+ ): readonly string[] {
343
+ switch (action.id) {
344
+ case "mode.select":
345
+ return CLEARANCE_MODES.map((mode) => modeLabel(mode));
346
+ case "reviewer.model":
347
+ return [
348
+ ACTIVE_SESSION_MODEL_LABEL,
349
+ ...reviewerModelOptions.map((model) => model.label),
350
+ ];
351
+ case "reviewer.posture.select":
352
+ return SHIPPED_REVIEWER_POSTURE_OPTIONS.map((option) => option.label);
353
+ case "scope.preset.select":
354
+ return ["Project only", "Home + project", "Full minus danger list"];
355
+ case "scope.unknown-path.select":
356
+ return ["Review unknown paths", "Deny unknown paths"];
357
+ case "briefing.mode.select":
358
+ return REVIEW_NOTE_MODES.map((mode) => `Note mode: ${mode}`);
359
+ case "gated-tools.add": {
360
+ const metadata = deps.toolMetadata?.();
361
+ return metadata === undefined
362
+ ? []
363
+ : activeToolNames(metadata)
364
+ .filter((name) => name !== "bash")
365
+ .filter((name) => !gatedTools.includes(name));
366
+ }
367
+ default:
368
+ return [];
369
+ }
370
+ }
371
+
372
+ function selectorTitle(action: SettingsAction): string {
373
+ switch (action.id) {
374
+ case "mode.select":
375
+ return "Choose Clearance mode";
376
+ case "reviewer.model":
377
+ return "Choose reviewer model";
378
+ case "reviewer.posture.select":
379
+ return "Choose reviewer posture";
380
+ case "scope.preset.select":
381
+ return "Choose scope preset";
382
+ case "scope.unknown-path.select":
383
+ return "Choose unknown-path behavior";
384
+ case "briefing.mode.select":
385
+ return "Choose briefing mode";
386
+ case "gated-tools.add":
387
+ return "Add exact gated non-Bash tool";
388
+ default:
389
+ return "Choose setting";
390
+ }
391
+ }
392
+
393
+ function selectorSelection(
394
+ action: SettingsAction,
395
+ selected: string,
396
+ reviewerModelOptions: readonly ReviewerModelOption[],
397
+ ): SettingsAction | undefined {
398
+ switch (action.id) {
399
+ case "mode.select": {
400
+ const mode = CLEARANCE_MODES.find(
401
+ (candidate) => selected === modeLabel(candidate),
402
+ );
403
+ return mode === undefined
404
+ ? undefined
405
+ : { id: "mode.set", args: { mode } };
406
+ }
407
+ case "reviewer.model": {
408
+ if (selected === ACTIVE_SESSION_MODEL_LABEL)
409
+ return { id: "reviewer.model", args: { model: null } };
410
+ const model = reviewerModelOptions.find(
411
+ (candidate) => candidate.label === selected,
412
+ );
413
+ return model === undefined
414
+ ? undefined
415
+ : { id: "reviewer.model", args: { model: model.spec } };
416
+ }
417
+ case "reviewer.posture.select": {
418
+ const posture = SHIPPED_REVIEWER_POSTURE_OPTIONS.find(
419
+ (option) => option.label === selected,
420
+ )?.id;
421
+ return posture === undefined
422
+ ? undefined
423
+ : { id: "reviewer.posture.set", args: { promptPosture: posture } };
424
+ }
425
+ case "scope.preset.select": {
426
+ const preset = {
427
+ "Project only": "project",
428
+ "Home + project": "home",
429
+ "Full minus danger list": "unrestricted",
430
+ }[selected];
431
+ return preset === undefined
432
+ ? undefined
433
+ : { id: "scope.preset", args: { preset } };
434
+ }
435
+ case "scope.unknown-path.select":
436
+ return selected === "Review unknown paths"
437
+ ? { id: "scope.unknown-path", args: { behavior: "review" } }
438
+ : selected === "Deny unknown paths"
439
+ ? { id: "scope.unknown-path", args: { behavior: "deny" } }
440
+ : undefined;
441
+ case "briefing.mode.select": {
442
+ const mode = selected.replace(/^Note mode: /, "");
443
+ return (REVIEW_NOTE_MODES as readonly string[]).includes(mode)
444
+ ? { id: "briefing.mode", args: { mode } }
445
+ : undefined;
446
+ }
447
+ case "gated-tools.add":
448
+ return { id: "gated-tools.add", args: { toolName: selected } };
449
+ default:
450
+ return undefined;
451
+ }
452
+ }
453
+
454
+ function modeLabel(mode: ClearanceMode): string {
455
+ return mode[0]?.toUpperCase() + mode.slice(1);
456
+ }
457
+
458
+ function activeToolNames(metadata: {
459
+ readonly activeToolNames: readonly string[];
460
+ readonly allToolNames: readonly string[];
461
+ }): readonly string[] {
462
+ return metadata.activeToolNames.length > 0
463
+ ? metadata.activeToolNames
464
+ : metadata.allToolNames;
465
+ }
466
+
239
467
  type MaterializedSettingsChange =
240
468
  | { readonly ok: true; readonly kind: "mode"; readonly mode: ClearanceMode }
469
+ | {
470
+ readonly ok: true;
471
+ readonly kind: "gated-tools";
472
+ readonly change: GatedToolCommandChange;
473
+ }
241
474
  | {
242
475
  readonly ok: true;
243
476
  readonly kind: "reviewer";
@@ -266,6 +499,41 @@ function materializeSettingsAction(
266
499
  }
267
500
  return { ok: true, kind: "mode", mode };
268
501
  }
502
+ case "gated-tools.add":
503
+ case "gated-tools.remove": {
504
+ const toolName = stringArg(action, "toolName");
505
+ if (toolName === undefined) {
506
+ return invalidArg(action, "toolName", "an exact non-Bash tool name");
507
+ }
508
+ return {
509
+ ok: true,
510
+ kind: "gated-tools",
511
+ change: {
512
+ kind: action.id === "gated-tools.add" ? "add" : "remove",
513
+ toolName,
514
+ },
515
+ };
516
+ }
517
+ case "reviewer.posture.set": {
518
+ const promptPosture = stringArg(action, "promptPosture");
519
+ if (
520
+ promptPosture === undefined ||
521
+ !isShippedReviewerPostureId(promptPosture)
522
+ ) {
523
+ return invalidArg(
524
+ action,
525
+ "promptPosture",
526
+ SHIPPED_REVIEWER_POSTURE_OPTIONS.map((option) => option.id).join(
527
+ ", ",
528
+ ),
529
+ );
530
+ }
531
+ return {
532
+ ok: true,
533
+ kind: "reviewer",
534
+ change: { kind: "prompt-posture", promptPosture },
535
+ };
536
+ }
269
537
  case "reviewer.model": {
270
538
  const model = nullableStringArg(action, "model");
271
539
  if (!model.ok) return { ok: false, reason: model.reason };
@@ -383,6 +651,11 @@ function materializeSettingsAction(
383
651
  change: { kind: "accent", enabled },
384
652
  };
385
653
  }
654
+ case "mode.select":
655
+ case "reviewer.posture.select":
656
+ case "scope.preset.select":
657
+ case "scope.unknown-path.select":
658
+ case "briefing.mode.select":
386
659
  case "reviewer.open":
387
660
  case "scope.open":
388
661
  case "packs.open":
@@ -0,0 +1,52 @@
1
+ import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
+
3
+ import type { ReviewerModelRegistry } from "../../reviewer-model.ts";
4
+
5
+ export interface ReviewerModelOption {
6
+ /** Canonical provider/modelId spec written to config. */
7
+ readonly spec: string;
8
+ /** Human-facing label shown by Pi's selector. */
9
+ readonly label: string;
10
+ }
11
+
12
+ export const ACTIVE_SESSION_MODEL_LABEL = "Use active session model" as const;
13
+ export const REVIEWER_MODEL_OPTION_LIMIT = 12;
14
+
15
+ /**
16
+ * Return the same capped, auth-filtered model catalog for both read models and
17
+ * selector dispatch. Keeping the spec beside its label avoids rebuilding a
18
+ * potentially different provider/model mapping at the point of selection.
19
+ */
20
+ export function availableReviewerModels(
21
+ ctx: ExtensionCommandContext,
22
+ ): readonly ReviewerModelOption[] {
23
+ const registry = (ctx as { readonly modelRegistry?: unknown })
24
+ .modelRegistry as ReviewerModelRegistry | undefined;
25
+ if (
26
+ registry === undefined ||
27
+ typeof registry.getAll !== "function" ||
28
+ typeof registry.hasConfiguredAuth !== "function"
29
+ ) {
30
+ return [];
31
+ }
32
+
33
+ try {
34
+ return registry
35
+ .getAll()
36
+ .filter((model) => registry.hasConfiguredAuth(model))
37
+ .map((model) => {
38
+ const spec = `${model.provider}/${model.id}`;
39
+ return {
40
+ spec,
41
+ label:
42
+ typeof model.name === "string" && model.name.length > 0
43
+ ? `${model.name} (${spec})`
44
+ : spec,
45
+ };
46
+ })
47
+ .sort((a, b) => a.spec.localeCompare(b.spec))
48
+ .slice(0, REVIEWER_MODEL_OPTION_LIMIT);
49
+ } catch {
50
+ return [];
51
+ }
52
+ }